QG8 Higher Baud Rates

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

QG8 Higher Baud Rates

4,937 Views
datamstr
Contributor II
Greetings!

Using the QG8 internal clock, I can receive a byte (SCI) at up to 38400 BAUD. Has anyone got it working at either 57600 or 115200 BAUD? How did you do it? Do I have to go up to a "non-standard" BAUD Rate?

Thanks,
David
Labels (1)
0 Kudos
Reply
26 Replies

1,791 Views
peg
Senior Contributor IV
Hi David,
 
A search of the forums with the keywords QG8 baud revealed the following:
 
 
along with several others that cover this well enough I think.
 
0 Kudos
Reply

1,791 Views
datamstr
Contributor II
Hi Peg,

I set the Internal Clock Freq to 36 KHZ and the Baud Rate Divisor to 5. The CW Bean Inspector shows the Baud Rate at 115,200, so far so good. I am actually missing every other byte using the SCI Port even when the transmitter sends only a few bytes at a time. If I add a delay after each byte on the transmitter side, the SCI receiver does get every byte. Therefore I suspect that have a small mismatch on the Baud Rate between Transmitter and Receiver. So I have two questions:

1. Do I need to deal the the Trim Values or does CW take care of that?
2. What is the simplest method to measure the Internal Bus Clock? (9.216 MHZ)

Thanks So Much!
David

0 Kudos
Reply

1,791 Views
peg
Senior Contributor IV
Hi David,
 
Your code should check for framing errors, then you could be pretty sure you have a mismatch. Also depending on what else the QG8 is doing you could be missing characters.
What happens if you slow the baudrate?
CW should handle the TRIM if it is set to do so.
One method to confirm baudrate is to get the SCI to output continuous stream of 'A''s. This gives a square wave you can check for timing.
Otherwise write a little port pin toggle programme and measure the frequency of the pin.
 
Are you completely missing chars of are some garbled?
 
0 Kudos
Reply

1,791 Views
datamstr
Contributor II
Hi Peg and Rocco,

I have posted my SCI ISR code below, now I am toggling a pin (PTB6) to scope when the ISR is executed.
Also, the SCI Interrupt is the only interrupt source. The only other code running is loading the SPI register and now I bypassed that as well just in case. The scope shows a pulse (PTB6) on every byte received so the ISR is executing on every byte, so my problem must be somewhere else in the code.

Thanks for your help!
David

** ===================================================================
**     Interrupt handler : isrVscirx
**
**     Description :
**         User interrupt service routine.
**     Parameters  : None
**     Returns     : Nothing
** ===================================================================
*/
__interrupt void isrVscirx(void)
  {
  /* Write your interrupt code here ... */
  if(SCIS1)             // Acknowledge Receiver Full Flag
    {
    PTBD_PTBD6 = ~PTBD_PTBD6;  
    tmp_data = SCID; // Read the Data Buffer
    PTBD_PTBD6 = ~PTBD_PTBD6;  
    }
  }
/* end of isrVscirx */
0 Kudos
Reply

1,791 Views
peg
Senior Contributor IV
Hi David,
 
Your simple ISR does not achieve a great deal as you just write the recieved data to one variable.
If your main loop does not service this variable at a rate greater than the byte rate then you will still lose the byte. So you may as well just poll for the recieved byte. If this is the case then slowing down the baudrate as a test will find this out.
 
Also I was presuming you are running the same code that you were before when you had this going before at 38400 baud. Is this the case?
 
Remember, 4MHz PC's used to be able to run 115kbaud serial ports.
Nowadays 2GHz ones require the help of a hardware FIFO buffer to be able to cope with much less than this.
 


Message Edited by peg on 2007-07-24 10:35 PM
0 Kudos
Reply

1,791 Views
datamstr
Contributor II
Hi Peg,

Well, I am bit puzzled at this point as I added some code in the SCI ISR to check for the value of the received character. Also, the code in main() has been shortened to a simple for(;:smileywink: loop and the COP is disabled.
At 115,200 BAUD I can detect the character 0x55, but not 0x54 and the transmitter is sending one character at a time. Normally, two pulses are seen on the scope, but when I transmit 0x54, the output pin does not generate two pulses even though the ISR has been executed. BTW, the scope shows the period of one bit at 115,200 BAUD to be 8.7 uS.

ISR Code:

  if(SCIS1)             // Acknowledge Receiver Full Flag
    {
      PTBD_PTBD6 = ~PTBD_PTBD6;  //toggle pin
      tmp_data = SCID; // Read the Data Buffer
      PTBD_PTBD6 = ~PTBD_PTBD6;  //toggle pin
      if(tmp_data == 0x55)
      {
      PTBD_PTBD6 = ~PTBD_PTBD6;  //toggle pin
      SCI_COUNTER = 0; // short delay between pin transistions
      PTBD_PTBD6 = ~PTBD_PTBD6;  //toggle pin
      }
    }

Now if I change the code to check for 0x54, and send a 0x54 from the transmitter, the second pulse does not occur. I wonder why changing 1 bit in the character causes this effect?

Still investigating ...

Thanks,
David
0 Kudos
Reply

1,791 Views
bigmac
Specialist III
Hello David,
 
Yes, at 115200 baud the bit period will be 8.7us, however the transmission period for one byte will be about 87 us.  So if a continuous transmission of characters is received, you should observe a gap of 87 us between pulses at PTBD6.  If the gap is twice as long, this would demonstrate the loss of alternate characters.  Is this what you observe?  Assuming a bus frequency of 9.216 MHz, the byte transmission period actually represents 800 cycles, so you are looking for processing delays of more than this amount.
 
Another test to confirm how many characters you are losing would be to immediately echo back each received character, within the ISR code.
 
You do not mention whether you checked for framing errors.  If there are still baud rate accuracy problems (due to oscillator trimming issues), framing errors would be probable.  Character dependent errors do suggest there might be a problem in this area.  You might try the character value 0x40 to exacerbate the problem even further.  This contains a run of seven bits with zero value.  The 0x54 character has a run of three bits to produce bit timing errors.
 
Regards,
Mac
 
0 Kudos
Reply

1,791 Views
datamstr
Contributor II
Hi Bigmac,

Forget about the last post, I made an error in the setting. The bit period on the TX output is 10 us, when it shoud be 8.7us. So the Bus Freq is running on the slow side.
Now that's a better explanation and it makes sense! The 26us period was way too far off to make any sense.

Now I just need to figure out how to calibrate the trim.

Thanks,
David

0 Kudos
Reply

1,791 Views
peg
Senior Contributor IV
Hi,
 
So the problem is one of mismatched baudrate! (random post rater take note!)
The byte $55 is the easiest to get through on a mis-matched baudrate as it is a square wave and all those falling edges re-synch the reciever sampler.
Why not do like Mac suggested, in the isr, just  tx the byte back out, now you can scope both tx and rx at the same time and compare - no silly errors reading the timebase etc.
Check your code for a write to the TRIM register.
Got to go now.
 
0 Kudos
Reply

1,791 Views
peg
Senior Contributor IV
Hi,
 
Following on from my previous post....
 
Note that the programmer will calculate and programme a trim value into flash if you ask it to. However this value needs to be copied across into the working trim register at runtime by your code (or some generated by Codewarrior). You need to check that both of these steps are occurring.
 
My point with the fast modern PC was that at higher baudrates and no buffers you need to be careful about how often you service the serial port. With Windows etc a modern PC is much busier than before and even with the phenominal speed increases still struggles to keep up with high baudrates that could be done before when little else other than one programme was running.
 
0 Kudos
Reply

1,791 Views
bigmac
Specialist III
Hello,
 
It is also possible that the programmer is calibrating the internal oscillator for a "default" frequency that is less than the required 36 kHz.
 
Note that, when a character value of 0xFF is sent, there should not be framing errors, even with severe baud rate errors.  This is because all data bit values are the same state as the stop bit.  This character value is not really suitable for testing purposes.
 
Regards,
Mac
 
0 Kudos
Reply

1,791 Views
datamstr
Contributor II
Hi Bigmac and Peg,

I tried a few values in the TRIM register, it turns out that 0x7C results in the TX output bit period to be very close to 8.7 us. I reran the test using 0x40 value characters from the transmitter and it works great!!

I found Peg's comment very interesting about the receiver re-synch, I was not aware of this.
"The byte $55 is the easiest to get through on a mis-matched baudrate as it is a square wave and all those falling edges re-synch the reciever sampler."

I am now working on how to auto calibrate the ICS.

Out of curiosity, I tried to find where the NV_ICSTRM_INITVAL is actually initialized in Flash (0xFFAF), but so far I have only found the following Tip and #define in the MC9S08QG8.h file.

/* Tip for register initialization in the user code:  const byte NV_ICSTRM_INIT @0x0000FFAF = <NV_ICSTRM_INITVAL>; */
#define _NV_ICSTRM (*(const NV_ICSTRMSTR * __far)0x0000FFAF)

I looked through the startup code as well.

Thanks so much for your help!
David



0 Kudos
Reply

1,791 Views
peg
Senior Contributor IV
Hi David
 
You won't find an initialisation of NVTRIM($FFAE:FFAF) it is determined and programmed by the programmer irrespective of the code being programmed into the device (if enabled to do so). You will only find (hopefully) code to move these values into $3B:3A.
 
Where did you specify that you wantes 36kHz?
 
David
 
0 Kudos
Reply

1,791 Views
datamstr
Contributor II
Hi Peg,

I set the value of 36 KHZ in the CPU Bean of the "Device Initialization" Screen.
I wonder if I can view the variable at $3A to see what the programmer set it to.
I changed the TRIM value to 0x7C in the MCUInit.c file.

Thanks,
David
0 Kudos
Reply

1,791 Views
peg
Senior Contributor IV
Hi David,
 
There is no restriction in reading either NV trim or normal trim registers after initialisation.
What I would like to know is: Are they the same?
 
0 Kudos
Reply

1,791 Views
datamstr
Contributor II
Hi Peg,

The programmer writes 0xAE to 0x3A (TRIM) and 0x01 to 0x3B (FTRIM).

Thanks,
David
0 Kudos
Reply

1,791 Views
peg
Senior Contributor IV
Hi,
I don't think so!
The programmer only progammes the FLASH versions at $FFAE:FFAF.
Does $FFAF contain $3A as well?
 
0 Kudos
Reply

1,791 Views
datamstr
Contributor II
Hi Peg,

Priorly, I used the wrong term. I should have said the "initialization code" copies 0xAE from FLASH to RAM.

Thanks,
David
0 Kudos
Reply

1,791 Views
peg
Senior Contributor IV
Hi David,
 
Yeah, OK.
 
You may want to take a look at AN2312, AN2496 and AN2498. One of them actually uses a PC sending to it over the SCI as a timing reference to calibrate the TRIM.
 
0 Kudos
Reply

1,791 Views
datamstr
Contributor II
Hi Peg,

I monitored the memory window and stepped through the code. To state the results another way:

1. RAM Location 0x3A contains the value 0xAE
2. RAM Location 0x3B contains the value 0x01

So, in MCUInit.c, I comment the line that writes RAM Location 0x3A and insert the following line:
ICSTRIM = 0x7C;

Then the BAUD Rate is correct. Somhow the programmer is coming up with the value for TRIM as 0xAE.

Thanks,
David
0 Kudos
Reply