2015-10-13 03:53 PM
I have been working on setting up and trying to test the SPI output from the Nucleo-F401RE. I am currently using a logic analyzer to view the data and clock lines, though I have not yet been able to see any change on either line...
Here is what I have so far (I am very new to STM and the HAL libraries...):
#include ''stm32f4xx.h''
#include ''NONPRECISIONDELAY.h''
int main(void)
{
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN;
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN;
RCC->APB1ENR |= RCC_APB1ENR_SPI2EN;
// HAL GPIO - Onboard LED init
GPIO_InitTypeDef ledInit;
ledInit.Pin = GPIO_PIN_5;
ledInit.Mode = GPIO_MODE_OUTPUT_PP;
ledInit.Pull = GPIO_NOPULL;
ledInit.Speed = GPIO_SPEED_HIGH;
HAL_GPIO_Init(GPIOA, &ledInit);
/* END GPIO INIT */
// CS
GPIO_InitTypeDef spiOneGpioInit_t;
spiOneGpioInit_t.Pin = GPIO_PIN_12;
spiOneGpioInit_t.Mode = GPIO_MODE_AF_PP;
spiOneGpioInit_t.Pull = GPIO_PULLUP;
spiOneGpioInit_t.Speed = GPIO_SPEED_LOW;
spiOneGpioInit_t.Alternate = GPIO_AF5_SPI2;
HAL_GPIO_Init(GPIOB, &spiOneGpioInit_t);
// SPI 2
spiOneGpioInit_t.Pin = GPIO_PIN_15 | GPIO_PIN_14 | GPIO_PIN_13;
spiOneGpioInit_t.Mode = GPIO_MODE_AF_PP;
spiOneGpioInit_t.Pull = GPIO_PULLDOWN;
spiOneGpioInit_t.Speed = GPIO_SPEED_LOW;
spiOneGpioInit_t.Alternate = GPIO_AF5_SPI2;
HAL_GPIO_Init(GPIOB, &spiOneGpioInit_t);
// SPI Handler
SPI_HandleTypeDef hspi;
hspi.Instance = SPI2;
hspi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32;
hspi.Init.Direction = SPI_DIRECTION_2LINES;
hspi.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi.Init.DataSize = SPI_DATASIZE_8BIT;
hspi.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi.Init.TIMode = SPI_TIMODE_DISABLED;
hspi.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED;
hspi.Init.NSS = SPI_NSS_HARD_OUTPUT;
if (HAL_SPI_Init(&hspi) != HAL_OK)
{
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5); // On board LED for indication
return 1;
}
uint8_t data[] = {0xff};
while(1)
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET); // On board LED for indication
delayMs(500);
HAL_SPI_Transmit(&hspi, data, 1, 10);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET); // On board LED for indication
delayMs(500);
}
}
2015-10-14 11:52 AM
So I ended up doing away with the HAL libraries, as they were just further confusing things... The SPI2 port works perfectly using the following test:
(Which just counts through 0 - 255 sending each after a period of delay, to see on a logic analyzer)
#include ''stm32f4xx.h''
#include ''NONPRECISIONDELAY.h''
#define GPIO_AFRH_AF5_15 ((uint32_t)0x50000000)
#define GPIO_AFRH_AF5_14 ((uint32_t)0x05000000)
#define GPIO_AFRH_AF5_13 ((uint32_t)0x00500000)
#define GPIO_AFRH_AF5_12 ((uint32_t)0x00050000)
int main(void)
{
// Turn on GPIOB and SPI2 Clocks
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN;
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN;
RCC->APB1ENR |= RCC_APB1ENR_SPI2EN;
// MOSI - PB15
GPIOB->MODER |= GPIO_MODER_MODER15_1;
GPIOB->OTYPER &= ~(GPIO_OTYPER_OT_15);
GPIOB->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR15;
GPIOB->PUPDR |= GPIO_PUPDR_PUPDR15_1;
GPIOB->AFR[1] |= GPIO_AFRH_AF5_15;
// MISO - PB14
GPIOB->MODER |= GPIO_MODER_MODER14_1;
GPIOB->OTYPER &= ~(GPIO_OTYPER_OT_14);
GPIOB->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR14;
GPIOB->PUPDR |= GPIO_PUPDR_PUPDR14_1;
GPIOB->AFR[1] |= GPIO_AFRH_AF5_14;
// SCLK - PB13
GPIOB->MODER |= GPIO_MODER_MODER13_1;
GPIOB->OTYPER &= ~(GPIO_OTYPER_OT_13);
GPIOB->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR13;
GPIOB->PUPDR |= GPIO_PUPDR_PUPDR13_1;
GPIOB->AFR[1] |= GPIO_AFRH_AF5_13;
// CS - PB12
GPIOB->MODER |= GPIO_MODER_MODER12_0;
GPIOB->OTYPER &= ~(GPIO_OTYPER_OT_12);
GPIOB->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR12;
GPIOB->PUPDR |= GPIO_PUPDR_PUPDR14_0;
GPIOB->ODR |= GPIO_ODR_ODR_12;
SPI2->CR1 |= SPI_CR1_BR_0 | SPI_CR1_BR_1;
SPI2->CR2 |= SPI_CR2_SSOE;
SPI2->CR1 |= SPI_CR1_MSTR;
SPI2->CR1 |= SPI_CR1_SPE;
volatile uint8_t data = 0x01;
uint8_t input;
while(1)
{
if (SPI2->SR & SPI_SR_TXE)
{
GPIOB->ODR &= ~(GPIO_ODR_ODR_12); // CS goes LOW
SPI2->DR = data++; // Send byte and increment
while ((SPI2->SR & SPI_SR_RXNE) == 0); // Wait for frame end RXNE = 1
input = SPI2->DR; // Read to clear RXNE for next time through
GPIOB->ODR |= GPIO_ODR_ODR_12; // CS goes HIGH - could swap with read
}
delayMs(500); //
}
}
2015-10-14 12:23 PM
> GPIOB->ODR &= ~(GPIO_ODR_ODR_12)
I recommend using the GPIOx_BSRR register instead of performing RMW operations on the GPIOx_ODR register. Check in stm32f4xx.h to for the GPIOx_BSRR register's name(s) there.
JW