diff --git a/targets/TARGET_STM/TARGET_STM32F0/TARGET_DISCO_F051R8/objects.h b/targets/TARGET_STM/TARGET_STM32F0/TARGET_DISCO_F051R8/objects.h index 4a19b70bd6..70b7bcf2a4 100644 --- a/targets/TARGET_STM/TARGET_STM32F0/TARGET_DISCO_F051R8/objects.h +++ b/targets/TARGET_STM/TARGET_STM32F0/TARGET_DISCO_F051R8/objects.h @@ -66,20 +66,6 @@ struct dac_s { uint32_t channel; }; -struct spi_s { - SPIName spi; - uint32_t bits; - uint32_t cpol; - uint32_t cpha; - uint32_t mode; - uint32_t nss; - uint32_t br_presc; - PinName pin_miso; - PinName pin_mosi; - PinName pin_sclk; - PinName pin_ssel; -}; - struct i2c_s { I2CName i2c; }; diff --git a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F030R8/objects.h b/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F030R8/objects.h index 16c179a610..f006abac8a 100644 --- a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F030R8/objects.h +++ b/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F030R8/objects.h @@ -60,20 +60,6 @@ struct analogin_s { uint32_t channel; }; -struct spi_s { - SPIName spi; - uint32_t bits; - uint32_t cpol; - uint32_t cpha; - uint32_t mode; - uint32_t nss; - uint32_t br_presc; - PinName pin_miso; - PinName pin_mosi; - PinName pin_sclk; - PinName pin_ssel; -}; - struct i2c_s { I2CName i2c; }; diff --git a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F031K6/objects.h b/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F031K6/objects.h index 16c179a610..f006abac8a 100644 --- a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F031K6/objects.h +++ b/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F031K6/objects.h @@ -60,20 +60,6 @@ struct analogin_s { uint32_t channel; }; -struct spi_s { - SPIName spi; - uint32_t bits; - uint32_t cpol; - uint32_t cpha; - uint32_t mode; - uint32_t nss; - uint32_t br_presc; - PinName pin_miso; - PinName pin_mosi; - PinName pin_sclk; - PinName pin_ssel; -}; - struct i2c_s { I2CName i2c; }; diff --git a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F042K6/objects.h b/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F042K6/objects.h index 10cf3d139b..6a4a844c46 100644 --- a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F042K6/objects.h +++ b/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F042K6/objects.h @@ -60,20 +60,6 @@ struct analogin_s { uint32_t channel; }; -struct spi_s { - SPIName spi; - uint32_t bits; - uint32_t cpol; - uint32_t cpha; - uint32_t mode; - uint32_t nss; - uint32_t br_presc; - PinName pin_miso; - PinName pin_mosi; - PinName pin_sclk; - PinName pin_ssel; -}; - struct i2c_s { I2CName i2c; }; diff --git a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F070RB/objects.h b/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F070RB/objects.h index 16c179a610..f006abac8a 100644 --- a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F070RB/objects.h +++ b/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F070RB/objects.h @@ -60,20 +60,6 @@ struct analogin_s { uint32_t channel; }; -struct spi_s { - SPIName spi; - uint32_t bits; - uint32_t cpol; - uint32_t cpha; - uint32_t mode; - uint32_t nss; - uint32_t br_presc; - PinName pin_miso; - PinName pin_mosi; - PinName pin_sclk; - PinName pin_ssel; -}; - struct i2c_s { I2CName i2c; }; diff --git a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F072RB/objects.h b/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F072RB/objects.h index 8f908717dc..11c94c0507 100644 --- a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F072RB/objects.h +++ b/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F072RB/objects.h @@ -66,20 +66,6 @@ struct dac_s { uint32_t channel; }; -struct spi_s { - SPIName spi; - uint32_t bits; - uint32_t cpol; - uint32_t cpha; - uint32_t mode; - uint32_t nss; - uint32_t br_presc; - PinName pin_miso; - PinName pin_mosi; - PinName pin_sclk; - PinName pin_ssel; -}; - struct i2c_s { I2CName i2c; }; diff --git a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F091RC/objects.h b/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F091RC/objects.h index 8f908717dc..11c94c0507 100644 --- a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F091RC/objects.h +++ b/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F091RC/objects.h @@ -66,20 +66,6 @@ struct dac_s { uint32_t channel; }; -struct spi_s { - SPIName spi; - uint32_t bits; - uint32_t cpol; - uint32_t cpha; - uint32_t mode; - uint32_t nss; - uint32_t br_presc; - PinName pin_miso; - PinName pin_mosi; - PinName pin_sclk; - PinName pin_ssel; -}; - struct i2c_s { I2CName i2c; }; diff --git a/targets/TARGET_STM/TARGET_STM32F0/common_objects.h b/targets/TARGET_STM/TARGET_STM32F0/common_objects.h index 41fa23726f..3bbfc82717 100644 --- a/targets/TARGET_STM/TARGET_STM32F0/common_objects.h +++ b/targets/TARGET_STM/TARGET_STM32F0/common_objects.h @@ -49,6 +49,21 @@ struct pwmout_s { uint8_t inverted; }; +struct spi_s { + SPI_HandleTypeDef handle; + IRQn_Type spiIRQ; + SPIName spi; + PinName pin_miso; + PinName pin_mosi; + PinName pin_sclk; + PinName pin_ssel; +#ifdef DEVICE_SPI_ASYNCH + uint32_t event; + uint8_t module; + uint8_t transfer_type; +#endif +}; + struct serial_s { UARTName uart; int index; // Used by irq diff --git a/targets/TARGET_STM/TARGET_STM32F0/spi_api.c b/targets/TARGET_STM/TARGET_STM32F0/spi_api.c index 117a441ded..d7dc4c10dd 100644 --- a/targets/TARGET_STM/TARGET_STM32F0/spi_api.c +++ b/targets/TARGET_STM/TARGET_STM32F0/spi_api.c @@ -32,260 +32,23 @@ #include "spi_api.h" #if DEVICE_SPI - -#include #include "cmsis.h" #include "pinmap.h" #include "PeripheralPins.h" -static SPI_HandleTypeDef SpiHandle; - -static void init_spi(spi_t *obj) { - SpiHandle.Instance = (SPI_TypeDef *)(obj->spi); - - __HAL_SPI_DISABLE(&SpiHandle); - - SpiHandle.Init.Mode = obj->mode; - SpiHandle.Init.BaudRatePrescaler = obj->br_presc; - SpiHandle.Init.Direction = SPI_DIRECTION_2LINES; - SpiHandle.Init.CLKPhase = obj->cpha; - SpiHandle.Init.CLKPolarity = obj->cpol; - SpiHandle.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED; - SpiHandle.Init.CRCPolynomial = 7; - SpiHandle.Init.DataSize = obj->bits; - SpiHandle.Init.FirstBit = SPI_FIRSTBIT_MSB; - SpiHandle.Init.NSS = obj->nss; - SpiHandle.Init.TIMode = SPI_TIMODE_DISABLED; - - HAL_SPI_Init(&SpiHandle); - - __HAL_SPI_ENABLE(&SpiHandle); -} - -void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel) { - // Determine the SPI to use - SPIName spi_mosi = (SPIName)pinmap_peripheral(mosi, PinMap_SPI_MOSI); - SPIName spi_miso = (SPIName)pinmap_peripheral(miso, PinMap_SPI_MISO); - SPIName spi_sclk = (SPIName)pinmap_peripheral(sclk, PinMap_SPI_SCLK); - SPIName spi_ssel = (SPIName)pinmap_peripheral(ssel, PinMap_SPI_SSEL); - - SPIName spi_data = (SPIName)pinmap_merge(spi_mosi, spi_miso); - SPIName spi_cntl = (SPIName)pinmap_merge(spi_sclk, spi_ssel); - - obj->spi = (SPIName)pinmap_merge(spi_data, spi_cntl); - MBED_ASSERT(obj->spi != (SPIName)NC); - - // Enable SPI clock - if (obj->spi == SPI_1) { - __SPI1_CLK_ENABLE(); - } -#if defined(SPI2_BASE) - if (obj->spi == SPI_2) { - __SPI2_CLK_ENABLE(); - } +#if DEVICE_SPI_ASYNCH + #define SPI_S(obj) (( struct spi_s *)(&(obj->spi))) +#else + #define SPI_S(obj) (( struct spi_s *)(obj)) #endif - // Configure the SPI pins - pinmap_pinout(mosi, PinMap_SPI_MOSI); - pinmap_pinout(miso, PinMap_SPI_MISO); - pinmap_pinout(sclk, PinMap_SPI_SCLK); - - // Save new values - obj->bits = SPI_DATASIZE_8BIT; - obj->cpol = SPI_POLARITY_LOW; - obj->cpha = SPI_PHASE_1EDGE; - obj->br_presc = SPI_BAUDRATEPRESCALER_256; - - obj->pin_miso = miso; - obj->pin_mosi = mosi; - obj->pin_sclk = sclk; - obj->pin_ssel = ssel; - - if (ssel != NC) { - pinmap_pinout(ssel, PinMap_SPI_SSEL); - } else { - obj->nss = SPI_NSS_SOFT; - } - - init_spi(obj); -} - -void spi_free(spi_t *obj) { - // Reset SPI and disable clock - if (obj->spi == SPI_1) { - __SPI1_FORCE_RESET(); - __SPI1_RELEASE_RESET(); - __SPI1_CLK_DISABLE(); - } - -#if defined(SPI2_BASE) - if (obj->spi == SPI_2) { - __SPI2_FORCE_RESET(); - __SPI2_RELEASE_RESET(); - __SPI2_CLK_DISABLE(); - } -#endif - - // Configure GPIOs - pin_function(obj->pin_miso, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0)); - pin_function(obj->pin_mosi, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0)); - pin_function(obj->pin_sclk, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0)); - pin_function(obj->pin_ssel, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0)); -} - -void spi_format(spi_t *obj, int bits, int mode, int slave) { - // Save new values - if (bits == 16) { - obj->bits = SPI_DATASIZE_16BIT; - } else { - obj->bits = SPI_DATASIZE_8BIT; - } - - switch (mode) { - case 0: - obj->cpol = SPI_POLARITY_LOW; - obj->cpha = SPI_PHASE_1EDGE; - break; - case 1: - obj->cpol = SPI_POLARITY_LOW; - obj->cpha = SPI_PHASE_2EDGE; - break; - case 2: - obj->cpol = SPI_POLARITY_HIGH; - obj->cpha = SPI_PHASE_1EDGE; - break; - default: - obj->cpol = SPI_POLARITY_HIGH; - obj->cpha = SPI_PHASE_2EDGE; - break; - } - - if (obj->nss != SPI_NSS_SOFT) { - obj->nss = (slave) ? SPI_NSS_HARD_INPUT : SPI_NSS_HARD_OUTPUT; - } - - obj->mode = (slave) ? SPI_MODE_SLAVE : SPI_MODE_MASTER; - - init_spi(obj); -} - -static const uint16_t baudrate_prescaler_table[] = {SPI_BAUDRATEPRESCALER_2, - SPI_BAUDRATEPRESCALER_4, - SPI_BAUDRATEPRESCALER_8, - SPI_BAUDRATEPRESCALER_16, - SPI_BAUDRATEPRESCALER_32, - SPI_BAUDRATEPRESCALER_64, - SPI_BAUDRATEPRESCALER_128, - SPI_BAUDRATEPRESCALER_256}; - -void spi_frequency(spi_t *obj, int hz) { - int spi_hz = 0; - uint8_t prescaler_rank = 0; - +/* + * Only the frequency is managed in the family specific part + * the rest of SPI management is common to all STM32 families + */ +int spi_get_clock_freq(spi_t *obj) { /* SPI_1, SPI_2. Source CLK is PCKL1 */ - spi_hz = HAL_RCC_GetPCLK1Freq(); - - /* Define pre-scaler in order to get highest available frequency below requested frequency */ - while ((spi_hz > hz) && (prescaler_rank < sizeof(baudrate_prescaler_table)/sizeof(baudrate_prescaler_table[0]))){ - spi_hz = spi_hz / 2; - prescaler_rank++; - } - - if (prescaler_rank <= sizeof(baudrate_prescaler_table)/sizeof(baudrate_prescaler_table[0])) { - obj->br_presc = baudrate_prescaler_table[prescaler_rank-1]; - } else { - error("Couldn't setup requested SPI frequency"); - } - - init_spi(obj); -} - -static inline int ssp_readable(spi_t *obj) { - int status; - SpiHandle.Instance = (SPI_TypeDef *)(obj->spi); - // Check if data is received - status = ((__HAL_SPI_GET_FLAG(&SpiHandle, SPI_FLAG_RXNE) != RESET) ? 1 : 0); - return status; -} - -static inline int ssp_writeable(spi_t *obj) { - int status; - SpiHandle.Instance = (SPI_TypeDef *)(obj->spi); - // Check if data is transmitted - status = ((__HAL_SPI_GET_FLAG(&SpiHandle, SPI_FLAG_TXE) != RESET) ? 1 : 0); - return status; -} - -static inline void ssp_write(spi_t *obj, int value) { - SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi); - while (!ssp_writeable(obj)); - if (obj->bits == SPI_DATASIZE_8BIT) { - // Force 8-bit access to the data register - uint8_t *p_spi_dr = 0; - p_spi_dr = (uint8_t *) & (spi->DR); - *p_spi_dr = (uint8_t)value; - } else { // SPI_DATASIZE_16BIT - spi->DR = (uint16_t)value; - } -} - -static inline int ssp_read(spi_t *obj) { - SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi); - while (!ssp_readable(obj)); - if (obj->bits == SPI_DATASIZE_8BIT) { - // Force 8-bit access to the data register - uint8_t *p_spi_dr = 0; - p_spi_dr = (uint8_t *) & (spi->DR); - return (int)(*p_spi_dr); - } else { - return (int)spi->DR; - } -} - -static inline int ssp_busy(spi_t *obj) { - int status; - SpiHandle.Instance = (SPI_TypeDef *)(obj->spi); - status = ((__HAL_SPI_GET_FLAG(&SpiHandle, SPI_FLAG_BSY) != RESET) ? 1 : 0); - return status; -} - -int spi_master_write(spi_t *obj, int value) { - ssp_write(obj, value); - return ssp_read(obj); -} - -int spi_slave_receive(spi_t *obj) { - return ((ssp_readable(obj) && !ssp_busy(obj)) ? 1 : 0); -}; - -int spi_slave_read(spi_t *obj) { - SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi); - while (!ssp_readable(obj)); - if (obj->bits == SPI_DATASIZE_8BIT) { - // Force 8-bit access to the data register - uint8_t *p_spi_dr = 0; - p_spi_dr = (uint8_t *) & (spi->DR); - return (int)(*p_spi_dr); - } else { - return (int)spi->DR; - } -} - -void spi_slave_write(spi_t *obj, int value) { - SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi); - while (!ssp_writeable(obj)); - if (obj->bits == SPI_DATASIZE_8BIT) { - // Force 8-bit access to the data register - uint8_t *p_spi_dr = 0; - p_spi_dr = (uint8_t *) & (spi->DR); - *p_spi_dr = (uint8_t)value; - } else { // SPI_DATASIZE_16BIT - spi->DR = (uint16_t)value; - } -} - -int spi_busy(spi_t *obj) { - return ssp_busy(obj); + return HAL_RCC_GetPCLK1Freq(); } #endif diff --git a/targets/TARGET_STM/TARGET_STM32F1/TARGET_BLUEPILL_F103C8/objects.h b/targets/TARGET_STM/TARGET_STM32F1/TARGET_BLUEPILL_F103C8/objects.h index 3fc3ed5c33..708f2f5f7c 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/TARGET_BLUEPILL_F103C8/objects.h +++ b/targets/TARGET_STM/TARGET_STM32F1/TARGET_BLUEPILL_F103C8/objects.h @@ -60,20 +60,6 @@ struct analogin_s { uint8_t channel; }; -struct spi_s { - SPIName spi; - uint32_t bits; - uint32_t cpol; - uint32_t cpha; - uint32_t mode; - uint32_t nss; - uint32_t br_presc; - PinName pin_miso; - PinName pin_mosi; - PinName pin_sclk; - PinName pin_ssel; -}; - struct i2c_s { I2CName i2c; uint32_t slave; diff --git a/targets/TARGET_STM/TARGET_STM32F1/TARGET_DISCO_F100RB/objects.h b/targets/TARGET_STM/TARGET_STM32F1/TARGET_DISCO_F100RB/objects.h index fa4a724352..da4126e6ce 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/TARGET_DISCO_F100RB/objects.h +++ b/targets/TARGET_STM/TARGET_STM32F1/TARGET_DISCO_F100RB/objects.h @@ -60,20 +60,6 @@ struct analogin_s { uint8_t channel; }; -struct spi_s { - SPIName spi; - uint32_t bits; - uint32_t cpol; - uint32_t cpha; - uint32_t mode; - uint32_t nss; - uint32_t br_presc; - PinName pin_miso; - PinName pin_mosi; - PinName pin_sclk; - PinName pin_ssel; -}; - struct i2c_s { I2CName i2c; uint32_t slave; diff --git a/targets/TARGET_STM/TARGET_STM32F1/TARGET_NUCLEO_F103RB/objects.h b/targets/TARGET_STM/TARGET_STM32F1/TARGET_NUCLEO_F103RB/objects.h index e16970c065..b0b234ba74 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/TARGET_NUCLEO_F103RB/objects.h +++ b/targets/TARGET_STM/TARGET_STM32F1/TARGET_NUCLEO_F103RB/objects.h @@ -60,20 +60,6 @@ struct analogin_s { uint8_t channel; }; -struct spi_s { - SPIName spi; - uint32_t bits; - uint32_t cpol; - uint32_t cpha; - uint32_t mode; - uint32_t nss; - uint32_t br_presc; - PinName pin_miso; - PinName pin_mosi; - PinName pin_sclk; - PinName pin_ssel; -}; - struct i2c_s { I2CName i2c; uint32_t slave; diff --git a/targets/TARGET_STM/TARGET_STM32F1/common_objects.h b/targets/TARGET_STM/TARGET_STM32F1/common_objects.h index 585d323084..e39a16c019 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/common_objects.h +++ b/targets/TARGET_STM/TARGET_STM32F1/common_objects.h @@ -68,6 +68,21 @@ struct serial_s { #endif }; +struct spi_s { + SPI_HandleTypeDef handle; + IRQn_Type spiIRQ; + SPIName spi; + PinName pin_miso; + PinName pin_mosi; + PinName pin_sclk; + PinName pin_ssel; +#ifdef DEVICE_SPI_ASYNCH + uint32_t event; + uint8_t module; + uint8_t transfer_type; +#endif +}; + #include "gpio_object.h" #ifdef __cplusplus diff --git a/targets/TARGET_STM/TARGET_STM32F1/spi_api.c b/targets/TARGET_STM/TARGET_STM32F1/spi_api.c index 198c29acb8..6cd4d8af9d 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/spi_api.c +++ b/targets/TARGET_STM/TARGET_STM32F1/spi_api.c @@ -32,159 +32,26 @@ #include "spi_api.h" #if DEVICE_SPI - -#include #include "cmsis.h" #include "pinmap.h" #include "PeripheralPins.h" -static SPI_HandleTypeDef SpiHandle; +#if DEVICE_SPI_ASYNCH + #define SPI_S(obj) (( struct spi_s *)(&(obj->spi))) +#else + #define SPI_S(obj) (( struct spi_s *)(obj)) +#endif -static void init_spi(spi_t *obj) -{ - SpiHandle.Instance = (SPI_TypeDef *)(obj->spi); - - __HAL_SPI_DISABLE(&SpiHandle); - - SpiHandle.Init.Mode = obj->mode; - SpiHandle.Init.BaudRatePrescaler = obj->br_presc; - SpiHandle.Init.Direction = SPI_DIRECTION_2LINES; - SpiHandle.Init.CLKPhase = obj->cpha; - SpiHandle.Init.CLKPolarity = obj->cpol; - SpiHandle.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED; - SpiHandle.Init.CRCPolynomial = 7; - SpiHandle.Init.DataSize = obj->bits; - SpiHandle.Init.FirstBit = SPI_FIRSTBIT_MSB; - SpiHandle.Init.NSS = obj->nss; - SpiHandle.Init.TIMode = SPI_TIMODE_DISABLED; - - HAL_SPI_Init(&SpiHandle); - - __HAL_SPI_ENABLE(&SpiHandle); -} - -void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel) -{ - // Determine the SPI to use - SPIName spi_mosi = (SPIName)pinmap_peripheral(mosi, PinMap_SPI_MOSI); - SPIName spi_miso = (SPIName)pinmap_peripheral(miso, PinMap_SPI_MISO); - SPIName spi_sclk = (SPIName)pinmap_peripheral(sclk, PinMap_SPI_SCLK); - SPIName spi_ssel = (SPIName)pinmap_peripheral(ssel, PinMap_SPI_SSEL); - - SPIName spi_data = (SPIName)pinmap_merge(spi_mosi, spi_miso); - SPIName spi_cntl = (SPIName)pinmap_merge(spi_sclk, spi_ssel); - - obj->spi = (SPIName)pinmap_merge(spi_data, spi_cntl); - MBED_ASSERT(obj->spi != (SPIName)NC); - - // Enable SPI clock - if (obj->spi == SPI_1) { - __SPI1_CLK_ENABLE(); - } - if (obj->spi == SPI_2) { - __SPI2_CLK_ENABLE(); - } - - // Configure the SPI pins - pinmap_pinout(mosi, PinMap_SPI_MOSI); - pinmap_pinout(miso, PinMap_SPI_MISO); - pinmap_pinout(sclk, PinMap_SPI_SCLK); - - // Save new values - obj->bits = SPI_DATASIZE_8BIT; - obj->cpol = SPI_POLARITY_LOW; - obj->cpha = SPI_PHASE_1EDGE; - obj->br_presc = SPI_BAUDRATEPRESCALER_256; - - obj->pin_miso = miso; - obj->pin_mosi = mosi; - obj->pin_sclk = sclk; - obj->pin_ssel = ssel; - - if (ssel != NC) { - pinmap_pinout(ssel, PinMap_SPI_SSEL); - } else { - obj->nss = SPI_NSS_SOFT; - } - - init_spi(obj); -} - -void spi_free(spi_t *obj) -{ - // Reset SPI and disable clock - if (obj->spi == SPI_1) { - __SPI1_FORCE_RESET(); - __SPI1_RELEASE_RESET(); - __SPI1_CLK_DISABLE(); - } - - if (obj->spi == SPI_2) { - __SPI2_FORCE_RESET(); - __SPI2_RELEASE_RESET(); - __SPI2_CLK_DISABLE(); - } - - // Configure GPIOs - pin_function(obj->pin_miso, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0)); - pin_function(obj->pin_mosi, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0)); - pin_function(obj->pin_sclk, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0)); - pin_function(obj->pin_ssel, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0)); -} - -void spi_format(spi_t *obj, int bits, int mode, int slave) -{ - // Save new values - if (bits == 16) { - obj->bits = SPI_DATASIZE_16BIT; - } else { - obj->bits = SPI_DATASIZE_8BIT; - } - - switch (mode) { - case 0: - obj->cpol = SPI_POLARITY_LOW; - obj->cpha = SPI_PHASE_1EDGE; - break; - case 1: - obj->cpol = SPI_POLARITY_LOW; - obj->cpha = SPI_PHASE_2EDGE; - break; - case 2: - obj->cpol = SPI_POLARITY_HIGH; - obj->cpha = SPI_PHASE_1EDGE; - break; - default: - obj->cpol = SPI_POLARITY_HIGH; - obj->cpha = SPI_PHASE_2EDGE; - break; - } - - if (obj->nss != SPI_NSS_SOFT) { - obj->nss = (slave) ? SPI_NSS_HARD_INPUT : SPI_NSS_HARD_OUTPUT; - } - - obj->mode = (slave) ? SPI_MODE_SLAVE : SPI_MODE_MASTER; - - init_spi(obj); -} - -static const uint16_t baudrate_prescaler_table[] = {SPI_BAUDRATEPRESCALER_2, - SPI_BAUDRATEPRESCALER_4, - SPI_BAUDRATEPRESCALER_8, - SPI_BAUDRATEPRESCALER_16, - SPI_BAUDRATEPRESCALER_32, - SPI_BAUDRATEPRESCALER_64, - SPI_BAUDRATEPRESCALER_128, - SPI_BAUDRATEPRESCALER_256}; - -void spi_frequency(spi_t *obj, int hz) -{ - int spi_hz = 0; - uint8_t prescaler_rank = 0; +/* + * Only the frequency is managed in the family specific part + * the rest of SPI management is common to all STM32 families + */ +int spi_get_clock_freq(spi_t *obj) { + struct spi_s *spiobj = SPI_S(obj); + int spi_hz = 0; /* Get source clock depending on SPI instance */ - switch ((int)obj->spi) { + switch ((int)spiobj->spi) { case SPI_1: /* SPI_1. Source CLK is PCKL2 */ spi_hz = HAL_RCC_GetPCLK2Freq(); @@ -194,120 +61,10 @@ void spi_frequency(spi_t *obj, int hz) spi_hz = HAL_RCC_GetPCLK1Freq(); break; default: - error("SPI instance not set"); + error("CLK: SPI instance not set"); + break; } - - /* Define pre-scaler in order to get highest available frequency below requested frequency */ - while ((spi_hz > hz) && (prescaler_rank < sizeof(baudrate_prescaler_table)/sizeof(baudrate_prescaler_table[0]))){ - spi_hz = spi_hz / 2; - prescaler_rank++; - } - - if (prescaler_rank <= sizeof(baudrate_prescaler_table)/sizeof(baudrate_prescaler_table[0])) { - obj->br_presc = baudrate_prescaler_table[prescaler_rank-1]; - } else { - error("Couldn't setup requested SPI frequency"); - } - - init_spi(obj); -} - -static inline int ssp_readable(spi_t *obj) -{ - int status; - SpiHandle.Instance = (SPI_TypeDef *)(obj->spi); - // Check if data is received - status = ((__HAL_SPI_GET_FLAG(&SpiHandle, SPI_FLAG_RXNE) != RESET) ? 1 : 0); - return status; -} - -static inline int ssp_writeable(spi_t *obj) -{ - int status; - SpiHandle.Instance = (SPI_TypeDef *)(obj->spi); - // Check if data is transmitted - status = ((__HAL_SPI_GET_FLAG(&SpiHandle, SPI_FLAG_TXE) != RESET) ? 1 : 0); - return status; -} - -static inline void ssp_write(spi_t *obj, int value) -{ - SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi); - while (!ssp_writeable(obj)); - if (obj->bits == SPI_DATASIZE_8BIT) { - // Force 8-bit access to the data register - uint8_t *p_spi_dr = 0; - p_spi_dr = (uint8_t *) & (spi->DR); - *p_spi_dr = (uint8_t)value; - } else { // SPI_DATASIZE_16BIT - spi->DR = (uint16_t)value; - } -} - -static inline int ssp_read(spi_t *obj) -{ - SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi); - while (!ssp_readable(obj)); - if (obj->bits == SPI_DATASIZE_8BIT) { - // Force 8-bit access to the data register - uint8_t *p_spi_dr = 0; - p_spi_dr = (uint8_t *) & (spi->DR); - return (int)(*p_spi_dr); - } else { - return (int)spi->DR; - } -} - -static inline int ssp_busy(spi_t *obj) -{ - int status; - SpiHandle.Instance = (SPI_TypeDef *)(obj->spi); - status = ((__HAL_SPI_GET_FLAG(&SpiHandle, SPI_FLAG_BSY) != RESET) ? 1 : 0); - return status; -} - -int spi_master_write(spi_t *obj, int value) -{ - ssp_write(obj, value); - return ssp_read(obj); -} - -int spi_slave_receive(spi_t *obj) -{ - return ((ssp_readable(obj) && !ssp_busy(obj)) ? 1 : 0); -}; - -int spi_slave_read(spi_t *obj) -{ - SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi); - while (!ssp_readable(obj)); - if (obj->bits == SPI_DATASIZE_8BIT) { - // Force 8-bit access to the data register - uint8_t *p_spi_dr = 0; - p_spi_dr = (uint8_t *) & (spi->DR); - return (int)(*p_spi_dr); - } else { - return (int)spi->DR; - } -} - -void spi_slave_write(spi_t *obj, int value) -{ - SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi); - while (!ssp_writeable(obj)); - if (obj->bits == SPI_DATASIZE_8BIT) { - // Force 8-bit access to the data register - uint8_t *p_spi_dr = 0; - p_spi_dr = (uint8_t *) & (spi->DR); - *p_spi_dr = (uint8_t)value; - } else { // SPI_DATASIZE_16BIT - spi->DR = (uint16_t)value; - } -} - -int spi_busy(spi_t *obj) -{ - return ssp_busy(obj); + return spi_hz; } #endif diff --git a/targets/TARGET_STM/TARGET_STM32F2/objects.h b/targets/TARGET_STM/TARGET_STM32F2/objects.h index a2cf58dc60..5834dcd655 100644 --- a/targets/TARGET_STM/TARGET_STM32F2/objects.h +++ b/targets/TARGET_STM/TARGET_STM32F2/objects.h @@ -85,17 +85,18 @@ struct serial_s { }; struct spi_s { + SPI_HandleTypeDef handle; + IRQn_Type spiIRQ; SPIName spi; - uint32_t bits; - uint32_t cpol; - uint32_t cpha; - uint32_t mode; - uint32_t nss; - uint32_t br_presc; PinName pin_miso; PinName pin_mosi; PinName pin_sclk; PinName pin_ssel; +#ifdef DEVICE_SPI_ASYNCH + uint32_t event; + uint8_t module; + uint8_t transfer_type; +#endif }; struct i2c_s { diff --git a/targets/TARGET_STM/TARGET_STM32F2/spi_api.c b/targets/TARGET_STM/TARGET_STM32F2/spi_api.c index 095ed728ac..39ffb1d152 100644 --- a/targets/TARGET_STM/TARGET_STM32F2/spi_api.c +++ b/targets/TARGET_STM/TARGET_STM32F2/spi_api.c @@ -33,217 +33,27 @@ #if DEVICE_SPI -#include #include "cmsis.h" #include "pinmap.h" #include "PeripheralPins.h" #include "mbed_error.h" -static SPI_HandleTypeDef SpiHandle; - -static void init_spi(spi_t *obj) -{ - SpiHandle.Instance = (SPI_TypeDef *)(obj->spi); - - __HAL_SPI_DISABLE(&SpiHandle); - - SpiHandle.Init.Mode = obj->mode; - SpiHandle.Init.BaudRatePrescaler = obj->br_presc; - SpiHandle.Init.Direction = SPI_DIRECTION_2LINES; - SpiHandle.Init.CLKPhase = obj->cpha; - SpiHandle.Init.CLKPolarity = obj->cpol; - SpiHandle.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED; - SpiHandle.Init.CRCPolynomial = 7; - SpiHandle.Init.DataSize = obj->bits; - SpiHandle.Init.FirstBit = SPI_FIRSTBIT_MSB; - SpiHandle.Init.NSS = obj->nss; - SpiHandle.Init.TIMode = SPI_TIMODE_DISABLED; - - if (HAL_SPI_Init(&SpiHandle) != HAL_OK) { - error("Cannot initialize SPI"); - } - - __HAL_SPI_ENABLE(&SpiHandle); -} - -void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel) -{ - // Determine the SPI to use - SPIName spi_mosi = (SPIName)pinmap_peripheral(mosi, PinMap_SPI_MOSI); - SPIName spi_miso = (SPIName)pinmap_peripheral(miso, PinMap_SPI_MISO); - SPIName spi_sclk = (SPIName)pinmap_peripheral(sclk, PinMap_SPI_SCLK); - SPIName spi_ssel = (SPIName)pinmap_peripheral(ssel, PinMap_SPI_SSEL); - - SPIName spi_data = (SPIName)pinmap_merge(spi_mosi, spi_miso); - SPIName spi_cntl = (SPIName)pinmap_merge(spi_sclk, spi_ssel); - - obj->spi = (SPIName)pinmap_merge(spi_data, spi_cntl); - MBED_ASSERT(obj->spi != (SPIName)NC); - - // Enable SPI clock - if (obj->spi == SPI_1) { - __HAL_RCC_SPI1_CLK_ENABLE(); - } - - if (obj->spi == SPI_2) { - __HAL_RCC_SPI2_CLK_ENABLE(); - } - -#if defined SPI3_BASE - if (obj->spi == SPI_3) { - __HAL_RCC_SPI3_CLK_ENABLE(); - } +#if DEVICE_SPI_ASYNCH + #define SPI_S(obj) (( struct spi_s *)(&(obj->spi))) +#else + #define SPI_S(obj) (( struct spi_s *)(obj)) #endif -#if defined SPI4_BASE - if (obj->spi == SPI_4) { - __HAL_RCC_SPI4_CLK_ENABLE(); - } -#endif - -#if defined SPI5_BASE - if (obj->spi == SPI_5) { - __HAL_RCC_SPI5_CLK_ENABLE(); - } -#endif - -#if defined SPI6_BASE - if (obj->spi == SPI_6) { - __HAL_RCC_SPI6_CLK_ENABLE(); - } -#endif - - // Configure the SPI pins - pinmap_pinout(mosi, PinMap_SPI_MOSI); - pinmap_pinout(miso, PinMap_SPI_MISO); - pinmap_pinout(sclk, PinMap_SPI_SCLK); - - // Save new values - obj->bits = SPI_DATASIZE_8BIT; - obj->cpol = SPI_POLARITY_LOW; - obj->cpha = SPI_PHASE_1EDGE; - obj->br_presc = SPI_BAUDRATEPRESCALER_256; - - obj->pin_miso = miso; - obj->pin_mosi = mosi; - obj->pin_sclk = sclk; - obj->pin_ssel = ssel; - - if (ssel != NC) { - pinmap_pinout(ssel, PinMap_SPI_SSEL); - } else { - obj->nss = SPI_NSS_SOFT; - } - - init_spi(obj); -} - -void spi_free(spi_t *obj) -{ - // Reset SPI and disable clock - if (obj->spi == SPI_1) { - __HAL_RCC_SPI1_FORCE_RESET(); - __HAL_RCC_SPI1_RELEASE_RESET(); - __HAL_RCC_SPI1_CLK_DISABLE(); - } - - if (obj->spi == SPI_2) { - __HAL_RCC_SPI2_FORCE_RESET(); - __HAL_RCC_SPI2_RELEASE_RESET(); - __HAL_RCC_SPI2_CLK_DISABLE(); - } -#if defined SPI3_BASE - if (obj->spi == SPI_3) { - __HAL_RCC_SPI3_FORCE_RESET(); - __HAL_RCC_SPI3_RELEASE_RESET(); - __HAL_RCC_SPI3_CLK_DISABLE(); - } -#endif - -#if defined SPI4_BASE - if (obj->spi == SPI_4) { - __HAL_RCC_SPI4_FORCE_RESET(); - __HAL_RCC_SPI4_RELEASE_RESET(); - __HAL_RCC_SPI4_CLK_DISABLE(); - } -#endif - -#if defined SPI5_BASE - if (obj->spi == SPI_5) { - __HAL_RCC_SPI5_FORCE_RESET(); - __HAL_RCC_SPI5_RELEASE_RESET(); - __HAL_RCC_SPI5_CLK_DISABLE(); - } -#endif - -#if defined SPI6_BASE - if (obj->spi == SPI_6) { - __HAL_RCC_SPI6_FORCE_RESET(); - __HAL_RCC_SPI6_RELEASE_RESET(); - __HAL_RCC_SPI6_CLK_DISABLE(); - } -#endif - - // Configure GPIOs - pin_function(obj->pin_miso, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0)); - pin_function(obj->pin_mosi, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0)); - pin_function(obj->pin_sclk, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0)); - pin_function(obj->pin_ssel, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0)); -} - -void spi_format(spi_t *obj, int bits, int mode, int slave) -{ - // Save new values - if (bits == 16) { - obj->bits = SPI_DATASIZE_16BIT; - } else { - obj->bits = SPI_DATASIZE_8BIT; - } - - switch (mode) { - case 0: - obj->cpol = SPI_POLARITY_LOW; - obj->cpha = SPI_PHASE_1EDGE; - break; - case 1: - obj->cpol = SPI_POLARITY_LOW; - obj->cpha = SPI_PHASE_2EDGE; - break; - case 2: - obj->cpol = SPI_POLARITY_HIGH; - obj->cpha = SPI_PHASE_1EDGE; - break; - default: - obj->cpol = SPI_POLARITY_HIGH; - obj->cpha = SPI_PHASE_2EDGE; - break; - } - - if (obj->nss != SPI_NSS_SOFT) { - obj->nss = (slave) ? SPI_NSS_HARD_INPUT : SPI_NSS_HARD_OUTPUT; - } - - obj->mode = (slave) ? SPI_MODE_SLAVE : SPI_MODE_MASTER; - - init_spi(obj); -} - -static const uint16_t baudrate_prescaler_table[] = {SPI_BAUDRATEPRESCALER_2, - SPI_BAUDRATEPRESCALER_4, - SPI_BAUDRATEPRESCALER_8, - SPI_BAUDRATEPRESCALER_16, - SPI_BAUDRATEPRESCALER_32, - SPI_BAUDRATEPRESCALER_64, - SPI_BAUDRATEPRESCALER_128, - SPI_BAUDRATEPRESCALER_256}; - -void spi_frequency(spi_t *obj, int hz) -{ +/* + * Only the frequency is managed in the family specific part + * the rest of SPI management is common to all STM32 families + */ +int spi_get_clock_freq(spi_t *obj) { + struct spi_s *spiobj = SPI_S(obj); int spi_hz = 0; - uint8_t prescaler_rank = 0; /* Get source clock depending on SPI instance */ - switch ((int)obj->spi) { + switch ((int)spiobj->spi) { case SPI_1: #if defined SPI4_BASE case SPI_4: @@ -266,91 +76,9 @@ void spi_frequency(spi_t *obj, int hz) break; default: error("SPI instance not set"); + break; } - - /* Define pre-scaler in order to get highest available frequency below requested frequency */ - while ((spi_hz > hz) && (prescaler_rank < sizeof(baudrate_prescaler_table)/sizeof(baudrate_prescaler_table[0]))){ - spi_hz = spi_hz / 2; - prescaler_rank++; - } - - if (prescaler_rank <= sizeof(baudrate_prescaler_table)/sizeof(baudrate_prescaler_table[0])) { - obj->br_presc = baudrate_prescaler_table[prescaler_rank-1]; - } else { - error("Couldn't setup requested SPI frequency"); - } - - init_spi(obj); -} - -static inline int ssp_readable(spi_t *obj) -{ - int status; - SpiHandle.Instance = (SPI_TypeDef *)(obj->spi); - // Check if data is received - status = ((__HAL_SPI_GET_FLAG(&SpiHandle, SPI_FLAG_RXNE) != RESET) ? 1 : 0); - return status; -} - -static inline int ssp_writeable(spi_t *obj) -{ - int status; - SpiHandle.Instance = (SPI_TypeDef *)(obj->spi); - // Check if data is transmitted - status = ((__HAL_SPI_GET_FLAG(&SpiHandle, SPI_FLAG_TXE) != RESET) ? 1 : 0); - return status; -} - -static inline void ssp_write(spi_t *obj, int value) -{ - SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi); - while (!ssp_writeable(obj)); - spi->DR = (uint16_t)value; -} - -static inline int ssp_read(spi_t *obj) -{ - SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi); - while (!ssp_readable(obj)); - return (int)spi->DR; -} - -static inline int ssp_busy(spi_t *obj) -{ - int status; - SpiHandle.Instance = (SPI_TypeDef *)(obj->spi); - status = ((__HAL_SPI_GET_FLAG(&SpiHandle, SPI_FLAG_BSY) != RESET) ? 1 : 0); - return status; -} - -int spi_master_write(spi_t *obj, int value) -{ - ssp_write(obj, value); - return ssp_read(obj); -} - -int spi_slave_receive(spi_t *obj) -{ - return ((ssp_readable(obj) && !ssp_busy(obj)) ? 1 : 0); -}; - -int spi_slave_read(spi_t *obj) -{ - SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi); - while (!ssp_readable(obj)); - return (int)spi->DR; -} - -void spi_slave_write(spi_t *obj, int value) -{ - SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi); - while (!ssp_writeable(obj)); - spi->DR = (uint16_t)value; -} - -int spi_busy(spi_t *obj) -{ - return ssp_busy(obj); + return spi_hz; } #endif diff --git a/targets/TARGET_STM/TARGET_STM32F3/TARGET_DISCO_F303VC/objects.h b/targets/TARGET_STM/TARGET_STM32F3/TARGET_DISCO_F303VC/objects.h index e784a105d3..aeabfa3307 100644 --- a/targets/TARGET_STM/TARGET_STM32F3/TARGET_DISCO_F303VC/objects.h +++ b/targets/TARGET_STM/TARGET_STM32F3/TARGET_DISCO_F303VC/objects.h @@ -66,20 +66,6 @@ struct dac_s { uint32_t channel; }; -struct spi_s { - SPIName spi; - uint32_t bits; - uint32_t cpol; - uint32_t cpha; - uint32_t mode; - uint32_t nss; - uint32_t br_presc; - PinName pin_miso; - PinName pin_mosi; - PinName pin_sclk; - PinName pin_ssel; -}; - struct i2c_s { I2CName i2c; uint32_t slave; diff --git a/targets/TARGET_STM/TARGET_STM32F3/TARGET_DISCO_F334C8/objects.h b/targets/TARGET_STM/TARGET_STM32F3/TARGET_DISCO_F334C8/objects.h index e784a105d3..aeabfa3307 100644 --- a/targets/TARGET_STM/TARGET_STM32F3/TARGET_DISCO_F334C8/objects.h +++ b/targets/TARGET_STM/TARGET_STM32F3/TARGET_DISCO_F334C8/objects.h @@ -66,20 +66,6 @@ struct dac_s { uint32_t channel; }; -struct spi_s { - SPIName spi; - uint32_t bits; - uint32_t cpol; - uint32_t cpha; - uint32_t mode; - uint32_t nss; - uint32_t br_presc; - PinName pin_miso; - PinName pin_mosi; - PinName pin_sclk; - PinName pin_ssel; -}; - struct i2c_s { I2CName i2c; uint32_t slave; diff --git a/targets/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F302R8/objects.h b/targets/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F302R8/objects.h index 9650260ca4..61a56f7c04 100644 --- a/targets/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F302R8/objects.h +++ b/targets/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F302R8/objects.h @@ -66,20 +66,6 @@ struct dac_s { uint32_t channel; }; -struct spi_s { - SPIName spi; - uint32_t bits; - uint32_t cpol; - uint32_t cpha; - uint32_t mode; - uint32_t nss; - uint32_t br_presc; - PinName pin_miso; - PinName pin_mosi; - PinName pin_sclk; - PinName pin_ssel; -}; - struct i2c_s { I2CName i2c; uint32_t slave; diff --git a/targets/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303K8/objects.h b/targets/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303K8/objects.h index 9650260ca4..61a56f7c04 100644 --- a/targets/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303K8/objects.h +++ b/targets/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303K8/objects.h @@ -66,20 +66,6 @@ struct dac_s { uint32_t channel; }; -struct spi_s { - SPIName spi; - uint32_t bits; - uint32_t cpol; - uint32_t cpha; - uint32_t mode; - uint32_t nss; - uint32_t br_presc; - PinName pin_miso; - PinName pin_mosi; - PinName pin_sclk; - PinName pin_ssel; -}; - struct i2c_s { I2CName i2c; uint32_t slave; diff --git a/targets/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303RE/objects.h b/targets/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303RE/objects.h index 9650260ca4..61a56f7c04 100644 --- a/targets/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303RE/objects.h +++ b/targets/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303RE/objects.h @@ -66,20 +66,6 @@ struct dac_s { uint32_t channel; }; -struct spi_s { - SPIName spi; - uint32_t bits; - uint32_t cpol; - uint32_t cpha; - uint32_t mode; - uint32_t nss; - uint32_t br_presc; - PinName pin_miso; - PinName pin_mosi; - PinName pin_sclk; - PinName pin_ssel; -}; - struct i2c_s { I2CName i2c; uint32_t slave; diff --git a/targets/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303ZE/device.h b/targets/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303ZE/device.h deleted file mode 100644 index bdad16c6f1..0000000000 --- a/targets/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303ZE/device.h +++ /dev/null @@ -1,54 +0,0 @@ -// The 'features' section in 'target.json' is now used to create the device's hardware preprocessor switches. -// Check the 'features' section of the target description in 'targets.json' for more details. -/* mbed Microcontroller Library - ******************************************************************************* - * Copyright (c) 2015, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#ifndef MBED_DEVICE_H -#define MBED_DEVICE_H - - - - - - - - - - - -//======================================= - -#define DEVICE_ID_LENGTH 24 - - - - -#include "objects.h" - -#endif diff --git a/targets/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303ZE/objects.h b/targets/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303ZE/objects.h index 81ebc1d371..61a56f7c04 100644 --- a/targets/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303ZE/objects.h +++ b/targets/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303ZE/objects.h @@ -66,51 +66,17 @@ struct dac_s { uint32_t channel; }; -struct serial_s { - UARTName uart; - int index; // Used by irq - uint32_t baudrate; - uint32_t databits; - uint32_t stopbits; - uint32_t parity; - PinName pin_tx; - PinName pin_rx; -}; - -struct spi_s { - SPIName spi; - uint32_t bits; - uint32_t cpol; - uint32_t cpha; - uint32_t mode; - uint32_t nss; - uint32_t br_presc; - PinName pin_miso; - PinName pin_mosi; - PinName pin_sclk; - PinName pin_ssel; -}; - struct i2c_s { I2CName i2c; uint32_t slave; }; -struct pwmout_s { - PWMName pwm; - PinName pin; - uint32_t prescaler; - uint32_t period; - uint32_t pulse; - uint32_t channel; - uint32_t inverted; -}; - struct can_s { CANName can; int index; }; +#include "common_objects.h" #include "gpio_object.h" #ifdef __cplusplus diff --git a/targets/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F334R8/objects.h b/targets/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F334R8/objects.h index 9650260ca4..61a56f7c04 100644 --- a/targets/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F334R8/objects.h +++ b/targets/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F334R8/objects.h @@ -66,20 +66,6 @@ struct dac_s { uint32_t channel; }; -struct spi_s { - SPIName spi; - uint32_t bits; - uint32_t cpol; - uint32_t cpha; - uint32_t mode; - uint32_t nss; - uint32_t br_presc; - PinName pin_miso; - PinName pin_mosi; - PinName pin_sclk; - PinName pin_ssel; -}; - struct i2c_s { I2CName i2c; uint32_t slave; diff --git a/targets/TARGET_STM/TARGET_STM32F3/common_objects.h b/targets/TARGET_STM/TARGET_STM32F3/common_objects.h index 585d323084..fd235f0781 100644 --- a/targets/TARGET_STM/TARGET_STM32F3/common_objects.h +++ b/targets/TARGET_STM/TARGET_STM32F3/common_objects.h @@ -49,6 +49,21 @@ struct pwmout_s { uint8_t inverted; }; +struct spi_s { + SPI_HandleTypeDef handle; + IRQn_Type spiIRQ; + SPIName spi; + PinName pin_miso; + PinName pin_mosi; + PinName pin_sclk; + PinName pin_ssel; +#ifdef DEVICE_SPI_ASYNCH + uint32_t event; + uint8_t module; + uint8_t transfer_type; +#endif +}; + struct serial_s { UARTName uart; int index; // Used by irq diff --git a/targets/TARGET_STM/TARGET_STM32F3/spi_api.c b/targets/TARGET_STM/TARGET_STM32F3/spi_api.c index 674b093645..c7082808e6 100644 --- a/targets/TARGET_STM/TARGET_STM32F3/spi_api.c +++ b/targets/TARGET_STM/TARGET_STM32F3/spi_api.c @@ -33,199 +33,27 @@ #if DEVICE_SPI -#include #include "cmsis.h" #include "pinmap.h" #include "PeripheralPins.h" -static SPI_HandleTypeDef SpiHandle; -static void init_spi(spi_t *obj) -{ - SpiHandle.Instance = (SPI_TypeDef *)(obj->spi); - - __HAL_SPI_DISABLE(&SpiHandle); - - SpiHandle.Init.Mode = obj->mode; - SpiHandle.Init.BaudRatePrescaler = obj->br_presc; - SpiHandle.Init.Direction = SPI_DIRECTION_2LINES; - SpiHandle.Init.CLKPhase = obj->cpha; - SpiHandle.Init.CLKPolarity = obj->cpol; - SpiHandle.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED; - SpiHandle.Init.CRCPolynomial = 7; - SpiHandle.Init.DataSize = obj->bits; - SpiHandle.Init.FirstBit = SPI_FIRSTBIT_MSB; - SpiHandle.Init.NSS = obj->nss; - SpiHandle.Init.TIMode = SPI_TIMODE_DISABLED; - - HAL_SPI_Init(&SpiHandle); - - __HAL_SPI_ENABLE(&SpiHandle); -} - -void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel) -{ - // Determine the SPI to use - SPIName spi_mosi = (SPIName)pinmap_peripheral(mosi, PinMap_SPI_MOSI); - SPIName spi_miso = (SPIName)pinmap_peripheral(miso, PinMap_SPI_MISO); - SPIName spi_sclk = (SPIName)pinmap_peripheral(sclk, PinMap_SPI_SCLK); - SPIName spi_ssel = (SPIName)pinmap_peripheral(ssel, PinMap_SPI_SSEL); - - SPIName spi_data = (SPIName)pinmap_merge(spi_mosi, spi_miso); - SPIName spi_cntl = (SPIName)pinmap_merge(spi_sclk, spi_ssel); - - obj->spi = (SPIName)pinmap_merge(spi_data, spi_cntl); - MBED_ASSERT(obj->spi != (SPIName)NC); - - // Enable SPI clock -#if defined(SPI1_BASE) - if (obj->spi == SPI_1) { - __SPI1_CLK_ENABLE(); - } -#endif - -#if defined(SPI2_BASE) - if (obj->spi == SPI_2) { - __SPI2_CLK_ENABLE(); - } -#endif - -#if defined(SPI3_BASE) - if (obj->spi == SPI_3) { - __SPI3_CLK_ENABLE(); - } -#endif - -#if defined(SPI4_BASE) - if (obj->spi == SPI_3) { - __SPI4_CLK_ENABLE(); - } -#endif - - // Configure the SPI pins - pinmap_pinout(mosi, PinMap_SPI_MOSI); - pinmap_pinout(miso, PinMap_SPI_MISO); - pinmap_pinout(sclk, PinMap_SPI_SCLK); - - // Save new values - obj->bits = SPI_DATASIZE_8BIT; - obj->cpol = SPI_POLARITY_LOW; - obj->cpha = SPI_PHASE_1EDGE; -#if defined(TARGET_STM32F334C8) - obj->br_presc = SPI_BAUDRATEPRESCALER_256; +#if DEVICE_SPI_ASYNCH + #define SPI_S(obj) (( struct spi_s *)(&(obj->spi))) #else - obj->br_presc = SPI_BAUDRATEPRESCALER_32; // 1 MHz (HSI) or 1.13 MHz (HSE) + #define SPI_S(obj) (( struct spi_s *)(obj)) #endif - obj->pin_miso = miso; - obj->pin_mosi = mosi; - obj->pin_sclk = sclk; - obj->pin_ssel = ssel; - - if (ssel != NC) { - pinmap_pinout(ssel, PinMap_SPI_SSEL); - } else { - obj->nss = SPI_NSS_SOFT; - } - - init_spi(obj); -} - -void spi_free(spi_t *obj) -{ - // Reset SPI and disable clock -#if defined(SPI1_BASE) - if (obj->spi == SPI_1) { - __SPI1_FORCE_RESET(); - __SPI1_RELEASE_RESET(); - __SPI1_CLK_DISABLE(); - } -#endif - -#if defined(SPI2_BASE) - if (obj->spi == SPI_2) { - __SPI2_FORCE_RESET(); - __SPI2_RELEASE_RESET(); - __SPI2_CLK_DISABLE(); - } -#endif - -#if defined(SPI3_BASE) - if (obj->spi == SPI_3) { - __SPI3_FORCE_RESET(); - __SPI3_RELEASE_RESET(); - __SPI3_CLK_DISABLE(); - } -#endif - -#if defined(SPI4_BASE) - if (obj->spi == SPI_4) { - __SPI4_FORCE_RESET(); - __SPI4_RELEASE_RESET(); - __SPI4_CLK_DISABLE(); - } -#endif - - // Configure GPIOs - pin_function(obj->pin_miso, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0)); - pin_function(obj->pin_mosi, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0)); - pin_function(obj->pin_sclk, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0)); - pin_function(obj->pin_ssel, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0)); -} - -void spi_format(spi_t *obj, int bits, int mode, int slave) -{ - // Save new values - if (bits == 16) { - obj->bits = SPI_DATASIZE_16BIT; - } else { - obj->bits = SPI_DATASIZE_8BIT; - } - - switch (mode) { - case 0: - obj->cpol = SPI_POLARITY_LOW; - obj->cpha = SPI_PHASE_1EDGE; - break; - case 1: - obj->cpol = SPI_POLARITY_LOW; - obj->cpha = SPI_PHASE_2EDGE; - break; - case 2: - obj->cpol = SPI_POLARITY_HIGH; - obj->cpha = SPI_PHASE_1EDGE; - break; - default: - obj->cpol = SPI_POLARITY_HIGH; - obj->cpha = SPI_PHASE_2EDGE; - break; - } - - if (obj->nss != SPI_NSS_SOFT) { - obj->nss = (slave) ? SPI_NSS_HARD_INPUT : SPI_NSS_HARD_OUTPUT; - } - - obj->mode = (slave) ? SPI_MODE_SLAVE : SPI_MODE_MASTER; - - init_spi(obj); -} - -static const uint16_t baudrate_prescaler_table[] = {SPI_BAUDRATEPRESCALER_2, - SPI_BAUDRATEPRESCALER_4, - SPI_BAUDRATEPRESCALER_8, - SPI_BAUDRATEPRESCALER_16, - SPI_BAUDRATEPRESCALER_32, - SPI_BAUDRATEPRESCALER_64, - SPI_BAUDRATEPRESCALER_128, - SPI_BAUDRATEPRESCALER_256}; - -void spi_frequency(spi_t *obj, int hz) -{ +/* + * Only the frequency is managed in the family specific part + * the rest of SPI management is common to all STM32 families + */ +int spi_get_clock_freq(spi_t *obj) { + struct spi_s *spiobj = SPI_S(obj); int spi_hz = 0; - uint8_t prescaler_rank = 0; /* Get source clock depending on SPI instance */ - switch ((int)obj->spi) { + switch ((int)spiobj->spi) { #if defined SPI1_BASE case SPI_1: /* SPI_1. Source CLK is PCKL2 */ @@ -245,120 +73,10 @@ void spi_frequency(spi_t *obj, int hz) spi_hz = HAL_RCC_GetPCLK1Freq(); break; default: - error("SPI instance not set"); + error("CLK: SPI instance not set"); + break; } - - /* Define pre-scaler in order to get highest available frequency below requested frequency */ - while ((spi_hz > hz) && (prescaler_rank < sizeof(baudrate_prescaler_table)/sizeof(baudrate_prescaler_table[0]))){ - spi_hz = spi_hz / 2; - prescaler_rank++; - } - - if (prescaler_rank <= sizeof(baudrate_prescaler_table)/sizeof(baudrate_prescaler_table[0])) { - obj->br_presc = baudrate_prescaler_table[prescaler_rank-1]; - } else { - error("Couldn't setup requested SPI frequency"); - } - - init_spi(obj); -} - -static inline int ssp_readable(spi_t *obj) -{ - int status; - SpiHandle.Instance = (SPI_TypeDef *)(obj->spi); - // Check if data is received - status = ((__HAL_SPI_GET_FLAG(&SpiHandle, SPI_FLAG_RXNE) != RESET) ? 1 : 0); - return status; -} - -static inline int ssp_writeable(spi_t *obj) -{ - int status; - SpiHandle.Instance = (SPI_TypeDef *)(obj->spi); - // Check if data is transmitted - status = ((__HAL_SPI_GET_FLAG(&SpiHandle, SPI_FLAG_TXE) != RESET) ? 1 : 0); - return status; -} - -static inline void ssp_write(spi_t *obj, int value) -{ - SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi); - while (!ssp_writeable(obj)); - if (obj->bits == SPI_DATASIZE_8BIT) { - // Force 8-bit access to the data register - uint8_t *p_spi_dr = 0; - p_spi_dr = (uint8_t *) & (spi->DR); - *p_spi_dr = (uint8_t)value; - } else { // SPI_DATASIZE_16BIT - spi->DR = (uint16_t)value; - } -} - -static inline int ssp_read(spi_t *obj) -{ - SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi); - while (!ssp_readable(obj)); - if (obj->bits == SPI_DATASIZE_8BIT) { - // Force 8-bit access to the data register - uint8_t *p_spi_dr = 0; - p_spi_dr = (uint8_t *) & (spi->DR); - return (int)(*p_spi_dr); - } else { - return (int)spi->DR; - } -} - -static inline int ssp_busy(spi_t *obj) -{ - int status; - SpiHandle.Instance = (SPI_TypeDef *)(obj->spi); - status = ((__HAL_SPI_GET_FLAG(&SpiHandle, SPI_FLAG_BSY) != RESET) ? 1 : 0); - return status; -} - -int spi_master_write(spi_t *obj, int value) -{ - ssp_write(obj, value); - return ssp_read(obj); -} - -int spi_slave_receive(spi_t *obj) -{ - return ((ssp_readable(obj) && !ssp_busy(obj)) ? 1 : 0); -}; - -int spi_slave_read(spi_t *obj) -{ - SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi); - while (!ssp_readable(obj)); - if (obj->bits == SPI_DATASIZE_8BIT) { - // Force 8-bit access to the data register - uint8_t *p_spi_dr = 0; - p_spi_dr = (uint8_t *) & (spi->DR); - return (int)(*p_spi_dr); - } else { - return (int)spi->DR; - } -} - -void spi_slave_write(spi_t *obj, int value) -{ - SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi); - while (!ssp_writeable(obj)); - if (obj->bits == SPI_DATASIZE_8BIT) { - // Force 8-bit access to the data register - uint8_t *p_spi_dr = 0; - p_spi_dr = (uint8_t *) & (spi->DR); - *p_spi_dr = (uint8_t)value; - } else { // SPI_DATASIZE_16BIT - spi->DR = (uint16_t)value; - } -} - -int spi_busy(spi_t *obj) -{ - return ssp_busy(obj); + return spi_hz; } #endif diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_ELMO_F411RE/PeripheralPins.c b/targets/TARGET_STM/TARGET_STM32F4/TARGET_ELMO_F411RE/PeripheralPins.c index 056931c039..f8f4654c52 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_ELMO_F411RE/PeripheralPins.c +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_ELMO_F411RE/PeripheralPins.c @@ -196,8 +196,8 @@ const PinMap PinMap_SPI_SCLK[] = { }; const PinMap PinMap_SPI_SSEL[] = { - {PA_4, SPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF5_SPI1)}, -// {PA_4, SPI_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF6_SPI3)}, + // {PA_4, SPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF5_SPI1)}, + {PA_4, SPI_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF6_SPI3)}, {PA_15, SPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF5_SPI1)}, // {PA_15, SPI_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF6_SPI3)}, {PB_1, SPI_5, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI5)}, diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_NUCLEO_F411RE/PeripheralPins.c b/targets/TARGET_STM/TARGET_STM32F4/TARGET_NUCLEO_F411RE/PeripheralPins.c index dd952ad24f..0a4fd7d9cd 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_NUCLEO_F411RE/PeripheralPins.c +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_NUCLEO_F411RE/PeripheralPins.c @@ -208,8 +208,8 @@ const PinMap PinMap_SPI_SCLK[] = { }; const PinMap PinMap_SPI_SSEL[] = { - {PA_4, SPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF5_SPI1)}, -// {PA_4, SPI_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF6_SPI3)}, +// {PA_4, SPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF5_SPI1)}, + {PA_4, SPI_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF6_SPI3)}, {PA_15, SPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF5_SPI1)}, // {PA_15, SPI_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF6_SPI3)}, {PB_1, SPI_5, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI5)}, diff --git a/targets/TARGET_STM/TARGET_STM32F4/spi_api.c b/targets/TARGET_STM/TARGET_STM32F4/spi_api.c index aa1a8b7b4e..af4414c150 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/spi_api.c +++ b/targets/TARGET_STM/TARGET_STM32F4/spi_api.c @@ -39,248 +39,19 @@ #include "pinmap.h" #include "PeripheralPins.h" -#if DEVICE_SPI_ASYNCH - #define SPI_INST(obj) ((SPI_TypeDef *)(obj->spi.spi)) -#else - #define SPI_INST(obj) ((SPI_TypeDef *)(obj->spi)) -#endif - #if DEVICE_SPI_ASYNCH #define SPI_S(obj) (( struct spi_s *)(&(obj->spi))) #else #define SPI_S(obj) (( struct spi_s *)(obj)) #endif -#ifndef DEBUG_STDIO -# define DEBUG_STDIO 0 -#endif - -#if DEBUG_STDIO -# include -# define DEBUG_PRINTF(...) do { printf(__VA_ARGS__); } while(0) -#else -# define DEBUG_PRINTF(...) {} -#endif - -static void init_spi(spi_t *obj) -{ +/* + * Only the frequency is managed in the family specific part + * the rest of SPI management is common to all STM32 families + */ +int spi_get_clock_freq(spi_t *obj) { struct spi_s *spiobj = SPI_S(obj); - SPI_HandleTypeDef *handle = &(spiobj->handle); - - __HAL_SPI_DISABLE(handle); - - DEBUG_PRINTF("init_spi: instance=0x%8X\r\n", (int)handle->Instance); - if (HAL_SPI_Init(handle) != HAL_OK) { - error("Cannot initialize SPI"); - } - - __HAL_SPI_ENABLE(handle); -} - -void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel) -{ - struct spi_s *spiobj = SPI_S(obj); - SPI_HandleTypeDef *handle = &(spiobj->handle); - - // Determine the SPI to use - SPIName spi_mosi = (SPIName)pinmap_peripheral(mosi, PinMap_SPI_MOSI); - SPIName spi_miso = (SPIName)pinmap_peripheral(miso, PinMap_SPI_MISO); - SPIName spi_sclk = (SPIName)pinmap_peripheral(sclk, PinMap_SPI_SCLK); - SPIName spi_ssel = (SPIName)pinmap_peripheral(ssel, PinMap_SPI_SSEL); - - SPIName spi_data = (SPIName)pinmap_merge(spi_mosi, spi_miso); - SPIName spi_cntl = (SPIName)pinmap_merge(spi_sclk, spi_ssel); - - spiobj->spi = (SPIName)pinmap_merge(spi_data, spi_cntl); - MBED_ASSERT(spiobj->spi != (SPIName)NC); - - // Enable SPI clock - if (spiobj->spi == SPI_1) { - __HAL_RCC_SPI1_CLK_ENABLE(); - spiobj->spiIRQ = SPI1_IRQn; - } - - if (spiobj->spi == SPI_2) { - __HAL_RCC_SPI2_CLK_ENABLE(); - spiobj->spiIRQ = SPI2_IRQn; - } - -#if defined SPI3_BASE - if (spiobj->spi == SPI_3) { - __HAL_RCC_SPI3_CLK_ENABLE(); - spiobj->spiIRQ = SPI3_IRQn; - } -#endif - -#if defined SPI4_BASE - if (spiobj->spi == SPI_4) { - __HAL_RCC_SPI4_CLK_ENABLE(); - spiobj->spiIRQ = SPI4_IRQn; - } -#endif - -#if defined SPI5_BASE - if (spiobj->spi == SPI_5) { - __HAL_RCC_SPI5_CLK_ENABLE(); - spiobj->spiIRQ = SPI5_IRQn; - } -#endif - -#if defined SPI6_BASE - if (spiobj->spi == SPI_6) { - __HAL_RCC_SPI6_CLK_ENABLE(); - spiobj->spiIRQ = SPI6_IRQn; - } -#endif - - // Configure the SPI pins - pinmap_pinout(mosi, PinMap_SPI_MOSI); - pinmap_pinout(miso, PinMap_SPI_MISO); - pinmap_pinout(sclk, PinMap_SPI_SCLK); - spiobj->pin_miso = miso; - spiobj->pin_mosi = mosi; - spiobj->pin_sclk = sclk; - spiobj->pin_ssel = ssel; - if (ssel != NC) { - pinmap_pinout(ssel, PinMap_SPI_SSEL); - } else { - handle->Init.NSS = SPI_NSS_SOFT; - } - - /* Fill default value */ - handle->Instance = SPI_INST(obj); - handle->Init.Mode = SPI_MODE_MASTER; - handle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256; - handle->Init.Direction = SPI_DIRECTION_2LINES; - handle->Init.CLKPhase = SPI_PHASE_1EDGE; - handle->Init.CLKPolarity = SPI_POLARITY_LOW; - handle->Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED; - handle->Init.CRCPolynomial = 7; - handle->Init.DataSize = SPI_DATASIZE_8BIT; - handle->Init.FirstBit = SPI_FIRSTBIT_MSB; - handle->Init.TIMode = SPI_TIMODE_DISABLED; - - init_spi(obj); -} - -void spi_free(spi_t *obj) -{ - struct spi_s *spiobj = SPI_S(obj); - SPI_HandleTypeDef *handle = &(spiobj->handle); - - DEBUG_PRINTF("spi_free\r\n"); - - __HAL_SPI_DISABLE(handle); - HAL_SPI_DeInit(handle); - - // Reset SPI and disable clock - if (spiobj->spi == SPI_1) { - __HAL_RCC_SPI1_FORCE_RESET(); - __HAL_RCC_SPI1_RELEASE_RESET(); - __HAL_RCC_SPI1_CLK_DISABLE(); - } - - if (spiobj->spi == SPI_2) { - __HAL_RCC_SPI2_FORCE_RESET(); - __HAL_RCC_SPI2_RELEASE_RESET(); - __HAL_RCC_SPI2_CLK_DISABLE(); - } -#if defined SPI3_BASE - if (spiobj->spi == SPI_3) { - __HAL_RCC_SPI3_FORCE_RESET(); - __HAL_RCC_SPI3_RELEASE_RESET(); - __HAL_RCC_SPI3_CLK_DISABLE(); - } -#endif - -#if defined SPI4_BASE - if (spiobj->spi == SPI_4) { - __HAL_RCC_SPI4_FORCE_RESET(); - __HAL_RCC_SPI4_RELEASE_RESET(); - __HAL_RCC_SPI4_CLK_DISABLE(); - } -#endif - -#if defined SPI5_BASE - if (spiobj->spi == SPI_5) { - __HAL_RCC_SPI5_FORCE_RESET(); - __HAL_RCC_SPI5_RELEASE_RESET(); - __HAL_RCC_SPI5_CLK_DISABLE(); - } -#endif - -#if defined SPI6_BASE - if (spiobj->spi == SPI_6) { - __HAL_RCC_SPI6_FORCE_RESET(); - __HAL_RCC_SPI6_RELEASE_RESET(); - __HAL_RCC_SPI6_CLK_DISABLE(); - } -#endif - - // Configure GPIOs - pin_function(spiobj->pin_miso, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0)); - pin_function(spiobj->pin_mosi, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0)); - pin_function(spiobj->pin_sclk, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0)); - if (handle->Init.NSS != SPI_NSS_SOFT) { - pin_function(spiobj->pin_ssel, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0)); - } -} - -void spi_format(spi_t *obj, int bits, int mode, int slave) -{ - struct spi_s *spiobj = SPI_S(obj); - SPI_HandleTypeDef *handle = &(spiobj->handle); - - DEBUG_PRINTF("spi_format, bits:%d, mode:%d, slave?:%d\r\n", bits, mode, slave); - - // Save new values - handle->Init.DataSize = (bits == 16) ? SPI_DATASIZE_16BIT : SPI_DATASIZE_8BIT; - - switch (mode) { - case 0: - handle->Init.CLKPolarity = SPI_POLARITY_LOW; - handle->Init.CLKPhase = SPI_PHASE_1EDGE; - break; - case 1: - handle->Init.CLKPolarity = SPI_POLARITY_LOW; - handle->Init.CLKPhase = SPI_PHASE_2EDGE; - break; - case 2: - handle->Init.CLKPolarity = SPI_POLARITY_HIGH; - handle->Init.CLKPhase = SPI_PHASE_1EDGE; - break; - default: - handle->Init.CLKPolarity = SPI_POLARITY_HIGH; - handle->Init.CLKPhase = SPI_PHASE_2EDGE; - break; - } - - if (handle->Init.NSS != SPI_NSS_SOFT) { - handle->Init.NSS = (slave) ? SPI_NSS_HARD_INPUT : SPI_NSS_HARD_OUTPUT; - } - - handle->Init.Mode = (slave) ? SPI_MODE_SLAVE : SPI_MODE_MASTER; - - init_spi(obj); -} - -static const uint16_t baudrate_prescaler_table[] = {SPI_BAUDRATEPRESCALER_2, - SPI_BAUDRATEPRESCALER_4, - SPI_BAUDRATEPRESCALER_8, - SPI_BAUDRATEPRESCALER_16, - SPI_BAUDRATEPRESCALER_32, - SPI_BAUDRATEPRESCALER_64, - SPI_BAUDRATEPRESCALER_128, - SPI_BAUDRATEPRESCALER_256}; - -void spi_frequency(spi_t *obj, int hz) -{ - struct spi_s *spiobj = SPI_S(obj); - SPI_HandleTypeDef *handle = &(spiobj->handle); int spi_hz = 0; - uint8_t prescaler_rank = 0; - - DEBUG_PRINTF("spi_frequency:%d\r\n", hz); /* Get source clock depending on SPI instance */ switch ((int)spiobj->spi) { @@ -305,284 +76,10 @@ void spi_frequency(spi_t *obj, int hz) spi_hz = HAL_RCC_GetPCLK1Freq(); break; default: - error("SPI instance not set"); - } - - /* Define pre-scaler in order to get highest available frequency below requested frequency */ - while ((spi_hz > hz) && (prescaler_rank < sizeof(baudrate_prescaler_table)/sizeof(baudrate_prescaler_table[0]))){ - spi_hz = spi_hz / 2; - prescaler_rank++; - } - - if (prescaler_rank <= sizeof(baudrate_prescaler_table)/sizeof(baudrate_prescaler_table[0])) { - handle->Init.BaudRatePrescaler = baudrate_prescaler_table[prescaler_rank-1]; - } else { - error("Couldn't setup requested SPI frequency"); - } - - init_spi(obj); -} - -static inline int ssp_readable(spi_t *obj) -{ - int status; - struct spi_s *spiobj = SPI_S(obj); - SPI_HandleTypeDef *handle = &(spiobj->handle); - - // Check if data is received - status = ((__HAL_SPI_GET_FLAG(handle, SPI_FLAG_RXNE) != RESET) ? 1 : 0); - return status; -} - -static inline int ssp_writeable(spi_t *obj) -{ - int status; - struct spi_s *spiobj = SPI_S(obj); - SPI_HandleTypeDef *handle = &(spiobj->handle); - - // Check if data is transmitted - status = ((__HAL_SPI_GET_FLAG(handle, SPI_FLAG_TXE) != RESET) ? 1 : 0); - return status; -} - -static inline void ssp_write(spi_t *obj, int value) -{ - SPI_TypeDef *spi = SPI_INST(obj); - while (!ssp_writeable(obj)); - spi->DR = (uint16_t)value; -} - -static inline int ssp_read(spi_t *obj) -{ - SPI_TypeDef *spi = SPI_INST(obj); - while (!ssp_readable(obj)); - return (int)spi->DR; -} - -static inline int ssp_busy(spi_t *obj) -{ - int status; - struct spi_s *spiobj = SPI_S(obj); - SPI_HandleTypeDef *handle = &(spiobj->handle); - - status = ((__HAL_SPI_GET_FLAG(handle, SPI_FLAG_BSY) != RESET) ? 1 : 0); - return status; -} - -int spi_master_write(spi_t *obj, int value) -{ - ssp_write(obj, value); - return ssp_read(obj); -} - -int spi_slave_receive(spi_t *obj) -{ - return ((ssp_readable(obj) && !ssp_busy(obj)) ? 1 : 0); -}; - -int spi_slave_read(spi_t *obj) -{ - SPI_TypeDef *spi = SPI_INST(obj); - while (!ssp_readable(obj)); - return (int)spi->DR; -} - -void spi_slave_write(spi_t *obj, int value) -{ - SPI_TypeDef *spi = SPI_INST(obj); - while (!ssp_writeable(obj)); - spi->DR = (uint16_t)value; -} - -int spi_busy(spi_t *obj) -{ - return ssp_busy(obj); -} - -#ifdef DEVICE_SPI_ASYNCH -typedef enum { - SPI_TRANSFER_TYPE_NONE = 0, - SPI_TRANSFER_TYPE_TX = 1, - SPI_TRANSFER_TYPE_RX = 2, - SPI_TRANSFER_TYPE_TXRX = 3, -} transfer_type_t; - - -/// @returns the number of bytes transferred, or `0` if nothing transferred -static int spi_master_start_asynch_transfer(spi_t *obj, transfer_type_t transfer_type, const void *tx, void *rx, size_t length) -{ - struct spi_s *spiobj = SPI_S(obj); - SPI_HandleTypeDef *handle = &(spiobj->handle); - bool is16bit = (handle->Init.DataSize == SPI_DATASIZE_16BIT); - // the HAL expects number of transfers instead of number of bytes - // so for 16 bit transfer width the count needs to be halved - size_t words; - - DEBUG_PRINTF("SPI inst=0x%8X Start: %u, %u\r\n", (int)handle->Instance, transfer_type, length); - - obj->spi.transfer_type = transfer_type; - - if (is16bit) words = length / 2; - else words = length; - - // enable the interrupt - IRQn_Type irq_n = spiobj->spiIRQ; - NVIC_ClearPendingIRQ(irq_n); - NVIC_DisableIRQ(irq_n); - NVIC_SetPriority(irq_n, 1); - NVIC_EnableIRQ(irq_n); - - // enable the right hal transfer - //static uint16_t sink; - int rc = 0; - switch(transfer_type) { - case SPI_TRANSFER_TYPE_TXRX: - rc = HAL_SPI_TransmitReceive_IT(handle, (uint8_t*)tx, (uint8_t*)rx, words); + error("CLK: SPI instance not set"); break; - case SPI_TRANSFER_TYPE_TX: - // TODO: we do not use `HAL_SPI_Transmit_IT`, since it has some unknown bug - // and makes the HAL keep some state and then that fails successive transfers - rc = HAL_SPI_Transmit_IT(handle, (uint8_t*)tx, words); - //rc = HAL_SPI_TransmitReceive_IT(handle, (uint8_t*)tx, (uint8_t*)&sink, 1); - //length = is16bit ? 2 : 1; - break; - case SPI_TRANSFER_TYPE_RX: - // the receive function also "transmits" the receive buffer so in order - // to guarantee that 0xff is on the line, we explicitly memset it here - memset(rx, SPI_FILL_WORD, length); - rc = HAL_SPI_Receive_IT(handle, (uint8_t*)rx, words); - break; - default: - length = 0; } - - if (rc) { - DEBUG_PRINTF("SPI: RC=%u\n", rc); - length = 0; - } - - return length; + return spi_hz; } -// asynchronous API -void spi_master_transfer(spi_t *obj, const void *tx, size_t tx_length, void *rx, size_t rx_length, uint8_t bit_width, uint32_t handler, uint32_t event, DMAUsage hint) -{ - struct spi_s *spiobj = SPI_S(obj); - SPI_HandleTypeDef *handle = &(spiobj->handle); - - // TODO: DMA usage is currently ignored - (void) hint; - - // check which use-case we have - bool use_tx = (tx != NULL && tx_length > 0); - bool use_rx = (rx != NULL && rx_length > 0); - bool is16bit = (handle->Init.DataSize == SPI_DATASIZE_16BIT); - - // don't do anything, if the buffers aren't valid - if (!use_tx && !use_rx) - return; - - // copy the buffers to the SPI object - obj->tx_buff.buffer = (void *) tx; - obj->tx_buff.length = tx_length; - obj->tx_buff.pos = 0; - obj->tx_buff.width = is16bit ? 16 : 8; - - obj->rx_buff.buffer = rx; - obj->rx_buff.length = rx_length; - obj->rx_buff.pos = 0; - obj->rx_buff.width = obj->tx_buff.width; - - obj->spi.event = event; - - DEBUG_PRINTF("SPI: Transfer: %u, %u\n", tx_length, rx_length); - - // register the thunking handler - IRQn_Type irq_n = spiobj->spiIRQ; - NVIC_SetVector(irq_n, (uint32_t)handler); - - // enable the right hal transfer - if (use_tx && use_rx) { - // we cannot manage different rx / tx sizes, let's use smaller one - size_t size = (tx_length < rx_length)? tx_length : rx_length; - if(tx_length != rx_length) { - DEBUG_PRINTF("SPI: Full duplex transfer only 1 size: %d\n", size); - obj->tx_buff.length = size; - obj->rx_buff.length = size; - } - spi_master_start_asynch_transfer(obj, SPI_TRANSFER_TYPE_TXRX, tx, rx, size); - } else if (use_tx) { - spi_master_start_asynch_transfer(obj, SPI_TRANSFER_TYPE_TX, tx, NULL, tx_length); - } else if (use_rx) { - spi_master_start_asynch_transfer(obj, SPI_TRANSFER_TYPE_RX, NULL, rx, rx_length); - } -} - -uint32_t spi_irq_handler_asynch(spi_t *obj) -{ - // use the right instance - struct spi_s *spiobj = SPI_S(obj); - SPI_HandleTypeDef *handle = &spiobj->handle; - int event = 0; - - // call the CubeF4 handler, this will update the handle - HAL_SPI_IRQHandler(handle); - - if (HAL_SPI_GetState(handle) == HAL_SPI_STATE_READY) { - // When HAL SPI is back to READY state, check if there was an error - int error = HAL_SPI_GetError(handle); - if(error != HAL_SPI_ERROR_NONE) { - // something went wrong and the transfer has definitely completed - event = SPI_EVENT_ERROR | SPI_EVENT_INTERNAL_TRANSFER_COMPLETE; - - if (error & HAL_SPI_ERROR_OVR) { - // buffer overrun - event |= SPI_EVENT_RX_OVERFLOW; - } - } else { - // else we're done - event = SPI_EVENT_COMPLETE | SPI_EVENT_INTERNAL_TRANSFER_COMPLETE; - } - } - - if (event) DEBUG_PRINTF("SPI: Event: 0x%x\n", event); - - return (event & (obj->spi.event | SPI_EVENT_INTERNAL_TRANSFER_COMPLETE)); -} - -uint8_t spi_active(spi_t *obj) -{ - struct spi_s *spiobj = SPI_S(obj); - SPI_HandleTypeDef *handle = &(spiobj->handle); - HAL_SPI_StateTypeDef state = HAL_SPI_GetState(handle); - - switch(state) { - case HAL_SPI_STATE_RESET: - case HAL_SPI_STATE_READY: - case HAL_SPI_STATE_ERROR: - return 0; - default: - return 1; - } -} - -void spi_abort_asynch(spi_t *obj) -{ - struct spi_s *spiobj = SPI_S(obj); - SPI_HandleTypeDef *handle = &(spiobj->handle); - - // disable interrupt - IRQn_Type irq_n = spiobj->spiIRQ; - NVIC_ClearPendingIRQ(irq_n); - NVIC_DisableIRQ(irq_n); - - // clean-up - __HAL_SPI_DISABLE(handle); - HAL_SPI_DeInit(handle); - HAL_SPI_Init(handle); - __HAL_SPI_ENABLE(handle); -} - -#endif //DEVICE_SPI_ASYNCH - #endif diff --git a/targets/TARGET_STM/TARGET_STM32F7/TARGET_DISCO_F746NG/objects.h b/targets/TARGET_STM/TARGET_STM32F7/TARGET_DISCO_F746NG/objects.h index 84c61ff544..40972f6574 100644 --- a/targets/TARGET_STM/TARGET_STM32F7/TARGET_DISCO_F746NG/objects.h +++ b/targets/TARGET_STM/TARGET_STM32F7/TARGET_DISCO_F746NG/objects.h @@ -66,20 +66,6 @@ struct dac_s { uint32_t channel; }; -struct spi_s { - SPIName spi; - uint32_t bits; - uint32_t cpol; - uint32_t cpha; - uint32_t mode; - uint32_t nss; - uint32_t br_presc; - PinName pin_miso; - PinName pin_mosi; - PinName pin_sclk; - PinName pin_ssel; -}; - struct i2c_s { I2CName i2c; uint32_t slave; diff --git a/targets/TARGET_STM/TARGET_STM32F7/TARGET_DISCO_F769NI/objects.h b/targets/TARGET_STM/TARGET_STM32F7/TARGET_DISCO_F769NI/objects.h index 7639c231df..3e253f11ac 100644 --- a/targets/TARGET_STM/TARGET_STM32F7/TARGET_DISCO_F769NI/objects.h +++ b/targets/TARGET_STM/TARGET_STM32F7/TARGET_DISCO_F769NI/objects.h @@ -66,20 +66,6 @@ struct dac_s { uint32_t channel; }; -struct spi_s { - SPIName spi; - uint32_t bits; - uint32_t cpol; - uint32_t cpha; - uint32_t mode; - uint32_t nss; - uint32_t br_presc; - PinName pin_miso; - PinName pin_mosi; - PinName pin_sclk; - PinName pin_ssel; -}; - struct i2c_s { I2CName i2c; uint32_t slave; diff --git a/targets/TARGET_STM/TARGET_STM32F7/TARGET_NUCLEO_F746ZG/objects.h b/targets/TARGET_STM/TARGET_STM32F7/TARGET_NUCLEO_F746ZG/objects.h index e8af139f96..84fc17241d 100644 --- a/targets/TARGET_STM/TARGET_STM32F7/TARGET_NUCLEO_F746ZG/objects.h +++ b/targets/TARGET_STM/TARGET_STM32F7/TARGET_NUCLEO_F746ZG/objects.h @@ -66,20 +66,6 @@ struct dac_s { uint32_t channel; }; -struct spi_s { - SPIName spi; - uint32_t bits; - uint32_t cpol; - uint32_t cpha; - uint32_t mode; - uint32_t nss; - uint32_t br_presc; - PinName pin_miso; - PinName pin_mosi; - PinName pin_sclk; - PinName pin_ssel; -}; - struct i2c_s { I2CName i2c; uint32_t slave; diff --git a/targets/TARGET_STM/TARGET_STM32F7/TARGET_NUCLEO_F767ZI/objects.h b/targets/TARGET_STM/TARGET_STM32F7/TARGET_NUCLEO_F767ZI/objects.h index 7639c231df..3e253f11ac 100644 --- a/targets/TARGET_STM/TARGET_STM32F7/TARGET_NUCLEO_F767ZI/objects.h +++ b/targets/TARGET_STM/TARGET_STM32F7/TARGET_NUCLEO_F767ZI/objects.h @@ -66,20 +66,6 @@ struct dac_s { uint32_t channel; }; -struct spi_s { - SPIName spi; - uint32_t bits; - uint32_t cpol; - uint32_t cpha; - uint32_t mode; - uint32_t nss; - uint32_t br_presc; - PinName pin_miso; - PinName pin_mosi; - PinName pin_sclk; - PinName pin_ssel; -}; - struct i2c_s { I2CName i2c; uint32_t slave; diff --git a/targets/TARGET_STM/TARGET_STM32F7/common_objects.h b/targets/TARGET_STM/TARGET_STM32F7/common_objects.h index eef1f6aced..1aa659360e 100644 --- a/targets/TARGET_STM/TARGET_STM32F7/common_objects.h +++ b/targets/TARGET_STM/TARGET_STM32F7/common_objects.h @@ -49,6 +49,21 @@ struct pwmout_s { uint8_t inverted; }; +struct spi_s { + SPI_HandleTypeDef handle; + IRQn_Type spiIRQ; + SPIName spi; + PinName pin_miso; + PinName pin_mosi; + PinName pin_sclk; + PinName pin_ssel; +#ifdef DEVICE_SPI_ASYNCH + uint32_t event; + uint8_t module; + uint8_t transfer_type; +#endif +}; + struct serial_s { UARTName uart; int index; // Used by irq diff --git a/targets/TARGET_STM/TARGET_STM32F7/spi_api.c b/targets/TARGET_STM/TARGET_STM32F7/spi_api.c index 255e03d38d..6e54e2bf93 100644 --- a/targets/TARGET_STM/TARGET_STM32F7/spi_api.c +++ b/targets/TARGET_STM/TARGET_STM32F7/spi_api.c @@ -33,202 +33,27 @@ #if DEVICE_SPI -#include #include "cmsis.h" #include "pinmap.h" #include "PeripheralPins.h" #include "mbed_error.h" -static SPI_HandleTypeDef SpiHandle; +#if DEVICE_SPI_ASYNCH + #define SPI_S(obj) (( struct spi_s *)(&(obj->spi))) +#else + #define SPI_S(obj) (( struct spi_s *)(obj)) +#endif -static void init_spi(spi_t *obj) -{ - SpiHandle.Instance = (SPI_TypeDef *)(obj->spi); - - __HAL_SPI_DISABLE(&SpiHandle); - - SpiHandle.Init.Mode = obj->mode; - SpiHandle.Init.BaudRatePrescaler = obj->br_presc; - SpiHandle.Init.Direction = SPI_DIRECTION_2LINES; - SpiHandle.Init.CLKPhase = obj->cpha; - SpiHandle.Init.CLKPolarity = obj->cpol; - SpiHandle.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED; - SpiHandle.Init.CRCPolynomial = 7; - SpiHandle.Init.DataSize = obj->bits; - SpiHandle.Init.FirstBit = SPI_FIRSTBIT_MSB; - SpiHandle.Init.NSS = obj->nss; - SpiHandle.Init.TIMode = SPI_TIMODE_DISABLED; - - if (HAL_SPI_Init(&SpiHandle) != HAL_OK) { - error("Cannot initialize SPI"); - } - - __HAL_SPI_ENABLE(&SpiHandle); -} - -void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel) -{ - // Determine the SPI to use - SPIName spi_mosi = (SPIName)pinmap_peripheral(mosi, PinMap_SPI_MOSI); - SPIName spi_miso = (SPIName)pinmap_peripheral(miso, PinMap_SPI_MISO); - SPIName spi_sclk = (SPIName)pinmap_peripheral(sclk, PinMap_SPI_SCLK); - SPIName spi_ssel = (SPIName)pinmap_peripheral(ssel, PinMap_SPI_SSEL); - - SPIName spi_data = (SPIName)pinmap_merge(spi_mosi, spi_miso); - SPIName spi_cntl = (SPIName)pinmap_merge(spi_sclk, spi_ssel); - - obj->spi = (SPIName)pinmap_merge(spi_data, spi_cntl); - MBED_ASSERT(obj->spi != (SPIName)NC); - - // Enable SPI clock - if (obj->spi == SPI_1) { - __HAL_RCC_SPI1_CLK_ENABLE(); - } - - if (obj->spi == SPI_2) { - __HAL_RCC_SPI2_CLK_ENABLE(); - } - - if (obj->spi == SPI_3) { - __HAL_RCC_SPI3_CLK_ENABLE(); - } - - if (obj->spi == SPI_4) { - __HAL_RCC_SPI4_CLK_ENABLE(); - } - - if (obj->spi == SPI_5) { - __HAL_RCC_SPI5_CLK_ENABLE(); - } - - if (obj->spi == SPI_6) { - __HAL_RCC_SPI6_CLK_ENABLE(); - } - - // Configure the SPI pins - pinmap_pinout(mosi, PinMap_SPI_MOSI); - pinmap_pinout(miso, PinMap_SPI_MISO); - pinmap_pinout(sclk, PinMap_SPI_SCLK); - - // Save new values - obj->bits = SPI_DATASIZE_8BIT; - obj->cpol = SPI_POLARITY_LOW; - obj->cpha = SPI_PHASE_1EDGE; - obj->br_presc = SPI_BAUDRATEPRESCALER_256; - - obj->pin_miso = miso; - obj->pin_mosi = mosi; - obj->pin_sclk = sclk; - obj->pin_ssel = ssel; - - if (ssel != NC) { - pinmap_pinout(ssel, PinMap_SPI_SSEL); - } else { - obj->nss = SPI_NSS_SOFT; - } - - init_spi(obj); -} - -void spi_free(spi_t *obj) -{ - // Reset SPI and disable clock - if (obj->spi == SPI_1) { - __HAL_RCC_SPI1_FORCE_RESET(); - __HAL_RCC_SPI1_RELEASE_RESET(); - __HAL_RCC_SPI1_CLK_DISABLE(); - } - - if (obj->spi == SPI_2) { - __HAL_RCC_SPI2_FORCE_RESET(); - __HAL_RCC_SPI2_RELEASE_RESET(); - __HAL_RCC_SPI2_CLK_DISABLE(); - } - - if (obj->spi == SPI_3) { - __HAL_RCC_SPI3_FORCE_RESET(); - __HAL_RCC_SPI3_RELEASE_RESET(); - __HAL_RCC_SPI3_CLK_DISABLE(); - } - - if (obj->spi == SPI_4) { - __HAL_RCC_SPI4_FORCE_RESET(); - __HAL_RCC_SPI4_RELEASE_RESET(); - __HAL_RCC_SPI4_CLK_DISABLE(); - } - - if (obj->spi == SPI_5) { - __HAL_RCC_SPI5_FORCE_RESET(); - __HAL_RCC_SPI5_RELEASE_RESET(); - __HAL_RCC_SPI5_CLK_DISABLE(); - } - - if (obj->spi == SPI_6) { - __HAL_RCC_SPI6_FORCE_RESET(); - __HAL_RCC_SPI6_RELEASE_RESET(); - __HAL_RCC_SPI6_CLK_DISABLE(); - } - - // Configure GPIOs - pin_function(obj->pin_miso, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0)); - pin_function(obj->pin_mosi, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0)); - pin_function(obj->pin_sclk, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0)); - pin_function(obj->pin_ssel, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0)); -} - -void spi_format(spi_t *obj, int bits, int mode, int slave) -{ - // Save new values - if (bits == 16) { - obj->bits = SPI_DATASIZE_16BIT; - } else { - obj->bits = SPI_DATASIZE_8BIT; - } - - switch (mode) { - case 0: - obj->cpol = SPI_POLARITY_LOW; - obj->cpha = SPI_PHASE_1EDGE; - break; - case 1: - obj->cpol = SPI_POLARITY_LOW; - obj->cpha = SPI_PHASE_2EDGE; - break; - case 2: - obj->cpol = SPI_POLARITY_HIGH; - obj->cpha = SPI_PHASE_1EDGE; - break; - default: - obj->cpol = SPI_POLARITY_HIGH; - obj->cpha = SPI_PHASE_2EDGE; - break; - } - - if (obj->nss != SPI_NSS_SOFT) { - obj->nss = (slave) ? SPI_NSS_HARD_INPUT : SPI_NSS_HARD_OUTPUT; - } - - obj->mode = (slave) ? SPI_MODE_SLAVE : SPI_MODE_MASTER; - - init_spi(obj); -} - -static const uint16_t baudrate_prescaler_table[] = {SPI_BAUDRATEPRESCALER_2, - SPI_BAUDRATEPRESCALER_4, - SPI_BAUDRATEPRESCALER_8, - SPI_BAUDRATEPRESCALER_16, - SPI_BAUDRATEPRESCALER_32, - SPI_BAUDRATEPRESCALER_64, - SPI_BAUDRATEPRESCALER_128, - SPI_BAUDRATEPRESCALER_256}; - -void spi_frequency(spi_t *obj, int hz) -{ +/* + * Only the frequency is managed in the family specific part + * the rest of SPI management is common to all STM32 families + */ +int spi_get_clock_freq(spi_t *obj) { + struct spi_s *spiobj = SPI_S(obj); int spi_hz = 0; - uint8_t prescaler_rank = 0; - + /* Get source clock depending on SPI instance */ - switch ((int)obj->spi) { + switch ((int)spiobj->spi) { case SPI_1: case SPI_4: case SPI_5: @@ -242,120 +67,10 @@ void spi_frequency(spi_t *obj, int hz) spi_hz = HAL_RCC_GetPCLK1Freq(); break; default: - error("SPI instance not set"); + error("CLK: SPI instance not set"); + break; } - - /* Define pre-scaler in order to get highest available frequency below requested frequency */ - while ((spi_hz > hz) && (prescaler_rank < sizeof(baudrate_prescaler_table)/sizeof(baudrate_prescaler_table[0]))){ - spi_hz = spi_hz / 2; - prescaler_rank++; - } - - if (prescaler_rank <= sizeof(baudrate_prescaler_table)/sizeof(baudrate_prescaler_table[0])) { - obj->br_presc = baudrate_prescaler_table[prescaler_rank-1]; - } else { - error("Couldn't setup requested SPI frequency"); - } - - init_spi(obj); -} - -static inline int ssp_readable(spi_t *obj) -{ - int status; - SpiHandle.Instance = (SPI_TypeDef *)(obj->spi); - // Check if data is received - status = ((__HAL_SPI_GET_FLAG(&SpiHandle, SPI_FLAG_RXNE) != RESET) ? 1 : 0); - return status; -} - -static inline int ssp_writeable(spi_t *obj) -{ - int status; - SpiHandle.Instance = (SPI_TypeDef *)(obj->spi); - // Check if data is transmitted - status = ((__HAL_SPI_GET_FLAG(&SpiHandle, SPI_FLAG_TXE) != RESET) ? 1 : 0); - return status; -} - -static inline void ssp_write(spi_t *obj, int value) -{ - SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi); - while (!ssp_writeable(obj)); - if (obj->bits == SPI_DATASIZE_8BIT) { - // Force 8-bit access to the data register - uint8_t *p_spi_dr = 0; - p_spi_dr = (uint8_t *) & (spi->DR); - *p_spi_dr = (uint8_t)value; - } else { // SPI_DATASIZE_16BIT - spi->DR = (uint16_t)value; - } -} - -static inline int ssp_read(spi_t *obj) -{ - SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi); - while (!ssp_readable(obj)); - if (obj->bits == SPI_DATASIZE_8BIT) { - // Force 8-bit access to the data register - uint8_t *p_spi_dr = 0; - p_spi_dr = (uint8_t *) & (spi->DR); - return (int)(*p_spi_dr); - } else { - return (int)spi->DR; - } -} - -static inline int ssp_busy(spi_t *obj) -{ - int status; - SpiHandle.Instance = (SPI_TypeDef *)(obj->spi); - status = ((__HAL_SPI_GET_FLAG(&SpiHandle, SPI_FLAG_BSY) != RESET) ? 1 : 0); - return status; -} - -int spi_master_write(spi_t *obj, int value) -{ - ssp_write(obj, value); - return ssp_read(obj); -} - -int spi_slave_receive(spi_t *obj) -{ - return ((ssp_readable(obj) && !ssp_busy(obj)) ? 1 : 0); -}; - -int spi_slave_read(spi_t *obj) -{ - SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi); - while (!ssp_readable(obj)); - if (obj->bits == SPI_DATASIZE_8BIT) { - // Force 8-bit access to the data register - uint8_t *p_spi_dr = 0; - p_spi_dr = (uint8_t *) & (spi->DR); - return (int)(*p_spi_dr); - } else { - return (int)spi->DR; - } -} - -void spi_slave_write(spi_t *obj, int value) -{ - SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi); - while (!ssp_writeable(obj)); - if (obj->bits == SPI_DATASIZE_8BIT) { - // Force 8-bit access to the data register - uint8_t *p_spi_dr = 0; - p_spi_dr = (uint8_t *) & (spi->DR); - *p_spi_dr = (uint8_t)value; - } else { // SPI_DATASIZE_16BIT - spi->DR = (uint16_t)value; - } -} - -int spi_busy(spi_t *obj) -{ - return ssp_busy(obj); + return spi_hz; } #endif diff --git a/targets/TARGET_STM/TARGET_STM32L0/TARGET_DISCO_L053C8/objects.h b/targets/TARGET_STM/TARGET_STM32L0/TARGET_DISCO_L053C8/objects.h index 3932d46128..5f05cd5bda 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/TARGET_DISCO_L053C8/objects.h +++ b/targets/TARGET_STM/TARGET_STM32L0/TARGET_DISCO_L053C8/objects.h @@ -66,20 +66,6 @@ struct dac_s { uint32_t channel; }; -struct spi_s { - SPIName spi; - uint32_t bits; - uint32_t cpol; - uint32_t cpha; - uint32_t mode; - uint32_t nss; - uint32_t br_presc; - PinName pin_miso; - PinName pin_mosi; - PinName pin_sclk; - PinName pin_ssel; -}; - struct i2c_s { I2CName i2c; }; diff --git a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L011K4/objects.h b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L011K4/objects.h index 2d78a15eed..f006abac8a 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L011K4/objects.h +++ b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L011K4/objects.h @@ -60,20 +60,6 @@ struct analogin_s { uint32_t channel; }; -struct spi_s { - SPIName spi; - uint32_t bits; - uint32_t cpol; - uint32_t cpha; - uint32_t mode; - uint32_t nss; - uint32_t br_presc; - PinName pin_miso; - PinName pin_mosi; - PinName pin_sclk; - PinName pin_ssel; -}; - struct i2c_s { I2CName i2c; }; diff --git a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L031K6/objects.h b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L031K6/objects.h index 2d78a15eed..f006abac8a 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L031K6/objects.h +++ b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L031K6/objects.h @@ -60,20 +60,6 @@ struct analogin_s { uint32_t channel; }; -struct spi_s { - SPIName spi; - uint32_t bits; - uint32_t cpol; - uint32_t cpha; - uint32_t mode; - uint32_t nss; - uint32_t br_presc; - PinName pin_miso; - PinName pin_mosi; - PinName pin_sclk; - PinName pin_ssel; -}; - struct i2c_s { I2CName i2c; }; diff --git a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L053R8/objects.h b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L053R8/objects.h index b464a5f2e7..617ccbb697 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L053R8/objects.h +++ b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L053R8/objects.h @@ -66,20 +66,6 @@ struct dac_s { uint32_t channel; }; -struct spi_s { - SPIName spi; - uint32_t bits; - uint32_t cpol; - uint32_t cpha; - uint32_t mode; - uint32_t nss; - uint32_t br_presc; - PinName pin_miso; - PinName pin_mosi; - PinName pin_sclk; - PinName pin_ssel; -}; - struct i2c_s { I2CName i2c; }; diff --git a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L073RZ/objects.h b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L073RZ/objects.h index 3932d46128..5f05cd5bda 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L073RZ/objects.h +++ b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L073RZ/objects.h @@ -66,20 +66,6 @@ struct dac_s { uint32_t channel; }; -struct spi_s { - SPIName spi; - uint32_t bits; - uint32_t cpol; - uint32_t cpha; - uint32_t mode; - uint32_t nss; - uint32_t br_presc; - PinName pin_miso; - PinName pin_mosi; - PinName pin_sclk; - PinName pin_ssel; -}; - struct i2c_s { I2CName i2c; }; diff --git a/targets/TARGET_STM/TARGET_STM32L0/common_objects.h b/targets/TARGET_STM/TARGET_STM32L0/common_objects.h index 585d323084..fd235f0781 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/common_objects.h +++ b/targets/TARGET_STM/TARGET_STM32L0/common_objects.h @@ -49,6 +49,21 @@ struct pwmout_s { uint8_t inverted; }; +struct spi_s { + SPI_HandleTypeDef handle; + IRQn_Type spiIRQ; + SPIName spi; + PinName pin_miso; + PinName pin_mosi; + PinName pin_sclk; + PinName pin_ssel; +#ifdef DEVICE_SPI_ASYNCH + uint32_t event; + uint8_t module; + uint8_t transfer_type; +#endif +}; + struct serial_s { UARTName uart; int index; // Used by irq diff --git a/targets/TARGET_STM/TARGET_STM32L0/spi_api.c b/targets/TARGET_STM/TARGET_STM32L0/spi_api.c index bbd0838a1f..44c422c9f2 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/spi_api.c +++ b/targets/TARGET_STM/TARGET_STM32L0/spi_api.c @@ -33,166 +33,28 @@ #if DEVICE_SPI -#include #include "cmsis.h" #include "pinmap.h" #include "mbed_error.h" #include "PeripheralPins.h" -static SPI_HandleTypeDef SpiHandle; - -static void init_spi(spi_t *obj) -{ - SpiHandle.Instance = (SPI_TypeDef *)(obj->spi); - - __HAL_SPI_DISABLE(&SpiHandle); - - SpiHandle.Init.Mode = obj->mode; - SpiHandle.Init.BaudRatePrescaler = obj->br_presc; - SpiHandle.Init.Direction = SPI_DIRECTION_2LINES; - SpiHandle.Init.CLKPhase = obj->cpha; - SpiHandle.Init.CLKPolarity = obj->cpol; - SpiHandle.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED; - SpiHandle.Init.CRCPolynomial = 7; - SpiHandle.Init.DataSize = obj->bits; - SpiHandle.Init.FirstBit = SPI_FIRSTBIT_MSB; - SpiHandle.Init.NSS = obj->nss; - SpiHandle.Init.TIMode = SPI_TIMODE_DISABLED; - - if (HAL_SPI_Init(&SpiHandle) != HAL_OK) { - error("Cannot initialize SPI"); - } - - __HAL_SPI_ENABLE(&SpiHandle); -} - -void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel) -{ - // Determine the SPI to use - SPIName spi_mosi = (SPIName)pinmap_peripheral(mosi, PinMap_SPI_MOSI); - SPIName spi_miso = (SPIName)pinmap_peripheral(miso, PinMap_SPI_MISO); - SPIName spi_sclk = (SPIName)pinmap_peripheral(sclk, PinMap_SPI_SCLK); - SPIName spi_ssel = (SPIName)pinmap_peripheral(ssel, PinMap_SPI_SSEL); - - SPIName spi_data = (SPIName)pinmap_merge(spi_mosi, spi_miso); - SPIName spi_cntl = (SPIName)pinmap_merge(spi_sclk, spi_ssel); - - obj->spi = (SPIName)pinmap_merge(spi_data, spi_cntl); - MBED_ASSERT(obj->spi != (SPIName)NC); - - // Enable SPI clock - if (obj->spi == SPI_1) { - __SPI1_CLK_ENABLE(); - } - -#if defined(SPI2_BASE) - if (obj->spi == SPI_2) { - __SPI2_CLK_ENABLE(); - } +#if DEVICE_SPI_ASYNCH + #define SPI_S(obj) (( struct spi_s *)(&(obj->spi))) +#else + #define SPI_S(obj) (( struct spi_s *)(obj)) #endif - // Configure the SPI pins - pinmap_pinout(mosi, PinMap_SPI_MOSI); - pinmap_pinout(miso, PinMap_SPI_MISO); - pinmap_pinout(sclk, PinMap_SPI_SCLK); - // Save new values - obj->bits = SPI_DATASIZE_8BIT; - obj->cpol = SPI_POLARITY_LOW; - obj->cpha = SPI_PHASE_1EDGE; - obj->br_presc = SPI_BAUDRATEPRESCALER_256; - - obj->pin_miso = miso; - obj->pin_mosi = mosi; - obj->pin_sclk = sclk; - obj->pin_ssel = ssel; - - if (ssel != NC) { - pinmap_pinout(ssel, PinMap_SPI_SSEL); - } else { - obj->nss = SPI_NSS_SOFT; - } - - init_spi(obj); -} - -void spi_free(spi_t *obj) -{ - // Reset SPI and disable clock - if (obj->spi == SPI_1) { - __SPI1_FORCE_RESET(); - __SPI1_RELEASE_RESET(); - __SPI1_CLK_DISABLE(); - } - -#if defined(SPI2_BASE) - if (obj->spi == SPI_2) { - __SPI2_FORCE_RESET(); - __SPI2_RELEASE_RESET(); - __SPI2_CLK_DISABLE(); - } -#endif - - // Configure GPIO - pin_function(obj->pin_miso, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0)); - pin_function(obj->pin_mosi, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0)); - pin_function(obj->pin_sclk, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0)); - pin_function(obj->pin_ssel, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0)); -} - -void spi_format(spi_t *obj, int bits, int mode, int slave) -{ - // Save new values - if (bits == 16) { - obj->bits = SPI_DATASIZE_16BIT; - } else { - obj->bits = SPI_DATASIZE_8BIT; - } - - switch (mode) { - case 0: - obj->cpol = SPI_POLARITY_LOW; - obj->cpha = SPI_PHASE_1EDGE; - break; - case 1: - obj->cpol = SPI_POLARITY_LOW; - obj->cpha = SPI_PHASE_2EDGE; - break; - case 2: - obj->cpol = SPI_POLARITY_HIGH; - obj->cpha = SPI_PHASE_1EDGE; - break; - default: - obj->cpol = SPI_POLARITY_HIGH; - obj->cpha = SPI_PHASE_2EDGE; - break; - } - - if (obj->nss != SPI_NSS_SOFT) { - obj->nss = (slave) ? SPI_NSS_HARD_INPUT : SPI_NSS_HARD_OUTPUT; - } - - obj->mode = (slave) ? SPI_MODE_SLAVE : SPI_MODE_MASTER; - - init_spi(obj); -} - -static const uint16_t baudrate_prescaler_table[] = {SPI_BAUDRATEPRESCALER_2, - SPI_BAUDRATEPRESCALER_4, - SPI_BAUDRATEPRESCALER_8, - SPI_BAUDRATEPRESCALER_16, - SPI_BAUDRATEPRESCALER_32, - SPI_BAUDRATEPRESCALER_64, - SPI_BAUDRATEPRESCALER_128, - SPI_BAUDRATEPRESCALER_256}; - -void spi_frequency(spi_t *obj, int hz) -{ +/* + * Only the frequency is managed in the family specific part + * the rest of SPI management is common to all STM32 families + */ +int spi_get_clock_freq(spi_t *obj) { + struct spi_s *spiobj = SPI_S(obj); int spi_hz = 0; - uint8_t prescaler_rank = 0; /* Get source clock depending on SPI instance */ - switch ((int)obj->spi) { + switch ((int)spiobj->spi) { case SPI_1: /* SPI_1. Source CLK is PCKL2 */ spi_hz = HAL_RCC_GetPCLK2Freq(); @@ -204,92 +66,10 @@ void spi_frequency(spi_t *obj, int hz) break; #endif default: - error("SPI instance not set"); + error("CLK: SPI instance not set"); + break; } - - /* Define pre-scaler in order to get highest available frequency below requested frequency */ - while ((spi_hz > hz) && (prescaler_rank < sizeof(baudrate_prescaler_table)/sizeof(baudrate_prescaler_table[0]))){ - spi_hz = spi_hz / 2; - prescaler_rank++; - } - - if (prescaler_rank <= sizeof(baudrate_prescaler_table)/sizeof(baudrate_prescaler_table[0])) { - obj->br_presc = baudrate_prescaler_table[prescaler_rank-1]; - } else { - error("Couldn't setup requested SPI frequency"); - } - - init_spi(obj); -} - -static inline int ssp_readable(spi_t *obj) -{ - int status; - SpiHandle.Instance = (SPI_TypeDef *)(obj->spi); - // Check if data is received - status = ((__HAL_SPI_GET_FLAG(&SpiHandle, SPI_FLAG_RXNE) != RESET) ? 1 : 0); - return status; -} - -static inline int ssp_writeable(spi_t *obj) -{ - int status; - SpiHandle.Instance = (SPI_TypeDef *)(obj->spi); - // Check if data is transmitted - status = ((__HAL_SPI_GET_FLAG(&SpiHandle, SPI_FLAG_TXE) != RESET) ? 1 : 0); - return status; -} - -static inline void ssp_write(spi_t *obj, int value) -{ - SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi); - while (!ssp_writeable(obj)); - spi->DR = (uint16_t)value; -} - -static inline int ssp_read(spi_t *obj) -{ - SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi); - while (!ssp_readable(obj)); - return (int)spi->DR; -} - -static inline int ssp_busy(spi_t *obj) -{ - int status; - SpiHandle.Instance = (SPI_TypeDef *)(obj->spi); - status = ((__HAL_SPI_GET_FLAG(&SpiHandle, SPI_FLAG_BSY) != RESET) ? 1 : 0); - return status; -} - -int spi_master_write(spi_t *obj, int value) -{ - ssp_write(obj, value); - return ssp_read(obj); -} - -int spi_slave_receive(spi_t *obj) -{ - return (ssp_readable(obj) ? 1 : 0); -}; - -int spi_slave_read(spi_t *obj) -{ - SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi); - while (!ssp_readable(obj)); - return (int)spi->DR; -} - -void spi_slave_write(spi_t *obj, int value) -{ - SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi); - while (!ssp_writeable(obj)); - spi->DR = (uint16_t)value; -} - -int spi_busy(spi_t *obj) -{ - return ssp_busy(obj); + return spi_hz; } #endif diff --git a/targets/TARGET_STM/TARGET_STM32L1/TARGET_MOTE_L152RC/objects.h b/targets/TARGET_STM/TARGET_STM32L1/TARGET_MOTE_L152RC/objects.h index 7a0d5f1489..84754ae748 100644 --- a/targets/TARGET_STM/TARGET_STM32L1/TARGET_MOTE_L152RC/objects.h +++ b/targets/TARGET_STM/TARGET_STM32L1/TARGET_MOTE_L152RC/objects.h @@ -65,20 +65,6 @@ struct dac_s { PinName pin; }; -struct spi_s { - SPIName spi; - uint32_t bits; - uint32_t cpol; - uint32_t cpha; - uint32_t mode; - uint32_t nss; - uint32_t br_presc; - PinName pin_miso; - PinName pin_mosi; - PinName pin_sclk; - PinName pin_ssel; -}; - struct i2c_s { I2CName i2c; uint32_t slave; diff --git a/targets/TARGET_STM/TARGET_STM32L1/TARGET_NUCLEO_L152RE/objects.h b/targets/TARGET_STM/TARGET_STM32L1/TARGET_NUCLEO_L152RE/objects.h index 7a0d5f1489..84754ae748 100644 --- a/targets/TARGET_STM/TARGET_STM32L1/TARGET_NUCLEO_L152RE/objects.h +++ b/targets/TARGET_STM/TARGET_STM32L1/TARGET_NUCLEO_L152RE/objects.h @@ -65,20 +65,6 @@ struct dac_s { PinName pin; }; -struct spi_s { - SPIName spi; - uint32_t bits; - uint32_t cpol; - uint32_t cpha; - uint32_t mode; - uint32_t nss; - uint32_t br_presc; - PinName pin_miso; - PinName pin_mosi; - PinName pin_sclk; - PinName pin_ssel; -}; - struct i2c_s { I2CName i2c; uint32_t slave; diff --git a/targets/TARGET_STM/TARGET_STM32L1/TARGET_NZ32_SC151/objects.h b/targets/TARGET_STM/TARGET_STM32L1/TARGET_NZ32_SC151/objects.h index 7a0d5f1489..84754ae748 100644 --- a/targets/TARGET_STM/TARGET_STM32L1/TARGET_NZ32_SC151/objects.h +++ b/targets/TARGET_STM/TARGET_STM32L1/TARGET_NZ32_SC151/objects.h @@ -65,20 +65,6 @@ struct dac_s { PinName pin; }; -struct spi_s { - SPIName spi; - uint32_t bits; - uint32_t cpol; - uint32_t cpha; - uint32_t mode; - uint32_t nss; - uint32_t br_presc; - PinName pin_miso; - PinName pin_mosi; - PinName pin_sclk; - PinName pin_ssel; -}; - struct i2c_s { I2CName i2c; uint32_t slave; diff --git a/targets/TARGET_STM/TARGET_STM32L1/common_objects.h b/targets/TARGET_STM/TARGET_STM32L1/common_objects.h index 335b444aac..fbbbc9868a 100644 --- a/targets/TARGET_STM/TARGET_STM32L1/common_objects.h +++ b/targets/TARGET_STM/TARGET_STM32L1/common_objects.h @@ -66,6 +66,21 @@ struct serial_s { #endif }; +struct spi_s { + SPI_HandleTypeDef handle; + IRQn_Type spiIRQ; + SPIName spi; + PinName pin_miso; + PinName pin_mosi; + PinName pin_sclk; + PinName pin_ssel; +#ifdef DEVICE_SPI_ASYNCH + uint32_t event; + uint8_t module; + uint8_t transfer_type; +#endif +}; + #include "gpio_object.h" #ifdef __cplusplus diff --git a/targets/TARGET_STM/TARGET_STM32L1/spi_api.c b/targets/TARGET_STM/TARGET_STM32L1/spi_api.c index e312af1e4c..ed3efe7a8e 100644 --- a/targets/TARGET_STM/TARGET_STM32L1/spi_api.c +++ b/targets/TARGET_STM/TARGET_STM32L1/spi_api.c @@ -33,167 +33,27 @@ #if DEVICE_SPI -#include #include "cmsis.h" #include "pinmap.h" #include "PeripheralPins.h" -static SPI_HandleTypeDef SpiHandle; -static void init_spi(spi_t *obj) -{ - SpiHandle.Instance = (SPI_TypeDef *)(obj->spi); +#if DEVICE_SPI_ASYNCH + #define SPI_S(obj) (( struct spi_s *)(&(obj->spi))) +#else + #define SPI_S(obj) (( struct spi_s *)(obj)) +#endif - __HAL_SPI_DISABLE(&SpiHandle); - - SpiHandle.Init.Mode = obj->mode; - SpiHandle.Init.BaudRatePrescaler = obj->br_presc; - SpiHandle.Init.Direction = SPI_DIRECTION_2LINES; - SpiHandle.Init.CLKPhase = obj->cpha; - SpiHandle.Init.CLKPolarity = obj->cpol; - SpiHandle.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED; - SpiHandle.Init.CRCPolynomial = 7; - SpiHandle.Init.DataSize = obj->bits; - SpiHandle.Init.FirstBit = SPI_FIRSTBIT_MSB; - SpiHandle.Init.NSS = obj->nss; - SpiHandle.Init.TIMode = SPI_TIMODE_DISABLED; - - HAL_SPI_Init(&SpiHandle); - - __HAL_SPI_ENABLE(&SpiHandle); -} - -void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel) -{ - // Determine the SPI to use - SPIName spi_mosi = (SPIName)pinmap_peripheral(mosi, PinMap_SPI_MOSI); - SPIName spi_miso = (SPIName)pinmap_peripheral(miso, PinMap_SPI_MISO); - SPIName spi_sclk = (SPIName)pinmap_peripheral(sclk, PinMap_SPI_SCLK); - SPIName spi_ssel = (SPIName)pinmap_peripheral(ssel, PinMap_SPI_SSEL); - - SPIName spi_data = (SPIName)pinmap_merge(spi_mosi, spi_miso); - SPIName spi_cntl = (SPIName)pinmap_merge(spi_sclk, spi_ssel); - - obj->spi = (SPIName)pinmap_merge(spi_data, spi_cntl); - MBED_ASSERT(obj->spi != (SPIName)NC); - - // Enable SPI clock - if (obj->spi == SPI_1) { - __SPI1_CLK_ENABLE(); - } - if (obj->spi == SPI_2) { - __SPI2_CLK_ENABLE(); - } - if (obj->spi == SPI_3) { - __SPI3_CLK_ENABLE(); - } - - // Configure the SPI pins - pinmap_pinout(mosi, PinMap_SPI_MOSI); - pinmap_pinout(miso, PinMap_SPI_MISO); - pinmap_pinout(sclk, PinMap_SPI_SCLK); - - // Save new values - obj->bits = SPI_DATASIZE_8BIT; - obj->cpol = SPI_POLARITY_LOW; - obj->cpha = SPI_PHASE_1EDGE; - obj->br_presc = SPI_BAUDRATEPRESCALER_256; - - obj->pin_miso = miso; - obj->pin_mosi = mosi; - obj->pin_sclk = sclk; - obj->pin_ssel = ssel; - - if (ssel != NC) { - pinmap_pinout(ssel, PinMap_SPI_SSEL); - } else { - obj->nss = SPI_NSS_SOFT; - } - - init_spi(obj); -} - -void spi_free(spi_t *obj) -{ - // Reset SPI and disable clock - if (obj->spi == SPI_1) { - __SPI1_FORCE_RESET(); - __SPI1_RELEASE_RESET(); - __SPI1_CLK_DISABLE(); - } - - if (obj->spi == SPI_2) { - __SPI2_FORCE_RESET(); - __SPI2_RELEASE_RESET(); - __SPI2_CLK_DISABLE(); - } - - if (obj->spi == SPI_3) { - __SPI3_FORCE_RESET(); - __SPI3_RELEASE_RESET(); - __SPI3_CLK_DISABLE(); - } - - // Configure GPIO - pin_function(obj->pin_miso, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0)); - pin_function(obj->pin_mosi, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0)); - pin_function(obj->pin_sclk, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0)); - pin_function(obj->pin_ssel, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0)); -} - -void spi_format(spi_t *obj, int bits, int mode, int slave) -{ - // Save new values - if (bits == 16) { - obj->bits = SPI_DATASIZE_16BIT; - } else { - obj->bits = SPI_DATASIZE_8BIT; - } - - switch (mode) { - case 0: - obj->cpol = SPI_POLARITY_LOW; - obj->cpha = SPI_PHASE_1EDGE; - break; - case 1: - obj->cpol = SPI_POLARITY_LOW; - obj->cpha = SPI_PHASE_2EDGE; - break; - case 2: - obj->cpol = SPI_POLARITY_HIGH; - obj->cpha = SPI_PHASE_1EDGE; - break; - default: - obj->cpol = SPI_POLARITY_HIGH; - obj->cpha = SPI_PHASE_2EDGE; - break; - } - - if (obj->nss != SPI_NSS_SOFT) { - obj->nss = (slave) ? SPI_NSS_HARD_INPUT : SPI_NSS_HARD_OUTPUT; - } - - obj->mode = (slave) ? SPI_MODE_SLAVE : SPI_MODE_MASTER; - - init_spi(obj); -} - -static const uint16_t baudrate_prescaler_table[] = {SPI_BAUDRATEPRESCALER_2, - SPI_BAUDRATEPRESCALER_4, - SPI_BAUDRATEPRESCALER_8, - SPI_BAUDRATEPRESCALER_16, - SPI_BAUDRATEPRESCALER_32, - SPI_BAUDRATEPRESCALER_64, - SPI_BAUDRATEPRESCALER_128, - SPI_BAUDRATEPRESCALER_256}; - -void spi_frequency(spi_t *obj, int hz) -{ +/* + * Only the frequency is managed in the family specific part + * the rest of SPI management is common to all STM32 families + */ +int spi_get_clock_freq(spi_t *obj) { + struct spi_s *spiobj = SPI_S(obj); int spi_hz = 0; - uint8_t prescaler_rank = 0; /* Get source clock depending on SPI instance */ - switch ((int)obj->spi) { + switch ((int)spiobj->spi) { case SPI_1: /* SPI_1. Source CLK is PCKL2 */ spi_hz = HAL_RCC_GetPCLK2Freq(); @@ -204,92 +64,10 @@ void spi_frequency(spi_t *obj, int hz) spi_hz = HAL_RCC_GetPCLK1Freq(); break; default: - error("SPI instance not set"); + error("CLK: SPI instance not set"); + break; } - - /* Define pre-scaler in order to get highest available frequency below requested frequency */ - while ((spi_hz > hz) && (prescaler_rank < sizeof(baudrate_prescaler_table)/sizeof(baudrate_prescaler_table[0]))){ - spi_hz = spi_hz / 2; - prescaler_rank++; - } - - if (prescaler_rank <= sizeof(baudrate_prescaler_table)/sizeof(baudrate_prescaler_table[0])) { - obj->br_presc = baudrate_prescaler_table[prescaler_rank-1]; - } else { - error("Couldn't setup requested SPI frequency"); - } - - init_spi(obj); -} - -static inline int ssp_readable(spi_t *obj) -{ - int status; - SpiHandle.Instance = (SPI_TypeDef *)(obj->spi); - // Check if data is received - status = ((__HAL_SPI_GET_FLAG(&SpiHandle, SPI_FLAG_RXNE) != RESET) ? 1 : 0); - return status; -} - -static inline int ssp_writeable(spi_t *obj) -{ - int status; - SpiHandle.Instance = (SPI_TypeDef *)(obj->spi); - // Check if data is transmitted - status = ((__HAL_SPI_GET_FLAG(&SpiHandle, SPI_FLAG_TXE) != RESET) ? 1 : 0); - return status; -} - -static inline void ssp_write(spi_t *obj, int value) -{ - SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi); - while (!ssp_writeable(obj)); - spi->DR = (uint16_t)value; -} - -static inline int ssp_read(spi_t *obj) -{ - SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi); - while (!ssp_readable(obj)); - return (int)spi->DR; -} - -static inline int ssp_busy(spi_t *obj) -{ - int status; - SpiHandle.Instance = (SPI_TypeDef *)(obj->spi); - status = ((__HAL_SPI_GET_FLAG(&SpiHandle, SPI_FLAG_BSY) != RESET) ? 1 : 0); - return status; -} - -int spi_master_write(spi_t *obj, int value) -{ - ssp_write(obj, value); - return ssp_read(obj); -} - -int spi_slave_receive(spi_t *obj) -{ - return (ssp_readable(obj) ? 1 : 0); -}; - -int spi_slave_read(spi_t *obj) -{ - SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi); - while (!ssp_readable(obj)); - return (int)spi->DR; -} - -void spi_slave_write(spi_t *obj, int value) -{ - SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi); - while (!ssp_writeable(obj)); - spi->DR = (uint16_t)value; -} - -int spi_busy(spi_t *obj) -{ - return ssp_busy(obj); + return spi_hz; } #endif diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_DISCO_L476VG/objects.h b/targets/TARGET_STM/TARGET_STM32L4/TARGET_DISCO_L476VG/objects.h index 20556881d8..6d890131c3 100644 --- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_DISCO_L476VG/objects.h +++ b/targets/TARGET_STM/TARGET_STM32L4/TARGET_DISCO_L476VG/objects.h @@ -66,20 +66,6 @@ struct dac_s { uint32_t channel; }; -struct spi_s { - SPIName spi; - uint32_t bits; - uint32_t cpol; - uint32_t cpha; - uint32_t mode; - uint32_t nss; - uint32_t br_presc; - PinName pin_miso; - PinName pin_mosi; - PinName pin_sclk; - PinName pin_ssel; -}; - struct i2c_s { I2CName i2c; uint32_t slave; diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_NUCLEO_L432KC/objects.h b/targets/TARGET_STM/TARGET_STM32L4/TARGET_NUCLEO_L432KC/objects.h index c3407b008d..689609d797 100644 --- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_NUCLEO_L432KC/objects.h +++ b/targets/TARGET_STM/TARGET_STM32L4/TARGET_NUCLEO_L432KC/objects.h @@ -66,20 +66,6 @@ struct dac_s { uint32_t channel; }; -struct spi_s { - SPIName spi; - uint32_t bits; - uint32_t cpol; - uint32_t cpha; - uint32_t mode; - uint32_t nss; - uint32_t br_presc; - PinName pin_miso; - PinName pin_mosi; - PinName pin_sclk; - PinName pin_ssel; -}; - struct i2c_s { I2CName i2c; uint32_t slave; diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_NUCLEO_L476RG/objects.h b/targets/TARGET_STM/TARGET_STM32L4/TARGET_NUCLEO_L476RG/objects.h index 20556881d8..6d890131c3 100644 --- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_NUCLEO_L476RG/objects.h +++ b/targets/TARGET_STM/TARGET_STM32L4/TARGET_NUCLEO_L476RG/objects.h @@ -66,20 +66,6 @@ struct dac_s { uint32_t channel; }; -struct spi_s { - SPIName spi; - uint32_t bits; - uint32_t cpol; - uint32_t cpha; - uint32_t mode; - uint32_t nss; - uint32_t br_presc; - PinName pin_miso; - PinName pin_mosi; - PinName pin_sclk; - PinName pin_ssel; -}; - struct i2c_s { I2CName i2c; uint32_t slave; diff --git a/targets/TARGET_STM/TARGET_STM32L4/common_objects.h b/targets/TARGET_STM/TARGET_STM32L4/common_objects.h index 585d323084..fd235f0781 100644 --- a/targets/TARGET_STM/TARGET_STM32L4/common_objects.h +++ b/targets/TARGET_STM/TARGET_STM32L4/common_objects.h @@ -49,6 +49,21 @@ struct pwmout_s { uint8_t inverted; }; +struct spi_s { + SPI_HandleTypeDef handle; + IRQn_Type spiIRQ; + SPIName spi; + PinName pin_miso; + PinName pin_mosi; + PinName pin_sclk; + PinName pin_ssel; +#ifdef DEVICE_SPI_ASYNCH + uint32_t event; + uint8_t module; + uint8_t transfer_type; +#endif +}; + struct serial_s { UARTName uart; int index; // Used by irq diff --git a/targets/TARGET_STM/TARGET_STM32L4/spi_api.c b/targets/TARGET_STM/TARGET_STM32L4/spi_api.c index c0ec856511..d383c9d31f 100644 --- a/targets/TARGET_STM/TARGET_STM32L4/spi_api.c +++ b/targets/TARGET_STM/TARGET_STM32L4/spi_api.c @@ -32,311 +32,43 @@ #if DEVICE_SPI -#include #include "cmsis.h" #include "pinmap.h" #include "mbed_error.h" #include "PeripheralPins.h" -static SPI_HandleTypeDef SpiHandle; - -static void init_spi(spi_t *obj) -{ - SpiHandle.Instance = (SPI_TypeDef *)(obj->spi); - - __HAL_SPI_DISABLE(&SpiHandle); - - SpiHandle.Init.Mode = obj->mode; - SpiHandle.Init.BaudRatePrescaler = obj->br_presc; - SpiHandle.Init.Direction = SPI_DIRECTION_2LINES; - SpiHandle.Init.CLKPhase = obj->cpha; - SpiHandle.Init.CLKPolarity = obj->cpol; - SpiHandle.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; - SpiHandle.Init.CRCPolynomial = 7; - SpiHandle.Init.CRCLength = SPI_CRC_LENGTH_8BIT; - SpiHandle.Init.DataSize = obj->bits; - SpiHandle.Init.FirstBit = SPI_FIRSTBIT_MSB; - SpiHandle.Init.TIMode = SPI_TIMODE_DISABLE; - SpiHandle.Init.NSS = obj->nss; - SpiHandle.Init.NSSPMode = SPI_NSS_PULSE_DISABLE; - - if (HAL_SPI_Init(&SpiHandle) != HAL_OK) { - error("Cannot initialize SPI\n"); - } - - __HAL_SPI_ENABLE(&SpiHandle); -} - -void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel) -{ - // Determine the SPI to use - SPIName spi_mosi = (SPIName)pinmap_peripheral(mosi, PinMap_SPI_MOSI); - SPIName spi_miso = (SPIName)pinmap_peripheral(miso, PinMap_SPI_MISO); - SPIName spi_sclk = (SPIName)pinmap_peripheral(sclk, PinMap_SPI_SCLK); - SPIName spi_ssel = (SPIName)pinmap_peripheral(ssel, PinMap_SPI_SSEL); - - SPIName spi_data = (SPIName)pinmap_merge(spi_mosi, spi_miso); - SPIName spi_cntl = (SPIName)pinmap_merge(spi_sclk, spi_ssel); - - obj->spi = (SPIName)pinmap_merge(spi_data, spi_cntl); - MBED_ASSERT(obj->spi != (SPIName)NC); - - // Enable SPI clock - if (obj->spi == SPI_1) { - __HAL_RCC_SPI1_CLK_ENABLE(); - } -#if defined(SPI2_BASE) - if (obj->spi == SPI_2) { - __HAL_RCC_SPI2_CLK_ENABLE(); - } -#endif - if (obj->spi == SPI_3) { - __HAL_RCC_SPI3_CLK_ENABLE(); - } - - // Configure the SPI pins - pinmap_pinout(mosi, PinMap_SPI_MOSI); - pinmap_pinout(miso, PinMap_SPI_MISO); - pinmap_pinout(sclk, PinMap_SPI_SCLK); - - // Save new values - obj->bits = SPI_DATASIZE_8BIT; - obj->cpol = SPI_POLARITY_LOW; - obj->cpha = SPI_PHASE_1EDGE; - obj->br_presc = SPI_BAUDRATEPRESCALER_256; - - obj->pin_miso = miso; - obj->pin_mosi = mosi; - obj->pin_sclk = sclk; - obj->pin_ssel = ssel; - - if (ssel == NC) { // SW NSS Master mode - obj->mode = SPI_MODE_MASTER; - obj->nss = SPI_NSS_SOFT; - } else { // Slave - pinmap_pinout(ssel, PinMap_SPI_SSEL); - obj->mode = SPI_MODE_SLAVE; - obj->nss = SPI_NSS_HARD_INPUT; - } - - init_spi(obj); -} - -void spi_free(spi_t *obj) -{ - // Reset SPI and disable clock - if (obj->spi == SPI_1) { - __HAL_RCC_SPI1_FORCE_RESET(); - __HAL_RCC_SPI1_RELEASE_RESET(); - __HAL_RCC_SPI1_CLK_DISABLE(); - } - -#if defined(SPI2_BASE) - if (obj->spi == SPI_2) { - __HAL_RCC_SPI2_FORCE_RESET(); - __HAL_RCC_SPI2_RELEASE_RESET(); - __HAL_RCC_SPI2_CLK_DISABLE(); - } +#if DEVICE_SPI_ASYNCH + #define SPI_S(obj) (( struct spi_s *)(&(obj->spi))) +#else + #define SPI_S(obj) (( struct spi_s *)(obj)) #endif - if (obj->spi == SPI_3) { - __HAL_RCC_SPI3_FORCE_RESET(); - __HAL_RCC_SPI3_RELEASE_RESET(); - __HAL_RCC_SPI3_CLK_DISABLE(); - } - - // Configure GPIO - pin_function(obj->pin_miso, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0)); - pin_function(obj->pin_mosi, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0)); - pin_function(obj->pin_sclk, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0)); - pin_function(obj->pin_ssel, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0)); -} - -void spi_format(spi_t *obj, int bits, int mode, int slave) -{ - // Save new values - if (bits == 16) { - obj->bits = SPI_DATASIZE_16BIT; - } else { - obj->bits = SPI_DATASIZE_8BIT; - } - - switch (mode) { - case 0: - obj->cpol = SPI_POLARITY_LOW; - obj->cpha = SPI_PHASE_1EDGE; - break; - case 1: - obj->cpol = SPI_POLARITY_LOW; - obj->cpha = SPI_PHASE_2EDGE; - break; - case 2: - obj->cpol = SPI_POLARITY_HIGH; - obj->cpha = SPI_PHASE_1EDGE; - break; - default: - obj->cpol = SPI_POLARITY_HIGH; - obj->cpha = SPI_PHASE_2EDGE; - break; - } - - if (slave == 0) { - obj->mode = SPI_MODE_MASTER; - obj->nss = SPI_NSS_SOFT; - } else { - obj->mode = SPI_MODE_SLAVE; - obj->nss = SPI_NSS_HARD_INPUT; - } - - init_spi(obj); -} - -static const uint16_t baudrate_prescaler_table[] = {SPI_BAUDRATEPRESCALER_2, - SPI_BAUDRATEPRESCALER_4, - SPI_BAUDRATEPRESCALER_8, - SPI_BAUDRATEPRESCALER_16, - SPI_BAUDRATEPRESCALER_32, - SPI_BAUDRATEPRESCALER_64, - SPI_BAUDRATEPRESCALER_128, - SPI_BAUDRATEPRESCALER_256}; - -void spi_frequency(spi_t *obj, int hz) -{ +/* + * Only the frequency is managed in the family specific part + * the rest of SPI management is common to all STM32 families + */ +int spi_get_clock_freq(spi_t *obj) { + struct spi_s *spiobj = SPI_S(obj); int spi_hz = 0; - uint8_t prescaler_rank = 0; /* Get source clock depending on SPI instance */ - switch ((int)obj->spi) { + switch ((int)spiobj->spi) { case SPI_1: - /* SPI_1. Source CLK is PCKL2 */ - spi_hz = HAL_RCC_GetPCLK2Freq(); - break; + /* SPI_1. Source CLK is PCKL2 */ + spi_hz = HAL_RCC_GetPCLK2Freq(); + break; #if defined(SPI2_BASE) - case SPI_2: + case SPI_2: #endif - case SPI_3: - /* SPI_2, SPI_3. Source CLK is PCKL1 */ - spi_hz = HAL_RCC_GetPCLK1Freq(); - break; - default: - error("SPI instance not set"); + case SPI_3: + /* SPI_2, SPI_3. Source CLK is PCKL1 */ + spi_hz = HAL_RCC_GetPCLK1Freq(); + break; + default: + error("CLK: SPI instance not set"); + break; } - - /* Define pre-scaler in order to get highest available frequency below requested frequency */ - while ((spi_hz > hz) && (prescaler_rank < sizeof(baudrate_prescaler_table)/sizeof(baudrate_prescaler_table[0]))){ - spi_hz = spi_hz / 2; - prescaler_rank++; - } - - if (prescaler_rank <= sizeof(baudrate_prescaler_table)/sizeof(baudrate_prescaler_table[0])) { - obj->br_presc = baudrate_prescaler_table[prescaler_rank-1]; - } else { - error("Couldn't setup requested SPI frequency"); - } - - init_spi(obj); -} - -static inline int ssp_readable(spi_t *obj) -{ - int status; - SpiHandle.Instance = (SPI_TypeDef *)(obj->spi); - // Check if data is received - status = ((__HAL_SPI_GET_FLAG(&SpiHandle, SPI_FLAG_RXNE) != RESET) ? 1 : 0); - return status; -} - -static inline int ssp_writeable(spi_t *obj) -{ - int status; - SpiHandle.Instance = (SPI_TypeDef *)(obj->spi); - // Check if data is transmitted - status = ((__HAL_SPI_GET_FLAG(&SpiHandle, SPI_FLAG_TXE) != RESET) ? 1 : 0); - return status; -} - -static inline void ssp_write(spi_t *obj, int value) -{ - SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi); - while (!ssp_writeable(obj)); - //spi->DR = (uint16_t)value; - if (obj->bits == SPI_DATASIZE_8BIT) { - // Force 8-bit access to the data register - uint8_t *p_spi_dr = 0; - p_spi_dr = (uint8_t *) & (spi->DR); - *p_spi_dr = (uint8_t)value; - } else { // SPI_DATASIZE_16BIT - spi->DR = (uint16_t)value; - } -} - -static inline int ssp_read(spi_t *obj) -{ - SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi); - while (!ssp_readable(obj)); - //return (int)spi->DR; - if (obj->bits == SPI_DATASIZE_8BIT) { - // Force 8-bit access to the data register - uint8_t *p_spi_dr = 0; - p_spi_dr = (uint8_t *) & (spi->DR); - return (int)(*p_spi_dr); - } else { - return (int)spi->DR; - } -} - -static inline int ssp_busy(spi_t *obj) -{ - int status; - SpiHandle.Instance = (SPI_TypeDef *)(obj->spi); - status = ((__HAL_SPI_GET_FLAG(&SpiHandle, SPI_FLAG_BSY) != RESET) ? 1 : 0); - return status; -} - -int spi_master_write(spi_t *obj, int value) -{ - ssp_write(obj, value); - return ssp_read(obj); -} - -int spi_slave_receive(spi_t *obj) -{ - return (ssp_readable(obj) ? 1 : 0); -}; - -int spi_slave_read(spi_t *obj) -{ - SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi); - while (!ssp_readable(obj)); - //return (int)spi->DR; - if (obj->bits == SPI_DATASIZE_8BIT) { - // Force 8-bit access to the data register - uint8_t *p_spi_dr = 0; - p_spi_dr = (uint8_t *) & (spi->DR); - return (int)(*p_spi_dr); - } else { - return (int)spi->DR; - } -} - -void spi_slave_write(spi_t *obj, int value) -{ - SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi); - while (!ssp_writeable(obj)); - //spi->DR = (uint16_t)value; - if (obj->bits == SPI_DATASIZE_8BIT) { - // Force 8-bit access to the data register - uint8_t *p_spi_dr = 0; - p_spi_dr = (uint8_t *) & (spi->DR); - *p_spi_dr = (uint8_t)value; - } else { // SPI_DATASIZE_16BIT - spi->DR = (uint16_t)value; - } -} - -int spi_busy(spi_t *obj) -{ - return ssp_busy(obj); + return spi_hz; } #endif diff --git a/targets/TARGET_STM/stm_spi_api.c b/targets/TARGET_STM/stm_spi_api.c new file mode 100644 index 0000000000..4068a4cca3 --- /dev/null +++ b/targets/TARGET_STM/stm_spi_api.c @@ -0,0 +1,590 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2015, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ +#include "mbed_assert.h" +#include "mbed_error.h" +#include "spi_api.h" + +#if DEVICE_SPI +#include +#include +#include +#include "cmsis.h" +#include "pinmap.h" +#include "PeripheralPins.h" + +#if DEVICE_SPI_ASYNCH + #define SPI_INST(obj) ((SPI_TypeDef *)(obj->spi.spi)) +#else + #define SPI_INST(obj) ((SPI_TypeDef *)(obj->spi)) +#endif + +#if DEVICE_SPI_ASYNCH + #define SPI_S(obj) (( struct spi_s *)(&(obj->spi))) +#else + #define SPI_S(obj) (( struct spi_s *)(obj)) +#endif + +#ifndef DEBUG_STDIO +# define DEBUG_STDIO 0 +#endif + +#if DEBUG_STDIO +# include +# define DEBUG_PRINTF(...) do { printf(__VA_ARGS__); } while(0) +#else +# define DEBUG_PRINTF(...) {} +#endif + +void init_spi(spi_t *obj) +{ + struct spi_s *spiobj = SPI_S(obj); + SPI_HandleTypeDef *handle = &(spiobj->handle); + + __HAL_SPI_DISABLE(handle); + + DEBUG_PRINTF("init_spi: instance=0x%8X\r\n", (int)handle->Instance); + if (HAL_SPI_Init(handle) != HAL_OK) { + error("Cannot initialize SPI"); + } + + __HAL_SPI_ENABLE(handle); +} + +void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel) +{ + struct spi_s *spiobj = SPI_S(obj); + SPI_HandleTypeDef *handle = &(spiobj->handle); + + // Determine the SPI to use + SPIName spi_mosi = (SPIName)pinmap_peripheral(mosi, PinMap_SPI_MOSI); + SPIName spi_miso = (SPIName)pinmap_peripheral(miso, PinMap_SPI_MISO); + SPIName spi_sclk = (SPIName)pinmap_peripheral(sclk, PinMap_SPI_SCLK); + SPIName spi_ssel = (SPIName)pinmap_peripheral(ssel, PinMap_SPI_SSEL); + + SPIName spi_data = (SPIName)pinmap_merge(spi_mosi, spi_miso); + SPIName spi_cntl = (SPIName)pinmap_merge(spi_sclk, spi_ssel); + + spiobj->spi = (SPIName)pinmap_merge(spi_data, spi_cntl); + MBED_ASSERT(spiobj->spi != (SPIName)NC); + +#if defined SPI1_BASE + // Enable SPI clock + if (spiobj->spi == SPI_1) { + __HAL_RCC_SPI1_CLK_ENABLE(); + spiobj->spiIRQ = SPI1_IRQn; + } +#endif + +#if defined SPI2_BASE + if (spiobj->spi == SPI_2) { + __HAL_RCC_SPI2_CLK_ENABLE(); + spiobj->spiIRQ = SPI2_IRQn; + } +#endif + +#if defined SPI3_BASE + if (spiobj->spi == SPI_3) { + __HAL_RCC_SPI3_CLK_ENABLE(); + spiobj->spiIRQ = SPI3_IRQn; + } +#endif + +#if defined SPI4_BASE + if (spiobj->spi == SPI_4) { + __HAL_RCC_SPI4_CLK_ENABLE(); + spiobj->spiIRQ = SPI4_IRQn; + } +#endif + +#if defined SPI5_BASE + if (spiobj->spi == SPI_5) { + __HAL_RCC_SPI5_CLK_ENABLE(); + spiobj->spiIRQ = SPI5_IRQn; + } +#endif + +#if defined SPI6_BASE + if (spiobj->spi == SPI_6) { + __HAL_RCC_SPI6_CLK_ENABLE(); + spiobj->spiIRQ = SPI6_IRQn; + } +#endif + + // Configure the SPI pins + pinmap_pinout(mosi, PinMap_SPI_MOSI); + pinmap_pinout(miso, PinMap_SPI_MISO); + pinmap_pinout(sclk, PinMap_SPI_SCLK); + spiobj->pin_miso = miso; + spiobj->pin_mosi = mosi; + spiobj->pin_sclk = sclk; + spiobj->pin_ssel = ssel; + if (ssel != NC) { + pinmap_pinout(ssel, PinMap_SPI_SSEL); + } else { + handle->Init.NSS = SPI_NSS_SOFT; + } + + /* Fill default value */ + handle->Instance = SPI_INST(obj); + handle->Init.Mode = SPI_MODE_MASTER; + handle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256; + handle->Init.Direction = SPI_DIRECTION_2LINES; + handle->Init.CLKPhase = SPI_PHASE_1EDGE; + handle->Init.CLKPolarity = SPI_POLARITY_LOW; + handle->Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED; + handle->Init.CRCPolynomial = 7; + handle->Init.DataSize = SPI_DATASIZE_8BIT; + handle->Init.FirstBit = SPI_FIRSTBIT_MSB; + handle->Init.TIMode = SPI_TIMODE_DISABLED; + + init_spi(obj); +} + +void spi_free(spi_t *obj) +{ + struct spi_s *spiobj = SPI_S(obj); + SPI_HandleTypeDef *handle = &(spiobj->handle); + + DEBUG_PRINTF("spi_free\r\n"); + + __HAL_SPI_DISABLE(handle); + HAL_SPI_DeInit(handle); + +#if defined SPI1_BASE + // Reset SPI and disable clock + if (spiobj->spi == SPI_1) { + __HAL_RCC_SPI1_FORCE_RESET(); + __HAL_RCC_SPI1_RELEASE_RESET(); + __HAL_RCC_SPI1_CLK_DISABLE(); + } +#endif +#if defined SPI2_BASE + if (spiobj->spi == SPI_2) { + __HAL_RCC_SPI2_FORCE_RESET(); + __HAL_RCC_SPI2_RELEASE_RESET(); + __HAL_RCC_SPI2_CLK_DISABLE(); + } +#endif + +#if defined SPI3_BASE + if (spiobj->spi == SPI_3) { + __HAL_RCC_SPI3_FORCE_RESET(); + __HAL_RCC_SPI3_RELEASE_RESET(); + __HAL_RCC_SPI3_CLK_DISABLE(); + } +#endif + +#if defined SPI4_BASE + if (spiobj->spi == SPI_4) { + __HAL_RCC_SPI4_FORCE_RESET(); + __HAL_RCC_SPI4_RELEASE_RESET(); + __HAL_RCC_SPI4_CLK_DISABLE(); + } +#endif + +#if defined SPI5_BASE + if (spiobj->spi == SPI_5) { + __HAL_RCC_SPI5_FORCE_RESET(); + __HAL_RCC_SPI5_RELEASE_RESET(); + __HAL_RCC_SPI5_CLK_DISABLE(); + } +#endif + +#if defined SPI6_BASE + if (spiobj->spi == SPI_6) { + __HAL_RCC_SPI6_FORCE_RESET(); + __HAL_RCC_SPI6_RELEASE_RESET(); + __HAL_RCC_SPI6_CLK_DISABLE(); + } +#endif + + // Configure GPIOs + pin_function(spiobj->pin_miso, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0)); + pin_function(spiobj->pin_mosi, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0)); + pin_function(spiobj->pin_sclk, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0)); + if (handle->Init.NSS != SPI_NSS_SOFT) { + pin_function(spiobj->pin_ssel, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0)); + } +} + +void spi_format(spi_t *obj, int bits, int mode, int slave) +{ + struct spi_s *spiobj = SPI_S(obj); + SPI_HandleTypeDef *handle = &(spiobj->handle); + + DEBUG_PRINTF("spi_format, bits:%d, mode:%d, slave?:%d\r\n", bits, mode, slave); + + // Save new values + handle->Init.DataSize = (bits == 16) ? SPI_DATASIZE_16BIT : SPI_DATASIZE_8BIT; + + switch (mode) { + case 0: + handle->Init.CLKPolarity = SPI_POLARITY_LOW; + handle->Init.CLKPhase = SPI_PHASE_1EDGE; + break; + case 1: + handle->Init.CLKPolarity = SPI_POLARITY_LOW; + handle->Init.CLKPhase = SPI_PHASE_2EDGE; + break; + case 2: + handle->Init.CLKPolarity = SPI_POLARITY_HIGH; + handle->Init.CLKPhase = SPI_PHASE_1EDGE; + break; + default: + handle->Init.CLKPolarity = SPI_POLARITY_HIGH; + handle->Init.CLKPhase = SPI_PHASE_2EDGE; + break; + } + + if (handle->Init.NSS != SPI_NSS_SOFT) { + handle->Init.NSS = (slave) ? SPI_NSS_HARD_INPUT : SPI_NSS_HARD_OUTPUT; + } + + handle->Init.Mode = (slave) ? SPI_MODE_SLAVE : SPI_MODE_MASTER; + + init_spi(obj); +} + +/* + * Only the IP clock input is family dependant so it computed + * separately in spi_get_clock_freq + */ +extern int spi_get_clock_freq(spi_t *obj); + +static const uint16_t baudrate_prescaler_table[] = {SPI_BAUDRATEPRESCALER_2, + SPI_BAUDRATEPRESCALER_4, + SPI_BAUDRATEPRESCALER_8, + SPI_BAUDRATEPRESCALER_16, + SPI_BAUDRATEPRESCALER_32, + SPI_BAUDRATEPRESCALER_64, + SPI_BAUDRATEPRESCALER_128, + SPI_BAUDRATEPRESCALER_256}; + +void spi_frequency(spi_t *obj, int hz) { + struct spi_s *spiobj = SPI_S(obj); + int spi_hz = 0; + uint8_t prescaler_rank = 0; + SPI_HandleTypeDef *handle = &(spiobj->handle); + + /* Get the clock of the peripheral */ + spi_hz = spi_get_clock_freq(obj); + + /* Define pre-scaler in order to get highest available frequency below requested frequency */ + while ((spi_hz > hz) && (prescaler_rank < sizeof(baudrate_prescaler_table)/sizeof(baudrate_prescaler_table[0]))){ + spi_hz = spi_hz / 2; + prescaler_rank++; + } + + if (prescaler_rank <= sizeof(baudrate_prescaler_table)/sizeof(baudrate_prescaler_table[0])) { + handle->Init.BaudRatePrescaler = baudrate_prescaler_table[prescaler_rank-1]; + } else { + error("Couldn't setup requested SPI frequency"); + } + + init_spi(obj); +} + +static inline int ssp_readable(spi_t *obj) +{ + int status; + struct spi_s *spiobj = SPI_S(obj); + SPI_HandleTypeDef *handle = &(spiobj->handle); + + // Check if data is received + status = ((__HAL_SPI_GET_FLAG(handle, SPI_FLAG_RXNE) != RESET) ? 1 : 0); + return status; +} + +static inline int ssp_writeable(spi_t *obj) +{ + int status; + struct spi_s *spiobj = SPI_S(obj); + SPI_HandleTypeDef *handle = &(spiobj->handle); + + // Check if data is transmitted + status = ((__HAL_SPI_GET_FLAG(handle, SPI_FLAG_TXE) != RESET) ? 1 : 0); + return status; +} + +static inline int ssp_busy(spi_t *obj) +{ + int status; + struct spi_s *spiobj = SPI_S(obj); + SPI_HandleTypeDef *handle = &(spiobj->handle); + status = ((__HAL_SPI_GET_FLAG(handle, SPI_FLAG_BSY) != RESET) ? 1 : 0); + return status; +} + +int spi_master_write(spi_t *obj, int value) +{ + uint16_t size, Rx, ret; + struct spi_s *spiobj = SPI_S(obj); + SPI_HandleTypeDef *handle = &(spiobj->handle); + + size = (handle->Init.DataSize == SPI_DATASIZE_16BIT) ? 2 : 1; + + /* Use 10ms timeout */ + ret = HAL_SPI_TransmitReceive(handle,(uint8_t*)&value,(uint8_t*)&Rx,size,10); + + if(ret == HAL_OK) { + return Rx; + } else { + DEBUG_PRINTF("SPI inst=0x%8X ERROR in write\r\n", (int)handle->Instance); + return -1; + } +} + +int spi_slave_receive(spi_t *obj) +{ + return ((ssp_readable(obj) && !ssp_busy(obj)) ? 1 : 0); +}; + +int spi_slave_read(spi_t *obj) +{ + SPI_TypeDef *spi = SPI_INST(obj); + struct spi_s *spiobj = SPI_S(obj); + SPI_HandleTypeDef *handle = &(spiobj->handle); + while (!ssp_readable(obj)); + if (handle->Init.DataSize == SPI_DATASIZE_8BIT) { + // Force 8-bit access to the data register + uint8_t *p_spi_dr = 0; + p_spi_dr = (uint8_t *) & (spi->DR); + return (int)(*p_spi_dr); + } else { + return (int)spi->DR; + } +} + +void spi_slave_write(spi_t *obj, int value) +{ + SPI_TypeDef *spi = SPI_INST(obj); + struct spi_s *spiobj = SPI_S(obj); + SPI_HandleTypeDef *handle = &(spiobj->handle); + while (!ssp_writeable(obj)); + if (handle->Init.DataSize == SPI_DATASIZE_8BIT) { + // Force 8-bit access to the data register + uint8_t *p_spi_dr = 0; + p_spi_dr = (uint8_t *) & (spi->DR); + *p_spi_dr = (uint8_t)value; + } else { // SPI_DATASIZE_16BIT + spi->DR = (uint16_t)value; + } +} + +int spi_busy(spi_t *obj) +{ + return ssp_busy(obj); +} + +#ifdef DEVICE_SPI_ASYNCH +typedef enum { + SPI_TRANSFER_TYPE_NONE = 0, + SPI_TRANSFER_TYPE_TX = 1, + SPI_TRANSFER_TYPE_RX = 2, + SPI_TRANSFER_TYPE_TXRX = 3, +} transfer_type_t; + + +/// @returns the number of bytes transferred, or `0` if nothing transferred +static int spi_master_start_asynch_transfer(spi_t *obj, transfer_type_t transfer_type, const void *tx, void *rx, size_t length) +{ + struct spi_s *spiobj = SPI_S(obj); + SPI_HandleTypeDef *handle = &(spiobj->handle); + bool is16bit = (handle->Init.DataSize == SPI_DATASIZE_16BIT); + // the HAL expects number of transfers instead of number of bytes + // so for 16 bit transfer width the count needs to be halved + size_t words; + + DEBUG_PRINTF("SPI inst=0x%8X Start: %u, %u\r\n", (int)handle->Instance, transfer_type, length); + + obj->spi.transfer_type = transfer_type; + + if (is16bit) { + words = length / 2; + } else { + words = length; + } + + // enable the interrupt + IRQn_Type irq_n = spiobj->spiIRQ; + NVIC_ClearPendingIRQ(irq_n); + NVIC_DisableIRQ(irq_n); + NVIC_SetPriority(irq_n, 1); + NVIC_EnableIRQ(irq_n); + + // enable the right hal transfer + int rc = 0; + switch(transfer_type) { + case SPI_TRANSFER_TYPE_TXRX: + rc = HAL_SPI_TransmitReceive_IT(handle, (uint8_t*)tx, (uint8_t*)rx, words); + break; + case SPI_TRANSFER_TYPE_TX: + rc = HAL_SPI_Transmit_IT(handle, (uint8_t*)tx, words); + break; + case SPI_TRANSFER_TYPE_RX: + // the receive function also "transmits" the receive buffer so in order + // to guarantee that 0xff is on the line, we explicitly memset it here + memset(rx, SPI_FILL_WORD, length); + rc = HAL_SPI_Receive_IT(handle, (uint8_t*)rx, words); + break; + default: + length = 0; + } + + if (rc) { + DEBUG_PRINTF("SPI: RC=%u\n", rc); + length = 0; + } + + return length; +} + +// asynchronous API +void spi_master_transfer(spi_t *obj, const void *tx, size_t tx_length, void *rx, size_t rx_length, uint8_t bit_width, uint32_t handler, uint32_t event, DMAUsage hint) +{ + struct spi_s *spiobj = SPI_S(obj); + SPI_HandleTypeDef *handle = &(spiobj->handle); + + // TODO: DMA usage is currently ignored + (void) hint; + + // check which use-case we have + bool use_tx = (tx != NULL && tx_length > 0); + bool use_rx = (rx != NULL && rx_length > 0); + bool is16bit = (handle->Init.DataSize == SPI_DATASIZE_16BIT); + + // don't do anything, if the buffers aren't valid + if (!use_tx && !use_rx) + return; + + // copy the buffers to the SPI object + obj->tx_buff.buffer = (void *) tx; + obj->tx_buff.length = tx_length; + obj->tx_buff.pos = 0; + obj->tx_buff.width = is16bit ? 16 : 8; + + obj->rx_buff.buffer = rx; + obj->rx_buff.length = rx_length; + obj->rx_buff.pos = 0; + obj->rx_buff.width = obj->tx_buff.width; + + obj->spi.event = event; + + DEBUG_PRINTF("SPI: Transfer: %u, %u\n", tx_length, rx_length); + + // register the thunking handler + IRQn_Type irq_n = spiobj->spiIRQ; + NVIC_SetVector(irq_n, (uint32_t)handler); + + // enable the right hal transfer + if (use_tx && use_rx) { + // we cannot manage different rx / tx sizes, let's use smaller one + size_t size = (tx_length < rx_length)? tx_length : rx_length; + if(tx_length != rx_length) { + DEBUG_PRINTF("SPI: Full duplex transfer only 1 size: %d\n", size); + obj->tx_buff.length = size; + obj->rx_buff.length = size; + } + spi_master_start_asynch_transfer(obj, SPI_TRANSFER_TYPE_TXRX, tx, rx, size); + } else if (use_tx) { + spi_master_start_asynch_transfer(obj, SPI_TRANSFER_TYPE_TX, tx, NULL, tx_length); + } else if (use_rx) { + spi_master_start_asynch_transfer(obj, SPI_TRANSFER_TYPE_RX, NULL, rx, rx_length); + } +} + +uint32_t spi_irq_handler_asynch(spi_t *obj) +{ + // use the right instance + struct spi_s *spiobj = SPI_S(obj); + SPI_HandleTypeDef *handle = &spiobj->handle; + int event = 0; + + // call the CubeF4 handler, this will update the handle + HAL_SPI_IRQHandler(handle); + + if (HAL_SPI_GetState(handle) == HAL_SPI_STATE_READY) { + // When HAL SPI is back to READY state, check if there was an error + int error = HAL_SPI_GetError(handle); + if(error != HAL_SPI_ERROR_NONE) { + // something went wrong and the transfer has definitely completed + event = SPI_EVENT_ERROR | SPI_EVENT_INTERNAL_TRANSFER_COMPLETE; + + if (error & HAL_SPI_ERROR_OVR) { + // buffer overrun + event |= SPI_EVENT_RX_OVERFLOW; + } + } else { + // else we're done + event = SPI_EVENT_COMPLETE | SPI_EVENT_INTERNAL_TRANSFER_COMPLETE; + } + } + + if (event) DEBUG_PRINTF("SPI: Event: 0x%x\n", event); + + return (event & (obj->spi.event | SPI_EVENT_INTERNAL_TRANSFER_COMPLETE)); +} + +uint8_t spi_active(spi_t *obj) +{ + struct spi_s *spiobj = SPI_S(obj); + SPI_HandleTypeDef *handle = &(spiobj->handle); + HAL_SPI_StateTypeDef state = HAL_SPI_GetState(handle); + + switch(state) { + case HAL_SPI_STATE_RESET: + case HAL_SPI_STATE_READY: + case HAL_SPI_STATE_ERROR: + return 0; + default: + return 1; + } +} + +void spi_abort_asynch(spi_t *obj) +{ + struct spi_s *spiobj = SPI_S(obj); + SPI_HandleTypeDef *handle = &(spiobj->handle); + + // disable interrupt + IRQn_Type irq_n = spiobj->spiIRQ; + NVIC_ClearPendingIRQ(irq_n); + NVIC_DisableIRQ(irq_n); + + // clean-up + __HAL_SPI_DISABLE(handle); + HAL_SPI_DeInit(handle); + HAL_SPI_Init(handle); + __HAL_SPI_ENABLE(handle); +} + +#endif //DEVICE_SPI_ASYNCH + +#endif diff --git a/targets/targets.json b/targets/targets.json index 4cf2d39899..11143b43ec 100644 --- a/targets/targets.json +++ b/targets/targets.json @@ -595,7 +595,8 @@ "supported_toolchains": ["ARM", "uARM", "IAR", "GCC_ARM"], "inherits": ["Target"], "detect_code": ["0725"], - "device_has": ["ANALOGIN", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"], + "macros": ["TRANSACTION_QUEUE_SIZE_SPI=2"], + "device_has": ["ANALOGIN", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES"], "default_lib": "small", "release_versions": ["2"], "device_name": "STM32F030R8" @@ -605,11 +606,11 @@ "core": "Cortex-M0", "default_toolchain": "uARM", "extra_labels": ["STM", "STM32F0", "STM32F031K6"], - "macros": ["RTC_LSI=1"], "supported_toolchains": ["ARM", "uARM", "IAR", "GCC_ARM"], "inherits": ["Target"], "detect_code": ["0791"], - "device_has": ["ANALOGIN", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"], + "macros": ["RTC_LSI=1", "TRANSACTION_QUEUE_SIZE_SPI=2"], + "device_has": ["ANALOGIN", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES"], "default_lib": "small", "release_versions": ["2"], "device_name": "STM32F031K6" @@ -619,11 +620,11 @@ "core": "Cortex-M0", "default_toolchain": "uARM", "extra_labels": ["STM", "STM32F0", "STM32F042K6"], - "macros": ["RTC_LSI=1"], "supported_toolchains": ["ARM", "uARM", "IAR", "GCC_ARM"], "inherits": ["Target"], "detect_code": ["0785"], - "device_has": ["ANALOGIN", "CAN", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"], + "macros": ["RTC_LSI=1", "TRANSACTION_QUEUE_SIZE_SPI=2"], + "device_has": ["ANALOGIN", "CAN", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES"], "default_lib": "small", "release_versions": ["2"], "device_name": "STM32F042K6" @@ -636,7 +637,8 @@ "supported_toolchains": ["ARM", "uARM", "IAR", "GCC_ARM"], "inherits": ["Target"], "detect_code": ["0755"], - "device_has": ["ANALOGIN", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SERIAL_ASYNCH", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"], + "macros": ["TRANSACTION_QUEUE_SIZE_SPI=2"], + "device_has": ["ANALOGIN", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SERIAL_ASYNCH", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES"], "release_versions": ["2", "5"], "device_name": "STM32F070RB" }, @@ -648,7 +650,8 @@ "supported_toolchains": ["ARM", "uARM", "IAR", "GCC_ARM"], "inherits": ["Target"], "detect_code": ["0730"], - "device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SERIAL_ASYNCH", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"], + "macros": ["TRANSACTION_QUEUE_SIZE_SPI=2"], + "device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SERIAL_ASYNCH", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES"], "release_versions": ["2", "5"], "device_name": "STM32F072RB" }, @@ -660,7 +663,8 @@ "supported_toolchains": ["ARM", "uARM", "IAR", "GCC_ARM"], "inherits": ["Target"], "detect_code": ["0750"], - "device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SERIAL_ASYNCH", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"], + "macros": ["TRANSACTION_QUEUE_SIZE_SPI=2"], + "device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SERIAL_ASYNCH", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES"], "release_versions": ["2", "5"], "device_name": "STM32F091RC" }, @@ -672,7 +676,8 @@ "supported_toolchains": ["ARM", "uARM", "GCC_ARM", "IAR"], "inherits": ["Target"], "detect_code": ["0700"], - "device_has": ["ANALOGIN", "CAN", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"], + "macros": ["TRANSACTION_QUEUE_SIZE_SPI=2"], + "device_has": ["ANALOGIN", "CAN", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES"], "release_versions": ["2", "5"], "device_name": "STM32F103RB" }, @@ -684,7 +689,8 @@ "supported_toolchains": ["ARM", "uARM", "IAR", "GCC_ARM"], "inherits": ["Target"], "detect_code": ["0835"], - "device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"], + "macros": ["TRANSACTION_QUEUE_SIZE_SPI=2"], + "device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES"], "features": ["LWIP"], "release_versions": ["2", "5"], "device_name" : "STM32F207ZG" @@ -697,7 +703,8 @@ "supported_toolchains": ["ARM", "uARM", "IAR", "GCC_ARM"], "inherits": ["Target"], "detect_code": ["0705"], - "device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"], + "macros": ["TRANSACTION_QUEUE_SIZE_SPI=2"], + "device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES"], "default_lib": "small", "release_versions": ["2"], "device_name": "STM32F302R8" @@ -707,12 +714,12 @@ "core": "Cortex-M4F", "default_toolchain": "ARM", "extra_labels": ["STM", "STM32F3", "STM32F303K8"], - "macros": ["RTC_LSI=1"], + "macros": ["RTC_LSI=1", "TRANSACTION_QUEUE_SIZE_SPI=2"], "supported_toolchains": ["ARM", "uARM", "IAR", "GCC_ARM"], "inherits": ["Target"], "detect_code": ["0775"], "default_lib": "small", - "device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"], + "device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES"], "release_versions": ["2"], "device_name": "STM32F303K8" }, @@ -724,7 +731,8 @@ "supported_toolchains": ["ARM", "uARM", "IAR", "GCC_ARM"], "inherits": ["Target"], "detect_code": ["0745"], - "device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"], + "macros": ["TRANSACTION_QUEUE_SIZE_SPI=2"], + "device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES"], "release_versions": ["2", "5"], "device_name": "STM32F303RE" }, @@ -736,7 +744,8 @@ "supported_toolchains": ["ARM", "uARM", "IAR", "GCC_ARM"], "inherits": ["Target"], "detect_code": ["0747"], - "device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"], + "macros": ["TRANSACTION_QUEUE_SIZE_SPI=2"], + "device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES"], "release_versions": ["2", "5"], "device_name": "STM32F303RE" }, @@ -748,7 +757,8 @@ "supported_toolchains": ["ARM", "uARM", "IAR", "GCC_ARM"], "inherits": ["Target"], "detect_code": ["0735"], - "device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"], + "macros": ["TRANSACTION_QUEUE_SIZE_SPI=2"], + "device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES"], "default_lib": "small", "release_versions": ["2"], "device_name": "STM32F334R8" @@ -788,7 +798,7 @@ "inherits": ["Target"], "detect_code": ["0740"], "macros": ["TRANSACTION_QUEUE_SIZE_SPI=2"], - "device_has": ["ANALOGIN", "ERROR_RED", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"], + "device_has": ["ANALOGIN", "ERROR_RED", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES"], "release_versions": ["2", "5"], "device_name": "STM32F411RE" }, @@ -866,9 +876,10 @@ "extra_labels": ["STM", "STM32F7", "STM32F746", "STM32F746ZG"], "supported_toolchains": ["ARM", "uARM", "GCC_ARM", "IAR"], "default_toolchain": "ARM", + "macros": ["TRANSACTION_QUEUE_SIZE_SPI=2"], "supported_form_factors": ["ARDUINO"], "detect_code": ["0816"], - "device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES", "TRNG"], + "device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES", "TRNG"], "features": ["LWIP"], "release_versions": ["2", "5"], "device_name": "STM32F746ZG" @@ -880,8 +891,9 @@ "supported_toolchains": ["ARM", "uARM", "GCC_ARM", "IAR"], "default_toolchain": "ARM", "supported_form_factors": ["ARDUINO"], + "macros": ["TRANSACTION_QUEUE_SIZE_SPI=2"], "detect_code": ["0818"], - "device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES", "TRNG"], + "device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES", "TRNG"], "features": ["LWIP"], "release_versions": ["2", "5"], "device_name" : "STM32F767ZI" @@ -957,7 +969,8 @@ "supported_toolchains": ["ARM", "uARM", "IAR", "GCC_ARM"], "inherits": ["Target"], "detect_code": ["0770"], - "device_has": ["ANALOGIN", "ANALOGOUT", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "CAN", "STDIO_MESSAGES", "TRNG"], + "macros": ["TRANSACTION_QUEUE_SIZE_SPI=2"], + "device_has": ["ANALOGIN", "ANALOGOUT", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "CAN", "SPI_ASYNCH", "STDIO_MESSAGES", "TRNG"], "release_versions": ["2", "5"], "device_name" : "STM32L432KC" }, @@ -969,7 +982,8 @@ "supported_toolchains": ["ARM", "uARM", "IAR", "GCC_ARM"], "inherits": ["Target"], "detect_code": ["0765"], - "device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES", "TRNG"], + "macros": ["TRANSACTION_QUEUE_SIZE_SPI=2"], + "device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES", "TRNG"], "release_versions": ["2", "5"], "device_name": "stm32l476rg" }, @@ -994,7 +1008,8 @@ "extra_labels": ["STM", "STM32F4", "STM32F407", "STM32F407VG"], "macros": ["LSI_VALUE=32000"], "inherits": ["Target"], - "device_has": ["ANALOGIN", "ANALOGOUT", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"], + "macros": ["TRANSACTION_QUEUE_SIZE_SPI=2"], + "device_has": ["ANALOGIN", "ANALOGOUT", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES"], "release_versions": ["2"], "device_name": "STM32F407VG" }, @@ -1004,7 +1019,8 @@ "default_toolchain": "ARM", "extra_labels": ["STM", "STM32F0", "STM32F051", "STM32F051R8"], "supported_toolchains": ["GCC_ARM"], - "device_has": ["ANALOGIN", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"], + "macros": ["TRANSACTION_QUEUE_SIZE_SPI=2"], + "device_has": ["ANALOGIN", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES"], "device_name": "STM32F051R8" }, "DISCO_F100RB": { @@ -1013,7 +1029,8 @@ "default_toolchain": "ARM", "extra_labels": ["STM", "STM32F1", "STM32F100RB"], "supported_toolchains": ["GCC_ARM"], - "device_has": ["ANALOGIN", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"], + "macros": ["TRANSACTION_QUEUE_SIZE_SPI=2"], + "device_has": ["ANALOGIN", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES"], "device_name": "STM32F100RB" }, "DISCO_F303VC": { @@ -1021,9 +1038,9 @@ "core": "Cortex-M4F", "default_toolchain": "ARM", "extra_labels": ["STM", "STM32F3", "STM32F303", "STM32F303VC"], - "macros": ["RTC_LSI=1"], + "macros": ["RTC_LSI=1", "TRANSACTION_QUEUE_SIZE_SPI=2"], "supported_toolchains": ["GCC_ARM"], - "device_has": ["ANALOGIN", "ANALOGOUT", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"], + "device_has": ["ANALOGIN", "ANALOGOUT", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES"], "device_name": "STM32F303VC" }, "DISCO_F334C8": { @@ -1031,10 +1048,10 @@ "core": "Cortex-M4F", "default_toolchain": "ARM", "extra_labels": ["STM", "STM32F3", "STM32F334C8"], - "macros": ["RTC_LSI=1"], + "macros": ["RTC_LSI=1", "TRANSACTION_QUEUE_SIZE_SPI=2"], "supported_toolchains": ["ARM", "uARM", "IAR", "GCC_ARM"], "detect_code": ["0810"], - "device_has": ["ANALOGIN", "ANALOGOUT", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"], + "device_has": ["ANALOGIN", "ANALOGOUT", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES"], "default_lib": "small", "release_versions": ["2"], "device_name": "STM32F334C8" @@ -1068,7 +1085,7 @@ "inherits": ["Target"], "macros": ["TRANSACTION_QUEUE_SIZE_SPI=2"], "detect_code": ["0788"], - "device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "ERROR_RED", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES", "TRNG"], + "device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "ERROR_RED", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES", "TRNG"], "release_versions": ["2", "5"], "device_name": "STM32F469NI" }, @@ -1091,7 +1108,8 @@ "default_toolchain": "ARM", "supported_form_factors": ["ARDUINO"], "detect_code": ["0815"], - "device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES", "TRNG"], + "macros": ["TRANSACTION_QUEUE_SIZE_SPI=2"], + "device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES", "TRNG"], "features": ["LWIP"], "release_versions": ["2", "5"], "device_name": "STM32F746NG" @@ -1103,7 +1121,8 @@ "supported_toolchains": ["ARM", "GCC_ARM", "IAR"], "default_toolchain": "ARM", "detect_code": ["0817"], - "device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"], + "macros": ["TRANSACTION_QUEUE_SIZE_SPI=2"], + "device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES"], "features": ["LWIP"], "release_versions": ["2"], "device_name": "STM32F769NI" @@ -1115,7 +1134,8 @@ "extra_labels": ["STM", "STM32L4", "STM32L476VG"], "supported_toolchains": ["ARM", "uARM", "IAR", "GCC_ARM"], "detect_code": ["0820"], - "device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES", "TRNG"], + "macros": ["TRANSACTION_QUEUE_SIZE_SPI=2"], + "device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES", "TRNG"], "release_versions": ["2", "5"], "device_name": "stm32l476vg" },