I have strange problem with LRAE bootloader. To example code from AN2546 I add a few lines which send by SCI the string: "LRAE\n". Code:
if (*(tU16 *)APPLICATION_START == ERASED)
{
/* ensure interrupts are disabled */
asm sei;
/* initialise the system clock. Fbus = 8MHz. Assumes 4MHz Oscillator */
CRG.synr.byte = 0x3; /* configure the PLL */
CRG.refdv.byte = 0x40;
CRG.postdiv.byte = 0x1;
while(!CRG.crgflg.bit.lock) /* wait for PLL to lock */
{
}
CRG.clksel.bit.pllsel = 1; /*select the PLL as the clock source */
/* continue with the LRAE routines */
asm lds #$4000;
//Initialize();
Delay(500);
SCI0.scibdh.byte = 0;
SCI0.scibdl.byte = SCI_Prescaler[0];
/* enable SCI0 to receive */
SCI0.scicr2.bit.re = 1;
SCI0.scicr2.bit.te = 1;
while (SCI_Ptr->scisr1.bit.tdre == 0){}; // Wait until Transmit Data Register is empty.
SCI_Ptr->scicr2.bit.te = 1;
SCI_Ptr->scidrl.byte = 'L';
while (SCI_Ptr->scisr1.bit.tdre == 0){}; // Wait until Transmit Data Register is empty.
SCI_Ptr->scicr2.bit.te = 1;
SCI_Ptr->scidrl.byte = 'R';
while (SCI_Ptr->scisr1.bit.tdre == 0){}; // Wait until Transmit Data Register is empty.
SCI_Ptr->scicr2.bit.te = 1;
SCI_Ptr->scidrl.byte = 'A';
while (SCI_Ptr->scisr1.bit.tdre == 0){}; // Wait until Transmit Data Register is empty.
SCI_Ptr->scicr2.bit.te = 1;
SCI_Ptr->scidrl.byte = 'E';
while (SCI_Ptr->scisr1.bit.tdre == 0){}; // Wait until Transmit Data Register is empty.
SCI_Ptr->scicr2.bit.te = 1;
SCI_Ptr->scidrl.byte = '\n';
......................................................
Problem is showing as follows:
- LRAE starts,
- *(tU16 *)APPLICATION_START is empty so LRAE is configuring PLL, SCI
- "LRAE\n" string is sending, but not always. Usually < 50% of resets causes sending of this string. But when I turn on debug and put a breakpoint on first line:
while (SCI_Ptr->scisr1.bit.tdre == 0){};
I see the all instructions below are executed! However I dont receive any bytes on PC. I check register SCI0 and all is ok.
I dont now where the problem is. Please help me.
Best regards
Lukasz
Solved! Go to Solution.
Thanks for reply. Admittedly this is not guilt of .te bit. They have no sense they are setted all the time I wand send a char. But I find my bug . I dont set a pointer SCI_Ptr before a section which send "LRAE" string but after, when LRAE is waiting for synchronization byte 0x55. Because of sometimes afer reset pointer was correct and sometimes wasn't.
However thanks because you impel me to check a values of registers .
Best regards
Lukasz
Writing to SCICR2 register should queue idle character preambule for transmition (please check the docs). If it queues idle char for transmision, then in case transfer is already in progress, TDRE bit should get cleared after setting .te=1. And your core looks as follows:
SCI_Ptr->scidrl.byte = 'L';
while (SCI_Ptr->scisr1.bit.tdre == 0){}; // Wait until Transmit Data Register is empty.
SCI_Ptr->scicr2.bit.te = 1;
SCI_Ptr->scidrl.byte = 'R';
^^ here you queue 'L' char, wait for TDRE=1, queue idle character by setting .te=1, then without waiting for TDRE=1, you write 'R' to data register.
I think you should either remove .te=1 lines, or add necessary loops while(!TDRE).
Thanks for reply. Admittedly this is not guilt of .te bit. They have no sense they are setted all the time I wand send a char. But I find my bug . I dont set a pointer SCI_Ptr before a section which send "LRAE" string but after, when LRAE is waiting for synchronization byte 0x55. Because of sometimes afer reset pointer was correct and sometimes wasn't.
However thanks because you impel me to check a values of registers .
Best regards
Lukasz