diff --git a/cores/arduino/SPI.cpp b/cores/arduino/SPI.cpp index d63d246..9b7b996 100755 --- a/cores/arduino/SPI.cpp +++ b/cores/arduino/SPI.cpp @@ -11,33 +11,68 @@ * published by the Free Software Foundation. */ - /* - * Arduino srl - www.arduino.org - * 2016 Jun 9: Edited Francesco Alessi (alfran) - francesco@arduino.org - */ - extern "C" { #include #include #include - #include "stm32f4xx_hal.h" + #include "stm32f4xx_hal.h" } #include "SPI.h" -SPIClass SPI; -SPI_HandleTypeDef hSPIx; +SPIClass::SPIClass(SPI_TypeDef *spiInstance) +{ + hSPIx.Instance = spiInstance; +} /** * @brief Configure SPI, configure relatives IOs and enable SPIx * @param None * @retval None */ -void SPIClass::begin() { +void SPIClass::begin() +{ + if(hSPIx.Instance == SPIx) + { + GPIO_InitTypeDef GPIO_InitStruct; + + /* Enable GPIO clock */ + SPIx_SCK_CLK_ENABLE(); + SPIx_MISO_CLK_ENABLE(); + SPIx_MOSI_CLK_ENABLE(); + + /* Enable SPI clock */ + SPIx_CLK_ENABLE(); + + /* Configure SPI SCK pin(PB10) as alternate function */ + GPIO_InitStruct.Pin = SPIx_SCK_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_PULLDOWN; + GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; + GPIO_InitStruct.Alternate = SPIx_SCK_AF; + HAL_GPIO_Init(SPIx_SCK_GPIO_PORT, &GPIO_InitStruct); + + /* Configure SPI MISO pin(PB14) as alternate function */ + GPIO_InitStruct.Pin = SPIx_MISO_PIN; + GPIO_InitStruct.Alternate = SPIx_MISO_AF; + HAL_GPIO_Init(SPIx_MISO_GPIO_PORT, &GPIO_InitStruct); + + /* Configure SPI MOSI pin(PB15) as alternate function */ + GPIO_InitStruct.Pin = SPIx_MOSI_PIN; + GPIO_InitStruct.Alternate = SPIx_MOSI_AF; + HAL_GPIO_Init(SPIx_MOSI_GPIO_PORT, &GPIO_InitStruct); + + /* Put NSS pin as Output pin in order to be used as normal GPIO in Master mode */ + GPIO_InitStruct.Pin = SPIx_NSS_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + HAL_GPIO_Init(SPIx_NSS_GPIO_PORT, &GPIO_InitStruct); + } + /* SPIx configuration ----------------------------------------------------*/ hSPIx.Instance = SPIx; - hSPIx.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256; + hSPIx.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8; hSPIx.Init.Direction = SPI_DIRECTION_2LINES; hSPIx.Init.CLKPhase = SPI_PHASE_1EDGE; hSPIx.Init.CLKPolarity = SPI_POLARITY_LOW; @@ -57,19 +92,32 @@ void SPIClass::begin() { * @param slaveSelectPin: IO to configure * @retval None */ -void SPIClass::begin(uint8_t slaveSelectPin) { - GPIO_InitTypeDef GPIO_InitStruct; +void SPIClass::begin(uint8_t slaveSelectPin) +{ /* SPIx configuration */ - SPI.begin(); + begin(); + + /* TOBEFIXED: The correct way to proceed here it is to map the Arduino slaveSelectPin provided as parameter */ + /* with the Cube GPIO port and pin number and then call the HAL_GPIO_Init with the correct values */ + /* At the moment only NSS pin is supported */ + switch(slaveSelectPin) + { + case 10: + default: + { + GPIO_InitTypeDef GPIO_InitStruct; - /* NSS pin PB3 configuration */ - SPIx_NSS_CLK_ENABLE(); - GPIO_InitStruct.Pin = slaveSelectPin; - GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; - GPIO_InitStruct.Pull = GPIO_PULLDOWN; - GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; + SPIx_NSS_CLK_ENABLE(); + GPIO_InitStruct.Pin = SPIx_NSS_PIN; + GPIO_InitStruct.Alternate = SPIx_NSS_AF; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_PULLDOWN; + GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; - HAL_GPIO_Init(SPIx_NSS_GPIO_PORT, &GPIO_InitStruct); + HAL_GPIO_Init(SPIx_NSS_GPIO_PORT, &GPIO_InitStruct); + break; + } + } } /** @@ -78,8 +126,14 @@ void SPIClass::begin(uint8_t slaveSelectPin) { * @param settings: object containing parameters clock, bitOrder and dataMode * @retval None */ -void SPIClass::beginTransaction(SPISettings settings) { - // do nothing +void SPIClass::beginTransaction(SPISettings settings) +{ + hSPIx.Init.FirstBit = settings.FirstBit; + hSPIx.Init.CLKPhase = settings.CLKPhase; + hSPIx.Init.CLKPolarity = settings.CLKPolarity; + hSPIx.Init.BaudRatePrescaler = settings.BaudRatePrescaler; + + HAL_SPI_Init(&hSPIx); } /** @@ -87,8 +141,15 @@ void SPIClass::beginTransaction(SPISettings settings) { * @param None * @retval None */ -void SPIClass::endTransaction() { - HAL_SPI_DeInit(&hSPIx); +void SPIClass::endTransaction() +{ + /* Go back to default settings */ + hSPIx.Init.FirstBit = SPI_FIRSTBIT_MSB; + hSPIx.Init.CLKPhase = SPI_PHASE_1EDGE; + hSPIx.Init.CLKPolarity = SPI_POLARITY_LOW; + hSPIx.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4; + + HAL_SPI_Init(&hSPIx); } /** @@ -96,10 +157,11 @@ void SPIClass::endTransaction() { * @param data: data to be transmitted * @retval Byte received */ -uint8_t SPIClass::transfer(uint8_t data) { - uint8_t rxdata; - HAL_SPI_TransmitReceive(&hSPIx, (uint8_t*)&data, (uint8_t*)&rxdata, 1,5000); - return rxdata; +uint8_t SPIClass::transfer(uint8_t data) +{ + uint8_t rxdata; + HAL_SPI_TransmitReceive(&hSPIx, (uint8_t*)&data, (uint8_t*)&rxdata, 1,5000); + return rxdata; } /** @@ -107,10 +169,11 @@ uint8_t SPIClass::transfer(uint8_t data) { * @param data: data to be transmitted * @retval Bytes received */ -uint16_t SPIClass::transfer16(uint16_t data) { - uint16_t rxdata; - HAL_SPI_TransmitReceive(&hSPIx, (uint8_t*)&data, (uint8_t*)&rxdata, 2,5000); - return rxdata; +uint16_t SPIClass::transfer16(uint16_t data) +{ + uint16_t rxdata; + HAL_SPI_TransmitReceive(&hSPIx, (uint8_t*)&data, (uint8_t*)&rxdata, 2,5000); + return rxdata; } /** @@ -119,9 +182,10 @@ uint16_t SPIClass::transfer16(uint16_t data) { * @param count: number of data in byte to be transmitted * @retval None */ -void SPIClass::transfer(void *buf, size_t count) { - uint8_t rxdata; - HAL_SPI_TransmitReceive(&hSPIx, (uint8_t*)buf, (uint8_t*)&rxdata, count,5000); +void SPIClass::transfer(void *buf, size_t count) +{ + uint8_t rxdata; + HAL_SPI_TransmitReceive(&hSPIx, (uint8_t*)buf, (uint8_t*)&rxdata, count,5000); } /** @@ -129,14 +193,40 @@ void SPIClass::transfer(void *buf, size_t count) { * @param data: data to be transmitted * @retval Byte received */ -void SPIClass::transfer(uint8_t slaveSelectPin, uint8_t val, uint8_t transferMode) { - HAL_SPI_Transmit(&hSPIx, (uint8_t *)&val, 1,5000); - - if(transferMode == SPI_LAST) { - HAL_GPIO_WritePin(SPIx_NSS_GPIO_PORT, SPIx_NSS_PIN, GPIO_PIN_SET); - } else { - HAL_GPIO_WritePin(SPIx_NSS_GPIO_PORT, SPIx_NSS_PIN, GPIO_PIN_RESET); - } +uint8_t SPIClass::transfer(uint8_t slaveSelectPin, uint8_t val, SPITransferMode transferMode) +{ + uint8_t rxdata; + + /* TOBEFIXED: The correct way to proceed here it is to map the Arduino pin provided as parameter */ + /* with the Cube GPIO port and pin number and then call the HAL_GPIO_WritePin */ + switch(slaveSelectPin) + { + case 10: + default: + { + HAL_GPIO_WritePin(SPIx_NSS_GPIO_PORT, SPIx_NSS_PIN, GPIO_PIN_RESET); + break; + } + } + + HAL_SPI_TransmitReceive(&hSPIx, (uint8_t *)&val, (uint8_t*)&rxdata, 1,5000); + + /* If transferMode is SPI_CONTINUE we need to hold CS GPIO pin low */ + /* If transferMode is SPI_LAST we need to put CS GPIO pin high */ + if(transferMode == SPI_LAST) + { + switch(slaveSelectPin) + { + case 10: + default: + { + HAL_GPIO_WritePin(SPIx_NSS_GPIO_PORT, SPIx_NSS_PIN, GPIO_PIN_SET); + break; + } + } + } + + return rxdata; } /** @@ -144,16 +234,19 @@ void SPIClass::transfer(uint8_t slaveSelectPin, uint8_t val, uint8_t transferMo * @param bitOrder: LSBFIRST or MSBFIRST * @retval None */ -void SPIClass::setBitOrder(uint8_t bitOrder) { - if(bitOrder == LSBFIRST) { - bitOrder = SPI_FIRSTBIT_LSB; - } - else { - bitOrder = SPI_FIRSTBIT_MSB; - } - hSPIx.Init.FirstBit = bitOrder; - HAL_SPI_Init(&hSPIx); +void SPIClass::setBitOrder(uint8_t bitOrder) +{ + if(bitOrder == LSBFIRST) + { + bitOrder = SPI_FIRSTBIT_LSB; } + else + { + bitOrder = SPI_FIRSTBIT_MSB; + } + hSPIx.Init.FirstBit = bitOrder; + HAL_SPI_Init(&hSPIx); +} /** * @brief Set mode to control clock polarity and phase @@ -164,108 +257,53 @@ void SPIClass::setBitOrder(uint8_t bitOrder) { * SPI_MODE3 * @retval None */ -void SPIClass::setDataMode(uint8_t dataMode) { - if(dataMode == SPI_MODE0) { - hSPIx.Init.CLKPhase = SPI_PHASE_1EDGE; - hSPIx.Init.CLKPolarity = SPI_POLARITY_LOW; - } - else if(dataMode == SPI_MODE1) { - hSPIx.Init.CLKPhase = SPI_PHASE_2EDGE; - hSPIx.Init.CLKPolarity = SPI_POLARITY_LOW; - } - else if(dataMode == SPI_MODE2) { - hSPIx.Init.CLKPhase = SPI_PHASE_1EDGE; - hSPIx.Init.CLKPolarity = SPI_POLARITY_HIGH; - } - else { - hSPIx.Init.CLKPhase = SPI_PHASE_2EDGE; - hSPIx.Init.CLKPolarity = SPI_POLARITY_HIGH; - } - - /* Change CPOL and CPHASE */ - HAL_SPI_Init(&hSPIx); +void SPIClass::setDataMode(uint8_t dataMode) +{ + if(dataMode == SPI_MODE0) + { + hSPIx.Init.CLKPhase = SPI_PHASE_1EDGE; + hSPIx.Init.CLKPolarity = SPI_POLARITY_LOW; + } + else if(dataMode == SPI_MODE1) + { + hSPIx.Init.CLKPhase = SPI_PHASE_2EDGE; + hSPIx.Init.CLKPolarity = SPI_POLARITY_LOW; + } + else if(dataMode == SPI_MODE2) + { + hSPIx.Init.CLKPhase = SPI_PHASE_1EDGE; + hSPIx.Init.CLKPolarity = SPI_POLARITY_HIGH; } + else + { + hSPIx.Init.CLKPhase = SPI_PHASE_2EDGE; + hSPIx.Init.CLKPolarity = SPI_POLARITY_HIGH; + } + + /* Change CPOL and CPHASE */ + HAL_SPI_Init(&hSPIx); +} /** * @brief Set clock divider * @param clockDiv: clock divider * @retval None */ -void SPIClass::setClockDivider(uint8_t clockDiv) { - hSPIx.Init.BaudRatePrescaler = clockDiv; - HAL_SPI_Init(&hSPIx); - } - -/** - * @brief Disable SPIx peripheral. - * @param None - * @retval None - */ -void SPIClass::end() { - HAL_SPI_DeInit(&hSPIx); +void SPIClass::setClockDivider(uint8_t clockDiv) +{ + hSPIx.Init.BaudRatePrescaler = clockDiv; + HAL_SPI_Init(&hSPIx); } /** - * @brief Disable SPIx peripheral and SS pin. + * @brief Disable SPIx peripheral. * @param None * @retval None */ -void SPIClass::end(uint8_t slaveSelectPin) { - HAL_SPI_DeInit(&hSPIx); - SPIx_NSS_CLK_DISABLE(); -} - -/** - * @brief SPI MSP Initialization - * This function configures the hardware resources used in this example: - * - Peripheral's clock enable - * - Peripheral's GPIO Configuration - * @param hspi: SPI handle pointer - * @retval None - */ -void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi) { - GPIO_InitTypeDef GPIO_InitStruct; - if(hspi->Instance == SPIx) { - /* Enable GPIO clock */ - SPIx_SCK_CLK_ENABLE(); - SPIx_MISO_CLK_ENABLE(); - SPIx_MOSI_CLK_ENABLE(); - SPIx_NSS_CLK_ENABLE(); - - /* Enable SPI clock */ - SPIx_CLK_ENABLE(); - - /* Configure SPI SCK pin(PB10) as alternate function */ - GPIO_InitStruct.Pin = SPIx_SCK_PIN; - GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; - GPIO_InitStruct.Pull = GPIO_PULLDOWN; - GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; - GPIO_InitStruct.Alternate = SPIx_SCK_AF; - HAL_GPIO_Init(SPIx_SCK_GPIO_PORT, &GPIO_InitStruct); - - /* Configure SPI MISO pin(PB14) as alternate function */ - GPIO_InitStruct.Pin = SPIx_MISO_PIN; - GPIO_InitStruct.Alternate = SPIx_MISO_AF; - HAL_GPIO_Init(SPIx_MISO_GPIO_PORT, &GPIO_InitStruct); - - /* Configure SPI MOSI pin(PB15) as alternate function */ - GPIO_InitStruct.Pin = SPIx_MOSI_PIN; - GPIO_InitStruct.Alternate = SPIx_MOSI_AF; - HAL_GPIO_Init(SPIx_MOSI_GPIO_PORT, &GPIO_InitStruct); - - GPIO_InitStruct.Pin = SPIx_NSS_PIN; - GPIO_InitStruct.Alternate = SPIx_NSS_AF; - HAL_GPIO_Init(SPIx_NSS_GPIO_PORT, &GPIO_InitStruct); - } -} - -/** -* @brief SPI BSP Deinit -* @param hspi : SPI handle -* @retval None -*/ -void HAL_SPI_MspDeInit(SPI_HandleTypeDef *hspi) +void SPIClass::end() { + if(hSPIx.Instance == SPIx) + { /*##-1- Reset peripherals ##################################################*/ SPIx_FORCE_RESET(); SPIx_RELEASE_RESET(); @@ -277,4 +315,31 @@ void HAL_SPI_MspDeInit(SPI_HandleTypeDef *hspi) HAL_GPIO_DeInit(SPIx_MISO_GPIO_PORT, SPIx_MISO_PIN); /* Configure SPI MOSI as alternate function */ HAL_GPIO_DeInit(SPIx_MOSI_GPIO_PORT, SPIx_MOSI_PIN); + } + + HAL_SPI_DeInit(&hSPIx); } + +/** + * @brief Disable SPIx peripheral and SS pin. + * @param None + * @retval None + */ +void SPIClass::end(uint8_t slaveSelectPin) +{ + /* TOBEFIXED: The correct way to proceed here it is to map the Arduino slaveSelectPin provided as parameter */ + /* with the Cube GPIO port and pin number and then call the HAL_GPIO_DeInit with the correct values */ + switch(slaveSelectPin) + { + case 10: + default: + { + HAL_GPIO_DeInit(SPIx_NSS_GPIO_PORT, SPIx_NSS_PIN); + break; + } + } + + HAL_SPI_DeInit(&hSPIx); +} + +SPIClass SPI = SPIClass(HAL_SPI2); diff --git a/cores/arduino/spi.h b/cores/arduino/SPI.h similarity index 61% rename from cores/arduino/spi.h rename to cores/arduino/SPI.h index d4f590e..ecd9986 100755 --- a/cores/arduino/spi.h +++ b/cores/arduino/SPI.h @@ -15,7 +15,6 @@ #define _SPI_H_INCLUDED #include -extern SPI_HandleTypeDef hSPIx; #define SPIx HAL_SPI2 #define SPIx_CLK_ENABLE() __HAL_RCC_SPI2_CLK_ENABLE() @@ -68,93 +67,117 @@ extern SPI_HandleTypeDef hSPIx; #define SPI_MODE2 0x08 #define SPI_MODE3 0x0C -#define SPI_LAST 0 -#define SPI_CONTINUE 1 +enum SPITransferMode { + SPI_CONTINUE, + SPI_LAST +}; class SPISettings { public: - SPISettings(uint32_t clock, uint8_t bitOrder, uint8_t dataMode) { - init_AlwaysInline(clock, bitOrder, dataMode); + SPISettings(uint32_t clock, uint8_t bitOrder, uint8_t dataMode) + { + init_AlwaysInline(clock, bitOrder, dataMode); } - SPISettings() { - init_AlwaysInline(SPI_CLOCK_DIV4, MSBFIRST, SPI_MODE0); + SPISettings() + { + init_AlwaysInline(4000000, MSBFIRST, SPI_MODE0); } private: void init_AlwaysInline(uint32_t clock, uint8_t bitOrder, uint8_t dataMode) __attribute__((__always_inline__)) { /* Select the Bit Order */ - if(bitOrder == LSBFIRST) { - bitOrder = SPI_FIRSTBIT_LSB; + if(bitOrder == LSBFIRST) + { + FirstBit = SPI_FIRSTBIT_LSB; } - else { - bitOrder = SPI_FIRSTBIT_MSB; + else + { + FirstBit = SPI_FIRSTBIT_MSB; } - hSPIx.Init.FirstBit = bitOrder; /* Select the SPI Communication Mode */ - if(dataMode == SPI_MODE0) { - hSPIx.Init.CLKPhase = SPI_PHASE_1EDGE; - hSPIx.Init.CLKPolarity = SPI_POLARITY_LOW; + if(dataMode == SPI_MODE0) + { + CLKPhase = SPI_PHASE_1EDGE; + CLKPolarity = SPI_POLARITY_LOW; } - else if(dataMode == SPI_MODE1) { - hSPIx.Init.CLKPhase = SPI_PHASE_2EDGE; - hSPIx.Init.CLKPolarity = SPI_POLARITY_LOW; + else if(dataMode == SPI_MODE1) + { + CLKPhase = SPI_PHASE_2EDGE; + CLKPolarity = SPI_POLARITY_LOW; } - else if(dataMode == SPI_MODE2) { - hSPIx.Init.CLKPhase = SPI_PHASE_1EDGE; - hSPIx.Init.CLKPolarity = SPI_POLARITY_HIGH; + else if(dataMode == SPI_MODE2) + { + CLKPhase = SPI_PHASE_1EDGE; + CLKPolarity = SPI_POLARITY_HIGH; } - else { - hSPIx.Init.CLKPhase = SPI_PHASE_2EDGE; - hSPIx.Init.CLKPolarity = SPI_POLARITY_HIGH; + else + { + CLKPhase = SPI_PHASE_2EDGE; + CLKPolarity = SPI_POLARITY_HIGH; } /* Select the Clock Divider */ - hSPIx.Init.BaudRatePrescaler = clock; - - /* Initialize the SPIx */ - HAL_SPI_Init(&hSPIx); + BaudRatePrescaler = (((HAL_RCC_GetPCLK1Freq()) / 2 ) < clock) ? SPI_CLOCK_DIV2 + : (((HAL_RCC_GetPCLK1Freq()) / 4 ) < clock) ? SPI_CLOCK_DIV4 + : (((HAL_RCC_GetPCLK1Freq()) / 8 ) < clock) ? SPI_CLOCK_DIV8 + : (((HAL_RCC_GetPCLK1Freq()) / 16 ) < clock) ? SPI_CLOCK_DIV16 + : (((HAL_RCC_GetPCLK1Freq()) / 32 ) < clock) ? SPI_CLOCK_DIV32 + : (((HAL_RCC_GetPCLK1Freq()) / 64 ) < clock) ? SPI_CLOCK_DIV64 + : (((HAL_RCC_GetPCLK1Freq()) / 128) < clock) ? SPI_CLOCK_DIV128 + : SPI_CLOCK_DIV256; } + uint32_t FirstBit; + uint32_t CLKPhase; + uint32_t CLKPolarity; + uint32_t BaudRatePrescaler; + friend class SPIClass; }; class SPIClass { public: + /* Constructor */ + SPIClass(SPI_TypeDef *spiInstance); /* Initialize the SPI peripheral */ - static void begin(); + void begin(); /* Initialize the SPI peripheral and SS pin */ - static void begin(uint8_t slaveSelectPin); + void begin(uint8_t slaveSelectPin); /* Initialize the SPI peripheral with settings */ - static void beginTransaction(SPISettings settings); + void beginTransaction(SPISettings settings); /* Initialize the SPI peripheral */ - static void endTransaction(); + void endTransaction(); /* Begin the transfer */ - static uint8_t transfer(uint8_t data); - static uint16_t transfer16(uint16_t data); - static void transfer(void *buf, size_t count); - static void transfer(uint8_t slaveSelectPin, uint8_t val, uint8_t transferMode); + uint8_t transfer(uint8_t data); + uint16_t transfer16(uint16_t data); + void transfer(void *buf, size_t count); + uint8_t transfer(uint8_t slaveSelectPin, uint8_t val, SPITransferMode transferMode); /* End the transfer */ - static void end(); + void end(); - static void end(uint8_t slaveSelectPin); + void end(uint8_t slaveSelectPin); /* Set Bit Order */ - static void setBitOrder(uint8_t bitOrder); + void setBitOrder(uint8_t bitOrder); /* Set Clock Divider */ - static void setClockDivider(uint8_t clockDiv); + void setClockDivider(uint8_t clockDiv); /* Set Communication Mode */ - static void setDataMode(uint8_t dataMode); + void setDataMode(uint8_t dataMode); + +private: + + SPI_HandleTypeDef hSPIx; };