Skip to content

Fixed issue #11: SPI constructors and SS pin usage modified #15

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jun 9, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
177 changes: 115 additions & 62 deletions cores/arduino/stm32/spi_com.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,6 @@
* @{
*/

static PinName g_pin_mosi = NC;
static PinName g_pin_miso = NC;
static PinName g_pin_sclk = NC;
static PinName g_pin_ssel = NC;

/**
* @}
*/
Expand All @@ -106,6 +101,71 @@ static PinName g_pin_ssel = NC;
/** @addtogroup STM32F4xx_System_Private_Functions
* @{
*/
/**
* @brief return clock freq of an SPI instance
* @param spi_inst : SPI instance
* @retval clock freq of the instance else SystemCoreClock
*/
uint32_t spi_getClkFreqInst(SPI_TypeDef * spi_inst)
{
uint32_t spi_freq = SystemCoreClock;

#ifdef STM32F0xx
/* SPIx source CLK is PCKL1 */
spi_freq = HAL_RCC_GetPCLK1Freq();
#else
if(spi_inst != (SPI_TypeDef *)NC) {
/* Get source clock depending on SPI instance */
switch ((uint32_t)spi_inst) {
case (uint32_t)SPI1:
#if defined SPI4_BASE
case (uint32_t)SPI4:
#endif
#if defined SPI5_BASE
case (uint32_t)SPI5:
#endif
#if defined SPI6_BASE
case (uint32_t)SPI6:
#endif
/* SPI1, SPI4, SPI5 and SPI6. Source CLK is PCKL2 */
spi_freq = HAL_RCC_GetPCLK2Freq();
break;
case (uint32_t)SPI2:
#if defined SPI3_BASE
case (uint32_t)SPI3:
#endif
/* SPI_2 and SPI_3. Source CLK is PCKL1 */
spi_freq = HAL_RCC_GetPCLK1Freq();
break;
default:
printf("CLK: SPI instance not set");
break;
}
}
#endif
return spi_freq;
}

/**
* @brief return clock freq of an SPI instance
* @param obj : pointer to spi_t structure
* @retval clock freq of the instance else SystemCoreClock
*/
uint32_t spi_getClkFreq(spi_t *obj)
{
uint32_t spi_inst = NC;
uint32_t spi_freq = SystemCoreClock;

if(obj != NULL) {
spi_inst = pinmap_peripheral(obj->pin_sclk, PinMap_SPI_SCLK);

if(spi_inst != NC) {
spi_freq = spi_getClkFreqInst(spi_inst);
}
}
return spi_freq;
}

/**
* @brief SPI initialization function
* @param obj : pointer to spi_t structure
Expand All @@ -120,13 +180,21 @@ void spi_init(spi_t *obj, uint32_t speed, spi_mode_e mode, uint8_t msb)
return;

SPI_HandleTypeDef *handle = &(obj->handle);
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_TypeDef *port;
uint32_t spi_freq = 0;

// Determine the SPI to use
uint32_t spi_mosi = pinmap_peripheral(obj->pin_mosi, PinMap_SPI_MOSI);
uint32_t spi_miso = pinmap_peripheral(obj->pin_miso, PinMap_SPI_MISO);
uint32_t spi_sclk = pinmap_peripheral(obj->pin_sclk, PinMap_SPI_SCLK);
uint32_t spi_ssel = pinmap_peripheral(obj->pin_ssel, PinMap_SPI_SSEL);

/* Pins MOSI/MISO/SCLK must not be NC. ssel can be NC. */
if(spi_mosi == NC || spi_miso == NC || spi_sclk == NC) {
return;
}

uint32_t spi_data = pinmap_merge(spi_mosi, spi_miso);
uint32_t spi_cntl = pinmap_merge(spi_sclk, spi_ssel);

Expand All @@ -139,35 +207,32 @@ void spi_init(spi_t *obj, uint32_t speed, spi_mode_e mode, uint8_t msb)
}

// Configure the SPI pins
g_pin_mosi = obj->pin_mosi;
g_pin_miso = obj->pin_miso;
g_pin_sclk = obj->pin_sclk;
if (obj->pin_ssel != NC) {
g_pin_ssel = obj->pin_ssel;
handle->Init.NSS = SPI_NSS_HARD_OUTPUT;
} else {
g_pin_ssel = NC;
handle->Init.NSS = SPI_NSS_SOFT;
}

/* Fill default value */
handle->Instance = obj->spi;
handle->Init.Mode = SPI_MODE_MASTER;

if(speed >= SPI_SPEED_CLOCK_DIV2_MHZ) {
spi_freq = spi_getClkFreqInst(obj->spi);
if(speed >= (spi_freq/SPI_SPEED_CLOCK_DIV2_MHZ)) {
handle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
} else if(speed >= SPI_SPEED_CLOCK_DIV4_MHZ) {
} else if(speed >= (spi_freq/SPI_SPEED_CLOCK_DIV4_MHZ)) {
handle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
} else if (speed >= SPI_SPEED_CLOCK_DIV8_MHZ) {
} else if (speed >= (spi_freq/SPI_SPEED_CLOCK_DIV8_MHZ)) {
handle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8;
} else if (speed >= SPI_SPEED_CLOCK_DIV16_MHZ) {
} else if (speed >= (spi_freq/SPI_SPEED_CLOCK_DIV16_MHZ)) {
handle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;
} else if (speed >= SPI_SPEED_CLOCK_DIV32_MHZ) {
} else if (speed >= (spi_freq/SPI_SPEED_CLOCK_DIV32_MHZ)) {
handle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32;
} else if (speed >= SPI_SPEED_CLOCK_DIV64_MHZ) {
} else if (speed >= (spi_freq/SPI_SPEED_CLOCK_DIV64_MHZ)) {
handle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64;
} else if (speed >= SPI_SPEED_CLOCK_DIV128_MHZ) {
} else if (speed >= (spi_freq/SPI_SPEED_CLOCK_DIV128_MHZ)) {
handle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_128;
} else if (speed >= SPI_SPEED_CLOCK_DIV256_MHZ) {
} else if (speed >= (spi_freq/SPI_SPEED_CLOCK_DIV256_MHZ)) {
handle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256;
} else {
handle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;
Expand Down Expand Up @@ -199,96 +264,84 @@ void spi_init(spi_t *obj, uint32_t speed, spi_mode_e mode, uint8_t msb)

handle->Init.TIMode = SPI_TIMODE_DISABLED;

HAL_SPI_Init(handle);
}

/**
* @brief Initialize the SPI MSP.
* @param hspi: pointer to a SPI_HandleTypeDef structure that contains
* the configuration information for SPI module.
* @retval None
*/
void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi)
{
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_TypeDef *port;

if(g_pin_mosi != NC) {
port = set_GPIO_Port_Clock(STM_PORT(g_pin_mosi));
GPIO_InitStruct.Pin = STM_GPIO_PIN(g_pin_mosi);
GPIO_InitStruct.Mode = STM_PIN_MODE(pinmap_function(g_pin_mosi,PinMap_SPI_MOSI));
GPIO_InitStruct.Pull = STM_PIN_PUPD(pinmap_function(g_pin_mosi,PinMap_SPI_MOSI));
if(obj->pin_mosi != NC) {
port = set_GPIO_Port_Clock(STM_PORT(obj->pin_mosi));
GPIO_InitStruct.Pin = STM_GPIO_PIN(obj->pin_mosi);
GPIO_InitStruct.Mode = STM_PIN_MODE(pinmap_function(obj->pin_mosi,PinMap_SPI_MOSI));
GPIO_InitStruct.Pull = STM_PIN_PUPD(pinmap_function(obj->pin_mosi,PinMap_SPI_MOSI));
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = STM_PIN_AFNUM(pinmap_function(g_pin_mosi,PinMap_SPI_MOSI));
GPIO_InitStruct.Alternate = STM_PIN_AFNUM(pinmap_function(obj->pin_mosi,PinMap_SPI_MOSI));
HAL_GPIO_Init(port, &GPIO_InitStruct);
}

if(g_pin_miso != NC) {
port = set_GPIO_Port_Clock(STM_PORT(g_pin_miso));
GPIO_InitStruct.Pin = STM_GPIO_PIN(g_pin_miso);
GPIO_InitStruct.Mode = STM_PIN_MODE(pinmap_function(g_pin_miso,PinMap_SPI_MISO));
GPIO_InitStruct.Pull = STM_PIN_PUPD(pinmap_function(g_pin_miso,PinMap_SPI_MISO));
if(obj->pin_miso != NC) {
port = set_GPIO_Port_Clock(STM_PORT(obj->pin_miso));
GPIO_InitStruct.Pin = STM_GPIO_PIN(obj->pin_miso);
GPIO_InitStruct.Mode = STM_PIN_MODE(pinmap_function(obj->pin_miso,PinMap_SPI_MISO));
GPIO_InitStruct.Pull = STM_PIN_PUPD(pinmap_function(obj->pin_miso,PinMap_SPI_MISO));
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = STM_PIN_AFNUM(pinmap_function(g_pin_miso,PinMap_SPI_MISO));
GPIO_InitStruct.Alternate = STM_PIN_AFNUM(pinmap_function(obj->pin_miso,PinMap_SPI_MISO));
HAL_GPIO_Init(port, &GPIO_InitStruct);
}

if(g_pin_sclk != NC) {
port = set_GPIO_Port_Clock(STM_PORT(g_pin_sclk));
GPIO_InitStruct.Pin = STM_GPIO_PIN(g_pin_sclk);
GPIO_InitStruct.Mode = STM_PIN_MODE(pinmap_function(g_pin_sclk,PinMap_SPI_SCLK));
GPIO_InitStruct.Pull = STM_PIN_PUPD(pinmap_function(g_pin_sclk,PinMap_SPI_SCLK));
if(obj->pin_sclk != NC) {
port = set_GPIO_Port_Clock(STM_PORT(obj->pin_sclk));
GPIO_InitStruct.Pin = STM_GPIO_PIN(obj->pin_sclk);
GPIO_InitStruct.Mode = STM_PIN_MODE(pinmap_function(obj->pin_sclk,PinMap_SPI_SCLK));
GPIO_InitStruct.Pull = STM_PIN_PUPD(pinmap_function(obj->pin_sclk,PinMap_SPI_SCLK));
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = STM_PIN_AFNUM(pinmap_function(g_pin_sclk,PinMap_SPI_SCLK));
GPIO_InitStruct.Alternate = STM_PIN_AFNUM(pinmap_function(obj->pin_sclk,PinMap_SPI_SCLK));
HAL_GPIO_Init(port, &GPIO_InitStruct);
}

if(g_pin_ssel != NC) {
port = set_GPIO_Port_Clock(STM_PORT(g_pin_ssel));
GPIO_InitStruct.Pin = STM_GPIO_PIN(g_pin_ssel);
GPIO_InitStruct.Mode = STM_PIN_MODE(pinmap_function(g_pin_ssel,PinMap_SPI_SSEL));
GPIO_InitStruct.Pull = STM_PIN_PUPD(pinmap_function(g_pin_ssel,PinMap_SPI_SSEL));
if(obj->pin_ssel != NC) {
port = set_GPIO_Port_Clock(STM_PORT(obj->pin_ssel));
GPIO_InitStruct.Pin = STM_GPIO_PIN(obj->pin_ssel);
GPIO_InitStruct.Mode = STM_PIN_MODE(pinmap_function(obj->pin_ssel,PinMap_SPI_SSEL));
GPIO_InitStruct.Pull = STM_PIN_PUPD(pinmap_function(obj->pin_ssel,PinMap_SPI_SSEL));
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = STM_PIN_AFNUM(pinmap_function(g_pin_ssel,PinMap_SPI_SSEL));
GPIO_InitStruct.Alternate = STM_PIN_AFNUM(pinmap_function(obj->pin_ssel,PinMap_SPI_SSEL));
HAL_GPIO_Init(port, &GPIO_InitStruct);
}

#if defined SPI1_BASE
// Enable SPI clock
if (hspi->Instance == SPI1) {
if (handle->Instance == SPI1) {
__HAL_RCC_SPI1_CLK_ENABLE();
}
#endif

#if defined SPI2_BASE
if (hspi->Instance == SPI2) {
if (handle->Instance == SPI2) {
__HAL_RCC_SPI2_CLK_ENABLE();
}
#endif

#if defined SPI3_BASE
if (hspi->Instance == SPI3) {
if (handle->Instance == SPI3) {
__HAL_RCC_SPI3_CLK_ENABLE();
}
#endif

#if defined SPI4_BASE
if (hspi->Instance == SPI4) {
if (handle->Instance == SPI4) {
__HAL_RCC_SPI4_CLK_ENABLE();
}
#endif

#if defined SPI5_BASE
if (hspi->Instance == SPI5) {
if (handle->Instance == SPI5) {
__HAL_RCC_SPI5_CLK_ENABLE();
}
#endif

#if defined SPI6_BASE
if (hspi->Instance == SPI6) {
if (handle->Instance == SPI6) {
__HAL_RCC_SPI6_CLK_ENABLE();
}
#endif

HAL_SPI_Init(handle);
}

/**
Expand Down
19 changes: 11 additions & 8 deletions cores/arduino/stm32/spi_com.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,16 @@ typedef struct spi_s spi_t;


///@brief specifies the SPI speed bus in HZ.
#define SPI_SPEED_CLOCK_DIV2_MHZ ((uint32_t)(SystemCoreClock/2))
#define SPI_SPEED_CLOCK_DIV4_MHZ ((uint32_t)(SystemCoreClock/4))
#define SPI_SPEED_CLOCK_DIV8_MHZ ((uint32_t)(SystemCoreClock/8))
#define SPI_SPEED_CLOCK_DIV16_MHZ ((uint32_t)(SystemCoreClock/16))
#define SPI_SPEED_CLOCK_DIV32_MHZ ((uint32_t)(SystemCoreClock/32))
#define SPI_SPEED_CLOCK_DIV64_MHZ ((uint32_t)(SystemCoreClock/64))
#define SPI_SPEED_CLOCK_DIV128_MHZ ((uint32_t)(SystemCoreClock/128))
#define SPI_SPEED_CLOCK_DIV256_MHZ ((uint32_t)(SystemCoreClock/256))
#define SPI_SPEED_CLOCK_DEFAULT 4000000

#define SPI_SPEED_CLOCK_DIV2_MHZ ((uint32_t)2)
#define SPI_SPEED_CLOCK_DIV4_MHZ ((uint32_t)4)
#define SPI_SPEED_CLOCK_DIV8_MHZ ((uint32_t)8)
#define SPI_SPEED_CLOCK_DIV16_MHZ ((uint32_t)16)
#define SPI_SPEED_CLOCK_DIV32_MHZ ((uint32_t)32)
#define SPI_SPEED_CLOCK_DIV64_MHZ ((uint32_t)64)
#define SPI_SPEED_CLOCK_DIV128_MHZ ((uint32_t)128)
#define SPI_SPEED_CLOCK_DIV256_MHZ ((uint32_t)256)

///@brief speficies the SPI mode to use
//Mode Clock Polarity (CPOL) Clock Phase (CPHA)
Expand Down Expand Up @@ -101,6 +103,7 @@ void spi_deinit(spi_t *obj);
spi_status_e spi_send(spi_t *obj, uint8_t *Data, uint16_t len, uint32_t Timeout);
spi_status_e spi_transfer(spi_t *obj, uint8_t * tx_buffer,
uint8_t * rx_buffer, uint16_t len, uint32_t Timeout);
uint32_t spi_getClkFreq(spi_t *obj);

#ifdef __cplusplus
}
Expand Down
Loading