Forum - MCS Electronics

 

FAQFAQ SearchSearch RegisterRegister Log inLog in

UART Problem - Definition in Bootloader vs Main

 
Post new topic   Reply to topic    www.mcselec.com Forum Index -> BASCOM-AVR
View previous topic :: View next topic  
Author Message
enniom

Bascom Member



Joined: 20 Oct 2009
Posts: 537

PostPosted: Fri Jul 14, 2017 11:03 pm    Post subject: UART Problem - Definition in Bootloader vs Main Reply with quote

This problem is a little difficult to explain.

There seems to be a problem with the UART when the same UART is used in the MCS Sample Bootloader at one clock speed, and then used in the Main Program at a different clock speed, the UART output is garbled as if the UART parameters are inconsistent.

Code:

'Bootloader Snippet

$regfile = "xm32E5def.dat"
$loader = &H4000                                        

$hwstack = 80
$swstack = 80
$framesize = 80
$timeout = 1600000                                          'we use a timeout

$crystal = 22000000
Config Osc = Enabled , 32mhzosc = Disabled                  'internal 2 MHz and 32 MHz enabled
Osc_pllctrl = &B00_0_01011                                  ' 2MHz clock Source and Multiplication factor * 11 = 22
              '                ^    'Multiplication factor
                      '00 2mhZ
                      '10 PLL Source = 32MHz internal Oscillator (divided by 4 in hardware)
Set Osc_ctrl.4                                         ' PLL enable
Bitwait Osc_status.4 , Set                             'Check if PLL is ready
Config Sysclock = Pll , Prescalea = 1 , Prescalebc = 1_1       ' configure the systemclock ---> use PLL


Config Com1 = 57600 , Mode = Asynchroneous , Parity = None , Stopbits = 1 , Databits = 8
Open "COM1:" For Binary As #1

Const Maxwordbit = 6                                        ' Z7 is maximum bit                                   '
Const Maxword =(2 ^ Maxwordbit) * 2                         '128
Const Maxwordshift = Maxwordbit + 1

Dim Bstatus As Byte , Bretries As Byte , Bmincount As Byte , Bblock As Byte , Bblocklocal As Byte
Dim Bcsum1 As Byte , Bcsum2 As Byte , Buf(128) As Byte , Csum As Byte
Dim Spmcrval As Byte                                        ' self program command byte value

Dim Z As Long                                               'this is the Z pointer word
Dim Vl As Byte , Vh As Byte                                 ' these bytes are used for the data values
Dim Wrd As Word , Page As Word                              'these vars contain the page and word address

Disable Interrupts                                          'we do not use ints
Rampz = 0

Const Cnak = &H15
Const Cack = &H06
Const Ccan = &H18

Print #1 , "Bootloader ... 32E5"

'etc.

End
 


This sets up the COM1 UART on uC pins C2/C3 and the Bootloader works perfectly.

Then, once the Main Program is loaded in - BUT using a different uC clock speed (in this example 24MHz vs 22Mhz - but any clock combination seems to result in the same problem), then the UART output is GARBLED. (I have not tested the Input).

It appears that some of the UART setup parameters are not updated or are mixed up between the Bootloader and Main?

Code:

$regfile = "xm32E5def.dat"
$hwstack = 80
$swstack = 80
$framesize = 80

$crystal = 24000000
Config Osc = Enabled , 32mhzosc = Disabled                  'internal 2 MHz and 32 MHz enabled
Osc_pllctrl = &B00_0_01100                                  ' 2MHz clock Source and Multiplication factor * 12 = 24
              '                ^    'Multiplication factor
                      '00 2mhZ
                      '10 PLL Source = 32MHz internal Oscillator (divided by 4 in hardware)
Set Osc_ctrl.4                                              ' PLL enable
Bitwait Osc_status.4 , Set                             'Check if PLL is ready
Config Sysclock = Pll , Prescalea = 1 , Prescalebc = 1_1       ' configure the systemclock ---> use PLL

Config Com1 = 57600 , Mode = Asynchroneous , Parity = None , Stopbits = 1 , Databits = 8
Open "COM1:" For Binary As #2

Print #2 , "Hello Blinky"

Red_led Alias Portc.7
Config Red_led = Output
Red_led = 1

Do
    Toggle Red_led
    Wait 5
    Select Case Red_led
      Case 0 : Print #2 , "Off"
      Case 1 : Print #2 , "On"
    End Select

Loop
End
 


Am I making an error, or is this a bug/feature?

BTW - This problem does not appear if the Bootloader and Main Clock Speeds are the same.

Please let me know if someone needs the complete MCS Sample Bootloader.
E

(BASCOM-AVR version : 2.0.7.8 )
Back to top
View user's profile
MWS

Bascom Member



Joined: 22 Aug 2009
Posts: 2262

blank.gif
PostPosted: Sat Jul 15, 2017 5:44 am    Post subject: Reply with quote

Software-technical bootloader-code and main code are completely independent, means register values are actually calculated and written based on the respective code. What's not altered, beside by a reset (which would again start the loader), are hardware register values, which of course are able to be the culprit.
Quote:
It appears that some of the UART setup parameters are not updated
Can you substantiate this assessment?
It can as well be, that the desired main clock does not match, maybe it is locked after its first change done by bootloader, thought about that?
The bootloader configures a disabled PLL, while at the main code the PLL is already running.
It's a guess, I did not look up the data sheet, but I know some clock settings may need a special sequence, which also may apply for re-configuration of the PLL.

Further I know how the compiler behaves. The serial config is identical in both codes, so the only difference in configuration is the different value written to the baud rate register. The compiler writes this value absolutely and does not depend on a previous value, so the serial config is likely correct then.
But if a serial baud rate register mismatch is unlikely, the remaining potential error is the main clock.

Try to set more differing clock frequencies 16/24MHz and run a simple one second blink code to check, if your main clock matches.
Back to top
View user's profile
enniom

Bascom Member



Joined: 20 Oct 2009
Posts: 537

PostPosted: Sat Jul 15, 2017 12:39 pm    Post subject: Reply with quote

Thanks MWS for taking the time to study this question.

Quote:
Quote: It appears that some of the UART setup parameters are not updated

Can you substantiate this assessment?

The evidence is that the UART output from the Main Program is either non-existent or garbled as if an incorrect Baud Rate had been specified.

FYI. It is not just the PLL. The problem appears regardless of the clock source (although I have not tested an external oscillator).

Quote:
What's not altered, beside by a reset (which would again start the loader), are hardware register values, which of course are able to be the culprit.

I did not know this, but this is likely where the problem might be. So, to be sure I understand, once the hardware registers are set, there is no method available to change their values after exiting the Bootloader - other than one of the Reset methods; Watchdog, Power, Software, BOD, etc.???

Do you have a way of finding the culprit hardware registers?

E
Back to top
View user's profile
MWS

Bascom Member



Joined: 22 Aug 2009
Posts: 2262

blank.gif
PostPosted: Sat Jul 15, 2017 2:42 pm    Post subject: Reply with quote

enniom wrote:
The evidence is that the UART output from the Main Program is either non-existent or garbled as if an incorrect Baud Rate had been specified.
That's no evidence, that is only a hint.
It would be possible in the same, that the new system clock is not accepted, then the baud rate registers in main code are configured for 24MHz, while the actual speed is still 22MHz.

Did you try and forgot about the answer, or did you ignore it?
Quote:
Try to set more differing clock frequencies 16/24MHz and run a simple one second blink code to check, if your main clock matches.

Hmm, when did you learn that:
Quote:
I understand, once the hardware registers are set, there is no method available to change their values after exiting the Bootloader

The bootloader is only a preceding program which is able to alter the flash, or in the alternative case executing the main program.
Bascom's startup code then clears by default the complete SRam, sets the hardware registers according the main code's config-statements and then executes the main code itself.

After hard reset the hardware registers contain a default value. Now, as explained the bootloader simply is another chain of code, registers altered by the bootloader stay altered till they are overwritten by following main code. Or till a hard/watchdog/brownout-reset occurs

If in main code the UART is used and baud rate is defined, then this will overwrite previous baud rate settings.

Of course bugs are always possible, one possibility is if the compiler expects a certain default value and does not explicitly write this value.
For example, if the bootloader sets CLK2X in USART Register CTRLB and the main code, as well as it correctly sets values for BSEL and BSCALE in BAUDCTRLA/B, does not touch CTRLB, just because the calculation in main code did not require to set CLK2X.
This would result in an incorrect baud rate.
Description of these registers you find in the ATXMega E manual.

For debugging I would either simulate the main code and look what happens on ASM level, alternatively I would look up xm32E5def.dat and check the correct names for the used UART's configuration registers.
Then I would write some short code in main, which reads all affected UART registers, saves them to EEProm an then simply stops. As UART produces garbled output, this seems the only useful way.
Blinking them out via Morse code would be an less sophisticated alternative. Very Happy

You should be able to get the EEProm-values by reading out the EEProm in the programmers window.

These values I would compare then with values I'd get from a simulation.
Back to top
View user's profile
albertsm

Administrator



Joined: 09 Apr 2004
Posts: 5921
Location: Holland

blank.gif
PostPosted: Sat Jul 15, 2017 8:19 pm    Post subject: Reply with quote

the only real diff between the 2 programs is the value of the baud registers which are :
bootloader:
Ldi R24, 112 ;USART_BAUDA
St x+,R24 ; BAUDCTRLA
Ldi R24, 155 ;USART_BAUDB
St x,R24 ; BAUDCTRLB

normal app
Ldi R24, 133 ;USART_BAUDA
St x+,R24 ; BAUDCTRLA
Ldi R24, 156 ;USART_BAUDB
St x,R24 ; BAUDCTRLB

this has to do with the change in $crystal between the 2 of them.
But both versions write to the same registers.

you could rule out rampz by using:
$initmicro
_init_micro:
rampz = 0
return

_________________
Mark
Back to top
View user's profile Visit poster's website
MWS

Bascom Member



Joined: 22 Aug 2009
Posts: 2262

blank.gif
PostPosted: Sat Jul 15, 2017 9:09 pm    Post subject: Reply with quote

albertsm wrote:
BAUDCTRLA
BAUDCTRLB
Is CTRLB (CLK2X) written?
Back to top
View user's profile
albertsm

Administrator



Joined: 09 Apr 2004
Posts: 5921
Location: Holland

blank.gif
PostPosted: Sat Jul 15, 2017 9:20 pm    Post subject: Reply with quote

that should not matter since the entire register is written. but it isnt set.
_________________
Mark
Back to top
View user's profile Visit poster's website
enniom

Bascom Member



Joined: 20 Oct 2009
Posts: 537

PostPosted: Sun Jul 16, 2017 2:03 am    Post subject: Reply with quote

Thank-you Mark and MWS for your help and guidance.

It seems RAMPZ = 0 (or =1) does not affect the results for this 32E5. The UART output in the main program remains garbled but OK in the BL.

I was able to see the C0 UART Registers in the Bootloader and Main using MWS's suggestion for storing in EEPROM:

Quote:

Register.....................BL........................Main
USARTC0_BAUDCTRLA.70(112) 01110000 85(133) 10000101
USARTC0_BAUDCTRLB.9B(155) 01110000 9C(156) 10011100
USARTC0_CTRLA.........00 00000000 00 00000000
USARTC0_CTRLB.........18 00011000 18 00011000
USARTC0_CTRLC.........03 00000011 03 00000011
USARTC0_CTRLD.........00 00000000 00 00000000


The BAUDCTRLA/B registers have the same values as Mark's post.

This is what the "Off" "On" output looks like in the Main Program:

Quote:
淅ニ
鉦
照ニ

照ニ湮
照ニ

照ニ鉦
淅ニ


Or HEX:
Quote:
8F C6 C6 0D 1A 8F DE 0D 1A 9F C6 C6 0D 1A 8F DE
0D 1A 8F C6 C6 0D 0A 8F CE 0D 0A 8F C6 C6 0D 1A
8F CE 0D 1A 8F C6 C6 0D 1A 8F CE 0D 0A 8F C6 C6
1D 0A 8F CE 0D 1A 8F C6 C6 0D 0A


Interestingly, the chr(13) chr(10) combination appears occasionally???

E
Back to top
View user's profile
enniom

Bascom Member



Joined: 20 Oct 2009
Posts: 537

PostPosted: Sun Jul 16, 2017 2:44 am    Post subject: Reply with quote

------Update-------

It seems as if regardless of which clock source is used with the PLL (ie: 2MHz or 32/4MHz), then the uC clock speed cannot be changed from the BL to the Main Program. Only the first clock speed set in the BL remains active. However, the Config COMx statement in the Main modify the UART Baud Rate registers which were used in the BL and the output gets garbled.


I will continue testing and post any conclusions I reach.
Back to top
View user's profile
albertsm

Administrator



Joined: 09 Apr 2004
Posts: 5921
Location: Holland

blank.gif
PostPosted: Sun Jul 16, 2017 11:05 am    Post subject: Reply with quote

from the data sheet : "Hardware ensures that the PLL configuration cannot be changed when the PLL is in use. The PLL must be disabled
before a new configuration can be written."

this means that you need to set the system clock to say 32 mhz clock first , then change pll settings, then change back to internal clock for pll.

_________________
Mark
Back to top
View user's profile Visit poster's website
enniom

Bascom Member



Joined: 20 Oct 2009
Posts: 537

PostPosted: Sun Jul 16, 2017 12:30 pm    Post subject: Reply with quote

Thank-you Mark.

It was difficult to think of checking the PLL section of the Data Sheet when the symptoms were related to the UART.

I can confirm that this works properly to change the Clock Speed between the Bootloader and Main when using the PLL:

In BL:
Code:
$crystal = 22000000
Config Osc = Enabled , 32mhzosc = Disabled                  'internal 2 MHz and 32 MHz enabled
Osc_pllctrl = &B00_0_01011                                  ' 2MHz Clock Source * 11 = 22
Set Osc_ctrl.4                                              ' PLL enable
Bitwait Osc_status.4 , Set                                  'Check if PLL is ready
Config Sysclock = Pll , Prescalea = 1 , Prescalebc = 1_1    ' configure the systemclock ---> use PLL


In Main:
Code:
Config Osc = Enabled , 32mhzosc = Disabled                  'internal 2 MHz enabled
Config Sysclock = 2mhz , Prescalea = 1 , Prescalebc = 1_1   'use 2 MHz

$crystal = 24000000
Config Osc = Enabled , 32mhzosc = Disabled                  'internal 2 MHz
Osc_pllctrl = &B00_0_01100                                  ' 2MHz Clock Source * 12 = 24
Set Osc_ctrl.4                                              ' PLL enable
Bitwait Osc_status.4 , Set                                  'Check if PLL is ready
Config Sysclock = Pll , Prescalea = 1 , Prescalebc = 1_1    ' configure the systemclock ---> use PLL


With proper UART function.

E
Back to top
View user's profile
albertsm

Administrator



Joined: 09 Apr 2004
Posts: 5921
Location: Holland

blank.gif
PostPosted: Sun Jul 16, 2017 1:39 pm    Post subject: Reply with quote

first test should have been the speed test to see if the $crystal matches up to the expectations.
it is what i always write to users with baud problems. but i am glad it is solved.

_________________
Mark
Back to top
View user's profile Visit poster's website
MWS

Bascom Member



Joined: 22 Aug 2009
Posts: 2262

blank.gif
PostPosted: Sun Jul 16, 2017 4:24 pm    Post subject: Reply with quote

enniom wrote:
It was difficult to think of checking the PLL section of the Data Sheet when the symptoms were related to the UART.
No, imho it was not difficult, it was my first thought.
MWS wrote:
It can as well be, that the desired main clock does not match, maybe it is locked after its first change done by bootloader, thought about that?

The trick is always to open your mind and look over the edge of the can you're sitting in.
Your mother would now tell you, "boy, I told you so".
Well, I'm not your mother, but:
I told you so Very Happy Very Happy Very Happy

Edit:
AVR1003: Using the XMEGA Clock System, page 7:
Quote:
The PLL configuration cannot be changed without disabling it first. Hardware will disregard any attempts to change the configuration while it is enabled.


Last edited by MWS on Sun Jul 16, 2017 4:55 pm; edited 1 time in total
Back to top
View user's profile
enniom

Bascom Member



Joined: 20 Oct 2009
Posts: 537

PostPosted: Sun Jul 16, 2017 4:44 pm    Post subject: Reply with quote

MWS, you were way ahead of me. I didn't understand what I was being told.

As always, thank you to both you and Mark for your time and patience.

E
Back to top
View user's profile
Display posts from previous:   
Post new topic   Reply to topic    www.mcselec.com Forum Index -> BASCOM-AVR All times are GMT + 1 Hour
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You cannot download files in this forum