/** * @brief Main program * @param None * @retval None */ int main(void) { uint16_t addrcmd = 0; uint16_t comlength = 0; uint8_t pAddrcmd[CMD_LENGTH] = {0x00}; uint16_t ackbyte = 0x0000; /* STM32F4xx HAL library initialization: - Configure the Flash prefetch, instruction and Data caches - Configure the Systick to generate an interrupt each 1 msec - Set NVIC Group Priority to 4 - Global MSP (MCU Support Package) initialization */ HAL_Init(); /* Configure the system clock to 168 MHz */ SystemClock_Config(); /* Configure LED5 and LED6 */ BSP_LED_Init(LED5); BSP_LED_Init(LED6); /*##-1- Configure the SPI peripheral #######################################*/ /* Set the SPI parameters */ SpiHandle.Instance = SPIx; SpiHandle.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16; SpiHandle.Init.Direction = SPI_DIRECTION_2LINES; SpiHandle.Init.CLKPhase = SPI_PHASE_2EDGE; SpiHandle.Init.CLKPolarity = SPI_POLARITY_LOW; SpiHandle.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; SpiHandle.Init.CRCPolynomial = 7; SpiHandle.Init.DataSize = SPI_DATASIZE_8BIT; SpiHandle.Init.FirstBit = SPI_FIRSTBIT_MSB; SpiHandle.Init.NSS = SPI_NSS_SOFT; SpiHandle.Init.TIMode = SPI_TIMODE_DISABLE; SpiHandle.Init.Mode = SPI_MODE_SLAVE; if(HAL_SPI_Init(&SpiHandle) != HAL_OK) { /* Initialization Error */ Error_Handler(); } /* Enter while loop too keep treating new request from Master */ while(1) { /* Synchronization between Master and Slave */ Slave_Synchro(); /* Receive command from Master */ if(HAL_SPI_Receive_IT(&SpiHandle, pAddrcmd, CMD_LENGTH) != HAL_OK) { Error_Handler(); } /* Before starting a new communication transfer, you need to check the current state of the peripheral; if it’s busy you need to wait for the end of current transfer before starting a new one. For simplicity reasons, this example is just waiting till the end of the transfer, but application may perform other tasks while transfer operation is ongoing. */ while (HAL_SPI_GetState(&SpiHandle) != HAL_SPI_STATE_READY) {} /* Compute command and required data length */ addrcmd = (uint16_t) ((pAddrcmd[0] << 8) | pAddrcmd[1]); comlength = (uint16_t) ((pAddrcmd[2] << 8) | pAddrcmd[3]); /* Check if received command correct */ if(((addrcmd == ADDRCMD_MASTER_READ) || (addrcmd == ADDRCMD_MASTER_WRITE)) && (comlength > 0)) { /* Synchronization between Master and Slave */ Slave_Synchro(); /* Send acknowledge to Master */ ackbyte = SPI_ACK_BYTES; if(HAL_SPI_Transmit_IT(&SpiHandle, (uint8_t *)&ackbyte, sizeof(ackbyte)) != HAL_OK) { Error_Handler(); } while (HAL_SPI_GetState(&SpiHandle) != HAL_SPI_STATE_READY) {} /* Check if Master requiring data read or write */ if(addrcmd == ADDRCMD_MASTER_READ) { /* Synchronization between Master and Slave */ Slave_Synchro(); /* Send data to Master */ if(HAL_SPI_Transmit_IT(&SpiHandle, aTxSlaveBuffer, DATA_LENGTH) != HAL_OK) { Error_Handler(); } while (HAL_SPI_GetState(&SpiHandle) != HAL_SPI_STATE_READY) {} /* Synchronization between Master and Slave */ Slave_Synchro(); /* Receive acknowledgement from Master */ ackbyte = 0; if(HAL_SPI_Receive_IT(&SpiHandle, (uint8_t *)&ackbyte, sizeof(ackbyte)) != HAL_OK) { Error_Handler(); } while (HAL_SPI_GetState(&SpiHandle) != HAL_SPI_STATE_READY) {} /* Check acknowledgement */ if(ackbyte != SPI_ACK_BYTES) { Error_Handler(); } } else if(addrcmd == ADDRCMD_MASTER_WRITE) { /* Synchronization between Master and Slave */ Slave_Synchro(); /* Receive data from Master */ if(HAL_SPI_Receive_IT(&SpiHandle, aRxBuffer, DATA_LENGTH) != HAL_OK) { Error_Handler(); } while (HAL_SPI_GetState(&SpiHandle) != HAL_SPI_STATE_READY) {} /* Synchronization between Master and Slave */ Slave_Synchro(); /* Send acknowledgement to Master */ ackbyte = SPI_ACK_BYTES; if(HAL_SPI_Transmit_IT(&SpiHandle, (uint8_t *)&ackbyte, sizeof(ackbyte)) != HAL_OK) { Error_Handler(); } while (HAL_SPI_GetState(&SpiHandle) != HAL_SPI_STATE_READY) {} /* In case, Master has sent data, compare received buffer with one expected */ if(Buffercmp((uint8_t*)aTxMasterBuffer, (uint8_t*)aRxBuffer, DATA_LENGTH)) { /* Transfer error in transmission process */ Error_Handler(); } else { /* Toggle LED6 on: Reception is correct */ BSP_LED_Toggle(LED6); } } } else { /* Synchronization between Master and Slave */ Slave_Synchro(); /* Send acknowledgement to Master */ ackbyte = SPI_NACK_BYTES; if(HAL_SPI_Transmit_IT(&SpiHandle, (uint8_t *)&ackbyte, sizeof(ackbyte)) != HAL_OK) { Error_Handler(); } while (HAL_SPI_GetState(&SpiHandle) != HAL_SPI_STATE_READY) {} Error_Handler(); } /* Flush Rx buffer for next transmission */ Flush_Buffer(aRxBuffer, DATA_LENGTH); } }
/** * @brief SPIx Bus initialization */ static void SPIx_Init(void) { if(HAL_SPI_GetState(&SpiHandle) == HAL_SPI_STATE_RESET) { /* SPI configuration -----------------------------------------------------*/ SpiHandle.Instance = DISCOVERY_SPIx; /* SPI baudrate is set to 5.6 MHz (PCLK2/SPI_BaudRatePrescaler = 90/16 = 5.625 MHz) to verify these constraints: - ILI9341 LCD SPI interface max baudrate is 10MHz for write and 6.66MHz for read - l3gd20 SPI interface max baudrate is 10MHz for write/read - PCLK2 frequency is set to 90 MHz */ SpiHandle.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16; /* On STM32F429I-Discovery, LCD ID cannot be read then keep a common configuration */ /* for LCD and GYRO (SPI_DIRECTION_2LINES) */ /* Note: To read a register a LCD, SPI_DIRECTION_1LINE should be set */ SpiHandle.Init.Direction = SPI_DIRECTION_2LINES; SpiHandle.Init.CLKPhase = SPI_PHASE_1EDGE; SpiHandle.Init.CLKPolarity = SPI_POLARITY_LOW; SpiHandle.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED; SpiHandle.Init.CRCPolynomial = 7; SpiHandle.Init.DataSize = SPI_DATASIZE_8BIT; SpiHandle.Init.FirstBit = SPI_FIRSTBIT_MSB; SpiHandle.Init.NSS = SPI_NSS_SOFT; SpiHandle.Init.TIMode = SPI_TIMODE_DISABLED; SpiHandle.Init.Mode = SPI_MODE_MASTER; SPIx_MspInit(&SpiHandle); HAL_SPI_Init(&SpiHandle); } }
/** * @brief SPIx Bus initialization * @param None * @retval None */ static void SPIx_Init(void) { if(HAL_SPI_GetState(&SpiHandle) == HAL_SPI_STATE_RESET) { /* SPI Config */ SpiHandle.Instance = DISCOVERY_SPIx; /* SPI baudrate is set to 5.6 MHz (PCLK2/SPI_BaudRatePrescaler = 90/16 = 5.625 MHz) to verify these constraints: ILI9341 LCD SPI interface max baudrate is 10MHz for write and 6.66MHz for read l3gd20 SPI interface max baudrate is 10MHz for write/read PCLK2 frequency is set to 90 MHz */ SpiHandle.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16; SpiHandle.Init.Direction = SPI_DIRECTION_2LINES; SpiHandle.Init.CLKPhase = SPI_PHASE_1EDGE; SpiHandle.Init.CLKPolarity = SPI_POLARITY_LOW; SpiHandle.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED; SpiHandle.Init.CRCPolynomial = 7; SpiHandle.Init.DataSize = SPI_DATASIZE_8BIT; SpiHandle.Init.FirstBit = SPI_FIRSTBIT_MSB; SpiHandle.Init.NSS = SPI_NSS_SOFT; SpiHandle.Init.TIMode = SPI_TIMODE_DISABLED; SpiHandle.Init.Mode = SPI_MODE_MASTER; SPIx_MspInit(&SpiHandle); HAL_SPI_Init(&SpiHandle); } }
/** * @brief Initializes SPI HAL. * @retval None */ static void SPIx_Init(void) { if(HAL_SPI_GetState(&hnucleo_Spi) == HAL_SPI_STATE_RESET) { /* SPI Config */ hnucleo_Spi.Instance = NUCLEO_SPIx; /* SPI baudrate is set to 8 MHz maximum (PCLK2/SPI_BaudRatePrescaler = 64/8 = 8 MHz) to verify these constraints: - ST7735 LCD SPI interface max baudrate is 15MHz for write and 6.66MHz for read Since the provided driver doesn't use read capability from LCD, only constraint on write baudrate is considered. - SD card SPI interface max baudrate is 25MHz for write/read - PCLK2 max frequency is 32 MHz */ hnucleo_Spi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8; hnucleo_Spi.Init.Direction = SPI_DIRECTION_2LINES; hnucleo_Spi.Init.CLKPhase = SPI_PHASE_1EDGE; hnucleo_Spi.Init.CLKPolarity = SPI_POLARITY_LOW; hnucleo_Spi.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; hnucleo_Spi.Init.CRCPolynomial = 7; hnucleo_Spi.Init.DataSize = SPI_DATASIZE_8BIT; hnucleo_Spi.Init.FirstBit = SPI_FIRSTBIT_MSB; hnucleo_Spi.Init.NSS = SPI_NSS_SOFT; hnucleo_Spi.Init.TIMode = SPI_TIMODE_DISABLE; hnucleo_Spi.Init.Mode = SPI_MODE_MASTER; SPIx_MspInit(); HAL_SPI_Init(&hnucleo_Spi); } }
/********************************************************************* * @fn SPI1_Init * * @brief SPIx Bus initialization * * @param None * * @return void */ void SPI1_Init(void) { SX1276.Spi.Spi = ( SPI_TypeDef* )SPI1_BASE; if(HAL_SPI_GetState(&SpiHandle) == HAL_SPI_STATE_RESET) { /* SPI Config */ SpiHandle.Instance = SPIx; /* On STM32L0538-DISCO, EPD ID cannot be read then keep a common configuration */ /* for EPD (SPI_DIRECTION_2LINES) */ /* Note: To read a register a EPD, SPI_DIRECTION_1LINE should be set */ SpiHandle.Init.Mode = SPI_MODE_MASTER; SpiHandle.Init.Direction = SPI_DIRECTION_2LINES; SpiHandle.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8; SpiHandle.Init.DataSize = SPI_DATASIZE_8BIT; SpiHandle.Init.CLKPhase = SPI_PHASE_1EDGE;//SPI_PHASE_2EDGE; SpiHandle.Init.CLKPolarity = SPI_POLARITY_LOW;//SPI_POLARITY_HIGH;SPI_POLARITY_LOW SpiHandle.Init.FirstBit = SPI_FIRSTBIT_MSB; SpiHandle.Init.NSS = SPI_NSS_SOFT; SpiHandle.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED; SpiHandle.Init.CRCPolynomial = 7; SpiHandle.Init.TIMode = SPI_TIMODE_DISABLED; SPI1_MspInit(&SpiHandle); HAL_SPI_Init(&SpiHandle); } }
/** * @brief SPIx Bus initialization * @param None * @retval None */ static void SPIx_Init(void) { if(HAL_SPI_GetState(&heval_Spi) == HAL_SPI_STATE_RESET) { /* SPI Config */ heval_Spi.Instance = EVAL_SPIx; /* SPI baudrate is set to 16 MHz (PCLK2/SPI_BaudRatePrescaler = 32/2 = 16 MHz) to verify these constraints: HX8347D LCD SPI interface max baudrate is 50MHz for write and 6.66MHz for read PCLK1 frequency is set to 32 MHz - SD card SPI interface max baudrate is 25MHz for write/read */ heval_Spi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2; heval_Spi.Init.Direction = SPI_DIRECTION_2LINES; heval_Spi.Init.CLKPhase = SPI_PHASE_2EDGE; heval_Spi.Init.CLKPolarity = SPI_POLARITY_HIGH; heval_Spi.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; heval_Spi.Init.CRCPolynomial = 7; heval_Spi.Init.DataSize = SPI_DATASIZE_8BIT; heval_Spi.Init.FirstBit = SPI_FIRSTBIT_MSB; heval_Spi.Init.NSS = SPI_NSS_SOFT; heval_Spi.Init.TIMode = SPI_TIMODE_DISABLE; heval_Spi.Init.Mode = SPI_MODE_MASTER; SPIx_MspInit(&heval_Spi); HAL_SPI_Init(&heval_Spi); } }
/* void hal_nrf_write_multibyte_reg(uint8_t reg, const uint8_t *pbuf, uint8_t length) { uint8_t memtype; uint8_t volatile dummy; memtype = *(uint8_t*)(&pbuf); CSN_LOW(); HAL_SPI_TransmitReceive(&SpiHandle, (uint8_t*)®, (uint8_t *)&dummy, 1, 5000); if (memtype == 0x00U) { const uint8_t *buf = (const uint8_t *)pbuf; NRF_WRITE_MULTIBYTE_REG_COMMON_BODY } else if (memtype == 0x01U) { const uint8_t *buf = (const uint8_t *)pbuf; NRF_WRITE_MULTIBYTE_REG_COMMON_BODY } else if (memtype == 0xFEU) { const uint8_t *buf = (const uint8_t *)pbuf; NRF_WRITE_MULTIBYTE_REG_COMMON_BODY } else { const uint8_t *buf = (const uint8_t *)pbuf; NRF_WRITE_MULTIBYTE_REG_COMMON_BODY } CSN_HIGH(); } */ void hal_nrf_write_multibyte_reg(uint8_t reg, const uint8_t *pbuf, uint8_t length) { uint8_t *p = (uint8_t *)pbuf; while(SPI_busy); //waiting last tx finished while (HAL_SPI_GetState(&SpiHandle) != HAL_SPI_STATE_READY); CSN_LOW(); HAL_SPI_TransmitReceive(&SpiHandle, (uint8_t*)®, spi_rx, 1, 5000); // address if( (uint32_t)pbuf < 0x20000000 ){ while(1); } if(HAL_SPI_Transmit_DMA(&SpiHandle, (uint8_t *)pbuf, length) != HAL_OK) //32 bytes data { while(1); PRINTF("SPI DMA ERROR\r\n") } SPI_busy = true; /*while(length--){ if(HAL_SPI_TransmitReceive(&SpiHandle, (uint8_t *)p++, (uint8_t *)dummy, 1, 5000) != HAL_OK) { PRINTF("SPI DMA ERROR\r\n") } soft_delay(100); }*/ #ifdef DEBUG_NRF PRINTF("SPI DMA started") #endif /* CSN_HIGH(); #ifdef DEBUG_NRF PRINTF("SPI DMA finished") #endif */ }
/** * @brief Configures LIS3DSH * @param InitTypeDef: Specifies the configuration. * @retval None */ void LIS3DSH_init(LIS3DSH_InitTypeDef li) { GPIO_InitTypeDef GPIO_InitStructure; /* Configure the LIS3DSH Control pins --------------------------------*/ /* Enable CS GPIO clock and configure GPIO pin for LIS3DSH Chip select */ LIS3DSH_SPI_CS_GPIO_CLK_ENABLE(); /* Configure GPIO PIN for LIS Chip select */ GPIO_InitStructure.Pin = LIS3DSH_SPI_CS_PIN; GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStructure.Pull = GPIO_NOPULL; GPIO_InitStructure.Speed = GPIO_SPEED_MEDIUM; HAL_GPIO_Init(LIS3DSH_SPI_CS_GPIO_PORT, &GPIO_InitStructure); /* Deselect: Chip Select high */ /* SPI start when the chip select is low */ LIS3DSH_CS_HIGH(); /* Configure the SPI1 to communicate with the accelerometer */ if (HAL_SPI_GetState(&SpiHandle) == HAL_SPI_STATE_RESET) { /* SPI configuration -----------------------------------------------------*/ SpiHandle.Instance = LIS3DSH_SPI; SpiHandle.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16; SpiHandle.Init.Direction = SPI_DIRECTION_2LINES; SpiHandle.Init.CLKPhase = SPI_PHASE_1EDGE; SpiHandle.Init.CLKPolarity = SPI_POLARITY_LOW; SpiHandle.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED; SpiHandle.Init.CRCPolynomial = 7; SpiHandle.Init.DataSize = SPI_DATASIZE_8BIT; SpiHandle.Init.FirstBit = SPI_FIRSTBIT_MSB; SpiHandle.Init.NSS = SPI_NSS_SOFT; SpiHandle.Init.TIMode = SPI_TIMODE_DISABLED; SpiHandle.Init.Mode = SPI_MODE_MASTER; /* SPI low level configuration */ /* Enable the SPI peripheral */ LIS3DSH_SPI_CLK_ENABLE(); /* Enable SCK, MOSI and MISO GPIO clocks */ LIS3DSH_SPI_GPIO_CLK_ENABLE(); /* SPI SCK, MOSI, MISO pin configuration */ GPIO_InitStructure.Pin = (LIS3DSH_SPI_SCK_PIN | LIS3DSH_SPI_MISO_PIN | LIS3DSH_SPI_MOSI_PIN); GPIO_InitStructure.Mode = GPIO_MODE_AF_PP; GPIO_InitStructure.Pull = GPIO_PULLDOWN; GPIO_InitStructure.Speed = GPIO_SPEED_FAST; GPIO_InitStructure.Alternate = LIS3DSH_SPI_AF; HAL_GPIO_Init(LIS3DSH_SPI_GPIO_PORT, &GPIO_InitStructure); HAL_SPI_Init(&SpiHandle); } /* Configures the inner register of the accelerometer */ LIS3DSH_writeRegister(LIS3DSH_CTRL_REG4_ADDR, li.OutputDataRate | li.Axes_Enable | li.BlockDataUpdate); LIS3DSH_writeRegister(LIS3DSH_CTRL_REG5_ADDR, li.FullScale); }
unsigned char W5500ReadByte(void) { unsigned char txByte = 0xff;//dummy unsigned char rtnByte; while (HAL_SPI_GetState(&hspi1W5500) != HAL_SPI_STATE_READY); HAL_SPI_TransmitReceive(&hspi1W5500,&txByte,&rtnByte,1,10); return rtnByte; }
// ***** GP22 - Hardware Setup uint8_t gp22_hw_setup() { GPIO_InitTypeDef GPIO_InitStruct; HAL_SPI_StateTypeDef spi_status; // Init INT-Pin GPIO_InitStruct.Pin = GP22_INT_PIN; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; HAL_GPIO_Init(GP22_INT_PORT, &GPIO_InitStruct); GP22_INT_CLK_ENABLE(); // Init CS-Pin GPIO_InitStruct.Pin = GP22_CS_PIN; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FAST; HAL_GPIO_Init(GP22_CS_PORT, &GPIO_InitStruct); GP22_CS_CLK_ENABLE(); GP22_CS_HIGH(); // Init RESET-Pin GPIO_InitStruct.Pin = GP22_RESET_PIN; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FAST; HAL_GPIO_Init(GP22_RESET_PORT, &GPIO_InitStruct); GP22_RESET_CLK_ENABLE(); GP22_RESET_LOW(); // Init SPI hGP22_SPI.Instance = GP22_SPI; hGP22_SPI.Init.BaudRatePrescaler = GP22_SPI_PRESCALER; hGP22_SPI.Init.Direction = SPI_DIRECTION_2LINES; hGP22_SPI.Init.CLKPhase = SPI_PHASE_2EDGE; hGP22_SPI.Init.CLKPolarity = SPI_POLARITY_LOW; hGP22_SPI.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED; hGP22_SPI.Init.CRCPolynomial = 7; hGP22_SPI.Init.DataSize = SPI_DATASIZE_8BIT; hGP22_SPI.Init.FirstBit = SPI_FIRSTBIT_MSB; hGP22_SPI.Init.NSS = SPI_NSS_SOFT; hGP22_SPI.Init.TIMode = SPI_TIMODE_DISABLED; hGP22_SPI.Init.Mode = SPI_MODE_MASTER; spi_status = HAL_SPI_GetState(&hGP22_SPI); if (spi_status != HAL_SPI_STATE_RESET) { hal_status = HAL_SPI_DeInit(&hGP22_SPI); } hal_status = HAL_SPI_Init(&hGP22_SPI); return hal_status; }
void flexsea_start_receiving_from_master(void) { // start receive over SPI if (HAL_SPI_GetState(&spi4_handle) == HAL_SPI_STATE_READY) { if(HAL_SPI_TransmitReceive_IT(&spi4_handle, (uint8_t *)aTxBuffer, (uint8_t *)aRxBuffer, COMM_STR_BUF_LEN) != HAL_OK) { // Transfer error in transmission process flexsea_error(SE_RECEIVE_FROM_MASTER); } } }
uint8_t spi_active(spi_t *obj) { SPI_HandleTypeDef *handle = &SpiHandle[obj->spi.module]; 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; } }
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; } }
/** * @brief Slave synchronization with Master * @param None * @retval None */ static void Slave_Synchro(void) { uint8_t txackbyte = SPI_SLAVE_SYNBYTE, rxackbyte = 0x00; do { if (HAL_SPI_TransmitReceive_IT(&SpiHandle, (uint8_t *)&txackbyte, (uint8_t *)&rxackbyte, 1) != HAL_OK) { Error_Handler(); } while (HAL_SPI_GetState(&SpiHandle) != HAL_SPI_STATE_READY) {} } while (rxackbyte != SPI_MASTER_SYNBYTE); }
/** * @brief SPIx Bus initialization * @param None * @retval None */ static void SPIx_Init(void) { if(HAL_SPI_GetState(&SpiHandle) == HAL_SPI_STATE_RESET) { /* SPI configuration -----------------------------------------------------*/ SpiHandle.Instance = DISCOVERY_SPIx; SpiHandle.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16; SpiHandle.Init.Direction = SPI_DIRECTION_2LINES; SpiHandle.Init.CLKPhase = SPI_PHASE_1EDGE; SpiHandle.Init.CLKPolarity = SPI_POLARITY_LOW; SpiHandle.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED; SpiHandle.Init.CRCPolynomial = 7; SpiHandle.Init.DataSize = SPI_DATASIZE_8BIT; SpiHandle.Init.FirstBit = SPI_FIRSTBIT_MSB; SpiHandle.Init.NSS = SPI_NSS_SOFT; SpiHandle.Init.TIMode = SPI_TIMODE_DISABLED; SpiHandle.Init.Mode = SPI_MODE_MASTER; SPIx_MspInit(); HAL_SPI_Init(&SpiHandle); } }
/** * @brief Initializes SPI HAL. * @param None * @retval None */ static void SPIx_Init(void) { if(HAL_SPI_GetState(&heval_Spi) == HAL_SPI_STATE_RESET) { /* SPI Config */ heval_Spi.Instance = EVAL_SPIx; /* SPI baudrate is set to 36 MHz (PCLK2/SPI_BaudRatePrescaler = 72/2 = 36 MHz) */ heval_Spi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2; heval_Spi.Init.Direction = SPI_DIRECTION_2LINES; heval_Spi.Init.CLKPhase = SPI_PHASE_2EDGE; heval_Spi.Init.CLKPolarity = SPI_POLARITY_HIGH; heval_Spi.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED; heval_Spi.Init.CRCPolynomial = 7; heval_Spi.Init.DataSize = SPI_DATASIZE_8BIT; heval_Spi.Init.FirstBit = SPI_FIRSTBIT_MSB; heval_Spi.Init.NSS = SPI_NSS_SOFT; heval_Spi.Init.TIMode = SPI_TIMODE_DISABLED; heval_Spi.Init.Mode = SPI_MODE_MASTER; SPIx_MspInit(&heval_Spi); HAL_SPI_Init(&heval_Spi); } }
/** * @brief Main program * @param None * @retval None */ int main(void) { /* STM32F0xx HAL library initialization: - Configure the Flash prefetch - Systick timer is configured by default as source of time base, but user can eventually implement his proper time base source (a general purpose timer for example or other time source), keeping in mind that Time base duration should be kept 1ms since PPP_TIMEOUT_VALUEs are defined and handled in milliseconds basis. - Low Level Initialization */ HAL_Init(); /* Configure LED2, LED2 and LED2 */ BSP_LED_Init(LED2); /* Configure the system clock to 48 MHz */ SystemClock_Config(); /*##-1- Configure the SPI peripheral #######################################*/ /* Set the SPI parameters */ SpiHandle.Instance = SPIx; SpiHandle.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32; SpiHandle.Init.Direction = SPI_DIRECTION_2LINES; SpiHandle.Init.CLKPhase = SPI_PHASE_1EDGE; SpiHandle.Init.CLKPolarity = SPI_POLARITY_LOW; SpiHandle.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED; SpiHandle.Init.CRCPolynomial = 7; SpiHandle.Init.DataSize = SPI_DATASIZE_8BIT; SpiHandle.Init.FirstBit = SPI_FIRSTBIT_MSB; SpiHandle.Init.NSS = SPI_NSS_SOFT; SpiHandle.Init.TIMode = SPI_TIMODE_DISABLED; SpiHandle.Init.NSSPMode = SPI_NSS_PULSE_DISABLED; SpiHandle.Init.CRCLength = SPI_CRC_LENGTH_8BIT; #ifdef MASTER_BOARD SpiHandle.Init.Mode = SPI_MODE_MASTER; #else SpiHandle.Init.Mode = SPI_MODE_SLAVE; #endif /* MASTER_BOARD */ if (HAL_SPI_Init(&SpiHandle) != HAL_OK) { /* Initialization Error */ Error_Handler(); } #ifdef MASTER_BOARD /* Configure User push-button */ BSP_PB_Init(BUTTON_USER, BUTTON_MODE_GPIO); /* Wait for User push-button press before starting the Communication */ while (BSP_PB_GetState(BUTTON_USER) != GPIO_PIN_RESET) { BSP_LED_Toggle(LED2); HAL_Delay(100); } BSP_LED_Off(LED2); #endif /* MASTER_BOARD */ /*##-2- Start the Full Duplex Communication process ########################*/ /* While the SPI in TransmitReceive process, user can transmit data through "aTxBuffer" buffer & receive data through "aRxBuffer" */ if(HAL_SPI_TransmitReceive_DMA(&SpiHandle, (uint8_t*)aTxBuffer, (uint8_t *)aRxBuffer, BUFFERSIZE) != HAL_OK) { /* Transfer error in transmission process */ Error_Handler(); } /*##-3- Wait for the end of the transfer ###################################*/ /* Before starting a new communication transfer, you need to check the current state of the peripheral; if it’s busy you need to wait for the end of current transfer before starting a new one. For simplicity reasons, this example is just waiting till the end of the transfer, but application may perform other tasks while transfer operation is ongoing. */ while (HAL_SPI_GetState(&SpiHandle) != HAL_SPI_STATE_READY) { } /*##-4- Compare the sent and received buffers ##############################*/ if(Buffercmp((uint8_t*)aTxBuffer, (uint8_t*)aRxBuffer, BUFFERSIZE)) { /* Processing Error */ Error_Handler(); } /* Infinite loop */ while (1) { } }
/** * @brief Main program * @param None * @retval None */ int main(void) { /* STM32F4xx HAL library initialization: - Configure the Flash prefetch, instruction and Data caches - Configure the Systick to generate an interrupt each 1 msec - Set NVIC Group Priority to 4 - Global MSP (MCU Support Package) initialization */ HAL_Init(); /* Configure LED3, LED4, LED5 and LED6 */ BSP_LED_Init(LED3); BSP_LED_Init(LED4); BSP_LED_Init(LED5); BSP_LED_Init(LED6); /* Configure the system clock to 168 MHz */ SystemClock_Config(); /*##-1- Configure the SPI peripheral #######################################*/ /* Set the SPI parameters */ SpiHandle.Instance = SPIx; SpiHandle.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256; SpiHandle.Init.Direction = SPI_DIRECTION_2LINES; SpiHandle.Init.CLKPhase = SPI_PHASE_1EDGE; SpiHandle.Init.CLKPolarity = SPI_POLARITY_HIGH; SpiHandle.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; SpiHandle.Init.CRCPolynomial = 7; SpiHandle.Init.DataSize = SPI_DATASIZE_8BIT; SpiHandle.Init.FirstBit = SPI_FIRSTBIT_MSB; SpiHandle.Init.NSS = SPI_NSS_SOFT; SpiHandle.Init.TIMode = SPI_TIMODE_DISABLE; #ifdef MASTER_BOARD SpiHandle.Init.Mode = SPI_MODE_MASTER; #else SpiHandle.Init.Mode = SPI_MODE_SLAVE; #endif /* MASTER_BOARD */ if(HAL_SPI_Init(&SpiHandle) != HAL_OK) { /* Initialization Error */ Error_Handler(); } #ifdef MASTER_BOARD /* Configure USER Button */ BSP_PB_Init(BUTTON_KEY, BUTTON_MODE_GPIO); /* Wait for USER Button press before starting the Communication */ while (BSP_PB_GetState(BUTTON_KEY) != 1) { BSP_LED_Toggle(LED3); HAL_Delay(40); } BSP_LED_Off(LED3); #endif /* MASTER_BOARD */ /*##-2- Start the Full Duplex Communication process ########################*/ /* While the SPI in TransmitReceive process, user can transmit data through "aTxBuffer" buffer & receive data through "aRxBuffer" */ if(HAL_SPI_TransmitReceive_DMA(&SpiHandle, (uint8_t*)aTxBuffer, (uint8_t *)aRxBuffer, BUFFERSIZE) != HAL_OK) { /* Transfer error in transmission process */ Error_Handler(); } /*##-3- Wait for the end of the transfer ###################################*/ /* Before starting a new communication transfer, you need to check the current state of the peripheral; if it’s busy you need to wait for the end of current transfer before starting a new one. For simplicity reasons, this example is just waiting till the end of the transfer, but application may perform other tasks while transfer operation is ongoing. */ while (HAL_SPI_GetState(&SpiHandle) != HAL_SPI_STATE_READY) { } /*##-4- Compare the sent and received buffers ##############################*/ if(Buffercmp((uint8_t*)aTxBuffer, (uint8_t*)aRxBuffer, BUFFERSIZE)) { /* Transfer error in transmission process */ Error_Handler(); } /* Infinite loop */ while (1) { } }
void W5500WriteByte(unsigned char txByte) { unsigned char rtnByte; while (HAL_SPI_GetState(&hspi1W5500) != HAL_SPI_STATE_READY); HAL_SPI_TransmitReceive(&hspi1W5500,&txByte,&rtnByte,1,10); }
static rt_uint32_t spixfer(struct rt_spi_device *device, struct rt_spi_message *message) { HAL_StatusTypeDef state; rt_size_t message_length, already_send_length; rt_uint16_t send_length; rt_uint8_t *recv_buf; const rt_uint8_t *send_buf; RT_ASSERT(device != RT_NULL); RT_ASSERT(device->bus != RT_NULL); RT_ASSERT(device->bus->parent.user_data != RT_NULL); RT_ASSERT(message != RT_NULL); struct stm32_spi *spi_drv = rt_container_of(device->bus, struct stm32_spi, spi_bus); SPI_HandleTypeDef *spi_handle = &spi_drv->handle; struct stm32_hw_spi_cs *cs = device->parent.user_data; if (message->cs_take) { HAL_GPIO_WritePin(cs->GPIOx, cs->GPIO_Pin, GPIO_PIN_RESET); } LOG_D("%s transfer prepare and start", spi_drv->config->bus_name); LOG_D("%s sendbuf: %X, recvbuf: %X, length: %d", spi_drv->config->bus_name, (uint32_t)message->send_buf, (uint32_t)message->recv_buf, message->length); message_length = message->length; recv_buf = message->recv_buf; send_buf = message->send_buf; while (message_length) { /* the HAL library use uint16 to save the data length */ if (message_length > 65535) { send_length = 65535; message_length = message_length - 65535; } else { send_length = message_length; message_length = 0; } /* calculate the start address */ already_send_length = message->length - send_length - message_length; send_buf = (rt_uint8_t *)message->send_buf + already_send_length; recv_buf = (rt_uint8_t *)message->recv_buf + already_send_length; /* start once data exchange in DMA mode */ if (message->send_buf && message->recv_buf) { if ((spi_drv->spi_dma_flag & SPI_USING_TX_DMA_FLAG) && (spi_drv->spi_dma_flag & SPI_USING_RX_DMA_FLAG)) { state = HAL_SPI_TransmitReceive_DMA(spi_handle, (uint8_t *)send_buf, (uint8_t *)recv_buf, send_length); } else { state = HAL_SPI_TransmitReceive(spi_handle, (uint8_t *)send_buf, (uint8_t *)recv_buf, send_length, 1000); } } else if (message->send_buf) { if (spi_drv->spi_dma_flag & SPI_USING_TX_DMA_FLAG) { state = HAL_SPI_Transmit_DMA(spi_handle, (uint8_t *)send_buf, send_length); } else { state = HAL_SPI_Transmit(spi_handle, (uint8_t *)send_buf, send_length, 1000); } } else { memset((uint8_t *)recv_buf, 0xff, send_length); if (spi_drv->spi_dma_flag & SPI_USING_RX_DMA_FLAG) { state = HAL_SPI_Receive_DMA(spi_handle, (uint8_t *)recv_buf, send_length); } else { state = HAL_SPI_Receive(spi_handle, (uint8_t *)recv_buf, send_length, 1000); } } if (state != HAL_OK) { LOG_I("spi transfer error : %d", state); message->length = 0; spi_handle->State = HAL_SPI_STATE_READY; } else { LOG_D("%s transfer done", spi_drv->config->bus_name); } /* For simplicity reasons, this example is just waiting till the end of the transfer, but application may perform other tasks while transfer operation is ongoing. */ while (HAL_SPI_GetState(spi_handle) != HAL_SPI_STATE_READY); } if (message->cs_release) { HAL_GPIO_WritePin(cs->GPIOx, cs->GPIO_Pin, GPIO_PIN_SET); } return message->length; }
uint32_t spi_irq_handler_asynch(spi_t *obj) { // use the right instance SPI_HandleTypeDef *handle = &SpiHandle[obj->spi.module]; 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) { // adjust buffer positions size_t tx_size = (handle->TxXferSize - handle->TxXferCount); size_t rx_size = (handle->RxXferSize - handle->RxXferCount); // 16 bit transfers need to be doubled to get bytes if (handle->Init.DataSize == SPI_DATASIZE_16BIT) { tx_size *= 2; rx_size *= 2; } // adjust buffer positions if (obj->spi.transfer_type != SPI_TRANSFER_TYPE_RX) { obj->tx_buff.pos += tx_size; } if (obj->spi.transfer_type != SPI_TRANSFER_TYPE_TX) { obj->rx_buff.pos += rx_size; } if (handle->TxXferCount > 0) DEBUG_PRINTF("SPI%u: TxXferCount: %u\n", obj->spi.module+1, handle->TxXferCount); if (handle->RxXferCount > 0) DEBUG_PRINTF("SPI%u: RxXferCount: %u\n", obj->spi.module+1, handle->RxXferCount); 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 { // figure out if we need to transfer more data: if (obj->tx_buff.pos < obj->tx_buff.length) { // DEBUG_PRINTF("t%u ", obj->tx_buff.pos); // we need to transfer more data spi_master_start_asynch_transfer(obj, SPI_TRANSFER_TYPE_TX, obj->tx_buff.buffer + obj->tx_buff.pos, // offset the initial buffer by the position NULL, // there is no receive buffer obj->tx_buff.length - obj->tx_buff.pos); // transfer the remaining bytes only } else if (obj->rx_buff.pos < obj->rx_buff.length) { // DEBUG_PRINTF("r%u ", obj->rx_buff.pos); // we need to receive more data spi_master_start_asynch_transfer(obj, SPI_TRANSFER_TYPE_RX, NULL, // there is no transmit buffer obj->rx_buff.buffer + obj->rx_buff.pos, // offset the initial buffer by the position obj->rx_buff.length - obj->rx_buff.pos); // transfer one byte at a time, until we received everything } else { // everything is ok, nothing else needs to be transferred event = SPI_EVENT_COMPLETE | SPI_EVENT_INTERNAL_TRANSFER_COMPLETE; DEBUG_PRINTF("SPI%u: Done: %u, %u\n", obj->spi.module+1, obj->tx_buff.pos, obj->rx_buff.pos); } } } if (event) DEBUG_PRINTF("SPI%u: Event: 0x%x\n", obj->spi.module+1, event); return (event & (obj->spi.event | SPI_EVENT_INTERNAL_TRANSFER_COMPLETE)); }