cancel
Showing results for 
Search instead for 
Did you mean: 

SPI Status Flags Don't Update

spencerashiveley
Associate II
Posted on August 09, 2015 at 20:09

I'm sitting here pulling my hair out because I can't figure out what's going on, I've tried everything I can think of. I'm using SPI to communicate with an offboard periph, When I write to the data register the TXE flag doesn't go low. Here's my code I'm hoping someone can give me some insight that the Reference Manual isn't. The manual says there are 2 APB2 cycles before busy goes high and that I must wait on TXE. I've tried this to no avail.

void Nokia5110_Init(void)
{
volatile unsigned long delay;
volatile unsigned long tempReg=0;
SPI_InitTypeDef SPI_InitDef;
GPIO_InitTypeDef GPIO_InitDef;
//Initialization of gpio port A for SPI
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
GPIO_InitDef.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitDef.GPIO_Mode = GPIO_Mode_AF; //using alternative function
GPIO_InitDef.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitDef.GPIO_OType = GPIO_OType_PP;
GPIO_InitDef.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_SPI1); //set PA5 to SPI1_Sclk
GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_SPI1); //set PA6 to MISO (won't be used though, data only flows to Nokia5110)
GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_SPI1); //set PA7 to MOSI
GPIO_Init(GPIOA, &GPIO_InitDef);

//Initiazation of gpio port C PC4 -> used for Data/Command (D/C) to Nokia 5110
//Data: PC4 is high
//Command: PC4 is low
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
GPIO_InitDef.GPIO_Pin = GPIO_Pin_2| GPIO_Pin_4 | GPIO_Pin_5; //Pin 2 is Reset, Pin 4 is D/C, Pin 5 is CS
GPIO_InitDef.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitDef.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitDef.GPIO_OType = GPIO_OType_PP;
GPIO_InitDef.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_Init(GPIOC,&GPIO_InitDef);
//Initialization of SPI1
/*
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); //enable clock for SPI1
SPI_I2S_DeInit(SPI1);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); //enable clock for SPI1
SPI_InitDef.SPI_Direction = SPI_Direction_1Line_Tx;//only using Tx
SPI_InitDef.SPI_Mode = SPI_Mode_Master;//STM32f4 is master
SPI_InitDef.SPI_DataSize = SPI_DataSize_8b;
SPI_InitDef.SPI_CPOL = SPI_CPOL_Low; //Sclk is low in between transmissions
SPI_InitDef.SPI_CPHA = SPI_CPHA_1Edge;//clock data in on rising edge
SPI_InitDef.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32;// clk frequency = APB2/32 = 84MHz/32 = 2.625MHz
SPI_InitDef.SPI_FirstBit = SPI_FirstBit_LSB; //data is transmitted LSB first
SPI_InitDef.SPI_NSS = SPI_NSS_Soft;
SPI_Init(SPI1, &SPI_InitDef);//initialize spi1
SPI_Cmd(SPI1, ENABLE);//enable spi1
*/
//SPI1 HardCode Initialization
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); //enable clock for SPI1
tempReg |= (BRR | CPOL | PHASE | FRAME_LENGTH
| LSB_FIRST | NSS_SOFT | MSTER_MODE | BIDIR
| BIDIR_MODE);
SPI1_CR1 = 0;
SPI1_CR2 = 0; 
SPI1_CR1 |= tempReg;
SPI1_CR2 |= SS_OUT_EN;
SPI1_CR1 |= (SPI_EN | (0x1<<8)); //enable SPI, SET SS high
// initialize Nokia5110
GPIO_ResetBits(GPIOC, GPIO_Pin_2); //reset Nokia5110
delay = 50;
while(delay!=0)
{
delay--;
}
GPIO_SetBits(GPIOC, GPIO_Pin_2);
lcdwrite(COMMAND, 0x21);
lcdwrite(COMMAND, CONTRAST); // try 0xB1 (for 3.3V red SparkFun), 0xB8 (for 3.3V blue SparkFun), 0xBF if your display is too dark, or 0x80 to 0xFF if experimenting
lcdwrite(COMMAND, 0x04); // set temp coefficient
lcdwrite(COMMAND, 0x14); // LCD bias mode 1:48: try 0x13 or 0x14
lcdwrite(COMMAND, 0x20); // we must send 0x20 before modifying the display control mode
lcdwrite(COMMAND, 0x0C); // set display control to normal mode: 0x0D for inverse
}

I've tried using SPI 2 instead of SPI 1, I've tried manipulating the registers myself thinking something might be wrong with the ST library. Nothing seems to work. Below is my transmission code.

void static lcdwrite(enum typeOfWrite type, char message){ 
//SPI isn't quite working yet, TXE flag never goes low and Busy flag never sseems to go high.
if(type == COMMAND){
while ((SPI1_SR & SPI1_BUSY) == 0x80 ) //Check for busy flag
{}
while( !(SPI1_SR & SPI_I2S_FLAG_TXE) ) // wait until SPI not busy/transmit FIFO empty
{}
GPIO_ResetBits(GPIOC, GPIO_Pin_4|GPIO_Pin_5); //Pull slave select low
SPI1_DR = message; // command out // wait until SSI0 not busy/transmit FIFO empty
while( !(SPI1_SR & SPI_FLAG_TXE) ){} //wait for TXE to go high
while( (SPI1_SR & SPI_I2S_FLAG_BSY) ) //wait for SPI to not be busy
{}
GPIOC->ODR |= (0x1<<
5
); //Pull slave select high
} else{
while( !(SPI1_SR&SPI_I2S_FLAG_TXE) ) // wait until transmit FIFO not full
{}
GPIO_ResetBits(GPIOC,GPIO_Pin_5); //Pull slave select low
GPIO_SetBits(GPIOC, GPIO_Pin_4);
SPI1_DR = (unsigned long) message; // command out 
while( !(SPI1_SR&SPI_FLAG_TXE) ){} //wait for TXE flag to go high
while( (SPI1_SR&SPI_I2S_FLAG_BSY) ) //wait for SPI to not be busy
{}
GPIOC->ODR |= (0x1<<5); //Pull Slave Select high
}
}

Any help would be greatly appreciated. I can't find any posts regarding the same problem. Thank you in advance. #stm32f4 #error #!stm32f4-disco #spi #discovery
1 REPLY 1
spencerashiveley
Associate II
Posted on August 11, 2015 at 18:52

I'm thinking that my problem is that the shift out register isn't stepped through in debugging mode. So when I step through my code, I load the data into the shift register and by the time I step to the next statement, the data has already been shifted out and as a consequence, the flags have already been set and reset by hardware and that's why i'm not seeing them.