Hi Dor,
This is for AT91SAM7X512.
Take note how we handle the write.
Spi_Write()
1) Wait until the TX register is empty (make sure there isn't data waiting to go out)
2) Perform dummy read of RX register (makes sure Bit0 is clear)
3) Send the data to the TX register
4) Wait until a byte is RX'd (if we recieved a byte the TX is complete)
5) Read the RX register and return the value
I believe this is different than the way you write bytes.
Quote:
Code:
const short int dataSize = 5;
// Filling array with random data
unsigned char data[dataSize] = {0xA5, 0x34, 0x12, 0x00, 0xFF};
short int i = 0;
volatile unsigned short dummyRead;
SetCS3(); // NPCS3 == PIOA15
while(i-- < dataSize) {
mySPI_Write(data[i]);
while((AT91C_BASE_SPI0->SPI_SR & AT91C_SPI_TXEMPTY) == 0);
dummyRead = SPI_Read(); // SPI_Read() from Atmel's library
}
ClearCS3();
/**********************************/
void mySPI_Write(unsigned char data) {
while ((AT91C_BASE_SPI0->SPI_SR & AT91C_SPI_TXEMPTY) == 0);
AT91C_BASE_SPI0->SPI_TDR = data;
while ((AT91C_BASE_SPI0->SPI_SR & AT91C_SPI_TDRE) == 0); // <-- This is
// where the processor hangs, because that the SPI peripheral is disabled
// (SPIENS equals 0), which makes TDRE equal to 0 forever.
}
Try Changing this to:
Code:
// snip...
SetCS3(); // NPCS3 == PIOA15
while(i-- < dataSize) {
mySPI_Write(data[i]);
dummyRead = AT91C_BASE_SPI0->SPI_RDR;
}
ClearCS3();
/**********************************/
void mySPI_Write(unsigned char data) {
volatile unsigned int dummy;
while ((AT91C_BASE_SPI0->SPI_SR & AT91C_SPI_TXEMPTY) == 0);
dummy = AT91C_BASE_SPI0->SPI_RDR;
AT91C_BASE_SPI0->SPI_TDR = data;
while ((AT91C_BASE_SPI0->SPI_SR & AT91C_SPI_TDRE) == 0);
}
Or you could condense by returning the recieved byte from the write.
Then you could recieve data simply by "rxData = mySPI_Write(0)"
Code:
// snip...
SetCS3(); // NPCS3 == PIOA15
while(i-- < dataSize) {
(void)mySPI_Write(data[i]);
}
ClearCS3();
/**********************************/
unsigned char mySPI_Write(unsigned char data) {
unsigned char dummy;
// Make sure txer is empty
while ((AT91C_BASE_SPI0->SPI_SR & AT91C_SPI_TXEMPTY) == 0);
// clear the rx flag by performing a dummy read
dummy = AT91C_BASE_SPI0->SPI_RDR;
// send the data
AT91C_BASE_SPI0->SPI_TDR = data;
// wait for reception
while ((AT91C_BASE_SPI0->SPI_SR & AT91C_SPI_TDRE) == 0);
// return the recieved data
dummy = AT91C_BASE_SPI0->SPI_RDR;
return dummy;
}