Hi,
I am attempting to establish SPI communication between 2 GT16a MCUs, where one is the slave and the other the master. I am able to send data from the master to the slave, but am receiving rubbish when trying to get data sent from the slave to the master. Any idea as to what could be the problem.
// For the Master MCU void laserComm(char Data[]) { if (Data[0] == 'X')PTCD_PTCD6 = 0; //Pull low to select correct slave if (Data[0] == 'Y')PTCD_PTCD5 = 0; //Pull low to select correct slave if (Data[0] == 'Z')PTCD_PTCD4 = 0; //Pull low to select correct slave for(laserCommCount=0; laserCommCount <= dataSize ; laserCommCount++) SPIdataIn[laserCommCount] = SPItransfer(Data[laserCommCount]); PTCD_PTCD6 = 1; // Pull high after data transfer PTCD_PTCD5 = 1; PTCD_PTCD4 = 1; } byte SPItransfer (byte val) { // First send, then receive while(!SPIS_SPTEF); SPID = val; while(!SPIS_SPRF); return SPID; } // For the slave MCU interrupt 15 void receiveSPI (void) { SPIdataIn[SPIReceiveIndex] = SPItransfer(Packet1[SPIReceiveIndex]); if (SPIReceiveIndex == dataSize) { SPIdataReceived = 1; // Indicate the data has been received SPIReceiveIndex = 0; // Reset receive index } else SPIReceiveIndex++; }
all the data is an array of chars.
Thanks!
Hello,
As has already been mentioned, the SPItransfer() function is unsuited to slave use, and particularly so when using an interrupt for the slave process.
// Global variables:
byte SPIdataIn[BUF_SIZE];
byte Packet1[BUF_SIZE];
byte dataSize;
byte SPIdataReceived;
static byte *Recv_buf;
static byte *Send_buf;
static byte byte_count;
...
// Initialise pointers
Recv_buf = SPIdataIn;
Send_buf = Packet1;
byte_count = 0;
SPIdataReceived = 0;
...
interrupt 15
void receiveSPI (void)
{
(void)SPIS; // Part of flag clearing
*Recv_buf++ = SPID; // Receive current byte
SPID = *Send_buf++; // Load next byte to buffer
byte_count++;
if (byte_count == dataSize) {
SPIdataReceived = 1; // Flag data received
byte_count = 0; // Reset counter
}
}
Regards,
Mac
Thanks for the reply.
I just want to confirm that my code for the master to receive is valid, also is shown my modified code for the slave.
// Master
byte SPItransfer (byte val)
{
// First send, then receive
while(!SPIS_SPTEF);
SPID = val;
while(!SPIS_SPRF);
return SPID;
}
/////////////////////////////////////////////////////////////////////////////////////
//Master
void laserComm(char Data[])
{
if (Data[0] == 'X')PTCD_PTCD6 = 0; //Pull low to select correct slave
if (Data[0] == 'Y')PTCD_PTCD5 = 0; //Pull low to select correct slave
if (Data[0] == 'Z')PTCD_PTCD4 = 0; //Pull low to select correct slave
for(laserCommCount=0; laserCommCount <= dataSize ; laserCommCount++)
SPIdataIn[laserCommCount] = SPItransfer(Data[laserCommCount]);
PTCD_PTCD6 = 1; // Pull high after data transfer
PTCD_PTCD5 = 1;
PTCD_PTCD4 = 1;
}
/////////////////////////////////////////////////////////////////////////////////////
//Slave receive function
interrupt 15 // SPI receive interrupt
void receiveSPI (void)
{
(void)SPIS; // Clear flags
SPIdataIn[SPIReceiveIndex] = SPID; // Receive byte
SPID = Packet1[SPIReceiveIndex]; // Load byte to send
if (SPIReceiveIndex == dataSize)
{
SPIdataReceived = 1; // Indicate the data has been received
SPIReceiveIndex = 0; // Reset receive index
}
else SPIReceiveIndex++;
}
Also I still don't seem to be receiving the data I expect. Are there any timing considerations?
In the slave code, I would have checked the SPRF and read the data, followed by stuffing of byte to be sent... something like this