Receiving "ack" over SCI

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

Receiving "ack" over SCI

1,969 Views
Iain
Contributor I

I am trying to interface a HCS08QE32 to the uDRIVE-uSD-G1 (an embedded DOS uSD card module), which has a command set for reading/writing etc to it.


I am trying to write a file to it, this requires the micro to:
wait some time for device to settle,
send byte to lock onto baud rate,
micro should receive "ack" byte,
send bytes to set up file,
receive ack,
send file data bytes.
receive ack.

...problem is, my program sends the auto-baud command (tested with serial terminal, Docklight), then just sends random bytes while waiting for ack. I have tried removing the wait-for-ack code, replacing with delays, and just sending the commands, which seems to send all required bytes, followed by random bytes, but does not create file.

I can write a file by sending the commands through Docklight (and getting the expected acks), so uSD module is working fine.

I think the problem must lie in either my wait-for-ack code, or possibly the initial delay time (which I've tried changing a bit). Should I disable the micro Tx pin while waiting for ack, rather than let it send random data? Any Ideas?

 

 

#include <hidef.h> /* for EnableInterrupts macro */#include "derivative.h" /* include peripheral declarations *///Delay functionvoid delay( long val){   for ( ; val; val--);}void main(void) {    SCI2BD = 26; //set baud rate 96000 with busclock=4MHz                       //delay while device settles (should be ~500ms)   delay(5000);    SCI2C2 = 0b00000100;  //enable R  SCI2C2 = 0b00001000;  //enable T     while (!SCI2S1_TDRE);  // wait for the transmit buffer to be empty  SCI2D = 0x55; //auto baud    //wait for ack  do   {    while(!SCI2S1_RDRF); //wait for received byte  }   while (SCI2D != 0x06); //check for ack  //  delay(100);    //Set up file    //write  while (!SCI2S1_TDRE);  // wait for the transmit buffer to be empty  SCI2D = 0x40;    while (!SCI2S1_TDRE);  // wait for the transmit buffer to be empty  SCI2D = 0x74;  //no handshaking  while (!SCI2S1_TDRE);  // wait for the transmit buffer to be empty  SCI2D = 0x00;    //file name  while (!SCI2S1_TDRE);  // wait for the transmit buffer to be empty  SCI2D = 0x46;  //"F"   while (!SCI2S1_TDRE);  // wait for the transmit buffer to be empty  SCI2D = 0x6E;  //"N"  while (!SCI2S1_TDRE);  // wait for the transmit buffer to be empty  SCI2D = 0x74;  //"T"  while (!SCI2S1_TDRE);  // wait for the transmit buffer to be empty  SCI2D = 0x31;  //"1"  //null  while (!SCI2S1_TDRE);  // wait for the transmit buffer to be empty  SCI2D = 0x00;  //file size  while (!SCI2S1_TDRE);  // wait for the transmit buffer to be empty  SCI2D = 0x00;  while (!SCI2S1_TDRE); // wait for the transmit buffer to be empty  SCI2D = 0x00;  while (!SCI2S1_TDRE);  // wait for the transmit buffer to be empty  SCI2D = 0x00;  while (!SCI2S1_TDRE);  // wait for the transmit buffer to be empty  SCI2D = 0x05;  //5 bytes    delay(100);    //wait for ack  do   {    while(!SCI2S1_RDRF); //wait for received byte  }   while (SCI2D != 0x06);  //check for ack  //    //send data    while (!SCI2S1_TDRE);  // wait for the transmit buffer to be empty  SCI2D = 0x68;  //"h"  while (!SCI2S1_TDRE);  // wait for the transmit buffer to be empty  SCI2D = 0x65;  //"e"  while (!SCI2S1_TDRE);  // wait for the transmit buffer to be empty  SCI2D = 0x6C;  //"l"  while (!SCI2S1_TDRE);  // wait for the transmit buffer to be empty  SCI2D = 0x6C;  //"l"  while (!SCI2S1_TDRE);  // wait for the transmit buffer to be empty  SCI2D = 0x6F;  //"o"               delay(100);    //wait for ack  do   {    while(!SCI2S1_RDRF); //wait for received byte  }   while (SCI2D != 0x06); //check for ack  //   while(1);}

 Iain

Labels (1)
Tags (1)
0 Kudos
Reply
6 Replies

955 Views
eckhard
Contributor V

Hello,

 

with the two statements  you are disabeling the receiver right after enabling it.

So you wont receive an ACK.

 

Dont know about the random bytes, but maybe you need a pullup on RX and TX.

 

Eckhard

 

 
  SCI2C2 = 0b00000100;  //enable R
  SCI2C2 = 0b00001000;  //enable T


0 Kudos
Reply

955 Views
Lundin
Senior Contributor IV
Also, if your compiler is CW, then your delay function is never executed. CW will optimize it away. Delay functions like that shouldn't be used in embedded systems anyhow, as they are incredibly hardware & interrupt-intensity dependant. Instead, use the on-chip hardware timers.
0 Kudos
Reply

955 Views
bigmac
Specialist III

Hello,

 

I do question the basis of the previous statement that "CW will optimize it (the function) away".  This has not been my experience when using a similar function, and which also appears to have been utilised as a "quick and dirty" delay function in some of the examples given in Fabio Pereira's "HCS08 Unleashed".

 

I would also perceive that there is a difference between a "delay function" and a "timing function".  The delay function is used by the OP to create a minimum delay period, with the upper limit being non-critical.  True, the delay will be interrupt intensity dependent, but so will be the execution of the remainder of the code in which the delay function is used.

 

However, I might question the delay calibration implied within the code.  A delay value of 100 us per loop seems rather a lot for this simple function, assuming a reasonably fast bus clock is used.  The delay calibration might bear checking out, using full chip simulation, to ensure that the delay generated is sufficient.  With potentially long delay periods generated, COP timer reset will need to be implemented within the delay loop.

 

Regards,

Mac

 

0 Kudos
Reply

955 Views
Lundin
Senior Contributor IV

Depending on how you set up your optimizer, I bet you will get the code to behave differently. It is certainly completely non-portable. Just a simple thing such as whether you use "long", "int", "short" or "char" as the counter variable, will make tremendous differences in delay time.

 

At the very least you should make the counter variable volatile.

 

Whenever someone comes up with delays like this, I always ask them why they don't use hardware timers instead. The only answer to that question seems to be "I'm lazy and I don't know how timers work in the CPU I'm using".  :smileyhappy:

0 Kudos
Reply

955 Views
Iain
Contributor I

 

eckhard - thanks for pointing that out the control register mistake, however the configuration was correct in a previous version of the code, so that's not the problem unfortunately.
I added the pull up resistors, but they did not seem to fix the random output problem, even stranger, while my micro Tx pin is always high, the Rx pin is now always low...and I'm sure it was not like this even before adding the pull-ups.
When connected to a compatible USB-serial interface (with sucessful communication i.e. proper operation), the Tx and Rx are pulled high. Anyway this is a hardware issue, and probably not for this forum section.
The delay function implemented was taken from Fabio Pereira's book, I know there are better ways of creating a delay, but I was just trying something basic. I will see if I check my delays are in the range I want with full chip simulation.
Regards,
Iain

 

0 Kudos
Reply

955 Views
Lundin
Senior Contributor IV

The Tx pin is driven high from the SCI, it is an output so you shouldn't need pull resistors on that one. The Rx pin will be held at a certain level by external circuitry. Perhaps you have some sort of hardware issue with your tranceiver circuit?

0 Kudos
Reply