diff --git a/Makefile b/Makefile
index 2d97754..d236816 100644
--- a/Makefile
+++ b/Makefile
@@ -9,6 +9,7 @@ DEFS += -DF_CPU=72000000UL
DEFS += -DSTM32F10X_MD
DEFS += -DARM_MATH_CM3
DEFS += -DUSE_STDPERIPH_DRIVER
+DEFS += -DST_DSPIN_6470H_DISCOVERY
LDSCRIPT = lib/cmsis/stm32_flash.ld
STARTUP_SCRIPT = lib/cmsis/startup_stm32f10x_md.s
diff --git a/f103.pro b/f103.pro
deleted file mode 100644
index bdfeca4..0000000
--- a/f103.pro
+++ /dev/null
@@ -1,147 +0,0 @@
-TEMPLATE = app
-CONFIG += console
-CONFIG -= app_bundle
-CONFIG -= qt
-
-INCLUDEPATH += \
- project \
- lib/spl/inc \
- lib/cmsis \
- lib/sbmp/library \
- /usr/arm-none-eabi/include \
- /usr/lib/gcc/arm-none-eabi/5.3.0/include/
-
-DEFINES += F_CPU=72000000UL \
- STM32F10X_MD \
- USE_STDPERIPH_DRIVER \
- __null=0 \
- __STATIC_INLINE="static inline" \
- __INLINE="inline" \
- __ASM=__asm \
- __CORTEX_M=3 \
- VERBOSE_LOGGING=1
-
-HEADERS += \
- lib/cmsis/core_cm3.h \
- lib/cmsis/stm32f10x.h \
- lib/sbmp/library/crc32.h \
- lib/sbmp/library/payload_builder.h \
- lib/sbmp/library/payload_parser.h \
- lib/sbmp/library/sbmp.h \
- lib/sbmp/library/sbmp_bulk.h \
- lib/sbmp/library/sbmp_checksum.h \
- lib/sbmp/library/sbmp_config.example.h \
- lib/sbmp/library/sbmp_datagram.h \
- lib/sbmp/library/sbmp_frame.h \
- lib/sbmp/library/sbmp_session.h \
- lib/sbmp/library/type_coerce.h \
- lib/spl/inc/misc.h \
- lib/spl/inc/stm32f10x_adc.h \
- lib/spl/inc/stm32f10x_bkp.h \
- lib/spl/inc/stm32f10x_can.h \
- lib/spl/inc/stm32f10x_cec.h \
- lib/spl/inc/stm32f10x_crc.h \
- lib/spl/inc/stm32f10x_dac.h \
- lib/spl/inc/stm32f10x_dbgmcu.h \
- lib/spl/inc/stm32f10x_dma.h \
- lib/spl/inc/stm32f10x_exti.h \
- lib/spl/inc/stm32f10x_flash.h \
- lib/spl/inc/stm32f10x_fsmc.h \
- lib/spl/inc/stm32f10x_gpio.h \
- lib/spl/inc/stm32f10x_i2c.h \
- lib/spl/inc/stm32f10x_iwdg.h \
- lib/spl/inc/stm32f10x_pwr.h \
- lib/spl/inc/stm32f10x_rcc.h \
- lib/spl/inc/stm32f10x_rtc.h \
- lib/spl/inc/stm32f10x_sdio.h \
- lib/spl/inc/stm32f10x_spi.h \
- lib/spl/inc/stm32f10x_tim.h \
- lib/spl/inc/stm32f10x_usart.h \
- lib/spl/inc/stm32f10x_wwdg.h \
- project/stm32f10x_conf.h \
- project/stm32f10x_it.h \
- project/system_stm32f10x.h \
- project/sbmp_config.h \
- project/com/com_fileio.h \
- project/com/com_iface.h \
- project/com/datalink.h \
- project/com/debug.h \
- project/com/iface_noop.h \
- project/com/iface_usart.h \
- project/utils/circbuf.h \
- project/utils/minmax.h \
- project/utils/timebase.h \
- project/colorled.h \
- project/malloc_safe.h \
- project/hw_init.h \
- project/utils/debounce.h \
- project/bus/event_handler.h \
- project/bus/event_queue.h \
- project/utils/str_utils.h \
- project/main.h \
- project/utils/matcher.h \
- project/utils/meanbuf.h \
- project/display.h
-
-SOURCES += \
- lib/cmsis/core_cm3.c \
- lib/sbmp/library/crc32.c \
- lib/sbmp/library/payload_builder.c \
- lib/sbmp/library/payload_parser.c \
- lib/sbmp/library/sbmp_bulk.c \
- lib/sbmp/library/sbmp_checksum.c \
- lib/sbmp/library/sbmp_datagram.c \
- lib/sbmp/library/sbmp_frame.c \
- lib/sbmp/library/sbmp_session.c \
- lib/spl/src/misc.c \
- lib/spl/src/stm32f10x_adc.c \
- lib/spl/src/stm32f10x_bkp.c \
- lib/spl/src/stm32f10x_can.c \
- lib/spl/src/stm32f10x_cec.c \
- lib/spl/src/stm32f10x_crc.c \
- lib/spl/src/stm32f10x_dac.c \
- lib/spl/src/stm32f10x_dbgmcu.c \
- lib/spl/src/stm32f10x_dma.c \
- lib/spl/src/stm32f10x_exti.c \
- lib/spl/src/stm32f10x_flash.c \
- lib/spl/src/stm32f10x_fsmc.c \
- lib/spl/src/stm32f10x_gpio.c \
- lib/spl/src/stm32f10x_i2c.c \
- lib/spl/src/stm32f10x_iwdg.c \
- lib/spl/src/stm32f10x_pwr.c \
- lib/spl/src/stm32f10x_rcc.c \
- lib/spl/src/stm32f10x_rtc.c \
- lib/spl/src/stm32f10x_sdio.c \
- lib/spl/src/stm32f10x_spi.c \
- lib/spl/src/stm32f10x_tim.c \
- lib/spl/src/stm32f10x_usart.c \
- lib/spl/src/stm32f10x_wwdg.c \
- project/main.c \
- project/stm32f10x_it.c \
- project/system_stm32f10x.c \
- project/com/com_fileio.c \
- project/com/com_iface.c \
- project/com/datalink.c \
- project/com/debug.c \
- project/com/iface_noop.c \
- project/com/iface_usart.c \
- project/utils/circbuf.c \
- project/utils/debounce.c \
- project/utils/timebase.c \
- project/colorled.c \
- project/hw_init.c \
- project/malloc_safe.c \
- project/spl_assert.c \
- project/syscalls.c \
- project/bus/event_handler.c \
- project/bus/event_queue.c \
- project/utils/str_utils.c \
- project/utils/matcher.c \
- project/utils/meanbuf.c \
- project/display.c
-
-DISTFILES += \
- style.astylerc \
- Makefile \
- lib/cmsis/startup_stm32f10x_md.s \
- lib/cmsis/stm32_flash.ld
diff --git a/f103.pro.user b/f103.pro.user
deleted file mode 100644
index 60c5465..0000000
--- a/f103.pro.user
+++ /dev/null
@@ -1,299 +0,0 @@
-
-
-
-
-
- EnvironmentId
- {dfe3cb4a-0f3e-4da9-9c52-5d2c464adafb}
-
-
- ProjectExplorer.Project.ActiveTarget
- 0
-
-
- ProjectExplorer.Project.EditorSettings
-
- true
- false
- true
-
- Cpp
-
- CppGlobal
-
-
-
- QmlJS
-
- QmlJSGlobal
-
-
- 2
- UTF-8
- false
- 4
- true
- 80
- true
- true
- 1
- true
- false
- 0
- true
- 0
- 8
- true
- 1
- true
- true
- true
- true
-
-
-
- ProjectExplorer.Project.PluginSettings
-
-
-
- 1
-
-
-
-
- ProjectExplorer.Project.Target.0
-
- STLINK
- STLINK
- {15262c8f-05de-48ee-9452-3d289b21ba3e}
- 0
- -1
- 0
-
- /home/ondra/devel/f103
-
-
- true
- Make
-
- Qt4ProjectManager.MakeStep
-
- -w
- -r
-
- false
- -B -j 4
-
-
- 1
- Build
-
- ProjectExplorer.BuildSteps.Build
-
-
-
- true
- Make
-
- Qt4ProjectManager.MakeStep
-
- -w
- -r
-
- true
- clean
-
-
- 1
- Clean
-
- ProjectExplorer.BuildSteps.Clean
-
- 2
- false
-
- Debug
- Main
- Qt4ProjectManager.Qt4BuildConfiguration
- 2
- true
-
- 1
- 0
-
-
- false
- 1000
-
- true
-
- false
- false
- false
- false
- true
- 0.01
- 10
- true
- 1
- 25
-
- 1
- true
- false
- true
- valgrind
-
- 0
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
-
- 2
-
- flash
- /usr/bin/make
- %{buildDir}
- Run /usr/bin/make
- make flash
- ProjectExplorer.CustomExecutableRunConfiguration
- 3768
- false
- true
- false
- false
- true
-
-
- false
- 1000
-
- true
-
- false
- false
- false
- false
- true
- 0.01
- 10
- true
- 1
- 25
-
- 1
- true
- false
- true
- valgrind
-
- 0
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
-
-
- f103 (via GDB server or hardware debugger)
-
- BareMetal/home/ondra/devel/f103/f103.pro
-
- f103.pro
- 3768
- false
- true
- false
- false
- true
-
-
- false
- 1000
-
- true
-
- false
- false
- false
- false
- true
- 0.01
- 10
- true
- 1
- 25
-
- 1
- true
- false
- true
- valgrind
-
- 0
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
-
- 2
-
-
- /home/ondra/devel/f103/main.elf
- /home/ondra/devel/f103
- Run /home/ondra/devel/f103/main.elf
-
- ProjectExplorer.CustomExecutableRunConfiguration
- 3768
- false
- true
- false
- false
- true
-
- 3
-
-
-
- ProjectExplorer.Project.TargetCount
- 1
-
-
- ProjectExplorer.Project.Updater.FileVersion
- 18
-
-
- Version
- 18
-
-
diff --git a/f105motor.pro b/f105motor.pro
new file mode 100644
index 0000000..b71ed25
--- /dev/null
+++ b/f105motor.pro
@@ -0,0 +1,149 @@
+TEMPLATE = app
+CONFIG += console
+CONFIG -= app_bundle
+CONFIG -= qt
+
+INCLUDEPATH += \
+ project \
+ lib/spl/inc \
+ lib/cmsis \
+ lib/sbmp/library \
+ /usr/arm-none-eabi/include \
+ /usr/lib/gcc/arm-none-eabi/5.3.0/include/
+
+DEFINES += F_CPU=72000000UL \
+ STM32F10X_MD \
+ USE_STDPERIPH_DRIVER \
+ __null=0 \
+ __STATIC_INLINE="static inline" \
+ __INLINE="inline" \
+ __ASM=__asm \
+ __CORTEX_M=3 \
+ VERBOSE_LOGGING=1 \
+ ST_DSPIN_6470H_DISCOVERY
+
+HEADERS += \
+ lib/cmsis/core_cm3.h \
+ lib/cmsis/stm32f10x.h \
+ lib/sbmp/library/crc32.h \
+ lib/sbmp/library/payload_builder.h \
+ lib/sbmp/library/payload_parser.h \
+ lib/sbmp/library/sbmp.h \
+ lib/sbmp/library/sbmp_bulk.h \
+ lib/sbmp/library/sbmp_checksum.h \
+ lib/sbmp/library/sbmp_config.example.h \
+ lib/sbmp/library/sbmp_datagram.h \
+ lib/sbmp/library/sbmp_frame.h \
+ lib/sbmp/library/sbmp_session.h \
+ lib/sbmp/library/type_coerce.h \
+ lib/spl/inc/misc.h \
+ lib/spl/inc/stm32f10x_adc.h \
+ lib/spl/inc/stm32f10x_bkp.h \
+ lib/spl/inc/stm32f10x_can.h \
+ lib/spl/inc/stm32f10x_cec.h \
+ lib/spl/inc/stm32f10x_crc.h \
+ lib/spl/inc/stm32f10x_dac.h \
+ lib/spl/inc/stm32f10x_dbgmcu.h \
+ lib/spl/inc/stm32f10x_dma.h \
+ lib/spl/inc/stm32f10x_exti.h \
+ lib/spl/inc/stm32f10x_flash.h \
+ lib/spl/inc/stm32f10x_fsmc.h \
+ lib/spl/inc/stm32f10x_gpio.h \
+ lib/spl/inc/stm32f10x_i2c.h \
+ lib/spl/inc/stm32f10x_iwdg.h \
+ lib/spl/inc/stm32f10x_pwr.h \
+ lib/spl/inc/stm32f10x_rcc.h \
+ lib/spl/inc/stm32f10x_rtc.h \
+ lib/spl/inc/stm32f10x_sdio.h \
+ lib/spl/inc/stm32f10x_spi.h \
+ lib/spl/inc/stm32f10x_tim.h \
+ lib/spl/inc/stm32f10x_usart.h \
+ lib/spl/inc/stm32f10x_wwdg.h \
+ project/stm32f10x_conf.h \
+ project/stm32f10x_it.h \
+ project/system_stm32f10x.h \
+ project/sbmp_config.h \
+ project/com/com_fileio.h \
+ project/com/com_iface.h \
+ project/com/datalink.h \
+ project/com/debug.h \
+ project/com/iface_noop.h \
+ project/com/iface_usart.h \
+ project/utils/circbuf.h \
+ project/utils/minmax.h \
+ project/utils/timebase.h \
+ project/malloc_safe.h \
+ project/hw_init.h \
+ project/utils/debounce.h \
+ project/bus/event_handler.h \
+ project/bus/event_queue.h \
+ project/utils/str_utils.h \
+ project/main.h \
+ project/utils/matcher.h \
+ project/utils/meanbuf.h \
+ project/dspin.h \
+ project/dspin_config.h \
+ project/blinky.h
+
+SOURCES += \
+ lib/cmsis/core_cm3.c \
+ lib/sbmp/library/crc32.c \
+ lib/sbmp/library/payload_builder.c \
+ lib/sbmp/library/payload_parser.c \
+ lib/sbmp/library/sbmp_bulk.c \
+ lib/sbmp/library/sbmp_checksum.c \
+ lib/sbmp/library/sbmp_datagram.c \
+ lib/sbmp/library/sbmp_frame.c \
+ lib/sbmp/library/sbmp_session.c \
+ lib/spl/src/misc.c \
+ lib/spl/src/stm32f10x_adc.c \
+ lib/spl/src/stm32f10x_bkp.c \
+ lib/spl/src/stm32f10x_can.c \
+ lib/spl/src/stm32f10x_cec.c \
+ lib/spl/src/stm32f10x_crc.c \
+ lib/spl/src/stm32f10x_dac.c \
+ lib/spl/src/stm32f10x_dbgmcu.c \
+ lib/spl/src/stm32f10x_dma.c \
+ lib/spl/src/stm32f10x_exti.c \
+ lib/spl/src/stm32f10x_flash.c \
+ lib/spl/src/stm32f10x_fsmc.c \
+ lib/spl/src/stm32f10x_gpio.c \
+ lib/spl/src/stm32f10x_i2c.c \
+ lib/spl/src/stm32f10x_iwdg.c \
+ lib/spl/src/stm32f10x_pwr.c \
+ lib/spl/src/stm32f10x_rcc.c \
+ lib/spl/src/stm32f10x_rtc.c \
+ lib/spl/src/stm32f10x_sdio.c \
+ lib/spl/src/stm32f10x_spi.c \
+ lib/spl/src/stm32f10x_tim.c \
+ lib/spl/src/stm32f10x_usart.c \
+ lib/spl/src/stm32f10x_wwdg.c \
+ project/main.c \
+ project/stm32f10x_it.c \
+ project/system_stm32f10x.c \
+ project/com/com_fileio.c \
+ project/com/com_iface.c \
+ project/com/datalink.c \
+ project/com/debug.c \
+ project/com/iface_noop.c \
+ project/com/iface_usart.c \
+ project/utils/circbuf.c \
+ project/utils/debounce.c \
+ project/utils/timebase.c \
+ project/hw_init.c \
+ project/malloc_safe.c \
+ project/spl_assert.c \
+ project/syscalls.c \
+ project/bus/event_handler.c \
+ project/bus/event_queue.c \
+ project/utils/str_utils.c \
+ project/utils/matcher.c \
+ project/utils/meanbuf.c \
+ project/dspin.c \
+ project/blinky.c
+
+DISTFILES += \
+ style.astylerc \
+ Makefile \
+ lib/cmsis/startup_stm32f10x_md.s \
+ lib/cmsis/stm32_flash.ld
diff --git a/project/blinky.c b/project/blinky.c
new file mode 100644
index 0000000..d1b68ca
--- /dev/null
+++ b/project/blinky.c
@@ -0,0 +1,53 @@
+#include "main.h"
+#include "utils/timebase.h"
+#include "blinky.h"
+#include "dspin.h"
+
+typedef struct {
+ GPIO_TypeDef* GPIOx;
+ uint32_t pin;
+ task_pid_t blink_task;
+} LedInfo;
+
+static LedInfo leds[4] = {
+ {GPIOC, GPIO_Pin_3, 0}, // LED_READY
+ {GPIOC, GPIO_Pin_2, 0}, // LED_BUSY
+ {GPIOC, GPIO_Pin_1, 0}, // LED_ERROR
+ {GPIOC, GPIO_Pin_0, 0}, // LED_SPARE
+};
+
+void led_on(enum led_nr led)
+{
+ leds[led].GPIOx->BSRR = leds[led].pin;
+}
+
+void led_off(enum led_nr led)
+{
+ leds[led].GPIOx->BRR = leds[led].pin;
+}
+
+void led_toggle(enum led_nr led)
+{
+ leds[led].GPIOx->ODR ^= leds[led].pin;
+}
+
+static void led_off_cb(void *arg)
+{
+ enum led_nr led = (uint32_t)arg;
+
+ led_off(led);
+ leds[led].blink_task = 0;
+}
+
+void led_blink(enum led_nr led, ms_time_t ms)
+{
+ LedInfo *L = &leds[led];
+
+ if (L->blink_task) {
+ // re-schedule
+ abort_scheduled_task(L->blink_task);
+ }
+
+ led_on(led);
+ L->blink_task = schedule_task(led_off_cb, (uint32_t*)led, ms, false);
+}
diff --git a/project/blinky.h b/project/blinky.h
new file mode 100644
index 0000000..7bf4e46
--- /dev/null
+++ b/project/blinky.h
@@ -0,0 +1,17 @@
+#ifndef BLINKY_H
+#define BLINKY_H
+#include "utils/timebase.h"
+
+enum led_nr {
+ LED_READY,
+ LED_BUSY,
+ LED_ERROR,
+ LED_SPARE
+};
+
+void led_on(enum led_nr led);
+void led_off(enum led_nr led);
+void led_toggle(enum led_nr led);
+void led_blink(enum led_nr led, ms_time_t ms);
+
+#endif // BLINKY_H
diff --git a/project/colorled.c b/project/colorled.c
deleted file mode 100644
index 43e648b..0000000
--- a/project/colorled.c
+++ /dev/null
@@ -1,66 +0,0 @@
-#include "colorled.h"
-#include "utils/timebase.h"
-
-#define LONG_DELAY() for (volatile uint32_t __j = 4; __j > 0; __j--)
-#define SHORT_DELAY() for (volatile uint32_t __j = 1; __j > 0; __j--)
-
-static inline
-__attribute__((always_inline))
-void colorled_byte(uint8_t b)
-{
- for (register volatile uint8_t i = 0; i < 8; i++) {
- COLORLED_GPIO->BSRR = COLORLED_PIN; // set pin high
-
- // duty cycle determines bit value
- if (b & 0x80) {
- LONG_DELAY();
- COLORLED_GPIO->BRR = COLORLED_PIN; // set pin low
- SHORT_DELAY();
- } else {
- SHORT_DELAY();
- COLORLED_GPIO->BRR = COLORLED_PIN; // set pin low
- LONG_DELAY();
- }
-
- b <<= 1; // shift to next bit
- }
-}
-
-
-/** Set one RGB LED color */
-void colorled_set(uint32_t rgb)
-{
- __disable_irq(); // SysTick interrupt when sending data would break the timing
-
- colorled_byte((rgb & 0x00FF00) >> 8);
- colorled_byte((rgb & 0xFF0000) >> 16);
- colorled_byte(rgb & 0x0000FF);
-
- __enable_irq();
-
- delay_us(50); // show
-}
-
-
-/** Set many RGBs */
-void colorled_set_many(uint32_t *rgbs, int count)
-{
- __disable_irq();
-
- for (int i = 0; i < count; i++) {
- uint32_t rgb = *rgbs++;
- colorled_byte((rgb & 0x00FF00) >> 8);
- colorled_byte((rgb & 0xFF0000) >> 16);
- colorled_byte(rgb & 0x0000FF);
- }
-
- __enable_irq();
-
- delay_us(50); // show
-}
-
-
-void colorled_off(void)
-{
- colorled_set(RGB_BLACK);
-}
diff --git a/project/colorled.h b/project/colorled.h
deleted file mode 100644
index 5c36eb0..0000000
--- a/project/colorled.h
+++ /dev/null
@@ -1,79 +0,0 @@
-#pragma once
-
-/* Includes ------------------------------------------------------------------*/
-
-#include "main.h"
-
-/* Exported types ------------------------------------------------------------*/
-/* Exported constants --------------------------------------------------------*/
-
-// PB8 - WS2812B data line
-#define COLORLED_GPIO GPIOB
-#define COLORLED_PIN GPIO_Pin_12
-
-#define RGB_RED rgb(255, 0, 0)
-#define RGB_ORANGE rgb(255, 110, 0)
-#define RGB_YELLOW rgb(255, 255, 0)
-#define RGB_LIME rgb(160, 255, 0)
-#define RGB_GREEN rgb( 0, 255, 0)
-#define RGB_CYAN rgb( 0, 255, 120)
-#define RGB_BLUE rgb( 0, 0, 255)
-#define RGB_MAGENTA rgb(255, 0, 255)
-#define RGB_WHITE rgb(255, 255, 255)
-#define RGB_BLACK rgb( 0, 0, 0)
-
-/**
- * @brief Struct for easy manipulation of RGB colors.
- *
- * Set components in the xrgb.r (etc.) and you will get
- * the hex in xrgb.num.
- */
-typedef union {
-
- /** Struct for access to individual color components */
- struct __attribute__((packed)) {
- uint8_t b;
- uint8_t g;
- uint8_t r;
- };
-
- /** RGB color as a single uint32_t */
- uint32_t num;
-
-} ws2812_rgb_t;
-
-/* Exported macros -----------------------------------------------------------*/
-
-/**
- * @brief Compose an RGB color.
- * @param r, g, b - components 0xFF
- * @returns integer 0xRRGGBB
- */
-#define rgb(r, g, b) (((0xFF & (r)) << 16) | ((0xFF & (g)) << 8) | (0xFF & (b)))
-
-/* Get components */
-#define rgb_r(rgb) (((rgb) >> 16) & 0xFF)
-#define rgb_g(rgb) (((rgb) >> 8) & 0xFF)
-#define rgb_b(rgb) ((rgb) & 0xFF)
-
-/* Exported functions --------------------------------------------------------*/
-
-/**
- * @brief Turn OFF the rgb LED
- */
-void colorled_off(void);
-
-
-/**
- * @brief Set color of a WS2812B
- * @param rgb - color 0xRRGGBB
- */
-void colorled_set(uint32_t rgb);
-
-
-/**
- * @brief Set color of multiple chained RGB leds
- * @param rgbs - array of colors (0xRRGGBB)
- * @param count - number of LEDs
- */
-void colorled_set_many(uint32_t *rgbs, int count);
diff --git a/project/com/com_fileio.c b/project/com/com_fileio.c
index c6cfd9c..2302185 100644
--- a/project/com/com_fileio.c
+++ b/project/com/com_fileio.c
@@ -20,7 +20,7 @@ struct name_fd {
/** pre-assigned file descriptors for names */
static const struct name_fd name_fd_map[NAME_FD_MAP_LEN] = {
- {FNAME_DLNK, FD_DLNK}
+// {FNAME_DLNK, FD_DLNK}
};
@@ -39,7 +39,6 @@ int _write(int fd, const char *buf, int len)
switch (fd) {
case FD_STDOUT: return (int)com_tx_block(debug_iface, buf, (size_t)len);
case FD_STDERR: return (int)com_tx_block(debug_iface, buf, (size_t)len);
- case FD_DLNK: return (int)com_tx_block(data_iface, buf, (size_t)len);
default:
return 0;
}
diff --git a/project/com/com_fileio.h b/project/com/com_fileio.h
index f1159ec..04bcb82 100644
--- a/project/com/com_fileio.h
+++ b/project/com/com_fileio.h
@@ -17,7 +17,4 @@ enum {
FD_STDIN = 0,
FD_STDOUT = 1,
FD_STDERR = 2,
- FD_DLNK = 3,
};
-
-#define FNAME_DLNK "dlnk"
diff --git a/project/com/datalink.c b/project/com/datalink.c
index 8c35417..474b4f5 100644
--- a/project/com/datalink.c
+++ b/project/com/datalink.c
@@ -2,6 +2,7 @@
#include "com_fileio.h"
#include "debug.h"
#include "com_fileio.h"
+#include "dspin.h"
SBMP_Endpoint *dlnk_ep;
@@ -30,6 +31,9 @@ void dlnk_init(void)
static void dlnk_rx_bridge(ComIface *iface)
{
uint8_t b;
+
+ STATUS_LED_Port->BSRR = STATUS_LED_Pin;
+
while (com_rx(iface, &b)) {
SBMP_RxStatus st = sbmp_ep_receive(dlnk_ep, b);
@@ -39,6 +43,8 @@ static void dlnk_rx_bridge(ComIface *iface)
break;
}
}
+
+ STATUS_LED_Port->BRR = STATUS_LED_Pin;
}
/** Datalink Tx func */
diff --git a/project/com/datalink.h b/project/com/datalink.h
index a09f259..5c49807 100644
--- a/project/com/datalink.h
+++ b/project/com/datalink.h
@@ -7,15 +7,14 @@
#include "main.h"
#include
-#define DG_REQUEST_RAW 40 // request raw vector. Sample count [u16], Frequency [u32]
-#define DG_REQUEST_FFT 41 // request fft vector. Sample count [u16], Frequency [u32]. Result - count/2 bins. Count must be 2^n, 16..2048
-#define DG_REQUEST_STORE_REF 42 // calculate signal signature & store for comparing
-#define DG_REQUEST_COMPARE_REF 43
+#define DG_MOTOR_HOME 40
+#define DG_MOTOR_GOTO 41
+
// wifi status & control
#define DG_SETMODE_AP 44 // request AP mode (AP button pressed)
#define DG_WPS_START 45 // start WPS
-#define DG_WIFI_STATUS 46 // WiFi status report
-#define DG_REQUEST_STM_VERSION 47 // Get acquisition module firmware version
+#define DG_WIFI_STATUS 46 // WiFi status report (sent by the ESP every second)
+#define DG_REQUEST_STM_VERSION 47 // Get STM32 module firmware version
extern SBMP_Endpoint *dlnk_ep;
diff --git a/project/com/debug.h b/project/com/debug.h
index 7f97d2f..a384ea5 100644
--- a/project/com/debug.h
+++ b/project/com/debug.h
@@ -13,6 +13,8 @@
#define ESCAPE_DEBUG_MESSAGES 1
+#define VERBOSE_LOGGING 1
+
// formatting symbols
#define DEBUG_EOL "\r\n"
diff --git a/project/com/iface_noop.c b/project/com/iface_noop.c
index 4c69415..9e04e9d 100644
--- a/project/com/iface_noop.c
+++ b/project/com/iface_noop.c
@@ -66,7 +66,7 @@ static void if_poll(ComIface *iface)
(void)iface;
}
-ComIface *com_noop_init(void)
+ComIface *noop_iface_init(void)
{
ComIface *iface = malloc_s(sizeof(ComIface));
diff --git a/project/com/iface_noop.h b/project/com/iface_noop.h
index 08819ac..2320a56 100644
--- a/project/com/iface_noop.h
+++ b/project/com/iface_noop.h
@@ -11,4 +11,4 @@
* @param iface : iface pointer. If NULL, it'll be allocated.
* @return the iface pointer.
*/
-ComIface *com_noop_init(void);
+ComIface *noop_iface_init(void);
diff --git a/project/display.c b/project/display.c
deleted file mode 100644
index c45b092..0000000
--- a/project/display.c
+++ /dev/null
@@ -1,120 +0,0 @@
-#include "display.h"
-#include "com/debug.h"
-#include "utils/timebase.h"
-#include "utils/meanbuf.h"
-
-#include
-
-#define PIXEL_COUNT 30
-
-#define WAVEGRID_DEPTH 5
-#define WAVEGRID_LEN PIXEL_COUNT*WAVEGRID_DEPTH
-static float wavegrid[WAVEGRID_LEN];
-
-#define WAVE_DISSIPATION 0.011f
-
-
-static ws2812_rgb_t pixels[PIXEL_COUNT] = {};
-
-static MeanBuf *mb;
-
-void display_show(void)
-{
- for (int i = 0; i < PIXEL_COUNT; i++) {
-
- // 0 1 2 3 #0+i
- // 7 6 5 4 #2-i-1
- // 8 9 A B #2+i
- // F E D C #
- // G I J K
-
- float x = wavegrid[i] +
- wavegrid[PIXEL_COUNT*2-i-1] +
- wavegrid[PIXEL_COUNT*2+i] +
- wavegrid[PIXEL_COUNT*4-i-1] +
- wavegrid[PIXEL_COUNT*4+i];
-
- if (x > 255) x = 255;
-
- pixels[i].r = (x);
- pixels[i].b = (255.0f-x);
- }
-
- colorled_set_many((uint32_t*) pixels, PIXEL_COUNT);
-}
-
-
-static void handle_sonar_value(float mm)
-{
- for (int i = WAVEGRID_LEN-1; i > 0; i--) {
- wavegrid[i] = wavegrid[i-1] * (1.0f - WAVE_DISSIPATION);
- }
-
- float x = mm/5.0f;
- if (x>255) x = 255;
-
- wavegrid[0] = 255 - x;
-
- display_show();
-}
-
-
-static void show(void*arg)
-{
- (void)arg;
-
- handle_sonar_value(meanbuf_current(mb));
-}
-
-
-static void sonar(void* arg)
-{
- (void)arg;
-
- //info("Sonar");
-
- GPIOB->BSRR = GPIO_Pin_13;
- delay_us(10);
- GPIOB->BRR = GPIO_Pin_13;
-
- // wait for response
-
- bool suc = false;
- until_timeout(50) {
- if((GPIOB->IDR & (1 << 14)) != 0) {
- suc = true;
- break;
- }
- }
-
- if (!suc) {
- dbg("Not suc");
- return;
- }
-
- uint32_t cnt = 0;
- until_timeout(50) {
- if((GPIOB->IDR & (1 << 14)) == 0) break;
- cnt++;
- }
-
- float t = cnt / 11.2f;
-
- meanbuf_add(mb, t);
-}
-
-
-void display_init(void)
-{
- mb = meanbuf_create(10);
-
- for (int i = 0; i < WAVEGRID_LEN; i++) {
- wavegrid[i] = 0;
- }
-
- display_show();
-
- add_periodic_task(sonar, NULL, 50, true);
-
- add_periodic_task(show, NULL, 75, true);
-}
diff --git a/project/display.h b/project/display.h
deleted file mode 100644
index a60afb5..0000000
--- a/project/display.h
+++ /dev/null
@@ -1,11 +0,0 @@
-#ifndef DISPLAY_H
-#define DISPLAY_H
-
-#include "main.h"
-#include "colorled.h"
-
-void display_show(void);
-
-void display_init(void);
-
-#endif // DISPLAY_H
diff --git a/project/dspin.c b/project/dspin.c
new file mode 100644
index 0000000..1381243
--- /dev/null
+++ b/project/dspin.c
@@ -0,0 +1,1472 @@
+/**
+ ******************************************************************************
+ * @file dspin.c
+ * @author IPC Rennes
+ * @version V2.0
+ * @date October 4, 2013
+ * @brief dSPIN (L6470 and L6472) product related routines
+ * @note (C) COPYRIGHT 2013 STMicroelectronics
+ ******************************************************************************
+ * @copy
+ *
+ * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+ * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+ * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+ * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+ * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+ * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+ *
+ * © COPYRIGHT 2013 STMicroelectronics
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "dspin.h"
+#include "dspin_config.h"
+#include "stm32f10x_spi.h"
+
+/** @addtogroup dSPIN FW library interface
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+
+/* Private variables ---------------------------------------------------------*/
+static GPIO_InitTypeDef GPIO_InitStructure;
+static SPI_InitTypeDef SPI_InitStructure;
+static uint8_t spiTxBursts[dSPIN_CMD_ARG_MAX_NB_BYTES][NUMBER_OF_SLAVES];
+static uint8_t spiRxBursts[dSPIN_CMD_ARG_MAX_NB_BYTES][NUMBER_OF_SLAVES];
+static uint8_t arrayTxBytes[NUMBER_OF_SLAVES];
+static uint32_t arrayValues[NUMBER_OF_SLAVES];
+
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/**
+ * @brief Inserts a delay time.
+ * @param nCount specifies the delay time length.
+ * @retval None
+ */
+void dSPIN_Delay(__IO uint32_t nCount)
+{
+ for (; nCount != 0; nCount--);
+}
+
+/**
+ * @brief Resets DSPIN and puts it into standby mode
+ * @param None
+ * @retval None
+ */
+void dSPIN_Reset_And_Standby(void)
+{
+#if (defined(STEVAL_PCC009V2) || defined(ST_DSPIN_6470H_DISCOVERY))
+ GPIO_ResetBits(dSPIN_STBY_RESET_Port, dSPIN_STBY_RESET_Pin);
+ dSPIN_Delay(10000);
+ GPIO_SetBits(dSPIN_STBY_RESET_Port, dSPIN_STBY_RESET_Pin);
+#endif /* (defined(STEVAL_PCC009V2) || defined(ST_DSPIN_6470H_DISCOVERY)) */
+}
+
+/**
+ * @brief Toggles a GPIO output
+ * @param GPIOx gpio port
+ * @param GPIO_Pin pin number of the Gpio to toggle
+ * @retval None
+ */
+void dSPIN_Gpio_Toggle(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
+{
+ if (GPIO_ReadOutputDataBit(GPIOx, GPIO_Pin) != Bit_RESET) {
+ GPIO_ResetBits(GPIOx, GPIO_Pin);
+ } else {
+ GPIO_SetBits(GPIOx, GPIO_Pin);
+ }
+}
+
+/**
+ * @brief Initializes uC peripherals, GPIOs, clocks, interrupts channels used by dSPIN.
+ * @param None
+ * @retval None
+ */
+void dSPIN_Peripherals_Init(void)
+{
+ /* Used peripherals clock enable -------------------------------------------*/
+ RCC_APB1PeriphClockCmd(dSPIN_PERIPHERAL_CLKs_APB1, ENABLE);
+ RCC_APB2PeriphClockCmd(dSPIN_PERIPHERAL_CLKs_APB2, ENABLE);
+
+ /* Configure pins used by dSPIN --------------------------------------------*/
+#if (defined(STEVAL_PCC009V2) || defined(ST_DSPIN_6470H_DISCOVERY))
+ /* Configure on-board power LED ------------------------------------------*/
+ GPIO_InitStructure.GPIO_Pin = POWER_LED_Pin;
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
+ GPIO_Init(POWER_LED_Port, &GPIO_InitStructure);
+// GPIO_SetBits(POWER_LED_Port, POWER_LED_Pin);
+ /* Configure on-board status LED -----------------------------------------*/
+ GPIO_InitStructure.GPIO_Pin = STATUS_LED_Pin;
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
+ GPIO_Init(STATUS_LED_Port, &GPIO_InitStructure);
+ /* Configure STBY_RESET GPIO connected to dSPIN STBY_RESET pin*/
+ GPIO_InitStructure.GPIO_Pin = dSPIN_STBY_RESET_Pin;
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
+ GPIO_Init(dSPIN_STBY_RESET_Port, &GPIO_InitStructure);
+#endif /* (defined(STEVAL_PCC009V2) || defined(ST_DSPIN_6470H_DISCOVERY)) */
+#ifdef STEVAL_PCC009V2 /* Only if PCC009V2 evalboard is used ---------------*/
+ /* Configure Port C GPIO pin 2 connected to keypad button "*" */
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
+ GPIO_Init(GPIOC, &GPIO_InitStructure);
+ /* Configure Port C GPIO pin 3 connected to keypad button "7" */
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
+ GPIO_Init(GPIOC, &GPIO_InitStructure);
+ /* Configure Port C GPIO pin 6 connected to keypad button "4" */
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
+ GPIO_Init(GPIOC, &GPIO_InitStructure);
+#endif /* STEVAL_PCC009V2 */
+#ifdef ST_DSPIN_6470H_DISCOVERY /* Only if DISCOVERY board is used -----------*/
+ /* Configure on-board busy LED -----------------------------------------*/
+ GPIO_InitStructure.GPIO_Pin = LED_BUSY_Pin;
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
+ GPIO_Init(LED_BUSY_Port, &GPIO_InitStructure);
+ /* Configure on-board spare LED --------------------------------------------*/
+ GPIO_InitStructure.GPIO_Pin = LED_SPARE_Pin;
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
+ GPIO_Init(LED_SPARE_Port, &GPIO_InitStructure);
+ /* Configure GPIO connected to S1 button via BUTTON_A wire */
+ GPIO_InitStructure.GPIO_Pin = BUTTON_A_Pin;
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
+ GPIO_Init(BUTTON_A_Port, &GPIO_InitStructure);
+ /* Configure GPIO connected to S3 button via BUTTON_B wire */
+ GPIO_InitStructure.GPIO_Pin = BUTTON_B_Pin;
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
+ GPIO_Init(BUTTON_B_Port, &GPIO_InitStructure);
+ /* Configure SW_MOTOR GPIO connected to J8 jumper */
+ GPIO_InitStructure.GPIO_Pin = SW_MOTOR_Pin;
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
+ GPIO_Init(SW_MOTOR_Port, &GPIO_InitStructure);
+ /* Configure SW GPIO connected to dSPIN SW pin*/
+ GPIO_InitStructure.GPIO_Pin = dSPIN_SW_Pin;
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
+ GPIO_Init(dSPIN_SW_Port, &GPIO_InitStructure);
+ GPIO_SetBits(dSPIN_SW_Port, dSPIN_SW_Pin);
+#endif /* ST_DSPIN_6470H_DISCOVERY */
+
+ /* Configure SPI pin: SCK --------------------------------------------------*/
+ GPIO_InitStructure.GPIO_Pin = dSPIN_SCK_Pin;
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
+ GPIO_Init(dSPIN_SCK_Port, &GPIO_InitStructure);
+
+ /* Configure SPI pin: MOSI -------------------------------------------------*/
+ GPIO_InitStructure.GPIO_Pin = dSPIN_MOSI_Pin;
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
+ GPIO_Init(dSPIN_MOSI_Port, &GPIO_InitStructure);
+
+ /* Configure SPI pin: nSS --------------------------------------------------*/
+ GPIO_InitStructure.GPIO_Pin = dSPIN_nSS_Pin;
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
+ GPIO_Init(dSPIN_nSS_Port, &GPIO_InitStructure);
+
+ /* Configure SPI pin: MISO -------------------------------------------------*/
+ GPIO_InitStructure.GPIO_Pin = dSPIN_MISO_Pin;
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
+ GPIO_Init(dSPIN_MISO_Port, &GPIO_InitStructure);
+
+ /* Configure dSPIN - Busy pin ----------------------------------------------*/
+ GPIO_InitStructure.GPIO_Pin = dSPIN_BUSY_Pin;
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
+ GPIO_Init(dSPIN_BUSY_Port, &GPIO_InitStructure);
+
+ /* Configure dSPIN - Flag pin ----------------------------------------------*/
+ GPIO_InitStructure.GPIO_Pin = dSPIN_FLAG_Pin;
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
+ GPIO_Init(dSPIN_FLAG_Port, &GPIO_InitStructure);
+
+ /* Configure PWM connected to dSPin STCK -----------------------------------*/
+ GPIO_InitStructure.GPIO_Pin = dSPIN_PWM1_Pin;
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
+ GPIO_Init(dSPIN_PWM1_Port, &GPIO_InitStructure);
+
+ /* SPI configuration ------------------------------------------------------*/
+ SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
+ SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
+ SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
+ SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
+ SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
+ SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
+ SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16;
+ SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
+ SPI_InitStructure.SPI_CRCPolynomial = 7;
+ SPI_Init(dSPIN_SPI, &SPI_InitStructure);
+
+ /* Enable SPI */
+ SPI_Cmd(dSPIN_SPI, ENABLE);
+
+ /* Interrupt Channel configuration and enable */
+ dSPIN_Interrupt_Channel_Config();
+
+}
+
+/**
+ * @brief Interrupt channel configuration and enable
+ * @param None
+ * @retval None
+ */
+void dSPIN_Interrupt_Channel_Config(void)
+{
+
+ NVIC_InitTypeDef NVIC_InitStructure;
+#if (defined(STEVAL_PCC009V2) || defined(ST_DSPIN_6470H_DISCOVERY))
+ NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;
+ NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
+ NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
+ NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
+ NVIC_Init(&NVIC_InitStructure);
+
+ NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;
+ NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
+ NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
+ NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
+ NVIC_Init(&NVIC_InitStructure);
+#endif /* (defined(STEVAL_PCC009V2) || defined(ST_DSPIN_6470H_DISCOVERY)) */
+#if defined(STEVAL_PCC009V2)
+ NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn;
+ NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
+ NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
+ NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
+ NVIC_Init(&NVIC_InitStructure);
+
+ NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;
+ NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
+ NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
+ NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
+ NVIC_Init(&NVIC_InitStructure);
+#endif /* defined(STEVAL_PCC009V2) */
+#if defined(ST_DSPIN_6470H_DISCOVERY)
+ NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
+ NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
+ NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
+ NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
+ NVIC_Init(&NVIC_InitStructure);
+
+ NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;
+ NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
+ NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
+ NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
+ NVIC_Init(&NVIC_InitStructure);
+#endif /* defined(ST_DSPIN_6470H_DISCOVERY) */
+
+}
+
+/**
+ * @brief Led On and Off
+ * @param None
+ * @retval None
+ */
+void dSPIN_Led_Check(void)
+{
+#ifdef STEVAL_PCC009V2 /* Only if PCC009V2 evalboard is used ---------------*/
+ dSPIN_Delay(0x00100000);
+ GPIO_SetBits(STATUS_LED_Port, STATUS_LED_Pin);
+ dSPIN_Delay(0x00100000);
+ GPIO_ResetBits(STATUS_LED_Port, STATUS_LED_Pin);
+ dSPIN_Delay(0x00100000);
+#endif /* STEVAL_PCC009V2 */
+#ifdef ST_DSPIN_6470H_DISCOVERY /* Only if DISCOVERY board is used -----------*/
+ dSPIN_Delay(0x00100000);
+ GPIO_SetBits(STATUS_LED_Port, STATUS_LED_Pin);
+ dSPIN_Delay(0x00100000);
+ GPIO_SetBits(LED_BUSY_Port, LED_BUSY_Pin);
+ dSPIN_Delay(0x00100000);
+ GPIO_SetBits(LED_SPARE_Port, LED_SPARE_Pin);
+ dSPIN_Delay(0x00100000);
+ GPIO_ResetBits(STATUS_LED_Port, STATUS_LED_Pin);
+ GPIO_ResetBits(LED_BUSY_Port, LED_BUSY_Pin);
+ GPIO_ResetBits(LED_SPARE_Port, LED_SPARE_Pin);
+ dSPIN_Delay(0x00100000);
+#endif /* ST_DSPIN_6470H_DISCOVERY */
+}
+
+/**
+ * @brief GPIO config to manage FLAG signal as an interrupt
+ * @param None
+ * @retval None
+ */
+void dSPIN_Flag_Interrupt_GPIO_Config(void)
+{
+ EXTI_InitTypeDef EXTI_InitStructure;
+
+#if defined(STEVAL_PCC009V2)
+ /* Selects the GPIO pin 11 to be used as an EXTI Line */
+ /* STM32F10X PB11 pin connected to L6470 FLAG pin */
+ GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource11);
+
+ /* Configure EXTI Line11 to generate an interrupt on rising and falling edge */
+ EXTI_InitStructure.EXTI_Line = EXTI_Line11;
+ EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
+ EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
+ EXTI_InitStructure.EXTI_LineCmd = ENABLE;
+ EXTI_Init(&EXTI_InitStructure);
+ EXTI_ClearITPendingBit(EXTI_Line11);
+#endif /* defined(STEVAL_PCC009V2) */
+#if defined(ST_DSPIN_6470H_DISCOVERY)
+ /* Selects the GPIO pin 10 to be used as an EXTI Line */
+ /* STM32F10X PB10 pin connected to L6470 BUSY\SYNC pin */
+ GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource10);
+
+ /* Configure EXTI Line10 to generate an interrupt on falling edge */
+ EXTI_InitStructure.EXTI_Line = EXTI_Line10;
+ EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
+ EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
+ EXTI_InitStructure.EXTI_LineCmd = ENABLE;
+ EXTI_Init(&EXTI_InitStructure);
+ EXTI_ClearITPendingBit(EXTI_Line10);
+#endif /* defined(ST_DSPIN_6470H_DISCOVERY) */
+}
+
+/**
+ * @brief GPIO config to manage BUSY signal as an interrupt
+ * @param None
+ * @retval None
+ */
+void dSPIN_Busy_Interrupt_GPIO_Config(void)
+{
+ EXTI_InitTypeDef EXTI_InitStructure;
+
+#if defined(STEVAL_PCC009V2)
+ /* Selects the GPIO pin 10 to be used as an EXTI Line */
+ /* STM32F10X PB10 pin connected to L6470 BUSY\SYNC pin */
+ GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource10);
+
+ /* Configure EXTI Line10 to generate an interrupt on falling edge */
+ EXTI_InitStructure.EXTI_Line = EXTI_Line10;
+ EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
+ EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
+ EXTI_InitStructure.EXTI_LineCmd = ENABLE;
+ EXTI_Init(&EXTI_InitStructure);
+ EXTI_ClearITPendingBit(EXTI_Line10);
+#endif /* defined(STEVAL_PCC009V2) */
+#if defined(ST_DSPIN_6470H_DISCOVERY)
+ /* Selects the GPIO pin 11 to be used as an EXTI Line */
+ /* STM32F10X PB11 pin connected to L6470 BUSY\SYNC pin */
+ GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource11);
+
+ /* Configure EXTI Line11 to generate an interrupt on rising and falling edge */
+ EXTI_InitStructure.EXTI_Line = EXTI_Line11;
+ EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
+ EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
+ EXTI_InitStructure.EXTI_LineCmd = ENABLE;
+ EXTI_Init(&EXTI_InitStructure);
+ EXTI_ClearITPendingBit(EXTI_Line11);
+#endif /* defined(ST_DSPIN_6470H_DISCOVERY) */
+}
+
+/**
+ * @brief Disabling of external line interrupt corresponding to BUSY\SYNC GPIO
+ * @param None
+ * @retval None
+ */
+void dSPIN_Busy_Interrupt_GPIO_DeConfig(void)
+{
+ EXTI_InitTypeDef EXTI_InitStructure;
+
+#if defined(STEVAL_PCC009V2)
+ /* Disable EXTI Line10 interrupt */
+ EXTI_InitStructure.EXTI_Line = EXTI_Line10;
+ EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
+ EXTI_InitStructure.EXTI_LineCmd = DISABLE;
+ EXTI_Init(&EXTI_InitStructure);
+#endif /* defined(STEVAL_PCC009V2) */
+#if defined(ST_DSPIN_6470H_DISCOVERY)
+ /* Disable EXTI Line11 interrupt */
+ EXTI_InitStructure.EXTI_Line = EXTI_Line11;
+ EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
+ EXTI_InitStructure.EXTI_LineCmd = DISABLE;
+ EXTI_Init(&EXTI_InitStructure);
+#endif /* defined(ST_DSPIN_6470H_DISCOVERY) */
+}
+
+/**
+ * @brief Board buttons GPIO configuration to be used as EXTI lines
+ * and config of the EXTI lines.
+ * @param None
+ * @retval None
+ */
+void dSPIN_Buttons_Interrupts_GPIO_Config(void)
+{
+ EXTI_InitTypeDef EXTI_InitStructure;
+
+#if defined(STEVAL_PCC009V2)
+ /* Selects the Port C GPIO pins 2, 3 and 6 to be used as EXTI Lines */
+ GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource2);
+ GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource3);
+ GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource6);
+
+ /* Configure EXTI Line2 to generate an interrupt on rising edge */
+ EXTI_InitStructure.EXTI_Line = EXTI_Line2;
+ EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
+ EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
+ EXTI_InitStructure.EXTI_LineCmd = ENABLE;
+ EXTI_Init(&EXTI_InitStructure);
+ EXTI_ClearITPendingBit(EXTI_Line2);
+
+ /* Configure EXTI Line3 to generate an interrupt on rising edge */
+ EXTI_InitStructure.EXTI_Line = EXTI_Line3;
+ EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
+ EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
+ EXTI_InitStructure.EXTI_LineCmd = ENABLE;
+ EXTI_Init(&EXTI_InitStructure);
+ EXTI_ClearITPendingBit(EXTI_Line3);
+
+ /* Configure EXTI Line6 to generate an interrupt on rising edge */
+ EXTI_InitStructure.EXTI_Line = EXTI_Line6;
+ EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
+ EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
+ EXTI_InitStructure.EXTI_LineCmd = ENABLE;
+ EXTI_Init(&EXTI_InitStructure);
+ EXTI_ClearITPendingBit(EXTI_Line6);
+#endif /* defined(STEVAL_PCC009V2) */
+#if defined(ST_DSPIN_6470H_DISCOVERY)
+ /* Select the Port A GPIO pins 1 and 2 to be used as EXTI Lines */
+ GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource1);
+ GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource2);
+
+ /* Configure EXTI Line1 to generate an interrupt on rising edge */
+ EXTI_InitStructure.EXTI_Line = EXTI_Line1;
+ EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
+ EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
+ EXTI_InitStructure.EXTI_LineCmd = ENABLE;
+ EXTI_Init(&EXTI_InitStructure);
+ EXTI_ClearITPendingBit(EXTI_Line1);
+
+ /* Configure EXTI Line2 to generate an interrupt on rising edge */
+ EXTI_InitStructure.EXTI_Line = EXTI_Line2;
+ EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
+ EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
+ EXTI_InitStructure.EXTI_LineCmd = ENABLE;
+ EXTI_Init(&EXTI_InitStructure);
+ EXTI_ClearITPendingBit(EXTI_Line2);
+#endif /* defined(ST_DSPIN_6470H_DISCOVERY) */
+}
+
+/**
+ * @brief Switch motor GPIO configuration to be used as EXTI line
+ * and config of the EXTI line.
+ * @param None
+ * @retval None
+ */
+void dSPIN_Switch_Motor_Interrupt_Config(void)
+{
+#if defined(ST_DSPIN_6470H_DISCOVERY)
+ EXTI_InitTypeDef EXTI_InitStructure;
+ /* Select the Port A GPIO pin 0 as EXTI Line */
+ GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);
+ /* Configure EXTI Line0 to generate an interrupt on falling and rising edge */
+ EXTI_InitStructure.EXTI_Line = EXTI_Line0;
+ EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
+ EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
+ EXTI_InitStructure.EXTI_LineCmd = ENABLE;
+ EXTI_Init(&EXTI_InitStructure);
+ EXTI_ClearITPendingBit(EXTI_Line0);
+#endif /* defined(ST_DSPIN_6470H_DISCOVERY) */
+}
+
+/**
+ * @brief Enable a PWM on the STCK pin from STM32
+ * @param Period to be set (PWM Freq = 1MHZ/Period)
+ * @retval None
+ */
+void dSPIN_PWM_Enable(uint16_t Period)
+{
+#if (defined(STEVAL_PCC009V2) || defined(ST_DSPIN_6470H_DISCOVERY))
+ TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
+ TIM_OCInitTypeDef TIM_OCInitStruct;
+ RCC_ClocksTypeDef RCC_Clocks;
+
+ /*Get System Clock frequency */
+ RCC_GetClocksFreq(&RCC_Clocks);
+
+ /* Time base configuration */
+ TIM_TimeBaseStructInit(&TIM_TimeBaseInitStruct);
+ /* Set Prescaler to have a timer clock of 1MHZ */
+ TIM_TimeBaseInitStruct.TIM_Prescaler = (RCC_Clocks.SYSCLK_Frequency / 1000000) - 1;
+ /* PWM Frequency will be equal to 1MHZ/Period */
+ TIM_TimeBaseInitStruct.TIM_Period = Period - 1;
+
+ TIM_TimeBaseInit(TIM_PWM, &TIM_TimeBaseInitStruct);
+
+ /* PWM1 Mode configuration */
+ TIM_OCStructInit(&TIM_OCInitStruct);
+ TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;
+ TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;
+ TIM_OCInitStruct.TIM_Pulse = Period / 2; //range from 0 to TIM_Period,
+ //50% duty cycle is equal to Period/2
+#if defined(STEVAL_PCC009V2)
+ /* Channel 3 */
+ TIM_OC3Init(TIM_PWM, &TIM_OCInitStruct);
+#endif
+#if defined(ST_DSPIN_6470H_DISCOVERY)
+ /* Channel 4 */
+ TIM_OC4Init(TIM_PWM, &TIM_OCInitStruct);
+#endif
+
+ /* TIM_PWM enable or disable counter */
+ TIM_Cmd(TIM_PWM, ENABLE);
+#endif /* (defined(STEVAL_PCC009V2) || defined(ST_DSPIN_6470H_DISCOVERY)) */
+}
+
+/**
+ * @brief Disable PWM on the STCK pin from STM32
+ * @param None
+ * @retval None
+ */
+void dSPIN_PWM_DISABLE(void)
+{
+#if (defined(STEVAL_PCC009V2) || defined(ST_DSPIN_6470H_DISCOVERY))
+ /* TIM_PWM disable counter */
+ TIM_Cmd(TIM_PWM, DISABLE);
+#endif /* (defined(STEVAL_PCC009V2) || defined(ST_DSPIN_6470H_DISCOVERY)) */
+}
+
+/**
+ * @brief Fills-in dSPIN configuration structure with default values.
+ * @param dSPIN_RegsStruct structure address (pointer to struct)
+ * @retval None
+ */
+void dSPIN_Regs_Struct_Reset(dSPIN_RegsStruct_TypeDef* dSPIN_RegsStruct)
+{
+ dSPIN_RegsStruct->ABS_POS = 0;
+ dSPIN_RegsStruct->EL_POS = 0;
+ dSPIN_RegsStruct->MARK = 0;
+ dSPIN_RegsStruct->ACC = 0x08A;
+ dSPIN_RegsStruct->DEC = 0x08A;
+ dSPIN_RegsStruct->MAX_SPEED = 0x041;
+ dSPIN_RegsStruct->MIN_SPEED = 0;
+ dSPIN_RegsStruct->FS_SPD = 0x027;
+#if defined(L6470)
+ dSPIN_RegsStruct->KVAL_HOLD = 0x29;
+ dSPIN_RegsStruct->KVAL_RUN = 0x29;
+ dSPIN_RegsStruct->KVAL_ACC = 0x29;
+ dSPIN_RegsStruct->KVAL_DEC = 0x29;
+ dSPIN_RegsStruct->INT_SPD = 0x0408;
+ dSPIN_RegsStruct->ST_SLP = 0x19;
+ dSPIN_RegsStruct->FN_SLP_ACC = 0x29;
+ dSPIN_RegsStruct->FN_SLP_DEC = 0x29;
+ dSPIN_RegsStruct->K_THERM = 0;
+ dSPIN_RegsStruct->STALL_TH = 0x40;
+#endif /* defined(L6470) */
+#if defined(L6472)
+ dSPIN_RegsStruct->TVAL_HOLD = 0x29;
+ dSPIN_RegsStruct->TVAL_RUN = 0x29;
+ dSPIN_RegsStruct->TVAL_ACC = 0x29;
+ dSPIN_RegsStruct->TVAL_DEC = 0x29;
+ dSPIN_RegsStruct->T_FAST = 0x19;
+ dSPIN_RegsStruct->TON_MIN = 0x29;
+ dSPIN_RegsStruct->TOFF_MIN = 0x29;
+#endif /* defined(L6472) */
+ dSPIN_RegsStruct->OCD_TH = 0x8;
+ dSPIN_RegsStruct->STEP_MODE = 0x7;
+ dSPIN_RegsStruct->ALARM_EN = 0xFF;
+ dSPIN_RegsStruct->CONFIG = 0x2E88;
+}
+
+/**
+ * @brief Configures dSPIN internal registers with values in the config structure.
+ * @param dSPIN_RegsStruct Configuration structure address (pointer to configuration structure)
+ * @retval None
+ */
+void dSPIN_Registers_Set(dSPIN_RegsStruct_TypeDef* dSPIN_RegsStruct)
+{
+ dSPIN_Set_Param(dSPIN_ABS_POS, dSPIN_RegsStruct->ABS_POS);
+ dSPIN_Set_Param(dSPIN_EL_POS, dSPIN_RegsStruct->EL_POS);
+ dSPIN_Set_Param(dSPIN_MARK, dSPIN_RegsStruct->MARK);
+ dSPIN_Set_Param(dSPIN_ACC, dSPIN_RegsStruct->ACC);
+ dSPIN_Set_Param(dSPIN_DEC, dSPIN_RegsStruct->DEC);
+ dSPIN_Set_Param(dSPIN_MAX_SPEED, dSPIN_RegsStruct->MAX_SPEED);
+ dSPIN_Set_Param(dSPIN_MIN_SPEED, dSPIN_RegsStruct->MIN_SPEED);
+ dSPIN_Set_Param(dSPIN_FS_SPD, dSPIN_RegsStruct->FS_SPD);
+#if defined(L6470)
+ dSPIN_Set_Param(dSPIN_KVAL_HOLD, dSPIN_RegsStruct->KVAL_HOLD);
+ dSPIN_Set_Param(dSPIN_KVAL_RUN, dSPIN_RegsStruct->KVAL_RUN);
+ dSPIN_Set_Param(dSPIN_KVAL_ACC, dSPIN_RegsStruct->KVAL_ACC);
+ dSPIN_Set_Param(dSPIN_KVAL_DEC, dSPIN_RegsStruct->KVAL_DEC);
+ dSPIN_Set_Param(dSPIN_INT_SPD, dSPIN_RegsStruct->INT_SPD);
+ dSPIN_Set_Param(dSPIN_ST_SLP, dSPIN_RegsStruct->ST_SLP);
+ dSPIN_Set_Param(dSPIN_FN_SLP_ACC, dSPIN_RegsStruct->FN_SLP_ACC);
+ dSPIN_Set_Param(dSPIN_FN_SLP_DEC, dSPIN_RegsStruct->FN_SLP_DEC);
+ dSPIN_Set_Param(dSPIN_K_THERM, dSPIN_RegsStruct->K_THERM);
+ dSPIN_Set_Param(dSPIN_STALL_TH, dSPIN_RegsStruct->STALL_TH);
+#endif /* defined(L6470) */
+#if defined(L6472)
+ dSPIN_Set_Param(dSPIN_TVAL_HOLD, dSPIN_RegsStruct->TVAL_HOLD);
+ dSPIN_Set_Param(dSPIN_TVAL_RUN, dSPIN_RegsStruct->TVAL_RUN);
+ dSPIN_Set_Param(dSPIN_TVAL_ACC, dSPIN_RegsStruct->TVAL_ACC);
+ dSPIN_Set_Param(dSPIN_TVAL_DEC, dSPIN_RegsStruct->TVAL_DEC);
+ dSPIN_Set_Param(dSPIN_T_FAST, dSPIN_RegsStruct->T_FAST);
+ dSPIN_Set_Param(dSPIN_TON_MIN, dSPIN_RegsStruct->TON_MIN);
+ dSPIN_Set_Param(dSPIN_TOFF_MIN, dSPIN_RegsStruct->TOFF_MIN);
+#endif /* defined(L6472) */
+ dSPIN_Set_Param(dSPIN_OCD_TH, dSPIN_RegsStruct->OCD_TH);
+ dSPIN_Set_Param(dSPIN_STEP_MODE, dSPIN_RegsStruct->STEP_MODE);
+ dSPIN_Set_Param(dSPIN_ALARM_EN, dSPIN_RegsStruct->ALARM_EN);
+ dSPIN_Set_Param(dSPIN_CONFIG, dSPIN_RegsStruct->CONFIG);
+}
+
+
+/**
+ * @brief Issues dSPIN NOP command.
+ * @param None
+ * @retval None
+ */
+void dSPIN_Nop(void)
+{
+ /* Send NOP operation code to dSPIN */
+ dSPIN_Write_Byte(dSPIN_NOP);
+}
+
+/**
+ * @brief Issues dSPIN Set Param command.
+ * @param param dSPIN register address
+ * @param value to be set
+ * @retval None
+ */
+void dSPIN_Set_Param(dSPIN_Registers_TypeDef param, uint32_t value)
+{
+ /* Send SetParam operation code to dSPIN */
+ dSPIN_Write_Byte((uint8_t)dSPIN_SET_PARAM | (uint8_t)param);
+ switch (param) {
+ case dSPIN_ABS_POS: ;
+ case dSPIN_MARK: ;
+ /* Send parameter - byte 2 to dSPIN */
+ dSPIN_Write_Byte((uint8_t)(value >> 16));
+ case dSPIN_EL_POS: ;
+ case dSPIN_ACC: ;
+ case dSPIN_DEC: ;
+ case dSPIN_MAX_SPEED: ;
+ case dSPIN_MIN_SPEED: ;
+ case dSPIN_FS_SPD: ;
+#if defined(L6470)
+ case dSPIN_INT_SPD: ;
+#endif /* defined(L6470) */
+ case dSPIN_CONFIG: ;
+ case dSPIN_STATUS:
+ /* Send parameter - byte 1 to dSPIN */
+ dSPIN_Write_Byte((uint8_t)(value >> 8));
+ default:
+ /* Send parameter - byte 0 to dSPIN */
+ dSPIN_Write_Byte((uint8_t)(value));
+ }
+}
+
+/**
+ * @brief Issues dSPIN Get Param command.
+ * @param param dSPIN register address
+ * @retval Register value - 1 to 3 bytes (depends on register)
+ */
+uint32_t dSPIN_Get_Param(dSPIN_Registers_TypeDef param)
+{
+ uint32_t temp = 0;
+ uint32_t rx = 0;
+
+ /* Send GetParam operation code to dSPIN */
+ temp = dSPIN_Write_Byte((uint8_t)dSPIN_GET_PARAM | (uint8_t)param);
+ /* MSB which should be 0 */
+ temp = temp << 24;
+ rx |= temp;
+ switch (param) {
+ case dSPIN_ABS_POS: ;
+ case dSPIN_MARK: ;
+ case dSPIN_SPEED:
+ temp = dSPIN_Write_Byte((uint8_t)(0x00));
+ temp = temp << 16;
+ rx |= temp;
+ case dSPIN_EL_POS: ;
+ case dSPIN_ACC: ;
+ case dSPIN_DEC: ;
+ case dSPIN_MAX_SPEED: ;
+ case dSPIN_MIN_SPEED: ;
+ case dSPIN_FS_SPD: ;
+#if defined(L6470)
+ case dSPIN_INT_SPD: ;
+#endif /* defined(L6470) */
+ case dSPIN_CONFIG: ;
+ case dSPIN_STATUS:
+ temp = dSPIN_Write_Byte((uint8_t)(0x00));
+ temp = temp << 8;
+ rx |= temp;
+ default:
+ temp = dSPIN_Write_Byte((uint8_t)(0x00));
+ rx |= temp;
+ }
+ return rx;
+}
+
+/**
+ * @brief Issues dSPIN Run command.
+ * @param direction Movement direction (FWD, REV)
+ * @param speed over 3 bytes
+ * @retval None
+ */
+void dSPIN_Run(dSPIN_Direction_TypeDef direction, uint32_t speed)
+{
+ /* Send RUN operation code to dSPIN */
+ dSPIN_Write_Byte((uint8_t)dSPIN_RUN | (uint8_t)direction);
+ /* Send speed - byte 2 data dSPIN */
+ dSPIN_Write_Byte((uint8_t)(speed >> 16));
+ /* Send speed - byte 1 data dSPIN */
+ dSPIN_Write_Byte((uint8_t)(speed >> 8));
+ /* Send speed - byte 0 data dSPIN */
+ dSPIN_Write_Byte((uint8_t)(speed));
+}
+
+/**
+ * @brief Issues dSPIN Step Clock command.
+ * @param direction Movement direction (FWD, REV)
+ * @retval None
+ */
+void dSPIN_Step_Clock(dSPIN_Direction_TypeDef direction)
+{
+ /* Send StepClock operation code to dSPIN */
+ dSPIN_Write_Byte((uint8_t)dSPIN_STEP_CLOCK | (uint8_t)direction);
+}
+
+/**
+ * @brief Issues dSPIN Move command.
+ * @param direction mMovement direction
+ * @param n_step number of steps
+ * @retval None
+ */
+void dSPIN_Move(dSPIN_Direction_TypeDef direction, uint32_t n_step)
+{
+ /* Send Move operation code to dSPIN */
+ dSPIN_Write_Byte((uint8_t)dSPIN_MOVE | (uint8_t)direction);
+ /* Send n_step - byte 2 data dSPIN */
+ dSPIN_Write_Byte((uint8_t)(n_step >> 16));
+ /* Send n_step - byte 1 data dSPIN */
+ dSPIN_Write_Byte((uint8_t)(n_step >> 8));
+ /* Send n_step - byte 0 data dSPIN */
+ dSPIN_Write_Byte((uint8_t)(n_step));
+}
+
+/**
+ * @brief Issues dSPIN Go To command.
+ * @param abs_pos absolute position where requested to move
+ * @retval None
+ */
+void dSPIN_Go_To(uint32_t abs_pos)
+{
+ /* Send GoTo operation code to dSPIN */
+ dSPIN_Write_Byte(dSPIN_GO_TO);
+ /* Send absolute position parameter - byte 2 data to dSPIN */
+ dSPIN_Write_Byte((uint8_t)(abs_pos >> 16));
+ /* Send absolute position parameter - byte 1 data to dSPIN */
+ dSPIN_Write_Byte((uint8_t)(abs_pos >> 8));
+ /* Send absolute position parameter - byte 0 data to dSPIN */
+ dSPIN_Write_Byte((uint8_t)(abs_pos));
+}
+
+/**
+ * @brief Issues dSPIN Go To Dir command.
+ * @param direction movement direction
+ * @param abs_pos absolute position where requested to move
+ * @retval None
+ */
+void dSPIN_Go_To_Dir(dSPIN_Direction_TypeDef direction, uint32_t abs_pos)
+{
+ /* Send GoTo_DIR operation code to dSPIN */
+ dSPIN_Write_Byte((uint8_t)dSPIN_GO_TO_DIR | (uint8_t)direction);
+ /* Send absolute position parameter - byte 2 data to dSPIN */
+ dSPIN_Write_Byte((uint8_t)(abs_pos >> 16));
+ /* Send absolute position parameter - byte 1 data to dSPIN */
+ dSPIN_Write_Byte((uint8_t)(abs_pos >> 8));
+ /* Send absolute position parameter - byte 0 data to dSPIN */
+ dSPIN_Write_Byte((uint8_t)(abs_pos));
+}
+
+/**
+ * @brief Issues dSPIN Go Until command.
+ * @param action
+ * @param direction movement direction
+ * @param speed
+ * @retval None
+ */
+void dSPIN_Go_Until(dSPIN_Action_TypeDef action, dSPIN_Direction_TypeDef direction, uint32_t speed)
+{
+ /* Send GoUntil operation code to dSPIN */
+ dSPIN_Write_Byte((uint8_t)dSPIN_GO_UNTIL | (uint8_t)action | (uint8_t)direction);
+ /* Send speed parameter - byte 2 data to dSPIN */
+ dSPIN_Write_Byte((uint8_t)(speed >> 16));
+ /* Send speed parameter - byte 1 data to dSPIN */
+ dSPIN_Write_Byte((uint8_t)(speed >> 8));
+ /* Send speed parameter - byte 0 data to dSPIN */
+ dSPIN_Write_Byte((uint8_t)(speed));
+}
+
+/**
+ * @brief Issues dSPIN Release SW command.
+ * @param action
+ * @param direction movement direction
+ * @retval None
+ */
+void dSPIN_Release_SW(dSPIN_Action_TypeDef action, dSPIN_Direction_TypeDef direction)
+{
+ /* Send ReleaseSW operation code to dSPIN */
+ dSPIN_Write_Byte((uint8_t)dSPIN_RELEASE_SW | (uint8_t)action | (uint8_t)direction);
+}
+
+/**
+ * @brief Issues dSPIN Go Home command. (Shorted path to zero position)
+ * @param None
+ * @retval None
+ */
+void dSPIN_Go_Home(void)
+{
+ /* Send GoHome operation code to dSPIN */
+ dSPIN_Write_Byte(dSPIN_GO_HOME);
+}
+
+/**
+ * @brief Issues dSPIN Go Mark command.
+ * @param None
+ * @retval None
+ */
+void dSPIN_Go_Mark(void)
+{
+ /* Send GoMark operation code to dSPIN */
+ dSPIN_Write_Byte(dSPIN_GO_MARK);
+}
+
+/**
+ * @brief Issues dSPIN Reset Pos command.
+ * @param None
+ * @retval None
+ */
+void dSPIN_Reset_Pos(void)
+{
+ /* Send ResetPos operation code to dSPIN */
+ dSPIN_Write_Byte(dSPIN_RESET_POS);
+}
+
+/**
+ * @brief Issues dSPIN Reset Device command.
+ * @param None
+ * @retval None
+ */
+void dSPIN_Reset_Device(void)
+{
+ /* Send ResetDevice operation code to dSPIN */
+ dSPIN_Write_Byte(dSPIN_RESET_DEVICE);
+}
+
+/**
+ * @brief Issues dSPIN Soft Stop command.
+ * @param None
+ * @retval None
+ */
+void dSPIN_Soft_Stop(void)
+{
+ /* Send SoftStop operation code to dSPIN */
+ dSPIN_Write_Byte(dSPIN_SOFT_STOP);
+}
+
+/**
+ * @brief Issues dSPIN Hard Stop command.
+ * @param None
+ * @retval None
+ */
+void dSPIN_Hard_Stop(void)
+{
+ /* Send HardStop operation code to dSPIN */
+ dSPIN_Write_Byte(dSPIN_HARD_STOP);
+}
+
+/**
+ * @brief Issues dSPIN Soft HiZ command.
+ * @param None
+ * @retval None
+ */
+void dSPIN_Soft_HiZ(void)
+{
+ /* Send SoftHiZ operation code to dSPIN */
+ dSPIN_Write_Byte(dSPIN_SOFT_HIZ);
+}
+
+/**
+ * @brief Issues dSPIN Hard HiZ command.
+ * @param None
+ * @retval None
+ */
+void dSPIN_Hard_HiZ(void)
+{
+ /* Send HardHiZ operation code to dSPIN */
+ dSPIN_Write_Byte(dSPIN_HARD_HIZ);
+}
+
+/**
+ * @brief Issues dSPIN Get Status command.
+ * @param None
+ * @retval Status Register content
+ */
+uint16_t dSPIN_Get_Status(void)
+{
+ uint16_t temp = 0;
+ uint16_t rx = 0;
+
+ /* Send GetStatus operation code to dSPIN */
+ dSPIN_Write_Byte(dSPIN_GET_STATUS);
+ /* Send zero byte / receive MSByte from dSPIN */
+ temp = dSPIN_Write_Byte((uint8_t)(0x00));
+ temp = temp << 8;
+ rx |= temp;
+ /* Send zero byte / receive LSByte from dSPIN */
+ temp = dSPIN_Write_Byte((uint8_t)(0x00));
+ rx |= temp;
+ return rx;
+}
+
+/**
+ * @brief Checks if the dSPIN is Busy by hardware - active Busy signal.
+ * @param None
+ * @retval one if chip is busy, otherwise zero
+ */
+uint8_t dSPIN_Busy_HW(void)
+{
+ if (!(GPIO_ReadInputDataBit(dSPIN_BUSY_Port, dSPIN_BUSY_Pin))) return 0x01;
+ else return 0x00;
+}
+
+/**
+ * @brief Checks if the dSPIN is Busy by SPI - Busy flag bit in Status Register.
+ * @param None
+ * @retval one if chip is busy, otherwise zero
+ */
+uint8_t dSPIN_Busy_SW(void)
+{
+ if (!(dSPIN_Get_Status() & dSPIN_STATUS_BUSY)) return 0x01;
+ else return 0x00;
+}
+
+/**
+ * @brief Checks dSPIN Flag signal.
+ * @param None
+ * @retval one if Flag signal is active, otherwise zero
+ */
+uint8_t dSPIN_Flag(void)
+{
+ if (!(GPIO_ReadInputDataBit(dSPIN_FLAG_Port, dSPIN_FLAG_Pin))) return 0x01;
+ else return 0x00;
+}
+
+/**
+ * @brief Transmits/Receives one byte to/from dSPIN over SPI.
+ * @param byte Transmited byte
+ * @retval Received byte
+ */
+uint8_t dSPIN_Write_Byte(uint8_t byte)
+{
+ /* nSS signal activation - low */
+ GPIO_ResetBits(dSPIN_nSS_Port, dSPIN_nSS_Pin);
+ /* SPI byte send */
+ SPI_I2S_SendData(dSPIN_SPI, byte);
+ /* Wait for SPIx Busy flag */
+ while (SPI_I2S_GetFlagStatus(dSPIN_SPI, SPI_I2S_FLAG_BSY) != RESET);
+ /* nSS signal deactivation - high */
+ GPIO_SetBits(dSPIN_nSS_Port, dSPIN_nSS_Pin);
+ return (uint8_t)(SPI_I2S_ReceiveData(dSPIN_SPI));
+}
+
+/**
+ * @brief Transmits/Receives several bytes to dSPIN over SPI
+ * @param pTxByte pTxBytePointer to TX bytes
+ * @param pRxByte Pointer to RX bytes
+ * @param nBytes Number of TX = RX bytes
+ * @retval None
+ */
+void dSPIN_Write_Daisy_Chain_Bytes(uint8_t *pTxByte, uint8_t *pRxByte, uint8_t nBytes)
+{
+ uint32_t index;
+ /* nSS signal activation - low */
+ GPIO_ResetBits(dSPIN_nSS_Port, dSPIN_nSS_Pin);
+ /* SPI byte send */
+ for (index = 0; index < nBytes; index++) {
+ SPI_I2S_SendData(dSPIN_SPI, *pTxByte);
+ /* Wait for SPIx Busy flag */
+ while (SPI_I2S_GetFlagStatus(dSPIN_SPI, SPI_I2S_FLAG_BSY) != RESET);
+ *pRxByte = SPI_I2S_ReceiveData(dSPIN_SPI);
+ pTxByte++;
+ pRxByte++;
+ }
+ /* nSS signal deactivation - high */
+ GPIO_SetBits(dSPIN_nSS_Port, dSPIN_nSS_Pin);
+}
+
+/**
+ * @brief Issues dSPIN Set Param command to each device (slave).
+ * @param slaves_number number of slaves
+ * @param pParam Pointer to an array of dSPIN register address
+ * @param pValue Pointer to an array of dSPIN parameter value
+ * @retval None
+ */
+void dSPIN_All_Slaves_Set_Param(uint8_t slaves_number, uint8_t *pParam, uint32_t *pValue)
+{
+ uint32_t i;
+ uint8_t maxArgumentNbBytes = 0;
+
+ for (i = 0; i < slaves_number; i++) {
+ switch (*pParam) {
+ case dSPIN_ABS_POS: ;
+ case dSPIN_MARK: ;
+ case dSPIN_SPEED:
+ spiTxBursts[0][i] = *pParam;
+ spiTxBursts[1][i] = (uint8_t)(*pValue >> 16);
+ spiTxBursts[2][i] = (uint8_t)(*pValue >> 8);
+ maxArgumentNbBytes = 3;
+ break;
+ case dSPIN_EL_POS: ;
+ case dSPIN_ACC: ;
+ case dSPIN_DEC: ;
+ case dSPIN_MAX_SPEED: ;
+ case dSPIN_MIN_SPEED: ;
+ case dSPIN_FS_SPD: ;
+#if defined(L6470)
+ case dSPIN_INT_SPD: ;
+#endif /* defined(L6470) */
+ case dSPIN_CONFIG: ;
+ case dSPIN_STATUS:
+ spiTxBursts[0][i] = dSPIN_NOP;
+ spiTxBursts[1][i] = *pParam;
+ spiTxBursts[2][i] = (uint8_t)(*pValue >> 8);
+ if (maxArgumentNbBytes < 2) {
+ maxArgumentNbBytes = 2;
+ }
+ break;
+ default:
+ spiTxBursts[0][i] = dSPIN_NOP;
+ spiTxBursts[1][i] = dSPIN_NOP;
+ spiTxBursts[2][i] = *pParam;
+ if (maxArgumentNbBytes < 1) {
+ maxArgumentNbBytes = 1;
+ }
+ }
+ spiTxBursts[3][i] = (uint8_t)(*pValue);
+ pParam++;
+ pValue++;
+ }
+ for (i = dSPIN_CMD_ARG_MAX_NB_BYTES - 1 - maxArgumentNbBytes; i < dSPIN_CMD_ARG_MAX_NB_BYTES; i++) {
+ dSPIN_Write_Daisy_Chain_Bytes(&spiTxBursts[i][0], &spiRxBursts[i][0], slaves_number);
+ }
+}
+
+/**
+ * @brief Issues dSPIN Get Param command to each device (slave).
+ * @param slaves_number number of slaves
+ * @param pParam Pointer to an array of dSPIN register address
+ * @param pValue Pointer to an array of dSPIN parameter value
+ * @retval None
+ */
+void dSPIN_All_Slaves_Get_Param(uint8_t slaves_number, uint8_t *pParam, uint32_t *pValue)
+{
+ uint32_t i;
+ uint8_t maxArgumentNbBytes = 0;
+
+ for (i = 0; i < slaves_number; i++) {
+ switch (*pParam) {
+ case dSPIN_ABS_POS: ;
+ case dSPIN_MARK: ;
+ case dSPIN_SPEED:
+ spiTxBursts[0][i] = ((uint8_t)dSPIN_GET_PARAM) | (*pParam);
+ spiTxBursts[1][i] = dSPIN_NOP;
+ spiTxBursts[2][i] = dSPIN_NOP;
+ maxArgumentNbBytes = 3;
+ break;
+ case dSPIN_EL_POS: ;
+ case dSPIN_ACC: ;
+ case dSPIN_DEC: ;
+ case dSPIN_MAX_SPEED: ;
+ case dSPIN_MIN_SPEED: ;
+ case dSPIN_FS_SPD: ;
+#if defined(L6470)
+ case dSPIN_INT_SPD: ;
+#endif /* defined(L6470) */
+ case dSPIN_CONFIG: ;
+ case dSPIN_STATUS:
+ spiTxBursts[0][i] = dSPIN_NOP;
+ spiTxBursts[1][i] = ((uint8_t)dSPIN_GET_PARAM) | (*pParam);
+ spiTxBursts[2][i] = dSPIN_NOP;
+ if (maxArgumentNbBytes < 2) {
+ maxArgumentNbBytes = 2;
+ }
+ break;
+ default:
+ spiTxBursts[0][i] = dSPIN_NOP;
+ spiTxBursts[1][i] = dSPIN_NOP;
+ spiTxBursts[2][i] = ((uint8_t)dSPIN_GET_PARAM) | (*pParam);
+ if (maxArgumentNbBytes < 1) {
+ maxArgumentNbBytes = 1;
+ }
+ }
+ spiTxBursts[3][i] = dSPIN_NOP;
+ spiRxBursts[1][i] = 0;
+ spiRxBursts[2][i] = 0;
+ spiRxBursts[3][i] = 0;
+ pParam++;
+ }
+ for (i = dSPIN_CMD_ARG_MAX_NB_BYTES - 1 - maxArgumentNbBytes; i < dSPIN_CMD_ARG_MAX_NB_BYTES; i++) {
+ dSPIN_Write_Daisy_Chain_Bytes(&spiTxBursts[i][0], &spiRxBursts[i][0], slaves_number);
+ }
+ for (i = 0; i < slaves_number; i++) {
+ *pValue = (spiRxBursts[1][i] << 16) | (spiRxBursts[2][i] << 8) | (spiRxBursts[3][i]);
+ pValue++;
+ }
+}
+
+/**
+ * @brief Configures dSPIN slaves internal registers with values in the config structure.
+ * @param slaves_number number of slaves
+ * @param dSPIN_RegsStructArray Configuration structure array address (pointer to configuration structure array)
+ * @retval None
+ */
+void dSPIN_All_Slaves_Registers_Set(uint8_t slaves_number, dSPIN_RegsStruct_TypeDef *dSPIN_RegsStructArray)
+{
+ uint32_t i;
+
+ /* ABS_POS */
+ for (i = 0; i < slaves_number; i++) {
+ arrayTxBytes[i] = dSPIN_ABS_POS;
+ arrayValues[i] = dSPIN_RegsStructArray[i].ABS_POS;
+ }
+ dSPIN_All_Slaves_Set_Param(slaves_number, arrayTxBytes, arrayValues);
+ /* EL_POS */
+ for (i = 0; i < slaves_number; i++) {
+ arrayTxBytes[i] = dSPIN_EL_POS;
+ arrayValues[i] = dSPIN_RegsStructArray[i].EL_POS;
+ }
+ dSPIN_All_Slaves_Set_Param(slaves_number, arrayTxBytes, arrayValues);
+ /* MARK */
+ for (i = 0; i < slaves_number; i++) {
+ arrayTxBytes[i] = dSPIN_MARK;
+ arrayValues[i] = dSPIN_RegsStructArray[i].MARK;
+ }
+ dSPIN_All_Slaves_Set_Param(slaves_number, arrayTxBytes, arrayValues);
+ /* ACC */
+ for (i = 0; i < slaves_number; i++) {
+ arrayTxBytes[i] = dSPIN_ACC;
+ arrayValues[i] = dSPIN_RegsStructArray[i].ACC;
+ }
+ dSPIN_All_Slaves_Set_Param(slaves_number, arrayTxBytes, arrayValues);
+ /* DEC*/
+ for (i = 0; i < slaves_number; i++) {
+ arrayTxBytes[i] = dSPIN_DEC;
+ arrayValues[i] = dSPIN_RegsStructArray[i].DEC;
+ }
+ dSPIN_All_Slaves_Set_Param(slaves_number, arrayTxBytes, arrayValues);
+ /* MAX_SPEED */
+ for (i = 0; i < slaves_number; i++) {
+ arrayTxBytes[i] = dSPIN_MAX_SPEED;
+ arrayValues[i] = dSPIN_RegsStructArray[i].MAX_SPEED;
+ }
+ dSPIN_All_Slaves_Set_Param(slaves_number, arrayTxBytes, arrayValues);
+ /* MIN_SPEED */
+ for (i = 0; i < slaves_number; i++) {
+ arrayTxBytes[i] = dSPIN_MIN_SPEED;
+ arrayValues[i] = dSPIN_RegsStructArray[i].MIN_SPEED;
+ }
+ dSPIN_All_Slaves_Set_Param(slaves_number, arrayTxBytes, arrayValues);
+ /* FS_SPD */
+ for (i = 0; i < slaves_number; i++) {
+ arrayTxBytes[i] = dSPIN_FS_SPD;
+ arrayValues[i] = dSPIN_RegsStructArray[i].FS_SPD;
+ }
+ dSPIN_All_Slaves_Set_Param(slaves_number, arrayTxBytes, arrayValues);
+#if defined(L6470)
+ /* KVAL_HOLD */
+ for (i = 0; i < slaves_number; i++) {
+ arrayTxBytes[i] = dSPIN_KVAL_HOLD;
+ arrayValues[i] = dSPIN_RegsStructArray[i].KVAL_HOLD;
+ }
+ dSPIN_All_Slaves_Set_Param(slaves_number, arrayTxBytes, arrayValues);
+ /* KVAL_RUN */
+ for (i = 0; i < slaves_number; i++) {
+ arrayTxBytes[i] = dSPIN_KVAL_RUN;
+ arrayValues[i] = dSPIN_RegsStructArray[i].KVAL_RUN;
+ }
+ dSPIN_All_Slaves_Set_Param(slaves_number, arrayTxBytes, arrayValues);
+ /* KVAL_ACC */
+ for (i = 0; i < slaves_number; i++) {
+ arrayTxBytes[i] = dSPIN_KVAL_ACC;
+ arrayValues[i] = dSPIN_RegsStructArray[i].KVAL_ACC;
+ }
+ dSPIN_All_Slaves_Set_Param(slaves_number, arrayTxBytes, arrayValues);
+ /* KVAL_DEC */
+ for (i = 0; i < slaves_number; i++) {
+ arrayTxBytes[i] = dSPIN_KVAL_DEC;
+ arrayValues[i] = dSPIN_RegsStructArray[i].KVAL_DEC;
+ }
+ dSPIN_All_Slaves_Set_Param(slaves_number, arrayTxBytes, arrayValues);
+ /* INT_SPD */
+ for (i = 0; i < slaves_number; i++) {
+ arrayTxBytes[i] = dSPIN_INT_SPD;
+ arrayValues[i] = dSPIN_RegsStructArray[i].INT_SPD;
+ }
+ dSPIN_All_Slaves_Set_Param(slaves_number, arrayTxBytes, arrayValues);
+ /* ST_SLP */
+ for (i = 0; i < slaves_number; i++) {
+ arrayTxBytes[i] = dSPIN_ST_SLP;
+ arrayValues[i] = dSPIN_RegsStructArray[i].ST_SLP;
+ }
+ dSPIN_All_Slaves_Set_Param(slaves_number, arrayTxBytes, arrayValues);
+ /* FN_SLP_ACC */
+ for (i = 0; i < slaves_number; i++) {
+ arrayTxBytes[i] = dSPIN_FN_SLP_ACC;
+ arrayValues[i] = dSPIN_RegsStructArray[i].FN_SLP_ACC;
+ }
+ dSPIN_All_Slaves_Set_Param(slaves_number, arrayTxBytes, arrayValues);
+ /* FN_SLP_DEC */
+ for (i = 0; i < slaves_number; i++) {
+ arrayTxBytes[i] = dSPIN_FN_SLP_DEC;
+ arrayValues[i] = dSPIN_RegsStructArray[i].FN_SLP_DEC;
+ }
+ dSPIN_All_Slaves_Set_Param(slaves_number, arrayTxBytes, arrayValues);
+ /* K_THERM */
+ for (i = 0; i < slaves_number; i++) {
+ arrayTxBytes[i] = dSPIN_K_THERM;
+ arrayValues[i] = dSPIN_RegsStructArray[i].K_THERM;
+ }
+ dSPIN_All_Slaves_Set_Param(slaves_number, arrayTxBytes, arrayValues);
+ /* STALL_TH */
+ for (i = 0; i < slaves_number; i++) {
+ arrayTxBytes[i] = dSPIN_STALL_TH;
+ arrayValues[i] = dSPIN_RegsStructArray[i].STALL_TH;
+ }
+ dSPIN_All_Slaves_Set_Param(slaves_number, arrayTxBytes, arrayValues);
+#endif /* defined(L6470) */
+#if defined(L6472)
+ /* TVAL_HOLD */
+ for (i = 0; i < slaves_number; i++) {
+ arrayTxBytes[i] = dSPIN_TVAL_HOLD;
+ arrayValues[i] = dSPIN_RegsStructArray[i].TVAL_HOLD;
+ }
+ dSPIN_All_Slaves_Set_Param(slaves_number, arrayTxBytes, arrayValues);
+ /* TVAL_RUN */
+ for (i = 0; i < slaves_number; i++) {
+ arrayTxBytes[i] = dSPIN_TVAL_RUN;
+ arrayValues[i] = dSPIN_RegsStructArray[i].TVAL_RUN;
+ }
+ dSPIN_All_Slaves_Set_Param(slaves_number, arrayTxBytes, arrayValues);
+ /* TVAL_ACC */
+ for (i = 0; i < slaves_number; i++) {
+ arrayTxBytes[i] = dSPIN_TVAL_ACC;
+ arrayValues[i] = dSPIN_RegsStructArray[i].TVAL_ACC;
+ }
+ dSPIN_All_Slaves_Set_Param(slaves_number, arrayTxBytes, arrayValues);
+ /* TVAL_DEC */
+ for (i = 0; i < slaves_number; i++) {
+ arrayTxBytes[i] = dSPIN_TVAL_DEC;
+ arrayValues[i] = dSPIN_RegsStructArray[i].TVAL_DEC;
+ }
+ dSPIN_All_Slaves_Set_Param(slaves_number, arrayTxBytes, arrayValues);
+ /* T_FAST */
+ for (i = 0; i < slaves_number; i++) {
+ arrayTxBytes[i] = dSPIN_T_FAST;
+ arrayValues[i] = dSPIN_RegsStructArray[i].T_FAST;
+ }
+ dSPIN_All_Slaves_Set_Param(slaves_number, arrayTxBytes, arrayValues);
+ /* TON_MIN */
+ for (i = 0; i < slaves_number; i++) {
+ arrayTxBytes[i] = dSPIN_TON_MIN;
+ arrayValues[i] = dSPIN_RegsStructArray[i].TON_MIN;
+ }
+ dSPIN_All_Slaves_Set_Param(slaves_number, arrayTxBytes, arrayValues);
+ /* TOFF_MIN */
+ for (i = 0; i < slaves_number; i++) {
+ arrayTxBytes[i] = dSPIN_TOFF_MIN;
+ arrayValues[i] = dSPIN_RegsStructArray[i].TOFF_MIN;
+ }
+ dSPIN_All_Slaves_Set_Param(slaves_number, arrayTxBytes, arrayValues);
+#endif /* defined(L6472) */
+ /* OCD_TH */
+ for (i = 0; i < slaves_number; i++) {
+ arrayTxBytes[i] = dSPIN_OCD_TH;
+ arrayValues[i] = dSPIN_RegsStructArray[i].OCD_TH;
+ }
+ dSPIN_All_Slaves_Set_Param(slaves_number, arrayTxBytes, arrayValues);
+ /* STEP_MODE */
+ for (i = 0; i < slaves_number; i++) {
+ arrayTxBytes[i] = dSPIN_STEP_MODE;
+ arrayValues[i] = dSPIN_RegsStructArray[i].STEP_MODE;
+ }
+ dSPIN_All_Slaves_Set_Param(slaves_number, arrayTxBytes, arrayValues);
+ /* ALARM_EN */
+ for (i = 0; i < slaves_number; i++) {
+ arrayTxBytes[i] = dSPIN_ALARM_EN;
+ arrayValues[i] = dSPIN_RegsStructArray[i].ALARM_EN;
+ }
+ dSPIN_All_Slaves_Set_Param(slaves_number, arrayTxBytes, arrayValues);
+ /* CONFIG */
+ for (i = 0; i < slaves_number; i++) {
+ arrayTxBytes[i] = dSPIN_CONFIG;
+ arrayValues[i] = dSPIN_RegsStructArray[i].CONFIG;
+ }
+ dSPIN_All_Slaves_Set_Param(slaves_number, arrayTxBytes, arrayValues);
+}
+
+/**
+ * @brief Issues dSPIN Move command to one slave device
+ * @param slaves_number number of slaves
+ * @param slaveNumber slave number
+ * @param direction movement direction
+ * @param n_step number of steps
+ * @retval None
+ */
+void dSPIN_One_Slave_Move(uint8_t slaves_number, uint8_t slaveNumber, dSPIN_Direction_TypeDef direction, uint32_t n_step)
+{
+ dSPIN_One_Slave_Send_Command(slaveNumber, slaves_number, (uint8_t)dSPIN_MOVE | (uint8_t)direction, n_step);
+}
+
+/**
+ * @brief Issues dSPIN Run command to one slave device
+ * @param slaveNumber slave number
+ * @param slaves_number number of slaves
+ * @param direction movement direction
+ * @param speed
+ * @retval None
+ */
+void dSPIN_One_Slave_Run(uint8_t slaveNumber, uint8_t slaves_number, dSPIN_Direction_TypeDef direction, uint32_t speed)
+{
+ dSPIN_One_Slave_Send_Command(slaveNumber, slaves_number, (uint8_t)dSPIN_RUN | (uint8_t)direction, speed);
+}
+
+/**
+ * @brief Issues a command to one slave device
+ * @param slaveNumber slave number
+ * @param slaves_number number of slaves
+ * @param param command to issue
+ * @param value command argument
+ * @retval None
+ */
+void dSPIN_One_Slave_Send_Command(uint8_t slaveNumber, uint8_t slaves_number, uint8_t param, uint32_t value)
+{
+ uint32_t i;
+
+ for (i = 0; i < slaves_number; i++) {
+ if (i == slaveNumber) {
+ spiTxBursts[0][i] = (param);
+ spiTxBursts[1][i] = (uint8_t)(value >> 16);
+ spiTxBursts[2][i] = (uint8_t)(value >> 8);
+ spiTxBursts[3][i] = (uint8_t)(value);
+ } else {
+ spiTxBursts[0][i] = dSPIN_NOP;
+ spiTxBursts[1][i] = dSPIN_NOP;
+ spiTxBursts[2][i] = dSPIN_NOP;
+ spiTxBursts[3][i] = dSPIN_NOP;
+ }
+ }
+ for (i = dSPIN_CMD_ARG_MAX_NB_BYTES - dSPIN_CMD_ARG_NB_BYTES_MOVE; i < dSPIN_CMD_ARG_MAX_NB_BYTES; i++) {
+ dSPIN_Write_Daisy_Chain_Bytes(&spiTxBursts[i][0], &spiRxBursts[i][0], slaves_number);
+ }
+}
+
+/**
+ * @brief Issues commands to the slave devices for synchronous execution
+ * @param slaves_number number of slaves
+ * @param pParam Pointer to an array of dSPIN commands
+ * @param pValue Pointer to an array of dSPIN arguments
+
+ * @retval None
+ */
+void dSPIN_All_Slaves_Send_Command(uint8_t slaves_number, uint8_t *pParam, uint32_t *pValue)
+{
+ uint32_t i;
+ uint8_t maxArgumentNbBytes = 0;
+
+ for (i = 0; i < slaves_number; i++) {
+ switch ((*pParam) & DAISY_CHAIN_COMMAND_MASK) {
+ case dSPIN_RUN: ;
+ case dSPIN_MOVE: ;
+ case dSPIN_GO_TO: ;
+ case dSPIN_GO_TO_DIR: ;
+ case dSPIN_GO_UNTIL: ;
+ case dSPIN_GO_UNTIL_ACT_CPY:
+ spiTxBursts[0][i] = *pParam;
+ spiTxBursts[1][i] = (uint8_t)(*pValue >> 16);
+ spiTxBursts[2][i] = (uint8_t)(*pValue >> 8);
+ spiTxBursts[3][i] = (uint8_t)(*pValue);
+ maxArgumentNbBytes = 3;
+ break;
+ default:
+ spiTxBursts[0][i] = dSPIN_NOP;
+ spiTxBursts[1][i] = dSPIN_NOP;
+ spiTxBursts[2][i] = dSPIN_NOP;
+ spiTxBursts[3][i] = *pParam;
+ }
+ pParam++;
+ pValue++;
+ }
+ for (i = dSPIN_CMD_ARG_MAX_NB_BYTES - 1 - maxArgumentNbBytes; i < dSPIN_CMD_ARG_MAX_NB_BYTES; i++) {
+ dSPIN_Write_Daisy_Chain_Bytes(&spiTxBursts[i][0], &spiRxBursts[i][0], slaves_number);
+ }
+}
+
+/**
+ * @brief Issues dSPIN Get Status command to each device (slave)
+ * @param slaves_number number of slaves
+ * @param pValue pointer to an array of Status Register content
+ * @retval None
+ */
+void dSPIN_All_Slaves_Get_Status(uint8_t slaves_number, uint32_t *pValue)
+{
+ uint32_t i;
+
+ for (i = 0; i < slaves_number; i++) {
+ spiTxBursts[0][i] = dSPIN_GET_STATUS;
+ spiTxBursts[1][i] = dSPIN_NOP;
+ spiTxBursts[2][i] = dSPIN_NOP;
+ spiRxBursts[1][i] = 0;
+ spiRxBursts[2][i] = 0;
+ }
+ for (i = 0; i < dSPIN_CMD_ARG_NB_BYTES_GET_STATUS + dSPIN_RSP_NB_BYTES_GET_STATUS; i++) {
+ dSPIN_Write_Daisy_Chain_Bytes(&spiTxBursts[i][0], &spiRxBursts[i][0], slaves_number);
+ }
+ for (i = 0; i < slaves_number; i++) {
+ *pValue = (spiRxBursts[1][i] << 8) | (spiRxBursts[2][i]);
+ pValue++;
+ }
+}
+
+/**
+ * @brief Checks if one of the dSPIN device (slave) is Busy by SPI - Busy flag bit in Status Register.
+ * @param slaves_number number of slaves
+ * @retval one if there is a busy chip, otherwise zero
+ */
+uint8_t dSPIN_One_Or_More_Slaves_Busy_SW(uint8_t slaves_number)
+{
+ uint32_t i;
+ uint16_t status = 0;
+ dSPIN_All_Slaves_Get_Status(slaves_number, arrayValues);
+ for (i = 0; i < slaves_number; i++) {
+ status |= arrayValues[i];
+ }
+ if (!(status & dSPIN_STATUS_BUSY)) return 0x01;
+ else return 0x00;
+}
+
+/** @} */
+/******************* (C) COPYRIGHT 2013 STMicroelectronics *****END OF FILE****/
diff --git a/project/dspin.h b/project/dspin.h
new file mode 100644
index 0000000..803247e
--- /dev/null
+++ b/project/dspin.h
@@ -0,0 +1,925 @@
+/**
+ ******************************************************************************
+ * @file dspin.h
+ * @author IPC Rennes
+ * @version V2.0
+ * @date October 4, 2013
+ * @brief Header for dspin.c module
+ * @note (C) COPYRIGHT 2013 STMicroelectronics
+ ******************************************************************************
+ * @copy
+ *
+ * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+ * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+ * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+ * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+ * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+ * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+ *
+ * © COPYRIGHT 2013 STMicroelectronics
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __DSPIN_H
+#define __DSPIN_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f10x.h"
+#include "dspin_config.h"
+
+/* Exported constants --------------------------------------------------------*/
+
+/* Select one of the following two evalboard options, comment the other one --*/
+/* #define STEVAL_PCC009V2 */
+/* #define STM32_VL_Discovery */
+/* #define ST_DSPIN_6470H_DISCOVERY*/
+
+/** @defgroup dSPIN FW library interface
+ *
+ * {
+ */
+
+#define FALSE (0)
+#define TRUE (1)
+
+
+#ifdef STEVAL_PCC009V2
+#define dSPIN_SPI SPI2
+
+#define dSPIN_SCK_Pin GPIO_Pin_13
+#define dSPIN_SCK_Port GPIOB
+
+#define dSPIN_MOSI_Pin GPIO_Pin_15
+#define dSPIN_MOSI_Port GPIOB
+
+#define dSPIN_MISO_Pin GPIO_Pin_14
+#define dSPIN_MISO_Port GPIOB
+
+#define dSPIN_nSS_Pin GPIO_Pin_12
+#define dSPIN_nSS_Port GPIOB
+
+#define dSPIN_BUSY_Pin GPIO_Pin_10
+#define dSPIN_BUSY_Port GPIOB
+
+#define dSPIN_FLAG_Pin GPIO_Pin_11
+#define dSPIN_FLAG_Port GPIOB
+
+#define dSPIN_PWM1_Pin GPIO_Pin_0
+#define dSPIN_PWM1_Port GPIOB
+
+#define dSPIN_PWM2_Pin GPIO_Pin_1
+#define dSPIN_PWM2_Port GPIOB
+
+#define POWER_LED_Pin GPIO_Pin_4
+#define POWER_LED_Port GPIOC
+
+#define STATUS_LED_Pin GPIO_Pin_8
+#define STATUS_LED_Port GPIOC
+
+#define dSPIN_STBY_RESET_Pin GPIO_Pin_1
+#define dSPIN_STBY_RESET_Port GPIOB
+
+#define TIM_PWM TIM3
+
+/* List all the peripherals, which CLKs have to be enabled! */
+#define dSPIN_PERIPHERAL_CLKs_APB1 (RCC_APB1Periph_SPI2|RCC_APB1Periph_TIM3)
+#define dSPIN_PERIPHERAL_CLKs_APB2 (RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO)
+/* Note : RCC_APB2Periph_AFIO is mandatory for interrupt enabling */
+#endif
+
+/* dSPIN maximum number of bytes of command and arguments to set a parameter */
+#define dSPIN_CMD_ARG_MAX_NB_BYTES (4)
+/* dSPIN command + argument bytes number */
+#define dSPIN_CMD_ARG_NB_BYTES_NOP (1)
+#define dSPIN_CMD_ARG_NB_BYTES_RUN (4)
+#define dSPIN_CMD_ARG_NB_BYTES_STEP_CLOCK (1)
+#define dSPIN_CMD_ARG_NB_BYTES_MOVE (4)
+#define dSPIN_CMD_ARG_NB_BYTES_GO_TO (4)
+#define dSPIN_CMD_ARG_NB_BYTES_GO_TO_DIR (4)
+#define dSPIN_CMD_ARG_NB_BYTES_GO_UNTIL (4)
+#define dSPIN_CMD_ARG_NB_BYTES_RELEASE_SW (1)
+#define dSPIN_CMD_ARG_NB_BYTES_GO_HOME (1)
+#define dSPIN_CMD_ARG_NB_BYTES_GO_MARK (1)
+#define dSPIN_CMD_ARG_NB_BYTES_RESET_POS (1)
+#define dSPIN_CMD_ARG_NB_BYTES_RESET_DEVICE (1)
+#define dSPIN_CMD_ARG_NB_BYTES_SOFT_STOP (1)
+#define dSPIN_CMD_ARG_NB_BYTES_HARD_STOP (1)
+#define dSPIN_CMD_ARG_NB_BYTES_SOFT_HIZ (1)
+#define dSPIN_CMD_ARG_NB_BYTES_HARD_HIZ (1)
+#define dSPIN_CMD_ARG_NB_BYTES_GET_STATUS (1)
+/* dSPIN response bytes number */
+#define dSPIN_RSP_NB_BYTES_GET_STATUS (2)
+/* Daisy chain command mask */
+#define DAISY_CHAIN_COMMAND_MASK (0xFA)
+
+/** dSPIN signals - Used for connection with STM32 discovery kit
+ * If another control board is used, please change the following settings
+ * according to the application board wiring diagram.
+ * Do not touch if STEVAL-PCC009V2 is used, see defs below for that evalboard.
+ *
+ */
+#ifdef STM32_VL_Discovery
+#define dSPIN_SPI SPI1
+
+#define dSPIN_SCK_Pin GPIO_Pin_5
+#define dSPIN_SCK_Port GPIOA
+
+#define dSPIN_MOSI_Pin GPIO_Pin_7
+#define dSPIN_MOSI_Port GPIOA
+
+#define dSPIN_MISO_Pin GPIO_Pin_6
+#define dSPIN_MISO_Port GPIOA
+
+#define dSPIN_nSS_Pin GPIO_Pin_4
+#define dSPIN_nSS_Port GPIOA
+
+#define dSPIN_BUSY_Pin GPIO_Pin_4
+#define dSPIN_BUSY_Port GPIOC
+
+#define dSPIN_FLAG_Pin GPIO_Pin_5
+#define dSPIN_FLAG_Port GPIOC
+
+#define dSPIN_PWM1_Pin GPIO_Pin_1
+#define dSPIN_PWM1_Port GPIOA
+
+#define dSPIN_PWM2_Pin GPIO_Pin_0
+#define dSPIN_PWM2_Port GPIOB
+
+/* List all the peripherals, which CLKs have to be enabled! */
+#define dSPIN_PERIPHERAL_CLKs_APB1 (0x00)
+#define dSPIN_PERIPHERAL_CLKs_APB2 (RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_SPI1)
+#endif
+
+/** dSPIN signals - Used for connection with ST_DSPIN_6470H_DISCOVERY
+ */
+
+#ifdef ST_DSPIN_6470H_DISCOVERY
+#define dSPIN_SPI SPI1
+
+#define dSPIN_SCK_Pin GPIO_Pin_5
+#define dSPIN_SCK_Port GPIOA
+
+#define dSPIN_MOSI_Pin GPIO_Pin_7
+#define dSPIN_MOSI_Port GPIOA
+
+#define dSPIN_MISO_Pin GPIO_Pin_6
+#define dSPIN_MISO_Port GPIOA
+
+#define dSPIN_nSS_Pin GPIO_Pin_4
+#define dSPIN_nSS_Port GPIOA
+
+#define dSPIN_BUSY_Pin GPIO_Pin_11
+#define dSPIN_BUSY_Port GPIOB
+
+#define dSPIN_FLAG_Pin GPIO_Pin_10
+#define dSPIN_FLAG_Port GPIOB
+
+/* LED_READY, GREEN*/
+#define POWER_LED_Pin GPIO_Pin_3
+#define POWER_LED_Port GPIOC
+
+/* LED_BUSY, ORANGE */
+#define LED_BUSY_Pin GPIO_Pin_2
+#define LED_BUSY_Port GPIOC
+
+/* LED_ERROR, RED */
+#define STATUS_LED_Pin GPIO_Pin_1
+#define STATUS_LED_Port GPIOC
+
+/* LED_SPARE, YELLOW */
+#define LED_SPARE_Pin GPIO_Pin_0
+#define LED_SPARE_Port GPIOC
+
+#define dSPIN_PWM1_Pin GPIO_Pin_3
+#define dSPIN_PWM1_Port GPIOA
+
+#define SW_MOTOR_Pin GPIO_Pin_0
+#define SW_MOTOR_Port GPIOA
+
+#define dSPIN_SW_Pin GPIO_Pin_4
+#define dSPIN_SW_Port GPIOC
+
+#define BUTTON_A_Pin GPIO_Pin_1
+#define BUTTON_A_Port GPIOA
+
+#define BUTTON_B_Pin GPIO_Pin_2
+#define BUTTON_B_Port GPIOA
+
+#define dSPIN_STBY_RESET_Pin GPIO_Pin_5
+#define dSPIN_STBY_RESET_Port GPIOC
+
+#define TIM_PWM TIM5
+
+/* List all the peripherals, which CLKs have to be enabled! */
+/* Note : RCC_APB2Periph_AFIO is mandatory for interrupt enabling */
+#define dSPIN_PERIPHERAL_CLKs_APB1 (RCC_APB1Periph_TIM5)
+#define dSPIN_PERIPHERAL_CLKs_APB2 (RCC_APB2Periph_SPI1 | \
+ RCC_APB2Periph_GPIOA | \
+ RCC_APB2Periph_GPIOB | \
+ RCC_APB2Periph_GPIOC | \
+ RCC_APB2Periph_AFIO)
+#endif
+
+/** dSPIN parameter min and max values
+ */
+#define dSPIN_CONF_PARAM_STALL_TH_MA_MAX ((uint16_t)(4000)) /* current in mA */
+
+/** Register bits / masks
+ */
+
+/* dSPIN electrical position register masks */
+#define dSPIN_ELPOS_STEP_MASK ((uint8_t)0xC0)
+#define dSPIN_ELPOS_MICROSTEP_MASK ((uint8_t)0x3F)
+
+/* dSPIN min speed register bit / mask */
+#define dSPIN_LSPD_OPT ((uint16_t)0x1000)
+#define dSPIN_MIN_SPEED_MASK ((uint16_t)0x0FFF)
+
+/* dSPIN Sync Output frequency enabling bit */
+#define dSPIN_SYNC_EN 0x80
+
+#if defined(L6472)
+/* dSPIN step mode bit3 must be 1 */
+#define dSPIN_STEP_MODE_BIT3 0x08
+#endif /* defined(L6472) */
+
+/* Exported types ------------------------------------------------------------*/
+
+#if defined(L6470)
+/**
+ * @brief dSPIN Init structure definition
+ */
+typedef struct {
+ uint32_t ABS_POS;
+ uint16_t EL_POS;
+ uint32_t MARK;
+ uint32_t SPEED;
+ uint16_t ACC;
+ uint16_t DEC;
+ uint16_t MAX_SPEED;
+ uint16_t MIN_SPEED;
+ uint16_t FS_SPD;
+ uint8_t KVAL_HOLD;
+ uint8_t KVAL_RUN;
+ uint8_t KVAL_ACC;
+ uint8_t KVAL_DEC;
+ uint16_t INT_SPD;
+ uint8_t ST_SLP;
+ uint8_t FN_SLP_ACC;
+ uint8_t FN_SLP_DEC;
+ uint8_t K_THERM;
+ uint8_t ADC_OUT;
+ uint8_t OCD_TH;
+ uint8_t STALL_TH;
+ uint8_t STEP_MODE;
+ uint8_t ALARM_EN;
+ uint16_t CONFIG;
+ uint16_t STATUS;
+} dSPIN_RegsStruct_TypeDef;
+
+/* dSPIN Low speed optimization */
+typedef enum {
+ dSPIN_LSPD_OPT_OFF = ((uint16_t)0x0000),
+ dSPIN_LSPD_OPT_ON = ((uint16_t)dSPIN_LSPD_OPT)
+} dSPIN_LSPD_OPT_TypeDef;
+
+/* dSPIN overcurrent threshold options */
+typedef enum {
+ dSPIN_OCD_TH_375mA = ((uint8_t)0x00),
+ dSPIN_OCD_TH_750mA = ((uint8_t)0x01),
+ dSPIN_OCD_TH_1125mA = ((uint8_t)0x02),
+ dSPIN_OCD_TH_1500mA = ((uint8_t)0x03),
+ dSPIN_OCD_TH_1875mA = ((uint8_t)0x04),
+ dSPIN_OCD_TH_2250mA = ((uint8_t)0x05),
+ dSPIN_OCD_TH_2625mA = ((uint8_t)0x06),
+ dSPIN_OCD_TH_3000mA = ((uint8_t)0x07),
+ dSPIN_OCD_TH_3375mA = ((uint8_t)0x08),
+ dSPIN_OCD_TH_3750mA = ((uint8_t)0x09),
+ dSPIN_OCD_TH_4125mA = ((uint8_t)0x0A),
+ dSPIN_OCD_TH_4500mA = ((uint8_t)0x0B),
+ dSPIN_OCD_TH_4875mA = ((uint8_t)0x0C),
+ dSPIN_OCD_TH_5250mA = ((uint8_t)0x0D),
+ dSPIN_OCD_TH_5625mA = ((uint8_t)0x0E),
+ dSPIN_OCD_TH_6000mA = ((uint8_t)0x0F)
+} dSPIN_OCD_TH_TypeDef;
+
+/* dSPIN STEP_MODE register masks */
+typedef enum {
+ dSPIN_STEP_MODE_STEP_SEL = ((uint8_t)0x07),
+ dSPIN_STEP_MODE_SYNC_SEL = ((uint8_t)0x70),
+ dSPIN_STEP_MODE_SYNC_EN = ((uint8_t)0x80)
+} dSPIN_STEP_MODE_Masks_TypeDef;
+
+/* dSPIN STEP_MODE register options */
+/* dSPIN STEP_SEL options */
+typedef enum {
+ dSPIN_STEP_SEL_1 = ((uint8_t)0x00),
+ dSPIN_STEP_SEL_1_2 = ((uint8_t)0x01),
+ dSPIN_STEP_SEL_1_4 = ((uint8_t)0x02),
+ dSPIN_STEP_SEL_1_8 = ((uint8_t)0x03),
+ dSPIN_STEP_SEL_1_16 = ((uint8_t)0x04),
+ dSPIN_STEP_SEL_1_32 = ((uint8_t)0x05),
+ dSPIN_STEP_SEL_1_64 = ((uint8_t)0x06),
+ dSPIN_STEP_SEL_1_128 = ((uint8_t)0x07)
+} dSPIN_STEP_SEL_TypeDef;
+
+/* dSPIN SYNC_SEL options */
+typedef enum {
+ dSPIN_SYNC_SEL_DISABLED = ((uint8_t)0x00),
+ dSPIN_SYNC_SEL_1_2 = ((uint8_t)(dSPIN_SYNC_EN | 0x00)),
+ dSPIN_SYNC_SEL_1 = ((uint8_t)(dSPIN_SYNC_EN | 0x10)),
+ dSPIN_SYNC_SEL_2 = ((uint8_t)(dSPIN_SYNC_EN | 0x20)),
+ dSPIN_SYNC_SEL_4 = ((uint8_t)(dSPIN_SYNC_EN | 0x30)),
+ dSPIN_SYNC_SEL_8 = ((uint8_t)(dSPIN_SYNC_EN | 0x40)),
+ dSPIN_SYNC_SEL_16 = ((uint8_t)(dSPIN_SYNC_EN | 0x50)),
+ dSPIN_SYNC_SEL_32 = ((uint8_t)(dSPIN_SYNC_EN | 0x60)),
+ dSPIN_SYNC_SEL_64 = ((uint8_t)(dSPIN_SYNC_EN | 0x70))
+} dSPIN_SYNC_SEL_TypeDef;
+
+/* dSPIN ALARM_EN register options */
+typedef enum {
+ dSPIN_ALARM_EN_OVERCURRENT = ((uint8_t)0x01),
+ dSPIN_ALARM_EN_THERMAL_SHUTDOWN = ((uint8_t)0x02),
+ dSPIN_ALARM_EN_THERMAL_WARNING = ((uint8_t)0x04),
+ dSPIN_ALARM_EN_UNDER_VOLTAGE = ((uint8_t)0x08),
+ dSPIN_ALARM_EN_STALL_DET_A = ((uint8_t)0x10),
+ dSPIN_ALARM_EN_STALL_DET_B = ((uint8_t)0x20),
+ dSPIN_ALARM_EN_SW_TURN_ON = ((uint8_t)0x40),
+ dSPIN_ALARM_EN_WRONG_NPERF_CMD = ((uint8_t)0x80)
+} dSPIN_ALARM_EN_TypeDef;
+
+/* dSPIN Config register masks */
+typedef enum {
+ dSPIN_CONFIG_OSC_SEL = ((uint16_t)0x0007),
+ dSPIN_CONFIG_EXT_CLK = ((uint16_t)0x0008),
+ dSPIN_CONFIG_SW_MODE = ((uint16_t)0x0010),
+ dSPIN_CONFIG_EN_VSCOMP = ((uint16_t)0x0020),
+ dSPIN_CONFIG_OC_SD = ((uint16_t)0x0080),
+ dSPIN_CONFIG_POW_SR = ((uint16_t)0x0300),
+ dSPIN_CONFIG_F_PWM_DEC = ((uint16_t)0x1C00),
+ dSPIN_CONFIG_F_PWM_INT = ((uint16_t)0xE000)
+} dSPIN_CONFIG_Masks_TypeDef;
+
+/* dSPIN Config register options */
+typedef enum {
+ dSPIN_CONFIG_INT_16MHZ = ((uint16_t)0x0000),
+ dSPIN_CONFIG_INT_16MHZ_OSCOUT_2MHZ = ((uint16_t)0x0008),
+ dSPIN_CONFIG_INT_16MHZ_OSCOUT_4MHZ = ((uint16_t)0x0009),
+ dSPIN_CONFIG_INT_16MHZ_OSCOUT_8MHZ = ((uint16_t)0x000A),
+ dSPIN_CONFIG_INT_16MHZ_OSCOUT_16MHZ = ((uint16_t)0x000B),
+ dSPIN_CONFIG_EXT_8MHZ_XTAL_DRIVE = ((uint16_t)0x0004),
+ dSPIN_CONFIG_EXT_16MHZ_XTAL_DRIVE = ((uint16_t)0x0005),
+ dSPIN_CONFIG_EXT_24MHZ_XTAL_DRIVE = ((uint16_t)0x0006),
+ dSPIN_CONFIG_EXT_32MHZ_XTAL_DRIVE = ((uint16_t)0x0007),
+ dSPIN_CONFIG_EXT_8MHZ_OSCOUT_INVERT = ((uint16_t)0x000C),
+ dSPIN_CONFIG_EXT_16MHZ_OSCOUT_INVERT = ((uint16_t)0x000D),
+ dSPIN_CONFIG_EXT_24MHZ_OSCOUT_INVERT = ((uint16_t)0x000E),
+ dSPIN_CONFIG_EXT_32MHZ_OSCOUT_INVERT = ((uint16_t)0x000F)
+} dSPIN_CONFIG_OSC_MGMT_TypeDef;
+
+typedef enum {
+ dSPIN_CONFIG_SW_HARD_STOP = ((uint16_t)0x0000),
+ dSPIN_CONFIG_SW_USER = ((uint16_t)0x0010)
+} dSPIN_CONFIG_SW_MODE_TypeDef;
+
+typedef enum {
+ dSPIN_CONFIG_VS_COMP_DISABLE = ((uint16_t)0x0000),
+ dSPIN_CONFIG_VS_COMP_ENABLE = ((uint16_t)0x0020)
+} dSPIN_CONFIG_EN_VSCOMP_TypeDef;
+
+typedef enum {
+ dSPIN_CONFIG_OC_SD_DISABLE = ((uint16_t)0x0000),
+ dSPIN_CONFIG_OC_SD_ENABLE = ((uint16_t)0x0080)
+} dSPIN_CONFIG_OC_SD_TypeDef;
+
+typedef enum {
+ dSPIN_CONFIG_SR_320V_us = ((uint16_t)0x0000),
+ dSPIN_CONFIG_SR_075V_us = ((uint16_t)0x0100),
+ dSPIN_CONFIG_SR_110V_us = ((uint16_t)0x0200),
+ dSPIN_CONFIG_SR_260V_us = ((uint16_t)0x0300)
+} dSPIN_CONFIG_POW_SR_TypeDef;
+
+typedef enum {
+ dSPIN_CONFIG_PWM_DIV_1 = (((uint16_t)0x00) << 13),
+ dSPIN_CONFIG_PWM_DIV_2 = (((uint16_t)0x01) << 13),
+ dSPIN_CONFIG_PWM_DIV_3 = (((uint16_t)0x02) << 13),
+ dSPIN_CONFIG_PWM_DIV_4 = (((uint16_t)0x03) << 13),
+ dSPIN_CONFIG_PWM_DIV_5 = (((uint16_t)0x04) << 13),
+ dSPIN_CONFIG_PWM_DIV_6 = (((uint16_t)0x05) << 13),
+ dSPIN_CONFIG_PWM_DIV_7 = (((uint16_t)0x06) << 13)
+} dSPIN_CONFIG_F_PWM_INT_TypeDef;
+
+typedef enum {
+ dSPIN_CONFIG_PWM_MUL_0_625 = (((uint16_t)0x00) << 10),
+ dSPIN_CONFIG_PWM_MUL_0_75 = (((uint16_t)0x01) << 10),
+ dSPIN_CONFIG_PWM_MUL_0_875 = (((uint16_t)0x02) << 10),
+ dSPIN_CONFIG_PWM_MUL_1 = (((uint16_t)0x03) << 10),
+ dSPIN_CONFIG_PWM_MUL_1_25 = (((uint16_t)0x04) << 10),
+ dSPIN_CONFIG_PWM_MUL_1_5 = (((uint16_t)0x05) << 10),
+ dSPIN_CONFIG_PWM_MUL_1_75 = (((uint16_t)0x06) << 10),
+ dSPIN_CONFIG_PWM_MUL_2 = (((uint16_t)0x07) << 10)
+} dSPIN_CONFIG_F_PWM_DEC_TypeDef;
+
+/* Status Register bit masks */
+typedef enum {
+ dSPIN_STATUS_HIZ = (((uint16_t)0x0001)),
+ dSPIN_STATUS_BUSY = (((uint16_t)0x0002)),
+ dSPIN_STATUS_SW_F = (((uint16_t)0x0004)),
+ dSPIN_STATUS_SW_EVN = (((uint16_t)0x0008)),
+ dSPIN_STATUS_DIR = (((uint16_t)0x0010)),
+ dSPIN_STATUS_MOT_STATUS = (((uint16_t)0x0060)),
+ dSPIN_STATUS_NOTPERF_CMD = (((uint16_t)0x0080)),
+ dSPIN_STATUS_WRONG_CMD = (((uint16_t)0x0100)),
+ dSPIN_STATUS_UVLO = (((uint16_t)0x0200)),
+ dSPIN_STATUS_TH_WRN = (((uint16_t)0x0400)),
+ dSPIN_STATUS_TH_SD = (((uint16_t)0x0800)),
+ dSPIN_STATUS_OCD = (((uint16_t)0x1000)),
+ dSPIN_STATUS_STEP_LOSS_A = (((uint16_t)0x2000)),
+ dSPIN_STATUS_STEP_LOSS_B = (((uint16_t)0x4000)),
+ dSPIN_STATUS_SCK_MOD = (((uint16_t)0x8000))
+} dSPIN_STATUS_Masks_TypeDef;
+
+/* Status Register options */
+typedef enum {
+ dSPIN_STATUS_MOT_STATUS_STOPPED = (((uint16_t)0x0000) << 5),
+ dSPIN_STATUS_MOT_STATUS_ACCELERATION = (((uint16_t)0x0001) << 5),
+ dSPIN_STATUS_MOT_STATUS_DECELERATION = (((uint16_t)0x0002) << 5),
+ dSPIN_STATUS_MOT_STATUS_CONST_SPD = (((uint16_t)0x0003) << 5)
+} dSPIN_STATUS_TypeDef;
+
+/* dSPIN internal register addresses */
+typedef enum {
+ dSPIN_ABS_POS = ((uint8_t)0x01),
+ dSPIN_EL_POS = ((uint8_t)0x02),
+ dSPIN_MARK = ((uint8_t)0x03),
+ dSPIN_SPEED = ((uint8_t)0x04),
+ dSPIN_ACC = ((uint8_t)0x05),
+ dSPIN_DEC = ((uint8_t)0x06),
+ dSPIN_MAX_SPEED = ((uint8_t)0x07),
+ dSPIN_MIN_SPEED = ((uint8_t)0x08),
+ dSPIN_FS_SPD = ((uint8_t)0x15),
+ dSPIN_KVAL_HOLD = ((uint8_t)0x09),
+ dSPIN_KVAL_RUN = ((uint8_t)0x0A),
+ dSPIN_KVAL_ACC = ((uint8_t)0x0B),
+ dSPIN_KVAL_DEC = ((uint8_t)0x0C),
+ dSPIN_INT_SPD = ((uint8_t)0x0D),
+ dSPIN_ST_SLP = ((uint8_t)0x0E),
+ dSPIN_FN_SLP_ACC = ((uint8_t)0x0F),
+ dSPIN_FN_SLP_DEC = ((uint8_t)0x10),
+ dSPIN_K_THERM = ((uint8_t)0x11),
+ dSPIN_ADC_OUT = ((uint8_t)0x12),
+ dSPIN_OCD_TH = ((uint8_t)0x13),
+ dSPIN_STALL_TH = ((uint8_t)0x14),
+ dSPIN_STEP_MODE = ((uint8_t)0x16),
+ dSPIN_ALARM_EN = ((uint8_t)0x17),
+ dSPIN_CONFIG = ((uint8_t)0x18),
+ dSPIN_STATUS = ((uint8_t)0x19),
+ dSPIN_RESERVED_REG2 = ((uint8_t)0x1A),
+ dSPIN_RESERVED_REG1 = ((uint8_t)0x1B)
+} dSPIN_Registers_TypeDef;
+
+/* dSPIN command set */
+typedef enum {
+ dSPIN_NOP = ((uint8_t)0x00),
+ dSPIN_SET_PARAM = ((uint8_t)0x00),
+ dSPIN_GET_PARAM = ((uint8_t)0x20),
+ dSPIN_RUN = ((uint8_t)0x50),
+ dSPIN_STEP_CLOCK = ((uint8_t)0x58),
+ dSPIN_MOVE = ((uint8_t)0x40),
+ dSPIN_GO_TO = ((uint8_t)0x60),
+ dSPIN_GO_TO_DIR = ((uint8_t)0x68),
+ dSPIN_GO_UNTIL = ((uint8_t)0x82),
+ dSPIN_GO_UNTIL_ACT_CPY = ((uint8_t)0x8A),
+ dSPIN_RELEASE_SW = ((uint8_t)0x92),
+ dSPIN_GO_HOME = ((uint8_t)0x70),
+ dSPIN_GO_MARK = ((uint8_t)0x78),
+ dSPIN_RESET_POS = ((uint8_t)0xD8),
+ dSPIN_RESET_DEVICE = ((uint8_t)0xC0),
+ dSPIN_SOFT_STOP = ((uint8_t)0xB0),
+ dSPIN_HARD_STOP = ((uint8_t)0xB8),
+ dSPIN_SOFT_HIZ = ((uint8_t)0xA0),
+ dSPIN_HARD_HIZ = ((uint8_t)0xA8),
+ dSPIN_GET_STATUS = ((uint8_t)0xD0),
+ dSPIN_RESERVED_CMD2 = ((uint8_t)0xEB),
+ dSPIN_RESERVED_CMD1 = ((uint8_t)0xF8)
+} dSPIN_Commands_TypeDef;
+
+/* dSPIN direction options */
+typedef enum {
+ FWD = ((uint8_t)0x01),
+ REV = ((uint8_t)0x00)
+} dSPIN_Direction_TypeDef;
+
+/* dSPIN action options */
+typedef enum {
+ ACTION_RESET = ((uint8_t)0x00),
+ ACTION_COPY = ((uint8_t)0x08)
+} dSPIN_Action_TypeDef;
+/**
+ * @}
+ */
+#endif /* defined(L6470) */
+
+#if defined(L6472)
+/**
+ * @brief dSPIN Init structure definition
+ */
+typedef struct {
+ uint32_t ABS_POS;
+ uint16_t EL_POS;
+ uint32_t MARK;
+ uint32_t SPEED;
+ uint16_t ACC;
+ uint16_t DEC;
+ uint16_t MAX_SPEED;
+ uint16_t MIN_SPEED;
+ uint16_t FS_SPD;
+ uint8_t TVAL_HOLD;
+ uint8_t TVAL_RUN;
+ uint8_t TVAL_ACC;
+ uint8_t TVAL_DEC;
+ uint16_t RESERVED_3;
+ uint8_t T_FAST;
+ uint8_t TON_MIN;
+ uint8_t TOFF_MIN;
+ uint8_t RESERVED_2;
+ uint8_t ADC_OUT;
+ uint8_t OCD_TH;
+ uint8_t RESERVED_1;
+ uint8_t STEP_MODE;
+ uint8_t ALARM_EN;
+ uint16_t CONFIG;
+} dSPIN_RegsStruct_TypeDef;
+
+/* dSPIN maximum fall step times */
+typedef enum {
+ dSPIN_FAST_STEP_2us = ((uint8_t)0x00),
+ dSPIN_FAST_STEP_4us = ((uint8_t)0x01),
+ dSPIN_FAST_STEP_6us = ((uint8_t)0x02),
+ dSPIN_FAST_STEP_8us = ((uint8_t)0x03),
+ dSPIN_FAST_STEP_10us = ((uint8_t)0x04),
+ dSPIN_FAST_STEP_12us = ((uint8_t)0x05),
+ dSPIN_FAST_STEP_14us = ((uint8_t)0x06),
+ dSPIN_FAST_STEP_16us = ((uint8_t)0x07),
+ dSPIN_FAST_STEP_18us = ((uint8_t)0x08),
+ dSPIN_FAST_STEP_20us = ((uint8_t)0x09),
+ dSPIN_FAST_STEP_22us = ((uint8_t)0x0A),
+ dSPIN_FAST_STEP_24s = ((uint8_t)0x0B),
+ dSPIN_FAST_STEP_26us = ((uint8_t)0x0C),
+ dSPIN_FAST_STEP_28us = ((uint8_t)0x0D),
+ dSPIN_FAST_STEP_30us = ((uint8_t)0x0E),
+ dSPIN_FAST_STEP_32us = ((uint8_t)0x0F)
+} dSPIN_FAST_STEP_TypeDef;
+
+/* dSPIN maximum fast decay times */
+typedef enum {
+ dSPIN_TOFF_FAST_2us = (((uint8_t)0x00) << 4),
+ dSPIN_TOFF_FAST_4us = (((uint8_t)0x01) << 4),
+ dSPIN_TOFF_FAST_6us = (((uint8_t)0x02) << 4),
+ dSPIN_TOFF_FAST_8us = (((uint8_t)0x03) << 4),
+ dSPIN_TOFF_FAST_10us = (((uint8_t)0x04) << 4),
+ dSPIN_TOFF_FAST_12us = (((uint8_t)0x05) << 4),
+ dSPIN_TOFF_FAST_14us = (((uint8_t)0x06) << 4),
+ dSPIN_TOFF_FAST_16us = (((uint8_t)0x07) << 4),
+ dSPIN_TOFF_FAST_18us = (((uint8_t)0x08) << 4),
+ dSPIN_TOFF_FAST_20us = (((uint8_t)0x09) << 4),
+ dSPIN_TOFF_FAST_22us = (((uint8_t)0x0A) << 4),
+ dSPIN_TOFF_FAST_24us = (((uint8_t)0x0B) << 4),
+ dSPIN_TOFF_FAST_26us = (((uint8_t)0x0C) << 4),
+ dSPIN_TOFF_FAST_28us = (((uint8_t)0x0D) << 4),
+ dSPIN_TOFF_FAST_30us = (((uint8_t)0x0E) << 4),
+ dSPIN_TOFF_FAST_32us = (((uint8_t)0x0F) << 4)
+} dSPIN_TOFF_FAST_TypeDef;
+
+/* dSPIN overcurrent threshold options */
+typedef enum {
+ dSPIN_OCD_TH_375mA = ((uint8_t)0x00),
+ dSPIN_OCD_TH_750mA = ((uint8_t)0x01),
+ dSPIN_OCD_TH_1125mA = ((uint8_t)0x02),
+ dSPIN_OCD_TH_1500mA = ((uint8_t)0x03),
+ dSPIN_OCD_TH_1875mA = ((uint8_t)0x04),
+ dSPIN_OCD_TH_2250mA = ((uint8_t)0x05),
+ dSPIN_OCD_TH_2625mA = ((uint8_t)0x06),
+ dSPIN_OCD_TH_3000mA = ((uint8_t)0x07),
+ dSPIN_OCD_TH_3375mA = ((uint8_t)0x08),
+ dSPIN_OCD_TH_3750mA = ((uint8_t)0x09),
+ dSPIN_OCD_TH_4125mA = ((uint8_t)0x0A),
+ dSPIN_OCD_TH_4500mA = ((uint8_t)0x0B),
+ dSPIN_OCD_TH_4875mA = ((uint8_t)0x0C),
+ dSPIN_OCD_TH_5250mA = ((uint8_t)0x0D),
+ dSPIN_OCD_TH_5625mA = ((uint8_t)0x0E),
+ dSPIN_OCD_TH_6000mA = ((uint8_t)0x0F)
+} dSPIN_OCD_TH_TypeDef;
+
+/* dSPIN STEP_MODE register masks */
+typedef enum {
+ dSPIN_STEP_MODE_STEP_SEL = ((uint8_t)0x07),
+ dSPIN_STEP_MODE_SYNC_SEL = ((uint8_t)0x70),
+ dSPIN_STEP_MODE_SYNC_EN = ((uint8_t)0x80)
+} dSPIN_STEP_MODE_Masks_TypeDef;
+
+/* dSPIN STEP_MODE register options */
+/* dSPIN STEP_SEL options */
+typedef enum {
+ dSPIN_STEP_SEL_1 = ((uint8_t)(dSPIN_STEP_MODE_BIT3 | 0x00)),
+ dSPIN_STEP_SEL_1_2 = ((uint8_t)(dSPIN_STEP_MODE_BIT3 | 0x01)),
+ dSPIN_STEP_SEL_1_4 = ((uint8_t)(dSPIN_STEP_MODE_BIT3 | 0x02)),
+ dSPIN_STEP_SEL_1_8 = ((uint8_t)(dSPIN_STEP_MODE_BIT3 | 0x03)),
+ dSPIN_STEP_SEL_1_16 = ((uint8_t)(dSPIN_STEP_MODE_BIT3 | 0x04))
+} dSPIN_STEP_SEL_TypeDef;
+
+/* dSPIN SYNC_SEL options */
+typedef enum {
+ dSPIN_SYNC_SEL_DISABLED = ((uint8_t)0x00),
+ dSPIN_SYNC_SEL_1_2 = ((uint8_t)(dSPIN_SYNC_EN | 0x00)),
+ dSPIN_SYNC_SEL_1 = ((uint8_t)(dSPIN_SYNC_EN | 0x10)),
+ dSPIN_SYNC_SEL_2 = ((uint8_t)(dSPIN_SYNC_EN | 0x20)),
+ dSPIN_SYNC_SEL_4 = ((uint8_t)(dSPIN_SYNC_EN | 0x30)),
+ dSPIN_SYNC_SEL_8 = ((uint8_t)(dSPIN_SYNC_EN | 0x40))
+} dSPIN_SYNC_SEL_TypeDef;
+
+/* dSPIN ALARM_EN register options */
+typedef enum {
+ dSPIN_ALARM_EN_OVERCURRENT = ((uint8_t)0x01),
+ dSPIN_ALARM_EN_THERMAL_SHUTDOWN = ((uint8_t)0x02),
+ dSPIN_ALARM_EN_THERMAL_WARNING = ((uint8_t)0x04),
+ dSPIN_ALARM_EN_UNDER_VOLTAGE = ((uint8_t)0x08),
+ dSPIN_ALARM_EN_SW_TURN_ON = ((uint8_t)0x40),
+ dSPIN_ALARM_EN_WRONG_NPERF_CMD = ((uint8_t)0x80)
+} dSPIN_ALARM_EN_TypeDef;
+
+/* dSPIN Config register masks */
+typedef enum {
+ dSPIN_CONFIG_OSC_SEL = ((uint16_t)0x0007),
+ dSPIN_CONFIG_EXT_CLK = ((uint16_t)0x0008),
+ dSPIN_CONFIG_SW_MODE = ((uint16_t)0x0010),
+ dSPIN_CONFIG_EN_VSCOMP = ((uint16_t)0x0020),
+ dSPIN_CONFIG_OC_SD = ((uint16_t)0x0080),
+ dSPIN_CONFIG_POW_SR = ((uint16_t)0x0300),
+ dSPIN_CONFIG_TSW = ((uint16_t)0x7C00),
+ dSPIN_CONFIG_PRED_EN = ((uint16_t)0x8000)
+} dSPIN_CONFIG_Masks_TypeDef;
+
+/* dSPIN Config register options */
+typedef enum {
+ dSPIN_CONFIG_INT_16MHZ = ((uint16_t)0x0000),
+ dSPIN_CONFIG_INT_16MHZ_OSCOUT_2MHZ = ((uint16_t)0x0008),
+ dSPIN_CONFIG_INT_16MHZ_OSCOUT_4MHZ = ((uint16_t)0x0009),
+ dSPIN_CONFIG_INT_16MHZ_OSCOUT_8MHZ = ((uint16_t)0x000A),
+ dSPIN_CONFIG_INT_16MHZ_OSCOUT_16MHZ = ((uint16_t)0x000B),
+ dSPIN_CONFIG_EXT_8MHZ_XTAL_DRIVE = ((uint16_t)0x0004),
+ dSPIN_CONFIG_EXT_16MHZ_XTAL_DRIVE = ((uint16_t)0x0005),
+ dSPIN_CONFIG_EXT_24MHZ_XTAL_DRIVE = ((uint16_t)0x0006),
+ dSPIN_CONFIG_EXT_32MHZ_XTAL_DRIVE = ((uint16_t)0x0007),
+ dSPIN_CONFIG_EXT_8MHZ_OSCOUT_INVERT = ((uint16_t)0x000C),
+ dSPIN_CONFIG_EXT_16MHZ_OSCOUT_INVERT = ((uint16_t)0x000D),
+ dSPIN_CONFIG_EXT_24MHZ_OSCOUT_INVERT = ((uint16_t)0x000E),
+ dSPIN_CONFIG_EXT_32MHZ_OSCOUT_INVERT = ((uint16_t)0x000F)
+} dSPIN_CONFIG_OSC_MGMT_TypeDef;
+
+typedef enum {
+ dSPIN_CONFIG_SW_HARD_STOP = ((uint16_t)0x0000),
+ dSPIN_CONFIG_SW_USER = ((uint16_t)0x0010)
+} dSPIN_CONFIG_SW_MODE_TypeDef;
+
+typedef enum {
+ dSPIN_CONFIG_TQ_REG_TVAL_USED = ((uint16_t)0x0000),
+ dSPIN_CONFIG_TQ_REG_ADC_OUT = ((uint16_t)0x0020)
+} dSPIN_CONFIG_EN_TQREG_TypeDef;
+
+typedef enum {
+ dSPIN_CONFIG_OC_SD_DISABLE = ((uint16_t)0x0000),
+ dSPIN_CONFIG_OC_SD_ENABLE = ((uint16_t)0x0080)
+} dSPIN_CONFIG_OC_SD_TypeDef;
+
+typedef enum {
+ dSPIN_CONFIG_SR_320V_us = ((uint16_t)0x0000),
+ dSPIN_CONFIG_SR_075V_us = ((uint16_t)0x0100),
+ dSPIN_CONFIG_SR_110V_us = ((uint16_t)0x0200),
+ dSPIN_CONFIG_SR_260V_us = ((uint16_t)0x0300)
+} dSPIN_CONFIG_POW_SR_TypeDef;
+
+typedef enum {
+ dSPIN_CONFIG_PRED_DISABLE = ((uint16_t)0x0000),
+ dSPIN_CONFIG_PRED_ENABLE = ((uint16_t)0x8000)
+} dSPIN_CONFIG_PRED_EN_TypeDef;
+
+typedef enum {
+ dSPIN_CONFIG_TSW_004us = (((uint16_t)0x01) << 10),
+ dSPIN_CONFIG_TSW_008us = (((uint16_t)0x02) << 10),
+ dSPIN_CONFIG_TSW_012us = (((uint16_t)0x03) << 10),
+ dSPIN_CONFIG_TSW_016us = (((uint16_t)0x04) << 10),
+ dSPIN_CONFIG_TSW_020us = (((uint16_t)0x05) << 10),
+ dSPIN_CONFIG_TSW_024us = (((uint16_t)0x06) << 10),
+ dSPIN_CONFIG_TSW_028us = (((uint16_t)0x07) << 10),
+ dSPIN_CONFIG_TSW_032us = (((uint16_t)0x08) << 10),
+ dSPIN_CONFIG_TSW_036us = (((uint16_t)0x09) << 10),
+ dSPIN_CONFIG_TSW_040us = (((uint16_t)0x0A) << 10),
+ dSPIN_CONFIG_TSW_044us = (((uint16_t)0x0B) << 10),
+ dSPIN_CONFIG_TSW_048us = (((uint16_t)0x0C) << 10),
+ dSPIN_CONFIG_TSW_052us = (((uint16_t)0x0D) << 10),
+ dSPIN_CONFIG_TSW_056us = (((uint16_t)0x0E) << 10),
+ dSPIN_CONFIG_TSW_060us = (((uint16_t)0x0F) << 10),
+ dSPIN_CONFIG_TSW_064us = (((uint16_t)0x10) << 10),
+ dSPIN_CONFIG_TSW_068us = (((uint16_t)0x11) << 10),
+ dSPIN_CONFIG_TSW_072us = (((uint16_t)0x12) << 10),
+ dSPIN_CONFIG_TSW_076us = (((uint16_t)0x13) << 10),
+ dSPIN_CONFIG_TSW_080us = (((uint16_t)0x14) << 10),
+ dSPIN_CONFIG_TSW_084us = (((uint16_t)0x15) << 10),
+ dSPIN_CONFIG_TSW_088us = (((uint16_t)0x16) << 10),
+ dSPIN_CONFIG_TSW_092us = (((uint16_t)0x17) << 10),
+ dSPIN_CONFIG_TSW_096us = (((uint16_t)0x18) << 10),
+ dSPIN_CONFIG_TSW_100us = (((uint16_t)0x19) << 10),
+ dSPIN_CONFIG_TSW_104us = (((uint16_t)0x1A) << 10),
+ dSPIN_CONFIG_TSW_108us = (((uint16_t)0x1B) << 10),
+ dSPIN_CONFIG_TSW_112us = (((uint16_t)0x1C) << 10),
+ dSPIN_CONFIG_TSW_116us = (((uint16_t)0x1D) << 10),
+ dSPIN_CONFIG_TSW_120us = (((uint16_t)0x1E) << 10),
+ dSPIN_CONFIG_TSW_124us = (((uint16_t)0x1F) << 10)
+} dSPIN_CONFIG_TSW_TypeDef;
+
+/* Status Register bit masks */
+typedef enum {
+ dSPIN_STATUS_HIZ = (((uint16_t)0x0001)),
+ dSPIN_STATUS_BUSY = (((uint16_t)0x0002)),
+ dSPIN_STATUS_SW_F = (((uint16_t)0x0004)),
+ dSPIN_STATUS_SW_EVN = (((uint16_t)0x0008)),
+ dSPIN_STATUS_DIR = (((uint16_t)0x0010)),
+ dSPIN_STATUS_MOT_STATUS = (((uint16_t)0x0060)),
+ dSPIN_STATUS_NOTPERF_CMD = (((uint16_t)0x0080)),
+ dSPIN_STATUS_WRONG_CMD = (((uint16_t)0x0100)),
+ dSPIN_STATUS_UVLO = (((uint16_t)0x0200)),
+ dSPIN_STATUS_TH_WRN = (((uint16_t)0x0400)),
+ dSPIN_STATUS_TH_SD = (((uint16_t)0x0800)),
+ dSPIN_STATUS_OCD = (((uint16_t)0x1000)),
+ dSPIN_STATUS_SCK_MOD = (((uint16_t)0x8000))
+} dSPIN_STATUS_Masks_TypeDef;
+
+/* Status Register options */
+typedef enum {
+ dSPIN_STATUS_MOT_STATUS_STOPPED = (((uint16_t)0x0000) << 5),
+ dSPIN_STATUS_MOT_STATUS_ACCELERATION = (((uint16_t)0x0001) << 5),
+ dSPIN_STATUS_MOT_STATUS_DECELERATION = (((uint16_t)0x0002) << 5),
+ dSPIN_STATUS_MOT_STATUS_CONST_SPD = (((uint16_t)0x0003) << 5)
+} dSPIN_STATUS_TypeDef;
+
+/* dSPIN internal register addresses */
+typedef enum {
+ dSPIN_ABS_POS = ((uint8_t)0x01),
+ dSPIN_EL_POS = ((uint8_t)0x02),
+ dSPIN_MARK = ((uint8_t)0x03),
+ dSPIN_SPEED = ((uint8_t)0x04),
+ dSPIN_ACC = ((uint8_t)0x05),
+ dSPIN_DEC = ((uint8_t)0x06),
+ dSPIN_MAX_SPEED = ((uint8_t)0x07),
+ dSPIN_MIN_SPEED = ((uint8_t)0x08),
+ dSPIN_FS_SPD = ((uint8_t)0x15),
+ dSPIN_TVAL_HOLD = ((uint8_t)0x09),
+ dSPIN_TVAL_RUN = ((uint8_t)0x0A),
+ dSPIN_TVAL_ACC = ((uint8_t)0x0B),
+ dSPIN_TVAL_DEC = ((uint8_t)0x0C),
+ dSPIN_RESERVED_REG5 = ((uint8_t)0x0D),
+ dSPIN_T_FAST = ((uint8_t)0x0E),
+ dSPIN_TON_MIN = ((uint8_t)0x0F),
+ dSPIN_TOFF_MIN = ((uint8_t)0x10),
+ dSPIN_RESERVED_REG4 = ((uint8_t)0x11),
+ dSPIN_ADC_OUT = ((uint8_t)0x12),
+ dSPIN_OCD_TH = ((uint8_t)0x13),
+ dSPIN_RESERVED_REG3 = ((uint8_t)0x14),
+ dSPIN_STEP_MODE = ((uint8_t)0x16),
+ dSPIN_ALARM_EN = ((uint8_t)0x17),
+ dSPIN_CONFIG = ((uint8_t)0x18),
+ dSPIN_STATUS = ((uint8_t)0x19),
+ dSPIN_RESERVED_REG2 = ((uint8_t)0x1A),
+ dSPIN_RESERVED_REG1 = ((uint8_t)0x1B)
+} dSPIN_Registers_TypeDef;
+
+/* dSPIN command set */
+typedef enum {
+ dSPIN_NOP = ((uint8_t)0x00),
+ dSPIN_SET_PARAM = ((uint8_t)0x00),
+ dSPIN_GET_PARAM = ((uint8_t)0x20),
+ dSPIN_RUN = ((uint8_t)0x50),
+ dSPIN_STEP_CLOCK = ((uint8_t)0x58),
+ dSPIN_MOVE = ((uint8_t)0x40),
+ dSPIN_GO_TO = ((uint8_t)0x60),
+ dSPIN_GO_TO_DIR = ((uint8_t)0x68),
+ dSPIN_GO_UNTIL = ((uint8_t)0x82),
+ dSPIN_GO_UNTIL_ACT_CPY = ((uint8_t)0x8A),
+ dSPIN_RELEASE_SW = ((uint8_t)0x92),
+ dSPIN_GO_HOME = ((uint8_t)0x70),
+ dSPIN_GO_MARK = ((uint8_t)0x78),
+ dSPIN_RESET_POS = ((uint8_t)0xD8),
+ dSPIN_RESET_DEVICE = ((uint8_t)0xC0),
+ dSPIN_SOFT_STOP = ((uint8_t)0xB0),
+ dSPIN_HARD_STOP = ((uint8_t)0xB8),
+ dSPIN_SOFT_HIZ = ((uint8_t)0xA0),
+ dSPIN_HARD_HIZ = ((uint8_t)0xA8),
+ dSPIN_GET_STATUS = ((uint8_t)0xD0),
+ dSPIN_RESERVED_CMD2 = ((uint8_t)0xEB),
+ dSPIN_RESERVED_CMD1 = ((uint8_t)0xF8)
+} dSPIN_Commands_TypeDef;
+
+/* dSPIN direction options */
+typedef enum {
+ FWD = ((uint8_t)0x01),
+ REV = ((uint8_t)0x00)
+} dSPIN_Direction_TypeDef;
+
+/* dSPIN action options */
+typedef enum {
+ ACTION_RESET = ((uint8_t)0x00),
+ ACTION_COPY = ((uint8_t)0x08)
+} dSPIN_Action_TypeDef;
+/**
+ * @}
+ */
+#endif /* defined(L6472) */
+
+/* Exported macro ------------------------------------------------------------*/
+#define Speed_Steps_to_Par(steps) ((uint32_t)(((steps)*67.108864)+0.5)) /* Speed conversion, range 0 to 15625 steps/s */
+#define AccDec_Steps_to_Par(steps) ((uint16_t)(((steps)*0.068719476736)+0.5)) /* Acc/Dec rates conversion, range 14.55 to 59590 steps/s2 */
+#define MaxSpd_Steps_to_Par(steps) ((uint16_t)(((steps)*0.065536)+0.5)) /* Max Speed conversion, range 15.25 to 15610 steps/s */
+#define MinSpd_Steps_to_Par(steps) ((uint16_t)(((steps)*4.194304)+0.5)) /* Min Speed conversion, range 0 to 976.3 steps/s */
+#define FSSpd_Steps_to_Par(steps) ((uint16_t)((steps)*0.065536)) /* Full Step Speed conversion, range 7.63 to 15625 steps/s */
+#if defined(L6470)
+#define IntSpd_Steps_to_Par(steps) ((uint16_t)(((steps)*4.194304)+0.5)) /* Intersect Speed conversion, range 0 to 3906 steps/s */
+#define Kval_Perc_to_Par(perc) ((uint8_t)(((perc)/0.390625)+0.5)) /* KVAL conversions, range 0.4% to 99.6% */
+#define BEMF_Slope_Perc_to_Par(perc) ((uint8_t)(((perc)/0.00156862745098)+0.5)) /* BEMF compensation slopes, range 0 to 0.4% s/step */
+#define KTherm_to_Par(KTherm) ((uint8_t)(((KTherm - 1)/0.03125)+0.5)) /* K_THERM compensation conversion, range 1 to 1.46875 */
+#define StallTh_to_Par(StallTh) ((uint8_t)(((StallTh - 31.25)/31.25)+0.5)) /* Stall Threshold conversion, range 31.25mA to 4000mA */
+#endif /* defined(L6470) */
+#if defined(L6472)
+#define Tval_Current_to_Par(Tval) ((uint8_t)(((Tval - 31.25)/31.25)+0.5)) /* Torque regulation DAC current conversion, range 31.25mA to 4000mA */
+#define Tmin_Time_to_Par(Tmin) ((uint8_t)(((Tmin - 0.5)*2)+0.5)) /* Minimum time conversion, range 0.5us to 64us */
+#endif /* defined(L6472) */
+
+/* Exported functions ------------------------------------------------------- */
+
+void dSPIN_Delay(__IO uint32_t nCount);
+void dSPIN_Gpio_Toggle(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
+void dSPIN_Led_Check(void);
+
+void dSPIN_Reset_And_Standby(void);
+void dSPIN_Peripherals_Init(void);
+
+void dSPIN_PWM_Enable(uint16_t Period);
+void dSPIN_PWM_DISABLE(void);
+
+void dSPIN_Interrupt_Channel_Config(void);
+void dSPIN_Flag_Interrupt_GPIO_Config(void);
+void dSPIN_Busy_Interrupt_GPIO_Config(void);
+void dSPIN_Busy_Interrupt_GPIO_DeConfig(void);
+void dSPIN_Buttons_Interrupts_GPIO_Config(void);
+void dSPIN_Switch_Motor_Interrupt_Config(void);
+
+/* Config */
+void dSPIN_Regs_Struct_Reset(dSPIN_RegsStruct_TypeDef* dSPIN_RegsStruct);
+void dSPIN_Registers_Set(dSPIN_RegsStruct_TypeDef* dSPIN_RegsStruct);
+
+/* Commands */
+void dSPIN_Nop(void);
+void dSPIN_Run(dSPIN_Direction_TypeDef direction, uint32_t speed);
+void dSPIN_Step_Clock(dSPIN_Direction_TypeDef direction);
+void dSPIN_Move(dSPIN_Direction_TypeDef direction, uint32_t n_step);
+void dSPIN_Go_To(uint32_t abs_pos);
+void dSPIN_Go_To_Dir(dSPIN_Direction_TypeDef direction, uint32_t abs_pos);
+void dSPIN_Go_Until(dSPIN_Action_TypeDef action, dSPIN_Direction_TypeDef direction, uint32_t speed);
+void dSPIN_Release_SW(dSPIN_Action_TypeDef action, dSPIN_Direction_TypeDef direction);
+void dSPIN_Go_Home(void);
+void dSPIN_Go_Mark(void);
+void dSPIN_Reset_Pos(void);
+void dSPIN_Reset_Device(void);
+void dSPIN_Soft_Stop(void);
+void dSPIN_Hard_Stop(void);
+void dSPIN_Soft_HiZ(void);
+void dSPIN_Hard_HiZ(void);
+
+/* Low level commands */
+void dSPIN_Set_Param(dSPIN_Registers_TypeDef param, uint32_t value);
+uint32_t dSPIN_Get_Param(dSPIN_Registers_TypeDef param);
+
+/* Low level stuff */
+uint16_t dSPIN_Get_Status(void);
+uint8_t dSPIN_Busy_HW(void);
+uint8_t dSPIN_Busy_SW(void);
+uint8_t dSPIN_Flag(void);
+uint8_t dSPIN_Write_Byte(uint8_t byte);
+
+/* TRASH */
+void dSPIN_Write_Daisy_Chain_Bytes(uint8_t *pTxByte, uint8_t *pRxByte, uint8_t nBytes);
+void dSPIN_All_Slaves_Registers_Set(uint8_t slaves_number, dSPIN_RegsStruct_TypeDef *dSPIN_RegsStructArray);
+void dSPIN_All_Slaves_Set_Param(uint8_t slaves_number, uint8_t *pParam, uint32_t *pValue);
+void dSPIN_All_Slaves_Get_Param(uint8_t slaves_number, uint8_t *pParam, uint32_t *pValue);
+void dSPIN_One_Slave_Move(uint8_t slaveNumber, uint8_t slaves_number, dSPIN_Direction_TypeDef direction, uint32_t n_step);
+void dSPIN_One_Slave_Run(uint8_t slaveNumber, uint8_t slaves_number, dSPIN_Direction_TypeDef direction, uint32_t speed);
+void dSPIN_One_Slave_Send_Command(uint8_t slaveNumber, uint8_t slaves_number, uint8_t param, uint32_t value);
+void dSPIN_All_Slaves_Send_Command(uint8_t slaves_number, uint8_t *pParam, uint32_t *pValue);
+void dSPIN_All_Slaves_Get_Status(uint8_t slaves_number, uint32_t *pValue);
+uint8_t dSPIN_One_Or_More_Slaves_Busy_SW(uint8_t slaves_number);
+
+/** @} */
+
+#endif /* __DSPIN_H */
+
+/******************* (C) COPYRIGHT 2013 STMicroelectronics *****END OF FILE****/
diff --git a/project/dspin_config.h b/project/dspin_config.h
new file mode 100644
index 0000000..d4cdcfb
--- /dev/null
+++ b/project/dspin_config.h
@@ -0,0 +1,344 @@
+/**
+ ******************************************************************************
+ * @file dspin_config.h
+ * @author IPC Rennes
+ * @version V2.0
+ * @date octobre 15, 2013
+ * @brief Header with configuration parameters for dspin.c module
+ * @note (C) COPYRIGHT 2013 STMicroelectronics
+ ******************************************************************************
+ * @copy
+ *
+ * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+ * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+ * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+ * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+ * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+ * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+ *
+ * © COPYRIGHT 2013 STMicroelectronics
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __DSPIN_CONFIG_H
+#define __DSPIN_CONFIG_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f10x.h"
+#include "dspin.h"
+
+/* Exported constants --------------------------------------------------------*/
+
+ /****************************************************************************/
+ /***************** DSPIN chip type ******************************************/
+ /****************************************************************************/
+ #define L6470 (1)
+
+ /****************************************************************************/
+ /***************** Operation Mode Choice ************************************/
+ /***************** 1 if daisy chain for one device or more, else 0 **********/
+ /****************************************************************************/
+ #define DAISY_CHAIN (0)
+
+ /****************************************************************************/
+ /******************Daisy Chain Mode *****************************************/
+ /****************************************************************************/
+
+///* Exported constants --------------------------------------------------------*/
+
+// /**************************** Slaves numbering ******************************/
+// /* Number of dPIN slaves */
+ #define NUMBER_OF_SLAVES (1)
+// /* Devices */
+// /* The first device of the chain receives the last byte transmitted by the master */
+// /* The last device of the chain receives the first byte transmitted by the master */
+ #define DEVICE_1 (NUMBER_OF_SLAVES-1)
+//#if (DEVICE_1>0)
+// #define DEVICE_2 (NUMBER_OF_SLAVES-2)
+//#else
+// #define DEVICE_2 (DEVICE_1)
+//#endif
+//#if (DEVICE_2>0)
+// #define DEVICE_3 (NUMBER_OF_SLAVES-3)
+//#else
+// #define DEVICE_3 (DEVICE_2)
+//#endif
+//#if (DEVICE_3>0)
+// #define DEVICE_4 (NUMBER_OF_SLAVES-4)
+//#else
+// #define DEVICE_4 (DEVICE_3)
+//#endif
+//#if (DEVICE_4>0)
+// #define DEVICE_5 (NUMBER_OF_SLAVES-5)
+//#else
+// #define DEVICE_5 (DEVICE_4)
+//#endif
+//#if (DEVICE_5>0)
+// #define DEVICE_6 (NUMBER_OF_SLAVES-6)
+//#else
+// #define DEVICE_6 (DEVICE_5)
+//#endif
+//#if (DEVICE_6>0)
+// #define DEVICE_7 (NUMBER_OF_SLAVES-7)
+//#else
+// #define DEVICE_7 (DEVICE_6)
+//#endif
+//#if (DEVICE_7>0)
+// #define DEVICE_8 (NUMBER_OF_SLAVES-8)
+//#else
+// #define DEVICE_8 (DEVICE_7)
+//#endif
+
+// /****************************************************************************/
+// /***** #define dSPIN_CONF_PARAM_XXX (DEVICE_N, DEVICE_N-1, ..., DEVICE_1) ***/
+// /****************************************************************************/
+
+
+// /**************************** Speed Profile *********************************/
+
+// /* Register : ACC */
+// /* Acceleration rate in step/s2, range 14.55 to 59590 steps/s2 */
+// #define dSPIN_DC_CONF_PARAM_ACC {2008.164}
+
+// /* Register : DEC */
+// /* Deceleration rate in step/s2, range 14.55 to 59590 steps/s2 */
+// #define dSPIN_DC_CONF_PARAM_DEC {2008.164}
+
+// /* Register : MAX_SPEED */
+// /* Maximum speed in step/s, range 15.25 to 15610 steps/s */
+// #define dSPIN_DC_CONF_PARAM_MAX_SPEED {991.821}
+
+// /* Register : MIN_SPEED */
+// /* Minimum speed in step/s, range 0 to 976.3 steps/s */
+// #define dSPIN_DC_CONF_PARAM_MIN_SPEED {0}
+
+// /* Register : FS_SPD */
+// /* Full step speed in step/s, range 7.63 to 15625 steps/s */
+// #define dSPIN_DC_CONF_PARAM_FS_SPD {595.093}
+
+// /************************ Phase Current Control *****************************/
+
+// /* Register : KVAL_HOLD */
+// /* Hold duty cycle (torque) in %, range 0 to 99.6% */
+// #define dSPIN_DC_CONF_PARAM_KVAL_HOLD {16.02}
+
+// /* Register : KVAL_RUN */
+// /* Run duty cycle (torque) in %, range 0 to 99.6% */
+// #define dSPIN_DC_CONF_PARAM_KVAL_RUN {16.02}
+
+// /* Register : KVAL_ACC */
+// /* Acceleration duty cycle (torque) in %, range 0 to 99.6% */
+// #define dSPIN_DC_CONF_PARAM_KVAL_ACC {16.02}
+
+// /* Register : KVAL_DEC */
+// /* Deceleration duty cycle (torque) in %, range 0 to 99.6% */
+// #define dSPIN_DC_CONF_PARAM_KVAL_DEC {16.02}
+
+// /* Register : CONFIG - field : EN_VSCOMP */
+// /* Motor Supply Voltage Compensation enabling , enum dSPIN_CONFIG_EN_VSCOMP_TypeDef */
+// #define dSPIN_DC_CONF_PARAM_VS_COMP {dSPIN_CONFIG_VS_COMP_DISABLE}
+
+// /* Register : MIN_SPEED - field : LSPD_OPT */
+// /* Low speed optimization bit, enum dSPIN_LSPD_OPT_TypeDef */
+// #define dSPIN_DC_CONF_PARAM_LSPD_BIT {dSPIN_LSPD_OPT_OFF}
+
+// /* Register : K_THERM */
+// /* Thermal compensation param, range 1 to 1.46875 */
+// #define dSPIN_DC_CONF_PARAM_K_THERM {1}
+
+// /* Register : INT_SPEED */
+// /* Intersect speed settings for BEMF compensation in steps/s, range 0 to 3906 steps/s */
+// #define dSPIN_DC_CONF_PARAM_INT_SPD {61.512}
+
+// /* Register : ST_SLP */
+// /* BEMF start slope settings for BEMF compensation in % step/s, range 0 to 0.4% s/step */
+// #define dSPIN_DC_CONF_PARAM_ST_SLP {0.03815}
+
+// /* Register : FN_SLP_ACC */
+// /* BEMF final acc slope settings for BEMF compensation in % step/s, range 0 to 0.4% s/step */
+// #define dSPIN_DC_CONF_PARAM_FN_SLP_ACC {0.06256}
+
+// /* Register : FN_SLP_DEC */
+// /* BEMF final dec slope settings for BEMF compensation in % step/s, range 0 to 0.4% s/step */
+// #define dSPIN_DC_CONF_PARAM_FN_SLP_DEC {0.06256}
+
+// /* Register : CONFIG - field : F_PWM_INT */
+// /* PWM Frequency Integer division, enum dSPIN_CONFIG_F_PWM_INT_TypeDef */
+// #define dSPIN_DC_CONF_PARAM_PWM_DIV {dSPIN_CONFIG_PWM_DIV_2}
+
+// /* Register : CONFIG - field : F_PWM_DEC */
+// /* PWM Frequency Integer Multiplier, enum dSPIN_CONFIG_F_PWM_INT_TypeDef */
+// #define dSPIN_DC_CONF_PARAM_PWM_MUL {dSPIN_CONFIG_PWM_MUL_1}
+
+// /******************************* Others *************************************/
+// /* Register : OCD_TH */
+// /* Overcurrent threshold settings via enum dSPIN_OCD_TH_TypeDef */
+// #define dSPIN_DC_CONF_PARAM_OCD_TH {dSPIN_OCD_TH_3375mA}
+
+// /* Register : STALL_TH */
+// /* Stall threshold settings in mA, range 31.25mA to 4000mA */
+// #define dSPIN_DC_CONF_PARAM_STALL_TH {2031.25}
+
+// /* Register : ALARM_EN */
+// /* Alarm settings via bitmap enum dSPIN_ALARM_EN_TypeDef */
+// #define dSPIN_DC_CONF_PARAM_ALARM_EN {dSPIN_ALARM_EN_OVERCURRENT | dSPIN_ALARM_EN_THERMAL_SHUTDOWN | dSPIN_ALARM_EN_THERMAL_WARNING | dSPIN_ALARM_EN_UNDER_VOLTAGE | dSPIN_ALARM_EN_STALL_DET_A | dSPIN_ALARM_EN_STALL_DET_B | dSPIN_ALARM_EN_SW_TURN_ON | dSPIN_ALARM_EN_WRONG_NPERF_CMD}
+
+// /* Register : STEP_MODE - field : STEP_MODE */
+// /* Step mode settings via enum dSPIN_STEP_SEL_TypeDef */
+// #define dSPIN_DC_CONF_PARAM_STEP_MODE {dSPIN_STEP_SEL_1_128}
+
+// /* Register : STEP_MODE - Field : SYNC_MODE and SYNC_EN */
+// /* Synch. Mode settings via enum dSPIN_SYNC_SEL_TypeDef */
+// #define dSPIN_DC_CONF_PARAM_SYNC_MODE {dSPIN_SYNC_SEL_DISABLED}
+
+// /* Register : CONFIG - field : POW_SR */
+// /* Slew rate, enum dSPIN_CONFIG_POW_SR_TypeDef */
+// #define dSPIN_DC_CONF_PARAM_SR {dSPIN_CONFIG_SR_110V_us}
+
+// /* Register : CONFIG - field : OC_SD */
+// /* Over current shutwdown enabling, enum dSPIN_CONFIG_OC_SD_TypeDef */
+// #define dSPIN_DC_CONF_PARAM_OC_SD {dSPIN_CONFIG_OC_SD_DISABLE}
+
+// /* Register : CONFIG - field : SW_MODE */
+// /* External switch hard stop interrupt mode, enum dSPIN_CONFIG_SW_MODE_TypeDef */
+// #define dSPIN_DC_CONF_PARAM_SW_MODE {dSPIN_CONFIG_SW_HARD_STOP}
+
+// /* Register : CONFIG - field : OSC_CLK_SEL */
+// /* Clock setting , enum dSPIN_CONFIG_OSC_MGMT_TypeDef */
+// #define dSPIN_DC_CONF_PARAM_CLOCK_SETTING {dSPIN_CONFIG_INT_16MHZ_OSCOUT_2MHZ}
+
+
+/* Exported types ------------------------------------------------------------*/
+
+/* Exported macro ------------------------------------------------------------*/
+
+/* Exported functions ------------------------------------------------------- */
+
+ /****************************************************************************/
+ /******************No Daisy Chain Mode **************************************/
+ /****************************************************************************/
+
+/* Exported constants --------------------------------------------------------*/
+
+ /**************************** Speed Profile *********************************/
+
+ /* Register : ACC */
+ /* Acceleration rate in step/s2, range 14.55 to 59590 steps/s2 */
+ #define dSPIN_CONF_PARAM_ACC 500//(2008.164)
+
+ /* Register : DEC */
+ /* Deceleration rate in step/s2, range 14.55 to 59590 steps/s2 */
+ #define dSPIN_CONF_PARAM_DEC 500//(2008.164)
+
+ /* Register : MAX_SPEED */
+ /* Maximum speed in step/s, range 15.25 to 15610 steps/s */
+ #define dSPIN_CONF_PARAM_MAX_SPEED 220//(991.821)
+
+ /* Register : MIN_SPEED */
+ /* Minimum speed in step/s, range 0 to 976.3 steps/s */
+ #define dSPIN_CONF_PARAM_MIN_SPEED (0)
+
+ /* Register : FS_SPD */
+ /* Full step speed in step/s, range 7.63 to 15625 steps/s */
+ #define dSPIN_CONF_PARAM_FS_SPD (595.093)
+
+ /************************ Phase Current Control *****************************/
+
+ /* Register : KVAL_HOLD */
+ /* Hold duty cycle (torque) in %, range 0 to 99.6% */
+ #define dSPIN_CONF_PARAM_KVAL_HOLD 10//(16.02)
+
+ /* Register : KVAL_RUN */
+ /* Run duty cycle (torque) in %, range 0 to 99.6% */
+ #define dSPIN_CONF_PARAM_KVAL_RUN 30//(16.02)
+
+ /* Register : KVAL_ACC */
+ /* Acceleration duty cycle (torque) in %, range 0 to 99.6% */
+ #define dSPIN_CONF_PARAM_KVAL_ACC 30//(16.02)
+
+ /* Register : KVAL_DEC */
+ /* Deceleration duty cycle (torque) in %, range 0 to 99.6% */
+ #define dSPIN_CONF_PARAM_KVAL_DEC 30//(16.02)
+
+ /* Register : CONFIG - field : EN_VSCOMP */
+ /* Motor Supply Voltage Compensation enabling , enum dSPIN_CONFIG_EN_VSCOMP_TypeDef */
+ #define dSPIN_CONF_PARAM_VS_COMP (dSPIN_CONFIG_VS_COMP_DISABLE)
+
+ /* Register : MIN_SPEED - field : LSPD_OPT */
+ /* Low speed optimization bit, enum dSPIN_LSPD_OPT_TypeDef */
+ #define dSPIN_CONF_PARAM_LSPD_BIT (dSPIN_LSPD_OPT_ON) // ??
+
+ /* Register : K_THERM */
+ /* Thermal compensation param, range 1 to 1.46875 */
+ #define dSPIN_CONF_PARAM_K_THERM (1)
+
+ /* Register : INT_SPEED */
+ /* Intersect speed settings for BEMF compensation in steps/s, range 0 to 3906 steps/s */
+ #define dSPIN_CONF_PARAM_INT_SPD (61.512)
+
+ /* Register : ST_SLP */
+ /* BEMF start slope settings for BEMF compensation in % step/s, range 0 to 0.4% s/step */
+ #define dSPIN_CONF_PARAM_ST_SLP (0.03815)
+
+ /* Register : FN_SLP_ACC */
+ /* BEMF final acc slope settings for BEMF compensation in % step/s, range 0 to 0.4% s/step */
+ #define dSPIN_CONF_PARAM_FN_SLP_ACC (0.06256)
+
+ /* Register : FN_SLP_DEC */
+ /* BEMF final dec slope settings for BEMF compensation in % step/s, range 0 to 0.4% s/step */
+ #define dSPIN_CONF_PARAM_FN_SLP_DEC (0.06256)
+
+ /* Register : CONFIG - field : F_PWM_INT */
+ /* PWM Frequency Integer division, enum dSPIN_CONFIG_F_PWM_INT_TypeDef */
+ #define dSPIN_CONF_PARAM_PWM_DIV (dSPIN_CONFIG_PWM_DIV_2)
+
+ /* Register : CONFIG - field : F_PWM_DEC */
+ /* PWM Frequency Integer Multiplier, enum dSPIN_CONFIG_F_PWM_INT_TypeDef */
+ #define dSPIN_CONF_PARAM_PWM_MUL (dSPIN_CONFIG_PWM_MUL_1)
+
+ /******************************* Others *************************************/
+ /* Register : OCD_TH */
+ /* Overcurrent threshold settings via enum dSPIN_OCD_TH_TypeDef */
+ #define dSPIN_CONF_PARAM_OCD_TH (dSPIN_OCD_TH_3375mA)
+
+ /* Register : STALL_TH */
+ /* Stall threshold settings in mA, range 31.25mA to 4000mA */
+ #define dSPIN_CONF_PARAM_STALL_TH (2031.25)
+
+ /* Register : ALARM_EN */
+ /* Alarm settings via bitmap enum dSPIN_ALARM_EN_TypeDef */
+ #define dSPIN_CONF_PARAM_ALARM_EN (dSPIN_ALARM_EN_OVERCURRENT | dSPIN_ALARM_EN_THERMAL_SHUTDOWN | dSPIN_ALARM_EN_THERMAL_WARNING | dSPIN_ALARM_EN_UNDER_VOLTAGE | dSPIN_ALARM_EN_STALL_DET_A | dSPIN_ALARM_EN_STALL_DET_B | dSPIN_ALARM_EN_SW_TURN_ON | dSPIN_ALARM_EN_WRONG_NPERF_CMD)
+
+ /* Register : STEP_MODE - field : STEP_MODE */
+ /* Step mode settings via enum dSPIN_STEP_SEL_TypeDef */
+ #define dSPIN_CONF_PARAM_STEP_MODE (dSPIN_STEP_SEL_1_128)
+
+ /* Register : STEP_MODE - Field : SYNC_MODE and SYNC_EN */
+ /* Synch. Mode settings via enum dSPIN_SYNC_SEL_TypeDef */
+ #define dSPIN_CONF_PARAM_SYNC_MODE (dSPIN_SYNC_SEL_DISABLED)
+
+ /* Register : CONFIG - field : POW_SR */
+ /* Slew rate, enum dSPIN_CONFIG_POW_SR_TypeDef */
+ #define dSPIN_CONF_PARAM_SR (dSPIN_CONFIG_SR_110V_us)
+
+ /* Register : CONFIG - field : OC_SD */
+ /* Over current shutwdown enabling, enum dSPIN_CONFIG_OC_SD_TypeDef */
+ #define dSPIN_CONF_PARAM_OC_SD (dSPIN_CONFIG_OC_SD_DISABLE)
+
+ /* Register : CONFIG - field : SW_MODE */
+ /* External switch hard stop interrupt mode, enum dSPIN_CONFIG_SW_MODE_TypeDef */
+ #define dSPIN_CONF_PARAM_SW_MODE (dSPIN_CONFIG_SW_HARD_STOP)
+
+ /* Register : CONFIG - field : OSC_CLK_SEL */
+ /* Clock setting , enum dSPIN_CONFIG_OSC_MGMT_TypeDef */
+ #define dSPIN_CONF_PARAM_CLOCK_SETTING (dSPIN_CONFIG_INT_16MHZ_OSCOUT_2MHZ)
+
+
+/* Exported types ------------------------------------------------------------*/
+
+/* Exported macro ------------------------------------------------------------*/
+
+/* Exported functions ------------------------------------------------------- */
+#endif /* __DSPIN_CONFIG_H */
+
+/******************* (C) COPYRIGHT 2013 STMicroelectronics *****END OF FILE****/
diff --git a/project/hw_init.c b/project/hw_init.c
index 2e9b194..eb21d6a 100644
--- a/project/hw_init.c
+++ b/project/hw_init.c
@@ -1,6 +1,8 @@
#include "hw_init.h"
+#include "dspin.h"
#include "com/iface_usart.h"
+#include "com/iface_noop.h"
#include "com/com_fileio.h"
#include "com/datalink.h"
@@ -14,8 +16,8 @@
static void conf_gpio(void);
static void conf_usart(void);
static void conf_systick(void);
-static void conf_subsystems(void);
static void conf_irq_prios(void);
+static void conf_dspin(void);
// ---- Public functions ----------
@@ -28,7 +30,16 @@ void hw_init(void)
conf_usart();
conf_systick();
conf_irq_prios();
- conf_subsystems();
+ conf_dspin();
+
+ // task scheduler subsystem
+ timebase_init(15, 15);
+
+ // event and task queues
+ queues_init(15, 15);
+
+ // initialize SBMP for ESP8266
+ dlnk_init();
}
@@ -36,32 +47,82 @@ void hw_init(void)
+static void conf_dspin(void)
+{
+ dSPIN_Peripherals_Init();
+ dSPIN_Reset_And_Standby();
+
+ dSPIN_RegsStruct_TypeDef dSPIN_RegsStruct;
+
+ /* Structure initialization by default values, in order to avoid blank records */
+ dSPIN_Regs_Struct_Reset(&dSPIN_RegsStruct);
+
+ /* Acceleration rate settings to dSPIN_CONF_PARAM_ACC in steps/s2, range 14.55 to 59590 steps/s2 */
+ dSPIN_RegsStruct.ACC = AccDec_Steps_to_Par(dSPIN_CONF_PARAM_ACC);
+ /* Deceleration rate settings to dSPIN_CONF_PARAM_DEC in steps/s2, range 14.55 to 59590 steps/s2 */
+ dSPIN_RegsStruct.DEC = AccDec_Steps_to_Par(dSPIN_CONF_PARAM_DEC);
+ /* Maximum speed settings to dSPIN_CONF_PARAM_MAX_SPEED in steps/s, range 15.25 to 15610 steps/s */
+ dSPIN_RegsStruct.MAX_SPEED = MaxSpd_Steps_to_Par(dSPIN_CONF_PARAM_MAX_SPEED);
+ /* Full step speed settings dSPIN_CONF_PARAM_FS_SPD in steps/s, range 7.63 to 15625 steps/s */
+ dSPIN_RegsStruct.FS_SPD = FSSpd_Steps_to_Par(dSPIN_CONF_PARAM_FS_SPD);
+
+ /* Minimum speed settings to dSPIN_CONF_PARAM_MIN_SPEED in steps/s, range 0 to 976.3 steps/s */
+ dSPIN_RegsStruct.MIN_SPEED = dSPIN_CONF_PARAM_LSPD_BIT | MinSpd_Steps_to_Par(dSPIN_CONF_PARAM_MIN_SPEED);
+ /* Acceleration duty cycle (torque) settings to dSPIN_CONF_PARAM_KVAL_ACC in %, range 0 to 99.6% */
+ dSPIN_RegsStruct.KVAL_ACC = Kval_Perc_to_Par(dSPIN_CONF_PARAM_KVAL_ACC);
+ /* Deceleration duty cycle (torque) settings to dSPIN_CONF_PARAM_KVAL_DEC in %, range 0 to 99.6% */
+ dSPIN_RegsStruct.KVAL_DEC = Kval_Perc_to_Par(dSPIN_CONF_PARAM_KVAL_DEC);
+ /* Run duty cycle (torque) settings to dSPIN_CONF_PARAM_KVAL_RUN in %, range 0 to 99.6% */
+ dSPIN_RegsStruct.KVAL_RUN = Kval_Perc_to_Par(dSPIN_CONF_PARAM_KVAL_RUN);
+ /* Hold duty cycle (torque) settings to dSPIN_CONF_PARAM_KVAL_HOLD in %, range 0 to 99.6% */
+ dSPIN_RegsStruct.KVAL_HOLD = Kval_Perc_to_Par(dSPIN_CONF_PARAM_KVAL_HOLD);
+ /* Thermal compensation param settings to dSPIN_CONF_PARAM_K_THERM, range 1 to 1.46875 */
+ dSPIN_RegsStruct.K_THERM = KTherm_to_Par(dSPIN_CONF_PARAM_K_THERM);
+ /* Intersect speed settings for BEMF compensation to dSPIN_CONF_PARAM_INT_SPD in steps/s, range 0 to 3906 steps/s */
+ dSPIN_RegsStruct.INT_SPD = IntSpd_Steps_to_Par(dSPIN_CONF_PARAM_INT_SPD);
+ /* BEMF start slope settings for BEMF compensation to dSPIN_CONF_PARAM_ST_SLP in % step/s, range 0 to 0.4% s/step */
+ dSPIN_RegsStruct.ST_SLP = BEMF_Slope_Perc_to_Par(dSPIN_CONF_PARAM_ST_SLP);
+ /* BEMF final acc slope settings for BEMF compensation to dSPIN_CONF_PARAM_FN_SLP_ACC in% step/s, range 0 to 0.4% s/step */
+ dSPIN_RegsStruct.FN_SLP_ACC = BEMF_Slope_Perc_to_Par(dSPIN_CONF_PARAM_FN_SLP_ACC);
+ /* BEMF final dec slope settings for BEMF compensation to dSPIN_CONF_PARAM_FN_SLP_DEC in% step/s, range 0 to 0.4% s/step */
+ dSPIN_RegsStruct.FN_SLP_DEC = BEMF_Slope_Perc_to_Par(dSPIN_CONF_PARAM_FN_SLP_DEC);
+ /* Stall threshold settings to dSPIN_CONF_PARAM_STALL_TH in mA, range 31.25 to 4000mA */
+ dSPIN_RegsStruct.STALL_TH = StallTh_to_Par(dSPIN_CONF_PARAM_STALL_TH);
+ /* Set Config register according to config parameters */
+ /* clock setting, switch hard stop interrupt mode, */
+ /* supply voltage compensation, overcurrent shutdown */
+ /* slew-rate , PWM frequency */
+ dSPIN_RegsStruct.CONFIG = (uint16_t)dSPIN_CONF_PARAM_CLOCK_SETTING |
+ (uint16_t)dSPIN_CONF_PARAM_SW_MODE |
+ (uint16_t)dSPIN_CONF_PARAM_VS_COMP |
+ (uint16_t)dSPIN_CONF_PARAM_OC_SD |
+ (uint16_t)dSPIN_CONF_PARAM_SR |
+ (uint16_t)dSPIN_CONF_PARAM_PWM_DIV |
+ (uint16_t)dSPIN_CONF_PARAM_PWM_MUL;
+
+ /* Overcurrent threshold settings to dSPIN_CONF_PARAM_OCD_TH in mA */
+ dSPIN_RegsStruct.OCD_TH = dSPIN_CONF_PARAM_OCD_TH;
+ /* Alarm settings to dSPIN_CONF_PARAM_ALARM_EN */
+ dSPIN_RegsStruct.ALARM_EN = dSPIN_CONF_PARAM_ALARM_EN;
+ /* Step mode and sycn mode settings via dSPIN_CONF_PARAM_SYNC_MODE and dSPIN_CONF_PARAM_STEP_MODE */
+ dSPIN_RegsStruct.STEP_MODE = (uint8_t)dSPIN_CONF_PARAM_SYNC_MODE |
+ (uint8_t)dSPIN_CONF_PARAM_STEP_MODE;
+
+ /* Program all dSPIN registers */
+ dSPIN_Registers_Set(&dSPIN_RegsStruct);
+
+ dSPIN_Go_Home(); // apply the idle current
+}
+
+
static void conf_irq_prios(void)
{
NVIC_SetPriorityGrouping(0); // 0 bits for sub-priority
// SysTick - highest prio, used for timeouts
NVIC_SetPriority(SysTick_IRQn, 0); // SysTick - for timeouts
- NVIC_SetPriority(USART2_IRQn, 6); // USART - datalink
+// NVIC_SetPriority(USART2_IRQn, 6); // USART - datalink
NVIC_SetPriority(USART1_IRQn, 10); // USART - debug
-
- // FIXME check , probably bad ports
-}
-
-
-/**
- * @brief Configure SW subsystems
- */
-static void conf_subsystems(void)
-{
- // task scheduler subsystem
- timebase_init(15, 15);
-
- // event and task queues
- queues_init(15, 15);
-
- // initialize SBMP for ESP8266
- dlnk_init();
}
@@ -72,31 +133,17 @@ static void conf_gpio(void)
{
GPIO_InitTypeDef gpio_cnf;
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
-
- // Red LED
- gpio_cnf.GPIO_Pin = GPIO_Pin_13;
- gpio_cnf.GPIO_Mode = GPIO_Mode_Out_PP;
- gpio_cnf.GPIO_Speed = GPIO_Speed_10MHz;
- GPIO_Init(GPIOC, &gpio_cnf);
-
- // colorled | sonar trig
- gpio_cnf.GPIO_Pin = GPIO_Pin_12|GPIO_Pin_13;
- gpio_cnf.GPIO_Mode = GPIO_Mode_Out_PP;
- gpio_cnf.GPIO_Speed = GPIO_Speed_10MHz;
- GPIO_Init(GPIOB, &gpio_cnf);
-
- gpio_cnf.GPIO_Pin = GPIO_Pin_14;
- gpio_cnf.GPIO_Mode = GPIO_Mode_IPD;
- gpio_cnf.GPIO_Speed = GPIO_Speed_10MHz;
- GPIO_Init(GPIOB, &gpio_cnf);
-
- // A0-sonar trig | UART2 - debug, UART1 - esp
- gpio_cnf.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_9 | GPIO_Pin_10;
+
+ // UART1
+ GPIO_StructInit(&gpio_cnf);
+ gpio_cnf.GPIO_Pin = GPIO_Pin_9;
gpio_cnf.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &gpio_cnf);
+
+ gpio_cnf.GPIO_Pin = GPIO_Pin_10;
+ gpio_cnf.GPIO_Mode = GPIO_Mode_IN_FLOATING;
+ GPIO_Init(GPIOA, &gpio_cnf);
}
@@ -106,12 +153,20 @@ static void conf_gpio(void)
static void conf_usart(void)
{
// Debug interface, working as stdout/stderr.
- debug_iface = usart_iface_init(USART2, 115200, 256, 256);
+// debug_iface = usart_iface_init(USART1, 115200, 256, 256);
+// setvbuf(stdout, NULL, _IONBF, 0);
+// setvbuf(stderr, NULL, _IONBF, 0);
+// debug_iface->file = stdout;
+
+ // dev null
+ debug_iface = noop_iface_init();
setvbuf(stdout, NULL, _IONBF, 0);
setvbuf(stderr, NULL, _IONBF, 0);
debug_iface->file = stdout;
// Datalink iface
+
+ // we have only one UART available - will be used for ESP8266
data_iface = usart_iface_init(USART1, 460800, 256, 256);
}
diff --git a/project/main.c b/project/main.c
index d2a0395..557a808 100644
--- a/project/main.c
+++ b/project/main.c
@@ -1,69 +1,136 @@
#include "main.h"
#include "hw_init.h"
+#include "com/datalink.h"
#include "com/debug.h"
#include "com/com_fileio.h"
#include "com/com_iface.h"
#include "bus/event_queue.h"
#include "bus/event_handler.h"
#include "utils/timebase.h"
+#include "utils/debounce.h"
-#include "colorled.h"
-#include "display.h"
#include
#include
-void poll_subsystems(void)
+#include "dspin.h"
+#include "blinky.h"
+
+ // 7.5deg motor -> 48 full steps. We use 128 step mode -> 6144 = full circle
+#define STEPS_360 6144
+
+
+static void poll_subsystems(void);
+static void conf_buttons(void);
+
+
+int main(void)
{
- // poll serial buffers (runs callback)
- com_poll(debug_iface);
- com_poll(data_iface);
+ hw_init();
+ conf_buttons();
- // run queued tasks
- tq_poll();
+ banner("*** STM32F105 stepper motor demo ***");
+ banner_info("(c) Ondrej Hruska, 2016");
+ banner_info("Katedra mereni K338, CVUT FEL");
- // handle queued events
- Event evt;
+ // Intro animation
+ led_blink(LED_SPARE, 200);
+ delay_ms(100);
+ led_blink(LED_ERROR, 200);
+ delay_ms(100);
+ led_blink(LED_BUSY, 200);
+ delay_ms(100);
+ led_toggle(LED_READY);
- until_timeout(2) { // take 2 ms max
- if (eq_take(&evt)) {
- run_event_handler(&evt);
- } else {
- break;
+ // Green LED starts flashing...
+
+ ms_time_t t = ms_now();
+ while (1) {
+ poll_subsystems();
+
+ // blink to indicate we're working OK
+ if (ms_loop_elapsed(&t, 500)) {
+ led_toggle(LED_READY);
}
}
}
-
-void blinky(void* arg)
+void left_btn_click(void)
{
- (void)arg;
- GPIOC->ODR ^= 1<<13;
+ led_blink(LED_BUSY, 500);
+ dSPIN_Move(FWD, STEPS_360/4);
}
+void right_btn_click(void)
+{
+ led_blink(LED_ERROR, 250);
+ dSPIN_Move(REV, STEPS_360/4);
+}
-int main(void)
+void dlnk_rx(SBMP_Datagram *dg)
{
- hw_init();
- display_init();
-
- banner("*** STM32F103K8T6 RGB LED demo ***");
- banner_info("(c) Ondrej Hruska, 2016");
- banner_info("Katedra mereni K338, CVUT FEL");
+ (void)dg;
+ PayloadParser pp = pp_start(dg->payload, dg->length);
- add_periodic_task(blinky, NULL, 500, false);
+ switch (dg->type) {
+ case DG_MOTOR_HOME:
+ dSPIN_Go_Home();
+ break;
- while (1) {
- poll_subsystems();
+ case DG_MOTOR_GOTO:;
+ int32_t pos = pp_i32(&pp);
+ dSPIN_Go_To(pos);
+ break;
}
}
-void dlnk_rx(SBMP_Datagram *dg)
+static void conf_buttons(void)
{
- dbg("Rx dg type %d", dg->type);
+ debounce_init(2);
+
+ // setup debouncer
+ debo_init_t debo = {};
+ debo.debo_time = 10;
+ debo.invert = true;
+
+ // button A
+ debo.GPIOx = BUTTON_A_Port;
+ debo.pin = BUTTON_A_Pin;
+ debo.rising_cb = left_btn_click;
+ debo_register_pin(&debo);
+
+ // Button B
+ debo.GPIOx = BUTTON_B_Port;
+ debo.pin = BUTTON_B_Pin;
+ debo.rising_cb = right_btn_click;
+ debo_register_pin(&debo);
+
+ add_periodic_task(debo_periodic_task, NULL, 10, true);
+}
+
+
+static void poll_subsystems(void)
+{
+ // poll serial buffers (runs callback)
+ com_poll(debug_iface);
+ com_poll(data_iface);
+
+ // run queued tasks
+ tq_poll();
+
+ // handle queued events
+ Event evt;
+
+ until_timeout(2) { // take 2 ms max
+ if (eq_take(&evt)) {
+ run_event_handler(&evt);
+ } else {
+ break;
+ }
+ }
}
diff --git a/project/stm32f10x_it.c b/project/stm32f10x_it.c
index 1938e00..fc03c8c 100644
--- a/project/stm32f10x_it.c
+++ b/project/stm32f10x_it.c
@@ -24,6 +24,9 @@
/* Includes ------------------------------------------------------------------*/
#include "stm32f10x_it.h"
#include "utils/timebase.h"
+#include "main.h"
+#include "dspin.h"
+#include "dspin_config.h"
/** @addtogroup STM32F10x_StdPeriph_Template
* @{
@@ -57,10 +60,9 @@ void NMI_Handler(void)
void __attribute__((noreturn))
HardFault_Handler(void)
{
- /* Go to infinite loop when Hard Fault exception occurs */
- while (1)
- {
- }
+ /* Go to infinite loop when Hard Fault exception occurs */
+ while (1) {
+ }
}
/**
@@ -71,10 +73,9 @@ HardFault_Handler(void)
void __attribute__((noreturn))
MemManage_Handler(void)
{
- /* Go to infinite loop when Memory Manage exception occurs */
- while (1)
- {
- }
+ /* Go to infinite loop when Memory Manage exception occurs */
+ while (1) {
+ }
}
/**
@@ -85,10 +86,9 @@ MemManage_Handler(void)
void __attribute__((noreturn))
BusFault_Handler(void)
{
- /* Go to infinite loop when Bus Fault exception occurs */
- while (1)
- {
- }
+ /* Go to infinite loop when Bus Fault exception occurs */
+ while (1) {
+ }
}
/**
@@ -99,10 +99,9 @@ BusFault_Handler(void)
void __attribute__((noreturn))
UsageFault_Handler(void)
{
- /* Go to infinite loop when Usage Fault exception occurs */
- while (1)
- {
- }
+ /* Go to infinite loop when Usage Fault exception occurs */
+ while (1) {
+ }
}
/**
@@ -149,14 +148,298 @@ void SysTick_Handler(void)
/* file (startup_stm32f10x_xx.s). */
/******************************************************************************/
+/******************************************************************************/
+/* STM32F10x Peripherals Interrupt Handlers */
+/******************************************************************************/
+
+/**
+ * @brief This function handles RCC interrupt request.
+ * @param None
+ * @retval None
+ */
+void RCC_IRQHandler(void)
+{
+ if (RCC_GetITStatus(RCC_IT_HSERDY) != RESET) {
+ /* Clear HSERDY interrupt pending bit */
+ RCC_ClearITPendingBit(RCC_IT_HSERDY);
+
+ /* Check if the HSE clock is still available */
+ if (RCC_GetFlagStatus(RCC_FLAG_HSERDY) != RESET) {
+#ifdef SYSCLK_HSE
+ /* Select HSE as system clock source */
+ RCC_SYSCLKConfig(RCC_SYSCLKSource_HSE);
+#else
+
+ /* Enable PLL: once the PLL is ready the PLLRDY interrupt is generated */
+ RCC_PLLCmd(ENABLE);
+
+#endif /* SYSCLK_HSE */
+ }
+ }
+
+ if (RCC_GetITStatus(RCC_IT_PLLRDY) != RESET) {
+ /* Clear PLLRDY interrupt pending bit */
+ RCC_ClearITPendingBit(RCC_IT_PLLRDY);
+
+ /* Check if the PLL is still locked */
+ if (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) != RESET) {
+ /* Select PLL as system clock source */
+ RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
+ }
+ }
+}
+
+#if defined(STEVAL_PCC009V2)
+/**
+ * @brief This function handles External interrupt Line 2 request.
+ * @param None
+ * @retval None
+ */
+void EXTI2_IRQHandler(void)
+{
+ if (EXTI_GetITStatus(EXTI_Line2) != RESET) {
+ /* Clear the EXTI line 2 pending bit */
+ EXTI_ClearITPendingBit(EXTI_Line2);
+ if (daisy_chain != 0) {
+ if (number_of_slaves > 1) {
+ cmdArray[DEVICE_1] = dSPIN_SOFT_HIZ;
+ cmdArray[DEVICE_2] = dSPIN_SOFT_HIZ;
+ dSPIN_All_Slaves_Send_Command(number_of_slaves, cmdArray, 0);
+ } else {
+ /* Wait just in case the motor is accelerating or decelerating */
+ while (dSPIN_Busy_HW());
+ dSPIN_All_Slaves_Get_Status(number_of_slaves, rspArray);
+ dSPIN_rxdata = rspArray[DEVICE_1] & dSPIN_STATUS_MOT_STATUS;
+ if (dSPIN_rxdata == dSPIN_STATUS_MOT_STATUS_CONST_SPD) {
+ cmdArray[DEVICE_1] = dSPIN_SOFT_STOP;
+ dSPIN_All_Slaves_Send_Command(number_of_slaves, cmdArray, 0);
+ } else if (dSPIN_rxdata == dSPIN_STATUS_MOT_STATUS_STOPPED) {
+ dSPIN_One_Slave_Run(DEVICE_1, number_of_slaves, FWD, Speed_Steps_to_Par(MAX_SPEED[DEVICE_1]) >> 2);
+ } else {
+ assert_param(0);
+ }
+ }
+ } else {
+ /* Wait just in case the motor is accelerating or decelerating */
+ while (dSPIN_Busy_HW());
+ dSPIN_rxdata = dSPIN_Get_Status() & dSPIN_STATUS_MOT_STATUS;
+ if (dSPIN_rxdata == dSPIN_STATUS_MOT_STATUS_CONST_SPD) {
+ dSPIN_Soft_HiZ();
+ } else if (dSPIN_rxdata == dSPIN_STATUS_MOT_STATUS_STOPPED) {
+ dSPIN_Run(FWD, Speed_Steps_to_Par(((uint16_t)(dSPIN_CONF_PARAM_MAX_SPEED)) >> 2));
+ } else {
+ assert_param(0);
+ }
+ }
+ }
+}
+
+/**
+ * @brief This function handles External interrupt Line 3 request.
+ * @param None
+ * @retval None
+ */
+void EXTI3_IRQHandler(void)
+{
+ if (EXTI_GetITStatus(EXTI_Line3) != RESET) {
+ /* Clear the EXTI line 3 pending bit */
+ EXTI_ClearITPendingBit(EXTI_Line3);
+ /* Wait until the motor is not busy */
+ while (dSPIN_Busy_HW());
+ if (daisy_chain != 0) {
+ if (number_of_slaves > 1) {
+ dSPIN_One_Slave_Run(DEVICE_2, number_of_slaves, FWD, Speed_Steps_to_Par(MAX_SPEED[DEVICE_2]));
+ } else {
+ /* Read current speed parameter from dSPIN */
+ cmdArray[DEVICE_1] = dSPIN_SPEED;
+ dSPIN_All_Slaves_Get_Param(number_of_slaves, cmdArray, rspArray);
+ /* Halve the motor speed */
+ dSPIN_One_Slave_Run(DEVICE_1, number_of_slaves, FWD, rspArray[DEVICE_1] >> 1);
+ }
+ } else {
+ /* Read current speed parameter from dSPIN */
+ dSPIN_rxdata = dSPIN_Get_Param(dSPIN_SPEED);
+ /* Halve the motor speed */
+ dSPIN_Run(FWD, dSPIN_rxdata >> 1);
+ }
+ }
+}
+
+/**
+ * @brief This function handles External lines 9 to 5 interrupt request.
+ * @param None
+ * @retval None
+ */
+void EXTI9_5_IRQHandler(void)
+{
+ if (EXTI_GetITStatus(EXTI_Line6) != RESET) {
+ /* Clear the EXTI line 6 pending bit */
+ EXTI_ClearITPendingBit(EXTI_Line6);
+ /* Wait until the motor is not busy */
+ while (dSPIN_Busy_HW());
+ if (daisy_chain != 0) {
+ if (number_of_slaves > 1) {
+ dSPIN_One_Slave_Run(DEVICE_1, number_of_slaves, FWD, Speed_Steps_to_Par(MAX_SPEED[DEVICE_1]));
+ } else {
+ /* Read current speed parameter from dSPIN */
+ cmdArray[DEVICE_1] = dSPIN_SPEED;
+ dSPIN_All_Slaves_Get_Param(number_of_slaves, cmdArray, rspArray);
+ /* Double the motor speed */
+ dSPIN_One_Slave_Run(DEVICE_1, number_of_slaves, FWD, rspArray[DEVICE_1] << 1);
+ }
+ } else {
+ /* Read current speed parameter from dSPIN */
+ dSPIN_rxdata = dSPIN_Get_Param(dSPIN_SPEED);
+ /* Double the motor speed */
+ dSPIN_Run(FWD, dSPIN_rxdata << 1);
+ }
+ }
+}
+
+/**
+ * @brief This function handles External lines 15 to 10 interrupt request.
+ * @param None
+ * @retval None
+ */
+void EXTI15_10_IRQHandler(void)
+{
+ if (EXTI_GetITStatus(EXTI_Line10) != RESET) {
+ /* Clear the EXTI line 10 pending bit */
+ EXTI_ClearITPendingBit(EXTI_Line10);
+ if (GPIO_ReadInputDataBit(dSPIN_BUSY_Port, dSPIN_BUSY_Pin) == Bit_RESET) {
+ GPIO_SetBits(POWER_LED_Port, POWER_LED_Pin);
+ } else {
+ GPIO_ResetBits(POWER_LED_Port, POWER_LED_Pin);
+ }
+ }
+ if (EXTI_GetITStatus(EXTI_Line11) != RESET) {
+ /* Clear the EXTI line 11 pending bit */
+ EXTI_ClearITPendingBit(EXTI_Line11);
+ if (GPIO_ReadInputDataBit(dSPIN_FLAG_Port, dSPIN_FLAG_Pin) == Bit_RESET) {
+ GPIO_SetBits(STATUS_LED_Port, STATUS_LED_Pin);
+ } else {
+ GPIO_ResetBits(STATUS_LED_Port, STATUS_LED_Pin);
+ }
+ }
+}
+#endif /* defined(STEVAL_PCC009V2) */
+
+#if defined(ST_DSPIN_6470H_DISCOVERY)
+/**
+ * @brief This function handles External interrupt Line 0 request.
+ * @param None
+ * @retval None
+ */
+void EXTI0_IRQHandler(void)
+{
+ if (EXTI_GetITStatus(EXTI_Line0) != RESET) {
+ /* Clear the EXTI line 0 pending bit */
+ EXTI_ClearITPendingBit(EXTI_Line0);
+ GPIO_ResetBits(dSPIN_SW_Port, dSPIN_SW_Pin);
+ dSPIN_Delay(0x00010000);
+ GPIO_SetBits(dSPIN_SW_Port, dSPIN_SW_Pin);
+ }
+}
+
+/**
+ * @brief This function handles External interrupt Line 1 request.
+ * @param None
+ * @retval None
+ */
+void EXTI1_IRQHandler(void)
+{
+ uint32_t dSPIN_rxdata;
+
+ if (EXTI_GetITStatus(EXTI_Line1) != RESET) {
+ /* Clear the EXTI line 1 pending bit */
+ EXTI_ClearITPendingBit(EXTI_Line1);
+ /* Wait just in case the motor is accelerating or decelerating */
+ while (dSPIN_Busy_HW());
+ dSPIN_rxdata = dSPIN_Get_Status() & dSPIN_STATUS_MOT_STATUS;
+ /* Accelerate if the motor is already running at constant speed */
+ if (dSPIN_rxdata == dSPIN_STATUS_MOT_STATUS_CONST_SPD) {
+ /* Read current speed parameter from dSPIN */
+ dSPIN_rxdata = dSPIN_Get_Param(dSPIN_SPEED);
+ /* Double the motor speed */
+ dSPIN_Run(FWD, dSPIN_rxdata << 1);
+ }
+ /* Start the motor */
+ else if (dSPIN_rxdata == dSPIN_STATUS_MOT_STATUS_STOPPED) {
+ dSPIN_Run(FWD, Speed_Steps_to_Par(((uint16_t)(dSPIN_CONF_PARAM_MAX_SPEED)) >> 2));
+ /* Warns the user that the motor is running by switching ON a LED */
+ GPIO_SetBits(LED_SPARE_Port, LED_SPARE_Pin);
+ }
+ /* Unexpected motor status */
+ else {
+ assert_param(0);
+ }
+ }
+}
+
/**
- * @brief This function handles PPP interrupt request.
+ * @brief This function handles External interrupt Line 2 request.
* @param None
* @retval None
*/
-/*void PPP_IRQHandler(void)
+void EXTI2_IRQHandler(void)
{
-}*/
+ uint32_t dSPIN_rxdata;
+
+ if (EXTI_GetITStatus(EXTI_Line2) != RESET) {
+ /* Clear the EXTI line 2 pending bit */
+ EXTI_ClearITPendingBit(EXTI_Line2);
+ /* Wait just in case the motor is accelerating or decelerating */
+ while (dSPIN_Busy_HW());
+ dSPIN_rxdata = dSPIN_Get_Status() & dSPIN_STATUS_MOT_STATUS;
+ /* Decelerate if the motor is already running at constant speed */
+ if (dSPIN_rxdata == dSPIN_STATUS_MOT_STATUS_CONST_SPD) {
+ /* Read current speed parameter from dSPIN */
+ dSPIN_rxdata = dSPIN_Get_Param(dSPIN_SPEED);
+ if ((dSPIN_rxdata >> 1) > Speed_Steps_to_Par(dSPIN_CONF_PARAM_MIN_SPEED)) {
+ /* Halve the motor speed */
+ dSPIN_Run(FWD, dSPIN_rxdata >> 1);
+ } else {
+ /* Disable the power bridges after a smooth stop */
+ dSPIN_Soft_HiZ();
+ /* Warns the user that the motor is stopped by switching off a LED */
+ GPIO_ResetBits(LED_SPARE_Port, LED_SPARE_Pin);
+ }
+ }
+ /* Unexpected motor status */
+ else if (dSPIN_rxdata != dSPIN_STATUS_MOT_STATUS_STOPPED) {
+ assert_param(0);
+ }
+ }
+}
+
+/**
+ * @brief This function handles External lines 15 to 10 interrupt request.
+ * @param None
+ * @retval None
+ */
+void EXTI15_10_IRQHandler(void)
+{
+ if (EXTI_GetITStatus(EXTI_Line10) != RESET) {
+ /* Clear the EXTI line 10 pending bit */
+ EXTI_ClearITPendingBit(EXTI_Line10);
+ if (GPIO_ReadInputDataBit(dSPIN_FLAG_Port, dSPIN_FLAG_Pin) == Bit_RESET) {
+ GPIO_SetBits(STATUS_LED_Port, STATUS_LED_Pin);
+ } else {
+ GPIO_ResetBits(STATUS_LED_Port, STATUS_LED_Pin);
+ }
+ }
+ if (EXTI_GetITStatus(EXTI_Line11) != RESET) {
+ /* Clear the EXTI line 11 pending bit */
+ EXTI_ClearITPendingBit(EXTI_Line11);
+ if (GPIO_ReadInputDataBit(dSPIN_BUSY_Port, dSPIN_BUSY_Pin) == Bit_RESET) {
+ GPIO_SetBits(LED_BUSY_Port, LED_BUSY_Pin);
+ } else {
+ GPIO_ResetBits(LED_BUSY_Port, LED_BUSY_Pin);
+ }
+ }
+}
+#endif /* defined(ST_DSPIN_6470H_DISCOVERY) */
+
/**
* @}
diff --git a/project/utils/debounce.c b/project/utils/debounce.c
index 0834d0a..d534abe 100644
--- a/project/utils/debounce.c
+++ b/project/utils/debounce.c
@@ -3,6 +3,8 @@
#include "timebase.h"
#include "malloc_safe.h"
+#include "com/debug.h"
+
// ms debounce time
#define DEF_DEBO_TIME 20
@@ -90,8 +92,10 @@ debo_id_t debo_register_pin(debo_init_t *init)
/** Callback that must be called every 1 ms */
-void debo_periodic_task(void)
+void debo_periodic_task(void *arg)
{
+ (void)arg;
+
for (size_t i = 0; i < debo_slot_count; i++) {
debo_slot_t *slot = &debo_slots[i];
if (slot->id == DEBO_PIN_NONE) continue; // unused
@@ -102,20 +106,20 @@ void debo_periodic_task(void)
if (slot->state != state) {
if (state == 0) {
// falling
-
- if (slot->counter_0++ == slot->debo_time) {
+ if (slot->counter_0++ >= slot->debo_time) {
slot->state = 0;
+
if (slot->falling_cb != NULL) {
slot->falling_cb();
}
}
} else {
// rising
-
- if (slot->counter_1++ == slot->debo_time) {
+ if (slot->counter_1++ >= slot->debo_time) {
slot->state = 1;
+
if (slot->rising_cb != NULL) {
slot->rising_cb();
}
diff --git a/project/utils/debounce.h b/project/utils/debounce.h
index ecc17e9..eb0c5f3 100644
--- a/project/utils/debounce.h
+++ b/project/utils/debounce.h
@@ -24,7 +24,7 @@ void debounce_init(size_t pin_count);
/**
* @brief 1 ms periodic callback for debouncer. Must be registered to timebase.
*/
-void debo_periodic_task(void);
+void debo_periodic_task(void*);
typedef struct {