LC60: SCI / Generating 1 second pulse for calibration

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

LC60: SCI / Generating 1 second pulse for calibration

4,419 Views
BasePointer
Contributor II
Hi,
 
I'm tring to generate accurate two falling egdes that have 1 second between them. MCU is in FBE mode and fbus=16,384 Hz. I have set baud rate divider to 128 at this bus frequency and send data binary 1 over SCI1. The data sent over TX pin has signal exatcly that I want. There is no problem on there. But eith the code below, RS485 line is disabled about 5.25sec later. Sending operation is not starting immediately I write to SCID register. The function should be completed with in about 1.25second.
 
Code:
void test(void){    DisableInterrupts;        // 8 data, 1 stop, no parity    SCIC1 = 0; SCIC2 = 0; SCIC3 = 0;            SCIBD = 128;  // set baud to 8    SCIC3_TXINV = 1;    SCIC2_TE = 1;        __RESET_WATCHDOG();        ICGC2 = 8; // Generate a reset request on loss of clock.    ICGC1 = 0b00110100;   // FBE mode, fbus=16,384 Hz, clock monitor enabled        while(ICGS1_CLKST != FBE) __RESET_WATCHDOG();        RS485_TX_EN(); // set TXCS pin    SCID = 1; // send a two falling edges have period one second over TX pin    while(!SCIS1_TC) __RESET_WATCHDOG();    RS485_TX_DIS(); // clear TXCS pin        asm("dcb 0x8D"); // reset the mcu   }

 See the gif file for the output of the function.
10x

 


Message Edited by BasePointer on 2007-12-27 10:13 AM
Labels (1)
0 Kudos
7 Replies

458 Views
Ake
Contributor II
Hi,
Yes your code looks OK.
But you wanted to remove the time from the
    RS485_TX_EN(); // set TXCS pin

to the code output.
I am not an expert on RS485, but the routine seems to be waiting for the TC flag.
In the 9S08LC manual it says:

Transmission Complete Flag

— TC is set out of reset and when TDRE = 1 and no data, preamble, or break

character is being transmitted.

0 Transmitter active (sending data, a preamble, or a break).

1 Transmitter idle (transmission activity complete).

TC is cleared automatically by reading SCIS1 with TC = 1 and then doing one of the following three things:

• Write to the SCI data register (SCID) to transmit new data

• Queue a preamble by changing TE from 0 to 1

• Queue a break character by writing 1 to SBK in SCIC2

Isn't the routine sending a break character, which is what is seen on the oscilloscope?

If you change the

    RS485_TX_EN(); // set TXCS pin

to

  for (;SCIS1_TC == 0:smileywink:;

and check what happens.

Regards,

Ake

 

0 Kudos

458 Views
BasePointer
Contributor II
Hi Ake,
 
Thank you for the response. I think I need to be more clear:
 
Here is my TX_EN, DIS macros, they just set port pin
Code:
#define RS485_TX_DIS()  {PTBD_PTBD3 = 0; PTBDD_PTBDD3 = 1;}#define RS485_TX_EN()   {PTBD_PTBD3 = 1; PTBDD_PTBDD3 = 1;}
 
If you look at my test code, I'm sending data immediately RS485_TX_EN() macro:
Code:
    RS485_TX_EN(); // set TXCS pin    SCID = 1; // send a two falling edges have period one second over TX pin

But according to this, if you look at attached SCI1_Startup_Time.gif, you will see it start sending data 1.365sec later after set TX_EN pin. It seems SCI module problem to me. It send two bytes after initializing SCI module first. But I'm not sure. Scope time base is 500ms/div
 
An other interesting note that, the sci module only work with this code in BDM mode. If I unplug the BDM socket end reset the MCU, it generates different TXCS form (so fast) and no TX output.
 
10x
BP.
0 Kudos

458 Views
kef
Specialist I
I think you should read SCIxS1 register before writing to SCIxD. It's a standard sequence to clear TC and TDRE flags and start a transmission: 1) read status with TDRE set, 2) write data. It was common for many MOT/FSL MCUs for many years. HC11, HC12, S12,S12X etc all do require to read status and only then write data register in order to Tx. Without reading status register I wouldn't expect any activity on Tx. I don't find it surprising your code doesn't send anything in normal mode.
 
0 Kudos

458 Views
BasePointer
Contributor II
Hi kef,
 
Thanks for your suggestion. Doesn't the code below do that it reads SCIS1 and clears TC flag if it is set? Do I need to read entire status register?
 
Code:
while(!SCIS1_TC) __RESET_WATCHDOG();

I also added line such as "dummy = SCIS1;" but the result was being same.
10x
0 Kudos

458 Views
kef
Specialist I

Sten must be right. From LC60 SCI module docs:

TE also can be used to queue an idle character by writing TE = 0 then TE = 1 while a transmission is in progress.Refer to Section 12.3.2.1, “Send Break and Queued Idle,” for more details

S12X SCI behaves exactly the same, though TE bit isn't documented equally well. It's interesting what transmission is in progress when we set TE=1 for the first time :smileyhappy:, but it seems that any TE rising edge makes SCI sending idle character.

BasePointer, regarding reading SCIS1. Your while(!SCIS1_TC) is OK for reading SCIS1 register, but it comes after you first time write to SCID register. Maybe you read it somewhere earlier then in the test() routine?

[SCID=?]   followed by   [while( !SCIS1_TC) ;]  should be OK, provided you read SCIS1 with SCIS1_TDRE set at least once before. You should clear TDRE before writing to SCID, and the only way to do that is reading TDRE==1 and writing then SCID. You say the result is the same if you read SCIS1 before SCID or not. You also said previously that you see no TX output with BDM not connected. Did you recheck if you see now TX output with no BDM connected?

Regarding unwanted idle character and delay between TXCS and TX. After writing TE=1, you should delay setting TXCS for idle character time. Try 1) setting baudrate divider to min value of 1, 2) enabling TE=1, 3) waiting for full character time at fastest baudrate, 4) setting baudrate divider to value you want (128). At least this works on S12XD.

0 Kudos

458 Views
BasePointer
Contributor II
Hi kef and Sten,
 
I added while(!SCIS1_TDRE) after set the TE bit. And SCI start working both in active background mode or not.
 
For the Idle character, I first set baudrate divider to 1 like suggested, and wait about 15ms after set MCU to FBE mode. Now the result is acceptable. Solved.gif.
 
Code:
void test(void){    DisableInterrupts;        // 8 data, 1 stop, no parity    SCIC1 = 0; SCIC2 = 0; SCIC3 = 0;            SCIBD = 1;  // set baud to 1024    SCIC3_TXINV = 1;    SCIC2_TE = 1;    while(!SCIS1_TDRE) __RESET_WATCHDOG(); // added with kef's warning        ICGC2 = 8; // Generate a reset request on loss of clock.    ICGC1 = 0b00110100;   // FBE mode, fbus=16,384 Hz, clock monitor enabled    while(ICGS1_CLKST != FBE) __RESET_WATCHDOG();        Delay20uS(1); // it waits about 15ms at that bus freq        SCIBD = 128;  // set baud to 8            RS485_TX_EN(); // set TXCS pin          SCID = 1;      while(!SCIS1_TC) __RESET_WATCHDOG();        RS485_TX_DIS(); // clear TXCS pin        asm("dcb 0x8D"); // reset the mcu   }

 
10x for the helps.
BP.
 


Message Edited by BasePointer on 2008-01-08 02:50 PM
0 Kudos

458 Views
Sten
Contributor IV
I didn't check how it is for the LC60, but on the S08DZ the SCI transmitter will start by sending a full idle character when it is enabled by writing TE to 1. This means that you will get the starbit a character's time later.
 
Sten
 
0 Kudos