2013-07-03 06:27 AM
Dear all I hope you can solve m problem. I need to configure the SPI2 on STM32F100V8 on pin PB12-14 in slave mode because I have a master board that communicates to other spi slaves. The SPI has the Clock normally High and the data of the master changes on falling edge of the clock (so I think the slave stm32 should be setted as CPOL High and CPHA = second edge, rising)
Here some little hardwareMaster CLK -> Slave STM32 CLK
Master MISO <- Slave STM32 MISO (unconnected from Master for debug purposes)Master MOSI -> Slave STM32 MOSIMaster CS -> dedicated line to Slave STM32 NSSIn this project i need to use UART3 but is used in asyncronous mode so this excludes some silicon bugs described in the ''errata''The gpio are congigured as AF_PP, the RCC is enabled for SPI2, and the SPI is initialized in this way:static void SPI2_Init (void){
SPI_InitTypeDef SPI_InitStructure;
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_Mode = SPI_Mode_Slave;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Hard;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_Init(SPI2, &SPI_InitStructure);
SPI_Cmd(SPI2, ENABLE);
}Here the task that is called in a while(1), no watchdog enabled no other tasks enabled for the moment
void task_spi(vpoid){
static unsigned char state;
unsigned char read
case 0:
if(READ_CS_SPI2()==0){
while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE)==RESET);
read = SPI_I2S_ReceiveData(SPI2);
if(read==0x02){
state = read;
read = 0;
}
}
case 2:
while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE)==RESET);
SPI_I2S_SendData(SPI2, 0xFF);
TOGGLE_S4();
state = 99;
break;
case 99:
while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE)==RESET);
SPI_I2S_SendData(SPI2, 0x00);
state = 0;
break;
default:
state = 0;
break;
}
}With this code i have correct receive of the data in the slave stm32 but i have troubles in sending response data. For example if i try to send a reply 0xFF in my oscilloscope I see: 0xFE. If I try to send 0xAA i only see glitches on the MISO line ( at the moment the miso line is disconnected from the master)Hope someone can take me away from troubles. Regards, Ivano
Attached two Stamps of the scope for more clarification...
#spi2-problem-stm32f100v82013-07-03 07:31 AM
This may be nothing to do with your problem. I'm using an STM32F4 When sending SPI data, I wait on TXE and then on BSY.
DataToSend = (0x7000 | (pData->Channel_H << 4));
XDAC1_CS_LOW();
SPI_I2S_SendData(SPI1, DataToSend); //Send 16 bits through the SPI1 peripheral
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET); //wait for TX buffer flag to set
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) == SET); //wait for BSY flag to clear
XDAC1_CS_HIGH();
I found a note from ST, ''During discontinuous communications, there is a 2 APB clock period delay between the write operation to SPI_DR and the BSY bit setting. As a consequence, in transmit-only mode, it is mandatory to wait first until TXE is set and then until BSY is cleared after writing the last data.''
2013-07-03 09:36 AM
Dear Sir John F, thank you for your reply but I'm still in troubles.
Here attached a printscreen and the modified code (as you suggest); from images especially in the one to the right you can see that STM32exits beforehand
from sending all data bits (second execution in case =2 of istruction TOGGLE_S4(), green line). The code:void task_spi(vpoid){
static unsigned char state; unsigned char read switch(state){ case 0: if(READ_CS_SPI2()==0){ while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE)==RESET);while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY)==SET);
read = SPI_I2S_ReceiveData(SPI2); if(read==2){ state = 2; } } break; case 2:TOGGLE_S4();
//FIRST TOGGLE OF GREEN LINE SPI_I2S_SendData(SPI2, 0xAA); while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE)==RESET);while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY)==SET);
TOGGLE_S4();
//SECOND TOGGLE OF GREEN LINE state = 99; break; case 99: SPI_I2S_SendData(SPI2, 0x00); while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE)==RESET);while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY)==SET);
state = 0; break; default: state = 0; break; }}Attached new images
________________ Attachments : 3.jpg : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I0vj&d=%2Fa%2F0X0000000bgG%2FWmwVXp2fODFLkP3x.8nruVVXbwm0cIZlrh5IAH4bnvE&asPdf=false2013-07-03 10:53 PM
2013-07-03 11:19 PM
2013-07-04 04:43 AM
While I wait for an answer I'll try the same code on STM32 discovery board MB963 B but the mcu is different and I don't know if it is a valid test
2013-07-04 05:43 AM
If I have understood your requirements ...
In slave mode, the clock is provided by the external master. Data for transmission must be loaded into the TX buffer before the SPI clock starts (and only if TXE flag is set). If you are responding to received data, your response cannot be sent until the master sends more data. Please have a look at the SPI section in RM0041 ''21.3.2 Configuring the SPI in slave mode'' where the Transmit and Receive sequences are described. Be aware that data already loaded into the TX buffer is transmitted only when the master is sending data you will receive - they happen at the same time - and consider if your task structure is suitable for what you want to do. The write to the DR must occur between SPI clock bursts. It looks like you should be writing new data to the DR with SPI_I2S_SendData() immediately after you have read received data. Straight after RXNE bit is set so it's ready to be sent next time the master clocks the SPI bus. I didn't see an STM32 SPI slave code example. Maybe someone has this working?