Hi everybody,
Im working with a K22 and a M25P16 flash memory.
Im using the following function to communicate by SPI:
"void fnSPI_command(uint8_t ucCommand, uint32_t ulPageNumberOffset, volatile uint8_t *ucData, uint32_t DataLength)"
So far, i can read the manufacturer register and also the status register succsessfully.
When i try to write data, i see how the SPI signals MOSI, SCK ad CS are OK
But when i try to red the data:
1- If i try to read 1 byte, i can't see anything at MISO and the code gets stuck at the first red code line.
2- If i try to read at least 2 bytes, i can see 2 bytes at MISO but the code gets sutck at the second red code line
case READ_DATA_BYTES: // read data from the chip
WRITE_SPI1_CMD0(ucCommand);
Delay();
WRITE_SPI1_CMD0((uint8_t)(ulPageNumberOffset >> 16));
Delay();
WRITE_SPI1_CMD0((uint8_t)(ulPageNumberOffset >> 8));
Delay();
WRITE_SPI1_CMD0((uint8_t)ulPageNumberOffset);
Delay();
ucTxCount = 4;
SPI_FLASH_Danger = 1; // mark that the chip will be busy for some time
break;
if (ucTxCount != 0) { //Read, with preamble writes?
if ((ucTxCount == 1) && (DataLength > 1))
WRITE_SPI1_CMD0(0xFF); //We have to come out of here with two xmit cmds in FIFO, if at least 2 RX are coming
//That's to make sure the TX FIFO keeps fully ahead of RX bytes and doesn't stall
while (ucTxCount != 0) { // while command bytes are going out
if ((ucTxCount == 2) && (DataLength > 1)) // before TX FIFO goes empty, put in 2 if we can!
WRITE_SPI1_CMD0(0xFF); // toss the associated RX bytes
if (ucTxCount == 1) // before TX FIFO goes empty, put in another
if (DataLength == 1) //Will this TX go with the last RX?
WRITE_SPI1_CMD0_LAST(0xFF);
else
WRITE_SPI1_CMD0(0xFF);
// toss the associated RX bytes
while( !(SPI1_SR & SPI_SR_RFDF_MASK) ) {} IF I TRY TO READ A BYTE
(void) READ_SPI1_DATA();//*(volatile uint8_t *)(DSPI0_BLOCK + 0x38); // SPI0 POP RX FIFO Register (read-only);
SPI1_SR |= SPI_SR_RFDF_MASK;
ucTxCount--;
do{
while( !(SPI1_SR & SPI_SR_RFDF_MASK) ) {} IF I TRY TO READ MORE THAN 2 BYTES
*ucData++ = READ_SPI1_DATA();
SPI1_SR |= SPI_SR_RFDF_MASK;
DataLength--;
if (DataLength == 2) //Will this TX go with the last RX?
WRITE_SPI1_CMD0_LAST(0xFF);
else
if (DataLength > 2)
WRITE_SPI1_CMD0(0xFF); // Make an associated TX byte
} while (DataLength != 0);
By the way, if i chage the value of ucTxCount = 1;//4; i receive data on MISO, i can't read it back from the function though. I get u8prueba = 0
fnSPI_command(READ_DATA_BYTES, 0x80001, &u8prueba, sizeof(u8prueba));
Any help will bw apreciated.
Thanks and best regards.
This code was optimized for very fast access (CPU clock /4) of Dword multiples ONLY.
and even THEN it doesn't quite 'keep up'; there are interbyte gaps. It is HARD to loop a byte every 320ns (32 instruction cycles). Note though that my original code did NOT have the Delay() functions between the initial byte-writes, so I think we can assume that those initial 40ns extra-clock gaps are driven by hardware, as the TX FIFO was surely 'well filled' for at least the first 4 bytes.
BUT still it does allow me to do a full 32bit CRC on a 512Kbyte potential-code-image in under 200ms.
You can restore to the original code from uTasker.