Hi everyone!
I'm trying to communicate serially between a TWR-S08PT60 kit, and the hyperterminal in my PC,
with the Processor Expert component "term", and the code generated by it.
I seem to be having two different problems, I don't know if they are related to each other...
First, the baudrate is off by roughly 10%
When I set it to 9600 baud, the length of one bit sent from the mcu is 115us instead of 104us
Here are a couple of screenshots on how I've set the timing:
(I changed the internal oscillator to 36kHz to allow for a wide variety of baud rates)
I can trick it into communicating in the correct baud rate if I set the baud rate to 10500 though...
The second problem is more critical.
When the mcu is reading a character from the PC, it's reading two characters even if there are only one sent.
The following code should echo the received character back to the PC:
void main(void)
unsigned char ch;
while(1)
{
Term1_ReadChar(&ch);
Term1_SendChar(ch);
}
But in my case it echoes back two characters for every character it receives.
The first character sent is the same as it receives (as long as I have set the baudrate to 10500),
the second one is the same as the first BUT shifted one bit.
ie. if i send an ascii '4' (0x34)=(00110100) from the PC
I will receive '4Ü' from the mcu.
'Ü' (0x9A)=(10011010)
I've tried this with both CW 10.5 and CW 10.6, but with the same result.
I've earlier done exactly the same thing with CW 10.2 and a MC9S08AW60 mcu, and it has worked well.
I've double checked the baud rate/parity/stop bit settings in hyperterminal.
Have I forgotten some settings, or is this a bug?
I'm very grateful for any input!
Best regards
Fredrik
I finally tried a third lab-kit, and the problem vanished...
It turned out that the first two had CPU:s from a certain batch (2N40C), which had a known problem with the UART.
When I googled the batch number I found this errata sheet:
http://cache.freescale.com/files/microcontrollers/doc/errata/PC9S08PT60_2N40C.pdf?fasp=1
e3869: SCI: When SCI is configured in 1 STOP bit mode, a false RDRF flag will be
generated after the correct RDRF flag is set.
Description: The SCI receiver sets Receive Data Register Full (RDRF) bit twice when 1 STOP bit frame
format is used. In this case, the first RDRF bit is correct, but the second RDRF bit is a false
flag. The false RDRF is generated after one bit time of the first RDRF gets set.
So if there is no delay or the delay is shorter than 1 bit time in between two data transmit
frames from the transmitter, the S08PT60 SCI receiver will generate a frame error in addition
to the RDRF flag.
Workaround: 1 bit time delay is required before reading SCI Data Register when RDRF bit is set. In addition,
in order for S08PT60 to receive the right data bytes in the data stream, the transmitter must
delay at least one bit time in between two consecutive data frames.
Sure, I should have checked all errata sheets earlier.
But one might expect that the Freescale support techs would be aware of it, and could have pointed this out to me from the beginning!
And I think this bug is far more serious than a simple "errata-issue".
What if I wrote the code for a CPU of a good batch, and one of these units later were used in the product.
Sure a delay between reading the status byte and the data buffer could be done with a firmware upgrade.
But since the other device it communicates with also needs a delay when transmitting,
what if the CPU:s were used in an application where I can't effect the delay from the other device.
Then a CPU from this batch would effectively kill the entire product.
This whole mess has made me think twice about choosing a freescale CPU...
A little update:
I've changed the "High speed clock" to external, and the internal buss freq to 2.0 MHz.
Now the measured baud rate is the same as the baud rate stated by the "component inspector", but I need to replace the stock 8MHz crystal with one with a more baud rate friendly frequency.
I can run it in 9615 now, but I will later need to use higher baud rates as well...
Why didn't it work when I based the bus freq on the internal clock?
But the second problem still persists...
I've tried all three UART-ports on the cpu with the same result.
I've also tried with my old MC9S08AW60 mcu again, this time with CW10.6.
And that one works perfectly.
So I suspect the problem is how the ProcessorExpert initializes the UARTs of the MCS08PT60...
Another update:
The baud rate issue is solved.
The component inspector for the cpu had the wrong addresses for the trim register (under advanced settings)
As default they were set to 0xFF6F and 0xFF6E, but should be 0x303A and 0x303B.
But the second problem still bugs me.
I've written a program that writes the contents of the UART-registers to a terminal window,
before and after I receive a character, and then it reads it one more time after that.
The code is something like this:
send_registers_before_read();
Term1_ReadChar(&ch); //Reads one character from PC
Term1_SendChar(ch); //returns the received character to the PC
send_registers_after_read();
send_registers_after_read_again();
And this is the result:
The problem seems to be that the RDRF and IDLE-bit (SCI1_S1 bit 5 and 4)doesn't get reset until it's been read a second time.
So they indicate that the receiver data buffer is still full...
The function "Term1_ReadChar(&ch)" reads both SCI1_S1 and SCI1_D and that should be enough to reset the RDRF and IDLE bits
The fact that the data still in the buffer(SCI1_D) is shifted one bit, I no longer think is a problem in itself.
That's probably just residual data, that shouldn't be read anyway...
Hello Fredrik,
The "Trim value address" property is not the address of the trim register, it is a location in flash memory from where the generated initialization code reads the value that will be used to initialize the trim register. You can see this assignment in generated code (file cpu.c, function _EntryPoint). The trim value is written in that flash location by the debugger when the code is downloaded.
If you need to change the internal oscillator frequency it is not enough to change it in PEx, you must also inform the debugger. You can do that in Run -> Debug configurations, Main tab, Target settings group, press Edit button, then Advanced Programming Options, and write the desired frequency in the box on the bottom of the window. This will cause the debugger to compute the trim value properly.
I could not reproduce the second issue, my echo example worked perfectly and all registers values were correct. Perhaps it is related to the first problem, can you please check if the problem persists after fixing the internal oscillator frequency?
Best regards,
Cristian
Hi Christian,
Thank you for explaining about the trim value addresses, I had that backwards.
I ended up adjusting the trim value manually instead by writing a value (0x55) to the ICS_C3 register.
But I have now changed back the trim value addresses, and I'm using the automatic trim adjustment when programming, as you suggest.
But it behaves exactly the same :smileysad:
I've mailed my project to a support guy (Jorge Alberto) and he can't replicate the problem either...
So I'm completely lost on what to do next, and my customer is loosing patience...