OK, I'll try to explain better.
This is the code for the master:
In main.cpp:
void main(void) {
MCU_init(); /* call Device Initialization */
asm SEI;
Delay();
while (!SPI1S_SPTEF); // wait until transmit buffer is empty
PTED_PTED2 = 0; //Slave Select set in low
SPI1D = 0x12; // Transmit byte
PTDD_PTDD1 = 1; // Turn on LED to indicate a byte has been sent
Delay();
PTDD_PTDD1 = 0; //Turn off LED
Delay();
asm CLI;
for(;
{
}
From here, the master will wait for a response from the slave to send the second byte, and so on. This will happen in the ISR for the spi in the MCUinit.c function of the master:
__interrupt void isrVspi1(void)
{
asm SEI;
SPI1S; // Acknowledge flag
dato = SPI1D; // Acknowledge flag
if(dato==0xB3){ //0xB3 is the ACK byte sent by the slave when it receives a valid byte from the master
switch(val){ // val is initialized as 'two' to send the second byte when it enters this routine for the first time, since the first one was already sent from the main() function
case one: {
PTDD_PTDD3 = 1; // Turn on LED to indicate a byte has been received
Delay();
PTDD_PTDD3 = 0;
Delay();
while (!SPI1S_SPTEF); // wait until transmit buffer is empty
PTED_PTED2 = 0; //Slave Select set in low
SPI1D = 0x12; // Transmit byte
PTDD_PTDD1 = 1; // Turn on LED to indicate a byte has been sent
Delay();
PTDD_PTDD1 = 0;
Delay();
val = two; // Change the value of 'val' so it'll send the next byte on the next time
break;
}
case two: {
PTDD_PTDD3 = 1;
Delay();
PTDD_PTDD3 = 0;
Delay();
while (!SPI1S_SPTEF); // wait until transmit buffer is empty
PTED_PTED2 = 0; //Slave Select set in low
SPI1D = 0x83; // Transmit byte
PTDD_PTDD1 = 1;
Delay();
PTDD_PTDD1 = 0;
Delay();
val = three;
break;
}
case three: {
PTDD_PTDD3 = 1;
Delay();
PTDD_PTDD3 = 0;
Delay();
while (!SPI1S_SPTEF); // wait until transmit buffer is empty
PTED_PTED2 = 0; //Slave Select set in low
SPI1D = 0x4A; // Transmit byte
PTDD_PTDD1 = 1;
Delay();
PTDD_PTDD1 = 0;
Delay();
val = four;
break;
}
case four: {
PTDD_PTDD3 = 1;
Delay();
PTDD_PTDD3 = 0;
Delay();
while (!SPI1S_SPTEF); // wait until transmit buffer is empty
PTED_PTED2 = 0; //Slave Select set in low
SPI1D = 0x09; // Transmit byte
PTDD_PTDD1 = 1;
Delay();
PTDD_PTDD1 = 0;
Delay();
val = one;
break;
}
}
}
asm CLI;
}
This routine sends 4 different bytes consecutively to the receiver, one for each ACK received from the slave.
The code for the slave is as follows:
In the main.cpp it just waits and does nothing, so: for(;
.
In the MCUinit.c:
__interrupt void isrVspi1(void)
{
asm SEI;
SPI1S; /*Acknowledge flag*/
glob = SPI1D; /*Acknowledge flag*/
switch(glob){
case 0x12: {
PTAD_PTAD4 = 0;
PTAD_PTAD5 = 0;
PTAD_PTAD6 = 0;
PTAD_PTAD7 = 0; // Turn off all LEDs
PTAD_PTAD7 = 1; // Turn on the LED that corresponds to the byte received
while (!SPI1S_SPTEF); // wait until transmit buffer is empty
SPI1D = 0xB3; // Transmit byte
Delay();
break;
}
case 0x83: {
PTAD_PTAD4 = 0;
PTAD_PTAD5 = 0;
PTAD_PTAD6 = 0;
PTAD_PTAD7 = 0;
PTAD_PTAD6 = 1;
while (!SPI1S_SPTEF); // wait until transmit buffer is empty
SPI1D = 0xB3; // Transmit byte
Delay();
break;
}
case 0x4A:{
PTAD_PTAD4 = 0;
PTAD_PTAD5 = 0;
PTAD_PTAD6 = 0;
PTAD_PTAD7 = 0;
PTAD_PTAD5 = 1;
while (!SPI1S_SPTEF); // wait until transmit buffer is empty
SPI1D = 0xB3; // Transmit byte
Delay();
break;
}
case 0x09: {
PTAD_PTAD4 = 0;
PTAD_PTAD5 = 0;
PTAD_PTAD6 = 0;
PTAD_PTAD7 = 0;
PTAD_PTAD4 = 1;
while (!SPI1S_SPTEF); // wait until transmit buffer is empty
SPI1D = 0xB3; // Transmit byte
Delay();
break;
}
default: {
PTAD_PTAD4 = 1;
PTAD_PTAD5 = 1;
PTAD_PTAD6 = 1;
PTAD_PTAD7 = 1; // If the byte is different from the four the master is supposed to send, turn on all LEDs to indicate an error in receiving a byte from the master
while (!SPI1S_SPTEF); // wait until transmit buffer is empty
SPI1D = 0xB3; // Transmit byte
Delay();
break;
}
}
asm CLI;
}
Here, the slave will wait for a byte from the master, and when it receives it, it'll turn on a LED to show which byte was received. When it does this, it sends back the ACK byte so that the master sends the next byte and the cycle can continue.
Also, the code for the Delay() function is as follows:
void Delay(void){
unsigned int b;
unsigned char a;
for(a=0;a<0x02;a++)
{
for(b=0;b<0xFFFF;b++)
{
;
}
}
}
I've tried to change the values of this function to modify the time of delay, but it has no effect in the freezing.
I hope it's as clear to you as it is to me. I have no idea where it could be failing; it seems pretty easy to me, no big deal. But still is not working properly. I've made some modifications to this code, changing the number of LEDs (that is, the number of bytes) that are handled, but it ALWAYS happens the same: the master transmits 16 correct data bytes (because the LEDs on the slave turn on in the correct order) and the slave transmits 16 correct ACK bytes (because the receiver LED on the master turns on after the slave's LEDs are turned on). Then, nothing happens. The receiver LED doesn't turn on the 17th time, so it could be one of these events that happen:
-The slave received correctly the 16th byte but failed to send the 16th ACK byte.
-the slave sent correctly the 16th ACK byte but the master failed to receive it.
Since the master's receiver LED never turned on, it remains waiting so it won't send a next byte to the slave. As a consecuence of this, the receiver will also remain waiting; so nothing happens on either side. The odd thing is that after a while (say maybe a minute or two) the system starts back again as if nothing happened. Weird, huh?
Oh, by the way, I've checked the watchdog and it's disabled; so it's not that...
Pleeeaaase someone help me ASAP; I'm in trouble if I can't solve this.
Thanx