HCS12 SPI

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

HCS12 SPI

6,468 Views
prog_ram
Contributor III
Hi,
I want to connect two HCS12 MCU's using the SPI communication.
one of them is the MASTER and the other is the SLAVE.
the SS pin for the MASTER is always pulled up and the SLAVE's is always pulled down.
I am using general I/O pin to inform the slave that the communication has been initiated, the slave will wait till the 8 pulses arrived and then read the SPI0DR register.
for both cases (master and slave), the SPI0DR register (data register) is always 0, meaning, it doesn't accept the data that is written to it although the SPETF flag (data register empty flag) is set when I write something to it.
here is some my line for both the master and the slave, and I appriciate any help, thank you.
SLAVE:
1. wait till the MASTER initiate the communication.
2. wait till the communication is done.
3. read the data register.
4. send the some data to the master.
void main()
{
if (!(PTP.b.b7)) // step 1.
{
while(!(SPI0SR.byte & SPIF));  // wait until a byte has been shifted in // sept 2.
test1=SPI0SR.byte;               // clear the SPIF flag
test1=SPI0DR;
if (test1==1)                          // if one received, then send 222 (some test value).
{while(!(SPI0SR.byte&SPTEF)); // wait till the transmit register is empty.
SPI0DR=222;
while(!(SPI0SR.byte & SPIF)); // wait till the communication is over. and repeat step 4.
test1=SPI0SR.byte;
test1=SPI0DR;
while(!(SPI0SR.byte & SPTEF));// wait till the transmit register is empty.
SPI0DR=111;
while(!(SPI0SR.byte & SPIF));
test1=SPI0SR.byte;
test1=SPI0DR;
while(!(SPI0SR.byte & SPTEF));// wait till the transmit register is empty.
SPI0DR=123;
while(!(SPI0SR.byte & SPIF));
test1=SPI0SR.byte;
test1=SPI0DR;
}
}
}
for the MASTER:
 
void putchar_spi0 (char cx)
{  char temp;
    while(!(SPI0SR.byte & SPTEF)); /* wait until write is permissible */
    SPI0DR  = cx;              /* output the byte to the SPI */
   while(!(SPI0SR.byte & SPIF));  /* wait until write operation is complete */
  temp=SPI0DR;  // clear the spif flag.
 
char getchar_spi0(void)
{
  unsigned int te;
    while(!(SPI0SR.byte & SPTEF)); /* wait until write is permissible */
    SPI0DR = 0x00; /* trigger 8 SCK pulses to shift in data */
    while(!(SPI0SR.byte & SPIF));  /* wait until a byte has been shifted in */
  te=SPI0DR;  // clear the spif flag.
  return te; /* return the character */
 
void main()
{
PORTA.b.b0=0; // 1. pull down the general i/o pin to inform the slave of the beginning of the transmission.
putchar_spi0(1); // send the data one byte (test value 1).
time[0]=getchar_spi0();  // receive 3 bytes.
time[1]=getchar_spi0();
time[2]=getchar_spi0();
PORTA.b.b0=1;      // pull up the i/o pin to end the transmission.
}
Labels (1)
0 Kudos
8 Replies

708 Views
Alban
Senior Contributor II
Hello,
 
I disagree slightly with the slave.
You need to read in step 4 to make sure the register doesn't already have something in it, ok.
But step 5 is receive from Master in the meantime as send from slave to Master.
This is a shift register in only one operation.
 
Cheers,
Alban
0 Kudos

708 Views
prog_ram
Contributor III
thanks Alban, for the reply,
Actually, I didn't get what you mean.. could you please explain more?
here is what is in my mind, (please correct me if something is wrong).
Since the SPI0DR register is for both reading and writing, it's the protocol that decides what is the current operation (read/write).
the slave job is just to monitor its SPIF flag, whenever it's set, means something has been shifted in/out.
however, in case the Slave is sending, it should be informed that the master is about to trigger the 8 pulses (request data), so it can put the requested data in the data register before the master starts sending the 8 pulses. instead of doing this in hardware (monitoring some I/O pin), I made the master send some data (here it's 1) and the slave will immediately put its data on the data register, I don't know if there is a glitch between the time the slave puts its data and the time the master will trigger the 8 pulses.
I checked the SPIF flag for the slave whenever the master sends data , and it's set but the SPI0DR (slave) has no data in it, I tried to solve this using the interrupt (for the slave), it didn't work as well.
 
thanks again for your reply and looking forward to more information
0 Kudos

708 Views
Alban
Senior Contributor II
You're welcome !
 
The register does BOTH all the time.
If you look at the module diagram (like S12SCIV2.pdf), you can see that you have a rolling register.
For both Slave and Master, the data is sent via the same register.
The data sent is shifted out by the right hand side and the data received is shifted in from the left in the same SPI clock.
 
As long as the data register is empty (means has been read and Tx Empty is set), the slave is ready to receive.
 
The data is not put in the register as a whole byte, but ONE BIT at a time during the shifting both ways.
 
Am I clearer now ?
Cheers,
Alban.
0 Kudos

708 Views
prog_ram
Contributor III
thanks, again Alban.
the problem is that I can see the MOSI signal (it's working), and I can see the clock working, and I have tied the SS pin of the master to 1 and SS pin of slave to 0, and they both have the same CPHA, CPOL settings.
and I still don't get anything on the MISO line. what supprises me is that the SPIF of both master and slave are working, meaning that I get all my data transfered, but still getting nothing on the MISO line and SPI0DR for both of them is still zero!!
(I guess it's sending zeros, that's why nothing on the MISO line, but why zeros?!!!).
beside my previous codes, here is the SPI0 setup:
Master:
SPI0BR.byte  =0b00000011;  
SPI0CR2.byte=0b00000010; 
SPI0CR1.byte=0b01010000;  
 
 
Slave:
SPI0BR.byte  =0b00000011;  
SPI0CR2.byte=0b00000010; 
SPI0CR1.byte=0b01000000;  
 
any idea to get at least one byte transfered in both directions?
thank you
0 Kudos

708 Views
bigmac
Specialist III
Hello,
 
I think that your problem may be that, since you have /SS line of the slave permanently set low, this is not compatible with CPHA = 0 setting.
 
There are two choices - either use a setting of CPHA = 1, or raise the /SS signal to the slave after the completion of each byte (SPIF flag becomes set at the master).
 
Regards,
Mac
 
0 Kudos

708 Views
prog_ram
Contributor III
Hello guys,
thanks a lot for the reply.
it is working now..
 
you are the best..
 
take care..
0 Kudos

708 Views
PRamaekers
Contributor I

Hello!

 

I know this topic is old, but is there any chance you can post me the working code? Both the master and slave. 

 

That would be a great help!

 

Thanks,

 

Pieter

0 Kudos

708 Views
Alban
Senior Contributor II
Hi again,
 
To send something on the MISO (Master in Slave out) line, you need your slave SPI data register to have a data in it.
You can write 0x55 in the register before the Master starts the transmission.
 
Also, your code does not enable /SS. You need to write SPICR1_SSOE to 1.
 
Alban.
0 Kudos