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 {