void task1_handler(void *arg) { int rc; /* Set the led pin for the E407 devboard */ g_led_pin = LED_BLINK_PIN; hal_gpio_init_out(g_led_pin, 1); spi_cb_arg = &spi_cb_obj; sblinky_spi_cfg(SPI_SLAVE_ID); hal_spi_enable(SPI_SLAVE_ID); /* Make the default character 0x77 */ hal_spi_slave_set_def_tx_val(SPI_SLAVE_ID, 0x77); /* * Fill buffer with 0x77 for first transfer. This should be a 0xdeadbeef * transfer from master to start things off */ memset(g_spi_tx_buf, 0x77, 32); rc = hal_spi_txrx_noblock(SPI_SLAVE_ID, g_spi_tx_buf, g_spi_rx_buf, 32); while (1) { /* Wait for semaphore from ISR */ os_sem_pend(&g_test_sem, OS_TIMEOUT_NEVER); if (g_spi_xfr_num == 0) { /* Since we dont know what master will send, we fill 0x88 */ memset(g_spi_tx_buf, 0x88, 32); rc = hal_spi_txrx_noblock(SPI_SLAVE_ID, g_spi_tx_buf, g_spi_rx_buf, 32); assert(rc == 0); } else { /* transmit back what we just received */ memcpy(prev_buf, g_spi_tx_buf, 32); memset(g_spi_tx_buf, 0xaa, 32); memcpy(g_spi_tx_buf, g_spi_rx_buf, spi_cb_obj.txlen); rc = hal_spi_txrx_noblock(SPI_SLAVE_ID, g_spi_tx_buf, g_spi_rx_buf, 32); assert(rc == 0); } ++g_spi_xfr_num; /* Toggle the LED */ hal_gpio_toggle(g_led_pin); } }
int hal_spi_config(int spi_num, struct hal_spi_settings *settings) { struct stm32_hal_spi *spi; struct stm32_hal_spi_cfg *cfg; SPI_InitTypeDef *init; GPIO_InitTypeDef gpio; uint32_t gpio_speed; IRQn_Type irq; uint32_t prescaler; int rc; int sr; __HAL_DISABLE_INTERRUPTS(sr); STM32_HAL_SPI_RESOLVE(spi_num, spi); init = &spi->handle.Init; cfg = spi->cfg; if (!spi->slave) { spi->handle.Init.NSS = SPI_NSS_HARD_OUTPUT; spi->handle.Init.Mode = SPI_MODE_MASTER; } else { spi->handle.Init.NSS = SPI_NSS_SOFT; spi->handle.Init.Mode = SPI_MODE_SLAVE; } gpio.Mode = GPIO_MODE_AF_PP; gpio.Pull = GPIO_NOPULL; /* TODO: also VERY_HIGH for STM32L1x */ if (settings->baudrate <= 2000) { gpio_speed = GPIO_SPEED_FREQ_LOW; } else if (settings->baudrate <= 12500) { gpio_speed = GPIO_SPEED_FREQ_MEDIUM; } else { gpio_speed = GPIO_SPEED_FREQ_HIGH; } /* Enable the clocks for this SPI */ switch (spi_num) { #if SPI_0_ENABLED case 0: __HAL_RCC_SPI1_CLK_ENABLE(); #if !defined(STM32F1) gpio.Alternate = GPIO_AF5_SPI1; #endif spi->handle.Instance = SPI1; break; #endif #if SPI_1_ENABLED case 1: __HAL_RCC_SPI2_CLK_ENABLE(); #if !defined(STM32F1) gpio.Alternate = GPIO_AF5_SPI2; #endif spi->handle.Instance = SPI2; break; #endif #if SPI_2_ENABLED case 2: __HAL_RCC_SPI3_CLK_ENABLE(); #if !defined(STM32F1) gpio.Alternate = GPIO_AF6_SPI3; #endif spi->handle.Instance = SPI3; break; #endif #if SPI_3_ENABLED case 3: __HAL_RCC_SPI4_CLK_ENABLE(); #if !defined(STM32F1) gpio.Alternate = GPIO_AF5_SPI4; #endif spi->handle.Instance = SPI4; break; #endif #if SPI_4_ENABLED case 4: __HAL_RCC_SPI5_CLK_ENABLE(); #if !defined(STM32F1) gpio.Alternate = GPIO_AF5_SPI5; #endif spi->handle.Instance = SPI5; break; #endif #if SPI_5_ENABLED case 5: __HAL_RCC_SPI6_CLK_ENABLE(); #if !defined(STM32F1) gpio.Alternate = GPIO_AF5_SPI6; #endif spi->handle.Instance = SPI6; break; #endif default: assert(0); rc = -1; goto err; } if (!spi->slave) { if (settings->data_mode == HAL_SPI_MODE2 || settings->data_mode == HAL_SPI_MODE3) { gpio.Pull = GPIO_PULLUP; } else { gpio.Pull = GPIO_PULLDOWN; } } /* NOTE: Errata ES0125: STM32L100x6/8/B, STM32L151x6/8/B and * STM32L152x6/8/B ultra-low-power device limitations. * * 2.6.6 - Corrupted last bit of data and or CRC, received in Master * mode with delayed SCK feedback * * This driver is always using very high speed for SCK on STM32L1x */ #if defined(STM32L152xC) if (!spi->slave) { gpio.Speed = GPIO_SPEED_FREQ_VERY_HIGH; } else { gpio.Speed = gpio_speed; } #else gpio.Speed = gpio_speed; #endif rc = hal_gpio_init_stm(cfg->sck_pin, &gpio); if (rc != 0) { goto err; } #if defined(STM32L152xC) if (!spi->slave) { gpio.Speed = gpio_speed; } #endif if (!spi->slave) { gpio.Pull = GPIO_NOPULL; } else { gpio.Mode = GPIO_MODE_AF_OD; } rc = hal_gpio_init_stm(cfg->mosi_pin, &gpio); if (rc != 0) { goto err; } if (!spi->slave) { gpio.Mode = GPIO_MODE_AF_OD; } else { gpio.Mode = GPIO_MODE_AF_PP; } rc = hal_gpio_init_stm(cfg->miso_pin, &gpio); if (rc != 0) { goto err; } switch (settings->data_mode) { case HAL_SPI_MODE0: init->CLKPolarity = SPI_POLARITY_LOW; init->CLKPhase = SPI_PHASE_1EDGE; break; case HAL_SPI_MODE1: init->CLKPolarity = SPI_POLARITY_LOW; init->CLKPhase = SPI_PHASE_2EDGE; break; case HAL_SPI_MODE2: init->CLKPolarity = SPI_POLARITY_HIGH; init->CLKPhase = SPI_PHASE_1EDGE; break; case HAL_SPI_MODE3: init->CLKPolarity = SPI_POLARITY_HIGH; init->CLKPhase = SPI_PHASE_2EDGE; break; default: rc = -1; goto err; } switch (settings->data_order) { case HAL_SPI_MSB_FIRST: init->FirstBit = SPI_FIRSTBIT_MSB; break; case HAL_SPI_LSB_FIRST: init->FirstBit = SPI_FIRSTBIT_LSB; break; default: rc = -1; goto err; } switch (settings->word_size) { case HAL_SPI_WORD_SIZE_8BIT: init->DataSize = SPI_DATASIZE_8BIT; break; case HAL_SPI_WORD_SIZE_9BIT: init->DataSize = SPI_DATASIZE_16BIT; break; default: rc = -1; goto err; } rc = stm32_spi_resolve_prescaler(spi_num, settings->baudrate * 1000, &prescaler); if (rc != 0) { goto err; } init->BaudRatePrescaler = prescaler; /* Add default values */ init->Direction = SPI_DIRECTION_2LINES; init->TIMode = SPI_TIMODE_DISABLE; init->CRCCalculation = SPI_CRCCALCULATION_DISABLE; init->CRCPolynomial = 1; #ifdef SPI_NSS_PULSE_DISABLE init->NSSPMode = SPI_NSS_PULSE_DISABLE; #endif irq = stm32_resolve_spi_irq(&spi->handle); NVIC_SetPriority(irq, cfg->irq_prio); NVIC_SetVector(irq, stm32_resolve_spi_irq_handler(&spi->handle)); NVIC_EnableIRQ(irq); /* Init, Enable */ rc = HAL_SPI_Init(&spi->handle); if (rc != 0) { goto err; } if (spi->slave) { hal_spi_slave_set_def_tx_val(spi_num, 0); rc = hal_gpio_irq_init(cfg->ss_pin, spi_ss_isr, spi, HAL_GPIO_TRIG_BOTH, HAL_GPIO_PULL_UP); spi_ss_isr(spi); } __HAL_ENABLE_INTERRUPTS(sr); return (0); err: __HAL_ENABLE_INTERRUPTS(sr); return (rc); }