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
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
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
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".
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?