Interfacing a MC9S12DG256 with a Parallax GPS module

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

Interfacing a MC9S12DG256 with a Parallax GPS module

1,454 Views
RyanSchwingle
Contributor I

Hello all,

 

I am attempting to interface my Microdragon to a Parallax GPS unit, I have already referenced the aforementioned section in the SCI users manual and here is the code that I have come up with:

 

void SCI1_init (void)
{
//SCI 1 (Used to interface with GPS)
//Baud Rate registers. Baud rate is determined by bus clock / (16*baud registers)
SCI1BDH = 0x01;
SCI1BDL = 0x38;// 4800 Baud with 24 Mhz clock
//Control registers
SCI1CR1 = 0xA0;//    A   |   0
               // 10100000
               // | | | | | | | |
               // | | | | | | | \ PT        = 0 => Even parity
               // | | | | | | \__ PE        = 0 => Parity function disabled
               // | | | | | \____ ILT          = 0 => Idle character bit count begins after start bit
               // | | | | \______ WAKE      = 0 => Idle Line wakeup
               // | | | \________ M          = 0 => One start bit, eight data bits, one stop bit
               // | | \__________ RSRC      = 1 => Single wire mode with Rx input connected to TXD
               // | \____________ SCISWAI    = 0 => SCI Enabled in wait mode
               // \______________ LOOPS   = 1 => Loop Operation
SCI1CR2 = 0x2C;//    2   |   C
               // 0 0 1 0 1 1 0 1
               // | | | | | | | |
               // | | | | | | | \ SBK        = 0 => No break characters
               // | | | | | | \__ RWU        = 0 => Normal Operation
               // | | | | | \____ RE          = 0 => Reviever Enabled
               // | | | | \______ TE        = 0 => Transmitter Enabled
               // | | | \________ ILIE    = 0 => IDLE interrupt requests disabled
               // | | \__________ RIE       = 0 => Revieve data register full flag and overrun flag interrupt requests enabled
               // | \____________ TCIE      = 0 => Transmission Complete interrupt requests disabled
               // \______________ TIE     = 0 => Transmit Data Register Empty interrupt requests disabled

//SCI1SR1 READ ONLY register containing flags
SCI1SR2 = 0x00;//    X   |   0
          // x x x x x 0 0 x
               //           | | |
               //           | | \ RAF        = 0 => reception in progress / not in progress. READ ONLY
               //           | \__ TXDIR   = 0 => TXD pin to be used as an input in single-wire mode
               //           \____ BK13      = 0 => Break character is 10 or 11 bits long
//SCI1DRH = 0x00;
//SCI1DRL = 0x00; // Recieve / transmit bits 7-0
}



void SCI1_TX      (char data)
{
SCI1SR2 = SCI1SR2 | BIT1;       // sets TX mode
SCI1DRL = data;                 // Send data
while ((SCI1SR1 & 0x80) == 0);  // Wait for TDRE flag
}



void SCI1_RX      (void)
{
int i;
// Note: To clear receiver interrupt, need to read
// SCI1SR1, then read SCI1DRL.
// The following code does that
SCI1SR2 = SCI1SR2 & ~BIT1;           //Sets RX mode
if ((SCI1SR1 & 0x20) == 0) return; // Not receiver interrrupt
sci1data[i] = SCI1DRL;
i = i+1;
}

 

 

void Send_to_GPS (char *ptr)
{
while (*ptr) // While character to send
  {
  SCI1_TX(*ptr);                  // Transmit characters
  ptr++; // Go to next character
  }

}

void GPS_info     (void)
{
  char serialdata[5];
  sprintf(serialdata,"!GPS%X", GetInfo);
  Send_to_GPS(serialdata);
  SCI1_RX();
  ver_hw = sci1data[1];
  ver_fw = sci1data[2];
}

 

 

It seems to hang while I wait for the TDRE flag. Are there any other approaches or a better way of doing this?

 

Any help would be greatly appreciated! Thanks!

Labels (1)
0 Kudos
5 Replies

571 Views
RyanSchwingle
Contributor I

After taking a logic analyzer to the circuit it appears it is sending three characters, "!GP" before waiting for the TDRE flag.  What would cause the data register to not shift out the character?

0 Kudos

571 Views
RyanSchwingle
Contributor I

Attached is the output from my logic probe

0 Kudos

571 Views
Lundin
Senior Contributor IV

Three things to consider:

 

1) When I RTFM I find the following:

 

"Clear TDRE by reading SCI status register 1 (SCISR1), with TDRE set and then writing to SCI data register low (SCIDRL)."

 You are not doing this. Try to move the while loop above the line writing to SCIDRL. This is the most likely solution.

 

 2) The CW debugger loves to destroy SCI and SPI flag registers, since they can be cleared by reading, and the debugger reads the memory map among other things. Try running the code without BDM attached and see if that solves anything.

 

3) S12DG256 has loads of silicon bugs in the SCI (and everywhere else). Particularly if you have an old mask set labelled "DG256B"... in that mask the SCI was pretty much impossible to use because of all hardware bugs. Check which mask you have and read up in the errata, which you can find on the Freescale site.

0 Kudos

571 Views
RyanSchwingle
Contributor I

After moving the while loop and stepping through the program I found that once again it is only outputting three characters. So I did as you suggested and removed the serial interface and let it free run. The Baud Rate went bonkers and it started outputting only 0x00. The attached image is the reading from the L.A.

 

I am using the mask 0L01Y. The errata does not show any issues with the SCI.

Any other suggestions?

0 Kudos

571 Views
kef
Specialist I

serialdata[] buffer in GPS_info() is too short. Since it is allocated on stack, return address from sprintf is probably destroyed and you may notice any weird behaviour. Of course SCI_TX() should be fixed as Lundin suggested.

0 Kudos