I'm running a FRAM as a slave on the SPI bus (BSPI1). I got a problem when reading from the bus or more precisely the receive buffer. The data is perfectly clocked out of the FRAM, but when reading the receive buffer I get a wrong value (0x00). When I dump the memory at 0xC000B000 (BSPI1) the correct value is in the buffer. When single stepping through the read routine, it works perfectly. I've tried to use both the ReceiveFifoNotEmpty and ReceiveFifoFull flag, but this does not help. Below is my code. I hope someone can help... Main routine: _________________________________________ GPIO_Config (GPIO0, 0x0010, GPIO_AF_PP); GPIO_Config (GPIO0, 0x0020, GPIO_AF_PP); GPIO_Config (GPIO0, 0x0040, GPIO_AF_PP); BSPI_Init ( BSPI1 ); // Initialize BSPI1 BSPI_ClockDividerConfig ( BSPI1,8); // Configure Baud rate Frequency :-->APB1/8 BSPI_Enable ( BSPI1 , ENABLE ); // Enable BSPI1 BSPI_MasterEnable ( BSPI1,ENABLE ); // Configure BSPI1 as Master BSPI_ClkActiveHigh(BSPI1,DISABLE); // Configure the clock to be active low BSPI_ClkFEdge(BSPI1,DISABLE); // Disable capturing the first Data sample on the first edge of SCK BSPI_8bLEn(BSPI1,ENABLE); // Set the word length to 8 bit FRAM_StatusReg=framReadStatusReg(); Read Status Register Routine: _________________________________________ u8 framReadStatusReg() { u8 dummy; Latch1_BitWrite(LATCH_CS_FR,0); // Select device while(BSPI1->CSR2&BSPI_RFNE) dummy = BSPI1->RXR; // Clear the RX Fifo. while(!(BSPI1->CSR2&BSPI_TFE)); // Wait until the Transmit FIFO is empty BSPI1->TXR = RDSR< while(!(BSPI1->CSR2&BSPI_TFE)); // Wait until the Transmit FIFO is empty while(BSPI1->CSR2&BSPI_RFNE) dummy = BSPI1->RXR; // Clear the RX Fifo. BSPI1->TXR = 0; // dummy write to generate a read clock while(!(BSPI1->CSR2&BSPI_RFF)); // Wait until data is received in FIFO (FIFO full) dummy = (BSPI1->RXR) >>8; // Read the received data Latch1_BitWrite(LATCH_CS_FR,1); // Deselect device return dummy; }
I cannot give you the whole schematic. But we use a FM25Cl64 from Ramtron and the wiring is as this: FM25CL64.SI -> STR710.S1.MOSI FM25CL64.SO -> STR710.S1.MISO FM25CL64.SCK -> STR710.S1.SCLK FM25CL64.!CS -> Latch on EMI FM25CL64.!Hold -> STR710.!RSTIN FM25CL64.!WP -> STR710.!RSTIN
Could you please replace your function framReadStatusReg() by this function:
u8 framReadStatusReg() { u8 dummy; u16 TempValue; Latch1_BitWrite(LATCH_CS_FR,0); // Select device while(BSPI1->CSR2&BSPI_RFNE) dummy = BSPI1->RXR; // Clear the RX Fifo. while(!(BSPI1->CSR2&BSPI_TFE)); // Wait until the Transmit FIFO is empty BSPI1->TXR = RDSR<while(!(BSPI1->CSR2&BSPI_TFE)); // Wait until the Transmit FIFO is empty while(BSPI1->CSR2&BSPI_RFNE) dummy = BSPI1->RXR; // Clear the RX Fifo. BSPI1->TXR = 0xAA; // dummy write to generate a read clock while(!(BSPI1->CSR2&BSPI_RFF)); // Wait until data is received in FIFO (FIFO full) TempValue = BSPI1->RXR; dummy = (TempValue ) >>8; // Read the received data Latch1_BitWrite(LATCH_CS_FR,1); // Deselect device return dummy; } please compile, run it and check the TempValue and dummy value
I've compiled and run the code. Both the TempValue and Dummy value is still 0x00.
It's strange because the correct value is shown at memory adress 0xC000B000 (BSPI1) when i make a break after the function has been executed. Somehow the receive buffer is read too early...
I think that we must Deselect device (!CS high) before write value from the STR7(see datasheet) that's why i suggest to try this example: u8 framReadStatusReg() { u8 dummy; u16 TempValue; Latch1_BitWrite(LATCH_CS_FR,0); // Select device while(BSPI1->CSR2&BSPI_RFNE) dummy = BSPI1->RXR; // Clear the RX Fifo. while(!(BSPI1->CSR2&BSPI_TFE)); // Wait until the Transmit FIFO is empty BSPI1->TXR = RDSR<while(!(BSPI1->CSR2&BSPI_TFE)); // Wait until the Transmit FIFO is empty while(BSPI1->CSR2&BSPI_RFNE) dummy = BSPI1->RXR; // Clear the RX Fifo. BSPI1->TXR = 0xAA; // dummy write to generate a read clock while(!(BSPI1->CSR2&BSPI_RFF)); // Wait until data is received in FIFO (FIFO full) Latch1_BitWrite(LATCH_CS_FR,1); // Deselect device TempValue = BSPI1->RXR; dummy = (TempValue ) >>8; // Read the received data return dummy; }
This problem may be related to one we are having with the SPI system, where if we try to read the Rx FIFO too fast we get bogus data.
Try waiting 8-10 clocks (count to 4 in tight loop for example) between the FIFO full flag being set and reading RXR. If the read out value is then correct, congratulations, you have the same problem we do. We have no idea why it happens. -Ben Edwards, Schneider Electric Raleigh[addsig]