MC9S08PA32 - SPI Problem

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

MC9S08PA32 - SPI Problem

1,751 Views
juanma_clautron
Contributor II

Hi everybody! This is my first request. Sorry if I don't explain correctly ^^ I'm using a S08 microcontroller and I need to use the SPI communication.

 

The S08 works as slave. When the master sends a byte, the slave recieved and prepare a byte to answer at next master's clock. For example:

 

SS goes 0

1. Master sends 0x90 and Slave has 0x00 (not defined previous buffer). Slave prepares a 0x20 for next CLK.

2. Master sends 0x40 and Slave has 0x20 (step 1). Slave prepares a 0xAA for next CLK.

3. Master sends 0x01 and Slave has 0xAA (step 2). Slave prepares a 0xBB for next CLK.

4. Master sends 0x01 and Slave has 0xBB (step 3). Slave prepares a 0xCC for next CLK.

5. Master sends 0x01 and Slave has 0xCC (step 4). Slave prepares a 0xDD for next CLK.

6. Master sends 0x01 and Slave has 0xDD (step 5). Slave prepares a 0x55 for next CLK.

SS goes 1


.....Next TX


SS goes 0

7. Repeat step 1 with: Master sends 0x90 and Slave has 0x55 (previous buffer). Slave prepares a 0x20 for next CLK.

...And so on

SS goes 1

 

The problem is I need to wait 2 cycles for each byte. Here's the example:

 

SS goes 0

1. Master sends 0x90 and Slave has 0x00 (not defined previous buffer). Slave prepares a 0x20 for next CLK.

2. Master sends 0x40 and Slave has 0x00 (not defined previous buffer). Slave prepares a 0xAA for next CLK.

3. Master sends 0x01 and Slave has 0x20 (step 1). Slave prepares a 0xBB for next CLK.

4. Master sends 0x01 and Slave has 0xBB (step 2). Slave prepares a 0xCC for next CLK.

5. Master sends 0x01 and Slave has 0xCC (step 3). Slave prepares a 0xDD for next CLK.

6. Master sends 0x01 and Slave has 0xDD (step 4). Slave prepares a 0x55 for next CLK.

SS goes 1


.....Next TX


SS goes 0

7. Repeat step 1 with: Master sends 0x90 and Slave has 0x55 (previous buffer). Slave prepares a 0x20 for next CLK.

...And so on

SS goes 1

 

If I read the datasheet:

 

17.3.4 SPI Status Register (SPIx_S)

...

bit 5 > SPTEF > " For an idle SPI, data written to DH:DL is transferred to the shifter almost immediately so that SPTEF is set within two bus cycles, allowing a second set of data to be queued into the transmit buffer. "

 

I lost 1 cycle and I should the byte always at next TX

 

Thanks in advance : )

Labels (1)
Tags (3)
3 Replies

1,025 Views
Rick_Li
NXP Employee
NXP Employee

Hi Bailen,

I appreciate your patience on this issue but I dont fully understand your problem.

if you want to delay 2 cycles in your application, then, I would suggest store the data received by SPI slave in a data buffer (an array with two element is OK), then, in the third SPI communication cycle, send the first received data back and move the second data to first position.

If I misunderstand your question, then, please directly reply it here!

1,025 Views
juanma_clautron
Contributor II

Hi Yong Li

It's just the opposite. I don't want to wait. I'm gonna explain you.

- The app has 2 buffers, 1 counter, and 1 byte for reading SPI status register:

unsigned char bufferIN[6]          // RX

unsigned char bufferOUT[6]      // TX > [ 0x20, 0xE8, 0x03, 0x00, 0x00, 0x81 ]

unisgned char counter_spi

unisgned char Status

- SPI = slave mode, Data buffer size = 8 bits (only uses SPI1_DL)

- And 1 interruption:

ISR (interrupciospi)

{

Status = SPI1_S;

bufferIN[counter_spi] = SPI1_DL;

/******HERE IS MY PROBLEM******/

SPI1_DL = bufferOUT[counter_spi];

if (counter_spi == 5)

counter_spi++;

else

counter_spi = 0;

}

Every interruption (each byte recieved) it calls interrupciospi. Read the SPI1_S, then copy the DL to bufferIN[counterspi] and put bufferOUT[counterspi] to DL. Here is when I have the problem:

- If I put the bufferOUT directly to SPI1_DL, the app works fine.

- But if I process what I've recieved at bufferIN, the app doesn't work. For example, if I put for (i=0;i<10;i++) (just a delay) at /******HERE IS MY PROBLEM******/ , automatically waits until next CLK for send the bufferOUT. For testing, I always send [ 0x20, 0xE8, 0x03, 0x00, 0x00, 0x81 ] , but if it works correctly, I want to process bufferIN[1] and:

- If bufferIN[1] = 0x33 send [ 0x20, 0xE8, 0x03, 0x00, 0x00, 0x81 ]

- If bufferIN[1] = 0x34 send [ 0x20, 0xC5, 0x12, 0x60, 0x13, 0x81 ]

Example (working correctly, but not processing what I recieved):

first transmission (ok.jpg left)

1. SPI1_DL (previously) = 0x00 > Interruption > RX = 0x92 > bufferIN[0] = 0x92 > bufferOUT[0] = 0x20

2. SPI1_DL (previously) = 0x20 > Interruption > RX = 0x33 > bufferIN[1] = 0x33 > bufferOUT[1] = 0xE8

3. SPI1_DL (previously) = 0xE8 > Interruption > RX = 0x00 > bufferIN[2] = 0x00 > bufferOUT[2] = 0x03

4. SPI1_DL (previously) = 0x03 > Interruption > RX = 0x00 > bufferIN[3] = 0x00 > bufferOUT[3] = 0x00

5. SPI1_DL (previously) = 0x00 > Interruption > RX = 0x00 > bufferIN[4] = 0x00 > bufferOUT[4] = 0x00

6. SPI1_DL (previously) = 0x00 > Interruption > RX = 0x00 > bufferIN[5] = 0x00 > bufferOUT[5] = 0x81

next transmission (ok.jpg right)

1. SPI1_DL (previously) = 0x81 > Interruption > RX = 0x92 > bufferIN[0] = 0x92 > bufferOUT[0] = 0x20

2. SPI1_DL (previously) = 0x20 > Interruption > RX = 0x33 > bufferIN[1] = 0x33 > bufferOUT[1] = 0xE8

3. SPI1_DL (previously) = 0xE8 > Interruption > RX = 0x00 > bufferIN[2] = 0x00 > bufferOUT[2] = 0x03

4. SPI1_DL (previously) = 0x03 > Interruption > RX = 0x92 > bufferIN[3] = 0x00 > bufferOUT[3] = 0x00

5. SPI1_DL (previously) = 0x00 > Interruption > RX = 0x33 > bufferIN[4] = 0x0 > bufferOUT[4] = 0x00

6. SPI1_DL (previously) = 0x00 > Interruption > RX = 0x00 > bufferIN[5] = 0x00 > bufferOUT[5] = 0x81

Example (not working correctly):

first transmission (left)

1. SPI1_DL (previously) = 0x00 > Interruption > RX = 0x92 > bufferIN[0] = 0x92 > TIME FOR PROCESS > bufferOUT[0] = 0x20

2. SPI1_DL (previously) = 0x00 > Interruption > RX = 0x33 > bufferIN[1] = 0x33 > TIME FOR PROCESS > bufferOUT[1] = 0xE8

3. SPI1_DL (previously) = 0x20 > Interruption > RX = 0x00 > bufferIN[2] = 0x00 > TIME FOR PROCESS > bufferOUT[2] = 0x03

4. SPI1_DL (previously) = 0xE8 > Interruption > RX = 0x00 > bufferIN[3] = 0x00 > TIME FOR PROCESS > bufferOUT[3] = 0x00

5. SPI1_DL (previously) = 0x03 > Interruption > RX = 0x00 > bufferIN[4] = 0x00 > TIME FOR PROCESS > bufferOUT[4] = 0x00

6. SPI1_DL (previously) = 0x00 > Interruption > RX = 0x00 > bufferIN[5] = 0x00 > TIME FOR PROCESS > bufferOUT[5] = 0x81

next transmission (right)

1. SPI1_DL (previously) = 0x00 > Interruption > RX = 0x92 > bufferIN[0] = 0x92 > TIME FOR PROCESS > bufferOUT[0] = 0x20

2. SPI1_DL (previously) = 0x81 > Interruption > RX = 0x33 > bufferIN[1] = 0x33 > TIME FOR PROCESS > bufferOUT[1] = 0xE8

3. SPI1_DL (previously) = 0x20 > Interruption > RX = 0x00 > bufferIN[2] = 0x00 > TIME FOR PROCESS > bufferOUT[2] = 0x03

4. SPI1_DL (previously) = 0xE8 > Interruption > RX = 0x00 > bufferIN[3] = 0x00 > TIME FOR PROCESS > bufferOUT[3] = 0x00

5. SPI1_DL (previously) = 0x03 > Interruption > RX = 0x00 > bufferIN[4] = 0x00 > TIME FOR PROCESS > bufferOUT[4] = 0x00

6. SPI1_DL (previously) = 0x00 > Interruption > RX = 0x00 > bufferIN[5] = 0x00 > TIME FOR PROCESS > bufferOUT[5] = 0x81

Hope I explained correctly ^^

Thanks for your answer

0 Kudos

1,025 Views
Rick_Li
NXP Employee
NXP Employee

Hi Juanma Bailen,

I'm sorry for delay response, I was heavily backlogged!

Thank you for your update on this issue!

The problem on your side is caused by the time that delayed in SPI interrupt routine if you want processing the received data.

To avoid this issue, I would suggest move statement "Status = SPI1_S;" at the end of your SPI interrupt routine.

the code could be as below:

ISR (interrupciospi)

{

//Status = SPI1_S;

bufferIN[counter_spi] = SPI1_DL;

(data processing code)

SPI1_DL = bufferOUT[counter_spi];

if (counter_spi == 5)

counter_spi++;

else

counter_spi = 0;


      Status = SPI1_S;

}

Hope it helps!

0 Kudos