MC68HC08EY16 and SPI

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

MC68HC08EY16 and SPI

1,775 Views
Stigaard
Contributor I
Hi,
I'm working with a 908E626, which is a chip containing 2 die's one MC68HC08EY16 and one analog die (motor driver). To communicate between the die's one needs to use the SPI interface of the MC68HC08EY16 die. However it seems that no matter what I do I cannot get in contact with the analog die, the spi registers is set up to
SPCR = 0x28
SPSCR = 0x08
and I'm running of a clock of 9.8304Mhz.
I appreciate any suggestions.

This is how the spi is to be setup acording to the datasheet (a diagram is also attached)

The serial peripheral interface (SPI) creates the communication link between the microcontroller and the 908E626.
The interface consists of four pins (see Figure 11):
•SS — Slave Select
•MOSI — Master-Out Slave-In
•MISO — Master-In Slave-Out
•SPSCK — Serial Clock (maximum frequency 4.0 MHz)
A complete data transfer via the SPI consists of 2 bytes. The master sends address and data, slave system status, and data of the selected address.

During the inactive phase of SS, the new data transfer is prepared. The falling edge on the SS line indicates the start of a new data transfer and puts MISO in the low-impedance mode. The first valid data are moved to MISO with the rising edge of SPSCK.
The MISO output changes data on a rising edge of SPSCK. The MOSI input is sampled on a falling edge of SPSCK. The data transfer is only valid if exactly 16 sample clock edges are present in the active phase of SS.
After a write operation, the transmitted data is latched into the register by the rising edge of SS. Register read data is internally latched into the SPI at the time when the parity bit is transferred. SS HIGH forces MISO to high impedance.
Labels (1)
0 Kudos
Reply
4 Replies

671 Views
Stigaard
Contributor I
Currently the code I'm using to send is the following
PTB_PTB1 = 0;
i = intSPI_SendChar(0b00001100); //0x0C
while(!SPSCR_SPTE);
i = intSPI_SendChar(0b10100000); //0xA0
while(!SPSCR_SPTE);
PTB_PTB1 = 1;

where PortB pin 1 is the pin connected to the slave spi select pin (active low)

the intSPI_SendChar is defined as the following
byte intSPI_SendChar(intSPI_TComData Chr)
{
if (!EnMode) { /* Is the device disabled in the actual speed CPU mode? */
return ERR_SPEED; /* If yes then error */
}
if (!SPSCR_SPTE) { /* Is last character sent? */
return ERR_TXFULL; /* If no then return error */
}
SPDR = Chr; /* Send character */
return ERR_OK; /* OK */
}

When running checking the value of i in the debugger with a breakpoint set right after the code, i is set to ERR_OK

I tried changing the value to 0x2A and I tried setting the DDR registers for the spi port explicitly in main (to avoid relying on processor expert to do it). But still with no luck.
0 Kudos
Reply

671 Views
bigmac
Specialist III
Hello Morten,
 
It seems there may be some misunderstanding about the operation of the flags SPTE and SPRF.  With the usual operation of the SPI as a master, the SPTE flag is relatively unimportant, since it is automatically set, and is usually so when an attempt to initiate a send is made.
 
However, the SPRF flag is very important because it indicates when a both-way transfer of data has been completed by the master (eight SPI clock cycles after the send was initiated).  Your code must clear this flag in a timely manner to prevent an overrun condition.  If an overrun condition should occur, the received data will not update the register while the SPRF flag remains set.
 
While it is possible to sequentially send two bytes without waiting for the SPRF flag to become set in between, I would strongly recommend that you do not do so.  Timing issues are introduced and must be met to prevent overrun from occurring.  Sending a single byte, and then waiting until SPRF becomes set (per my previous SPI_trans() function), is safer and has no timing issues.  To clear the SPRF flag, you must read the SPI data register, even if you have no interest in the data returned.
 
Your existing code probably does not work because of the failure to clear the SPRF flag.  You do not show how you send a dummy byte in order to read the wanted return data from the motor driver - following PTB_PTB1 = 1;  However, before you could do this, you would need to clear the SPRF flag twice.  Your intSPI_SendChar()function does not make sense to me in the context of SPI operation.
 
Regards,
Mac
 
0 Kudos
Reply

671 Views
bigmac
Specialist III
Hello, and welcome to the forum.
 
Firstly, it would seem that the setting should be SPCR = 0x2A; otherwise the SPI module is not enabled.  The other register should perhaps be SPSCR = 0x00; since writing 1 to bit-2 does nothing.
 
I suspect that the frequency you refer to is an external crystal frequency rather than the bus frequency, since the maximum bus frequency is limited to 8MHz.  In this case the bus frequency would be 2.4576MHz, and the SPI clock 1.2288MHz.  I presume this is OK for the E626 die.
 
When the SPI module is enabled, the SS pin is an input used for slave operation.  For master mode, you will need to determine the pin used for the SS output signal applied to the E626 die.  This pin will need to be controlled by your code.
 
You do not provide the details of your communications code, but be aware that the values returned as a result of sending the command and address bytes will probably be meaningless, and to recover the "latched" bytes from the slave, you need to send one or more dummy bytes to the slave, after the SS signal has been raised.  The number of dummy bytes will depend on how many bytes are returned.
 
The typical code for the transfer of a single byte in each direction would be -
 
byte SPI_trans( byte val)
{
   while (!SPSCR_SPTEF);
   SPDR = val;           // Send byte value
   while (!SPSCR_SPRF);  // Wait for completion of transfer
   return SPDR;
}
 
It would appear that the following sequence of events would then be required -
 
SS = 0;
(void)SPI_trans( command); // Ignore return data
(void)SPI_trans( address);
SS = 1;                    // Return data latched
dat = SPI_trans( 0);       // Send dummy byte/return data byte
 
// Return further data bytes if required
 
Is this code something similar to what you are using?
 
Regards,
Mac
 
0 Kudos
Reply

671 Views
Stigaard
Contributor I
I'm sorry about not including the code (will do as soon as I get back to the computer with the code on it).
The code I'm using for a reference for the spi is the one generated by the processor expert in codewarrior.

The frequency I referred to is the external frequency (though from a signal generator for now), acording to the datasheet I should be able to run the E626 up to 4 MHz.
I will try your suggestions tomorrow and let you know how it goes.

Thanks
Morten S. Laursen
0 Kudos
Reply