2016-07-08 11:03 PM
I am working on establishing SPI communication between STM32F407ZET6 and NRF52832 chipsets.
Currently, I am configuring STM32F407ZET6 is the slave as I need to send the data continuously from NRF52832.I found code in github for configuring STM32F407xx as master, not as slave.https://github.com/g4lvanix/STM32F4-examples/blob/master/SPI/main.cThe main function in this example continuously sends SPI data. In the same way, if you could show me how I can configure SPI slave and also continuously check for arrived data, it will be great. I am going to use polling method.I know there is example code in spi standard peripheral drivers from ST that use interrupt method, but I am looking for polling method, that continuously check for arrived data.Rgds,2016-07-09 06:54 AM
uint8_t GetSPIByte(void)
{
/*!< Wait to receive a byte */
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
/*!< Return the byte read from the SPI bus */
return SPI_I2S_ReceiveData(SPI1);
}
2016-07-09 04:30 PM
Hello Clive1,
Thanks for the reply. Please correct me if I am wrong. You did not include the slave configuration. Please look into the configuration and also corresponding main function that I am writing for SPI slave: // this function initializes the SPI1 peripheral void init_SPI1(void){ GPIO_InitTypeDef GPIO_InitStruct; SPI_InitTypeDef SPI_InitStruct; // enable clock for used IO pins RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); /* configure pins used by SPI1 * PA5 = SCK * PA6 = MISO * PA7 = MOSI */ GPIO_InitStruct.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_6 | GPIO_Pin_5; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOA, &GPIO_InitStruct); // connect SPI1 pins to SPI alternate function GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_SPI1); GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_SPI1); GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_SPI1); // enable clock for used IO pins RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE); /* Configure the chip select pin in this case we will use PE7 */ GPIO_InitStruct.GPIO_Pin = GPIO_Pin_7; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOE, &GPIO_InitStruct); GPIOE->BSRRL |= GPIO_Pin_7; // set PE7 high // enable peripheral clock RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); /* configure SPI1 in Mode 0 * CPOL = 0 --> clock is low when idle * CPHA = 0 --> data is sampled at the first edge */ SPI_InitStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex; // set to full duplex mode, seperate MOSI and MISO lines SPI_InitStruct.SPI_Mode = SPI_Mode_Slave; // slave mode. SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b; // one packet of data is 8 bits wide SPI_InitStruct.SPI_CPOL = SPI_CPOL_Low; // clock is low when idle SPI_InitStruct.SPI_CPHA = SPI_CPHA_1Edge; // data sampled at first edge SPI_InitStruct.SPI_NSS = SPI_NSS_Soft | SPI_NSSInternalSoft_Set; // set the NSS management to internal and pull internal NSS high SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB;// data is transmitted MSB first SPI_Init(SPI1, &SPI_InitStruct); SPI_Cmd(SPI1, ENABLE); // enable SPI1 } int main(void){ uint8_t received_val = 0; init_SPI1(); while(1){ received_val = GetSPIByte(); // receive data } } In the above code, PA5,PA6,PA7 are configured as sck, miso, mosi. PE7 as chip select. These pins are same as used in the master code that was there in the link I sent. I changed SPI_InitStruct.SPI_Mode = SPI_Mode_Master; to SPI_InitStruct.SPI_Mode = SPI_Mode_Slave; and commented out the line: SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4; I am thinking slave need not give the frequency to the master, which is why I commented out the line that give frequency. In the main function while loop, I am continuously checking for received data, should I give some delay here? Thanks, From: clive1 Posted: Saturday, July 09, 2016 3:54 PM Subject: STM32F407xx SPI Slave usage - Polling method. uint8_t GetSPIByte(void) { /*!< Wait to receive a byte */ while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET); /*!< Return the byte read from the SPI bus */ return SPI_I2S_ReceiveData(SPI1); } From: ch.pradeep Posted: Saturday, July 09, 2016 8:03 AM Subject: STM32F407xx SPI Slave usage - Polling method. I am working on establishing SPI communication between STM32F407ZET6 and NRF52832 chipsets. Currently, I am configuring STM32F407ZET6 is the slave as I need to send the data continuously from NRF52832. I found code in github for configuring STM32F407xx as master, not as slave. https://github.com/g4lvanix/STM32F4-examples/blob/master/SPI/main.c The main function in this example continuously sends SPI data. In the same way, if you could show me how I can configure SPI slave and also continuously check for arrived data, it will be great. I am going to use polling method. I know there is example code in spi standard peripheral drivers from ST that use interrupt method, but I am looking for polling method, that continuously check for arrived data. Rgds,2016-07-10 06:33 AM
The initialization for a Polling Slave should be nearly identical to that of an IRQ Slave.
I don't have any hardware set up to evaluate this, but there should be several slave examples within the SPL for EVAL or DISCO boards.2016-08-08 05:56 AM
Hello Clive1,
I am using the below SPI Slave configuration, Please look into it:void init_SPI1(void){ GPIO_InitTypeDef GPIO_InitStruct; SPI_InitTypeDef SPI_InitStruct; // enable clock for used IO pins RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); /* configure pins used by SPI1 * PA5 = SCK * PA6 = MISO * PA7 = MOSI */ GPIO_InitStruct.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_6 | GPIO_Pin_5; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOA, &GPIO_InitStruct); // connect SPI1 pins to SPI alternate function GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_SPI1); GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_SPI1); GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_SPI1); // enable clock for used IO pins //RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE); COMMENT THIS LINE AS PORTE IS NOT NEEDED NOW /* Configure the chip select pin in this case we will use PA4 */ GPIO_InitStruct.GPIO_Pin = GPIO_Pin_4; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN; GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOA, &GPIO_InitStruct); // enable peripheral clock RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); // 84 Mhz /* configure SPI1 in Mode 0 * CPOL = 0 --> clock is low when idle * CPHA = 0 --> data is sampled at the first edge */ SPI_InitStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex; // set to full duplex mode, seperate MOSI and MISO lines SPI_InitStruct.SPI_Mode = SPI_Mode_Slave; // transmit in slave mode, NSS pin has to be always high SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b; // one packet of data is 8 bits wide SPI_InitStruct.SPI_CPOL = SPI_CPOL_Low; // clock is low when idle SPI_InitStruct.SPI_CPHA = SPI_CPHA_1Edge; // data sampled at first edge SPI_InitStruct.SPI_NSS = SPI_NSS_Soft | SPI_NSSInternalSoft_Set; // set the NSS management to internal and pull internal NSS high SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB;// data is transmitted MSB first SPI_Init(SPI1, &SPI_InitStruct); SPI_Cmd(SPI1, ENABLE); // enable SPI1}uint8_t GetSPI1Byte(void){ /*!< Wait to receive a byte */ // while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET); /*!< Return the byte read from the SPI bus */ return SPI_I2S_ReceiveData(SPI1);}My main function is:void main(){ init_SPI1(); uint8_t rcd_data = 0; while (1) { if(!(GPIOA->IDR & 0x0010)) { rcd_data = GetSPI1Byte(); printf(''Data Received: %x\r\n'',rcd_data); } } // end of while loop }As I said, I am trying to establish SPI communication between NRF52832 and STM32F407ZET6. I am able to see the clock and Chip select signals on the Oscilloscope from NRF chip. I checked that data is also sent from NRF chip. On slave side, the chipselect is going low, but a NULL(0x00) data is received all the time.I configured Chip select as Input on Slave side. I am reading the Chipselect signal going low, and printing that value (NULL).Can you please check my configuration and my main() code as well.?Thanks,Pradeep Ch.2016-08-08 09:21 AM
Can you please check my configuration and my main() code as well?
I can only offer you a quick static analysis. Code looks to be reasonable. Make sure the data from the Master (it's Output) goes the the PA7 (the Slave's Input). The cross-check would be to pull PA7 high and low and confirm 0xFF and 0x00 are observed.