SPI problems for MC1321x programming in C

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

SPI problems for MC1321x programming in C

3,449 Views
drdr
Contributor I
Hello,

I am having trouble reading from the internal modem of an MC13212.  I have my code below and I am expecting to see a reset value of 0x007F from register GPIO_dir as per section 5.14 in document MC1321xRM.pdf and instead I am seeing 0x0000.  Please note that in my code I am using local port registers simply as a means to monitor the output.  Any suggestions will be greatly appreciated.

Thanks and regards,
drdr

/********************************/
#include <hidef.h> /* for EnableInterrupts macro */
#include "derivative.h" /* include peripheral declarations */

#define  ce_L        PTED_PTED2

void readREG() {

  PTEDD = 0xff;     //set the ce_L pin as output
  
  SPI1C1 = 0x54;   //=01010100 to enable SPI, disable interrupts, standard operation (tried 0x50)
  ce_L = 0;             //intiate transfer of three bytes

  while(!SPI1S_SPTEF);      //wait for SPI1D to be ready for 1st transfer
  SPI1D=0x8B;                     //initiate transfer to read from register GPIO_dir (0B) in modem
  while(!SPI1S_SPRF);        //wait for SPI1D to receive data from modem
  PTADD=SPI1D;                 //meaningless data -> just using PTADD to clear flag

  while(!SPI1S_SPTEF);      //wait for SPI1D to be ready for 2nd transfer
  SPI1D=0xFF;                     //send anything to get 1st byte of data
  while(!SPI1S_SPRF);        //wait for SPI1D to receive data from modem
  PTBDD=SPI1D;                //correctly received 0x00 in PTBDD
 
  while(!SPI1S_SPTEF);     //wait for SPI1D to be ready for 3rd transfer
  SPI1D=0x86;                     //send anything to get 2nd byte of data
  while(!SPI1S_SPRF);       //wait for SPI1D to receive data from modem
  PTCDD=SPI1D;               //expecting 0x7F but instead get 0x00 in PTCDD again!

  ce_L = 1;                           //terminate transfer of three bytes
 
}

void main(void) {

  EnableInterrupts;              //enable interrupts
  ce_L=1;                            //will start high when its output is enabled
  readREG();       

  for(;:smileywink: {
    __RESET_WATCHDOG(); /* feeds the dog */
  } /* loop forever */
}
Labels (1)
0 Kudos
13 Replies

987 Views
drdr
Contributor I

Hi Guys,

I completely re-wrote the code in the style that seems common on this forum and still it fails to work.  I run the code with and without the monitoring software and can tell that the values that I am getting are all 0x00 becuase of the LEDs I have on my board.  If anyone can find something that I am forgetting to set please let me know.

Thank you very much for your time,
drdr


#include <hidef.h> /* for EnableInterrupts macro */
#include "derivative.h" /* include peripheral declarations */

#define  ce_L         PTED_PTED2
#define  enable_ce    PTEDD_PTEDD2


void delay(int count)
{
  while(count--);  
}

void init_SPI(void)
{
 
   SPI1C1 = 0x00;             //in binary=01010000 to enable master SPI, disable interrupts, standard operation
   SPI1C2 = 0x00;             //default state for SPI control2
   SPI1BR = 0x00;             //default state for baud rate control
   ce_L=1;                    //reset CE before transaction begins
   enable_ce = 1;
}

byte SPI_transOne( byte val)
{
   while (!SPI1S_SPTEF);
   SPI1D = val;               // Send byte value
   while (!SPI1S_SPRF);       // Wait for completion of transfer
   return SPI1D;
}

void SPI_comms(void)
{
  ce_L = 0;                   //intiate SPI transfer

  (void)SPI_transOne( 0x8B);  //send byte & ignore returned byte
  delay(10);
  PTADD = SPI_transOne( 0);   //Dummy send to read a byte
  delay(10);
  PTBDD = SPI_transOne( 0);   //Dummy send to read a byte
  delay(10);
     
  ce_L = 1;                   //terminate SPI transfer
}

void main(void) {
 
  init_SPI();
  SPI_comms();
 
  for(;:smileywink: {
    __RESET_WATCHDOG(); /* feeds the dog */
    
  } /* loop forever */
}

0 Kudos

987 Views
peg
Senior Contributor IV
Hello drdr,

One easy test which is probably appropriate at this point is to disconnect the masters MISO line at the slave and pull it high. Now if you receive all FF's your code in the master is working. Now you need to look at why the slave is not responding as expected.

0 Kudos

987 Views
drdr
Contributor I
Hi Peg,

Thank you for your response and suggestion.  I wonder if it is possible to do this with an integrated MCU and modem in one mc13212 chip.  And if so, how?

Thanks and regards,

Andrey
0 Kudos

987 Views
peg
Senior Contributor IV
Hi,
You take a very small knife and ........
No, sorry my fault. Obviously it is not possible to do this in this case.
The actual SPI code looks OK but I don't know about the actual mode, commands etc required here.
Suggest you look at the examples etc.

0 Kudos

987 Views
drdr
Contributor I
Thanks again Peg. 

If anyone knows of sample code for an MC1321x part, I would really appreciate it.  Since this is just a hobby of mine, I cannot afford to buy a software stack.

Regards,

drdr
0 Kudos

987 Views
peg
Senior Contributor IV
Hi drdr,

Why can't you use SMAC. It is also a good place to look to see how it is all done.
BTW, in your code for C1 you have the correct value in the comment but the code actually has zero.

0 Kudos

987 Views
drdr
Contributor I
Good catch Peg.  I must have pasted an older code by accident.
 
I didn't realize that I could download SMAC without purchasing a development board but since your post I found out from a Freescale representative that it is indeed possible.  I will follow your suggestion.
 
Thank you very much for your time and expertise,
 
drdr
0 Kudos

987 Views
drdr
Contributor I

For anyone interested, I figured out what my issue was, though I don't understand why part of it is necessary and I hope someone knows a way around it. 

 

One uncontroversial error that I had was forgetting to take the modem out of reset.  After adding the following I was able to read/write using the BDM's step-by-step mode.

 

PTDDD_PTDDD3 = 1;    

PTDD_PTDD3 = 1;

 

However not until I put a considerable (and somewhat debilitating) delay into my master to slave transfer function that it worked as stand-alone. 

 

void delay(int count)
{
  while(count--); 
}

 

byte SPI_transOne( byte val)

{

   while (!SPI1S_SPTEF);

   delay(255);                  //very important delay...for some reason

   SPI1D = val;                 // Send byte value

   while (!SPI1S_SPRF);     // Wait for completion of transfer

   return SPI1D;

}

 

If anyone can tell me why I need a delay after my check I would greatly appreciate it.

 

Thank you,

 

drdr

0 Kudos

987 Views
peg
Senior Contributor IV

Hello drdr,

 

This delay is not required for the SPI to operate.

The slave device may require some "processing time" after a certain amount of bytes are sent or a complete command is sent.

More than likely the delay is only required sometimes and not at every transfer.

 

0 Kudos

987 Views
drdr
Contributor I

Hi Peg,

 

Shouldn't these checks have taken care of that? 

 

   while (!SPI1S_SPTEF);

 

   while (!SPI1S_SPRF); 

 

Otherwise how can I tell when it needs the delay and when it doesn't?

 

Thanks,

 

drdr

0 Kudos

987 Views
peg
Senior Contributor IV

Hi drdr,

 

As I said the actual SPI bit will work without delays. At the slave end the bytes must be unloaded out of the SPI register by the code running there. Normally this will be done quite quickly and transparently but once, say, a whole command is sent it may need time to gather the response and write it to the SCI in order to send it back. This quite often takes additinal time that must be allowed for in the master code.

 

0 Kudos

987 Views
drdr
Contributor I

Hi Peg,

 

The only operations I performed was to set GPIO_Dir and GPIO_Data_Out in the modem, so I don't see why any of that would take very long since I'm not expecting a response from the slave.  Either way, how can any logic to the master code work without some sort of feedback from the slave?  Unless there is a predictable table of the maximum times it takes to do certain operations, the master can never know for sure if it's okay to continue if there is no feedback.

 

Thanks for your help,

 

drdr

0 Kudos

987 Views
drdr
Contributor I

Hi Peg,

 

You were right about the delay not being necessary for every SPI access.  In fact, my problem was the lack of a 25ms wait needed after the modem's reset (which I formerly performed right before the access).  I hope not to come across any modem operation that requires more time as it seems extremely difficult to take such an event into account.

 

Thanks and Regards,

 

drdr

0 Kudos