SCI and Codewarrior Debug - HCS08Q8

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

SCI and Codewarrior Debug - HCS08Q8

3,190 Views
Viking
Contributor I
Hi,
 
I'm new to programming and i'm slowly working through building up a development system of my own.  I'm using the HCS08Q8 on HW i developed myself along with an LCD display.  I'm having an issue where when i run the program within the Codewarrior Debugger it behaves flawlessly (i.e. when using hyperterminal i can send characters to the uP via the RxD pin, the code then sends the character onto the LCD and its displayed as expected).  However when i run the code without the Codewarrior Debugger (and after a reset) only SOME characters are displayed correctly, where others are not??  This problem is consistant, i.e. its always the same characters which are effected.  I've monitored the RxD pin with a CRO and the bit stream of the "effected characters" are identical btw running the system under Codewarrior Debugger and out of a reset, so i know at least the character is being received at the pin correctly.   
 
If i change the line below  " LCDPrint(&SCID,1);"  to, for example,     LCDPrint("8",1); it prints 8 perfectly every time under both running conditions.  However if "8" is received by SCID over the SCI it prints "x" (It definately receives "8" at the RxD pin, CRO verified).  I've read in other posts that the SPI block has exhibited similar "quirkyness" but going through those posts and attempting to applying relevant fixes to the SCI block have not yielded any joy.
 
Any ideas?
Thanks.
 
 
#include <hidef.h> /* for EnableInterrupts macro */
#include "derivative.h" /* include peripheral declarations */
#include "gentypes.h"
#include "portsDef.h"
/**********************************************************************************************************/
/*      Function Pre Processors                                                                           */
/**********************************************************************************************************/

void delay(uint16 delayit);
uint8 CharToPrint=0;
uint8 temp; /*dummy storage variable*/
uint8 temp2;
/**********************************************************************************************************/
/*      Main Routine                                                                                     */
/**********************************************************************************************************/
void main(void) {
SOPT1 = 0x52;   /*Disable watchdog. disable STOP mode. Disable /RESET pin function*/
BaudRateH = 0x00;
BaudRateL = 0xD0; /*set baud rate to 1200bps: Baud Rate = BusClk/(16 x BaudRateH|BaudRateL) */
SCIC1 = 0x00;  /*TxD/RxD on different lines, normal mode, no parity*/
SCIC2 = 0x2C;  /*TxD int disabled, RxD int enabled, TxD/RxD on. Normal TxD/RxD*/
SCIC3 = 0x00;
PTADD = 0x0F;   /*PTA0-PTA3 output*/
PTBDD |= 0x08;  /*LED Display*/
EnableInterrupts; /* enable interrupts */
  initialiseLCD();
  cursorAddress(0x00);
 
  for(;:smileywink: {
 
  while (CharToPrint){
    LCDPrint(&SCID,1);
    CharToPrint=0;
   
  } /*end while */
  } /* end for loop forever */
  /* please make sure that you never leave main */
}
/**********************************************************************************************************/
/*      Delay Routine                                                                                     */
/**********************************************************************************************************/
void delay(uint16 delayit) {
 
  uint16 i;
  i=0;
    for (i=0;i<delayit;i++){ /*delayit value based on 4Mhz clock and this instruction 25clk cycles per run*/
    }
}

/**********************************************************************************************************/
/*      Interrupt Routines                                                                                */
/**********************************************************************************************************/

void interrupt 15 ReceiveBufferFull(void){
  if (ReceiverFull()==1){  /* 2 step process in order to clear RDRF flag i.e. this is always true*/
    temp=SCID;
  } 
  CharToPrint = 1;
}
 
Added p/n to subject.


Message Edited by NLFSJ on 2007-12-09 06:29 PM
Labels (1)
0 Kudos
Reply
5 Replies

1,212 Views
Viking
Contributor I
Hi Mac,
 
Yes you are correct, over-runs are possible.  I am teaching myself, so I do appreciate any and all coding tips.
 
Cheers.
0 Kudos
Reply

1,212 Views
Viking
Contributor I
Hi and thanks for your comments.

It's all fixed now.  I used the ProcessorExpert, selected SCI and allowed it to generate the MCUinit file.  I then cut the portion of code out of this relevant to the SCI and placed it in my code as shown below.  Away she went even after a power on reset.  Some different things the ProcessorExpert did that i hadn't was; 1) disabling of the SCI before the dummy reads and 2)the format in which the dummy reads were written (maybe the way i wrote it the compiler optimisation deleted it??)

See below for the code which works flawlessly, even after a POR! :smileyhappy:

#include <hidef.h> /* for EnableInterrupts macro */
#include "derivative.h" /* include peripheral declarations */
#include "gentypes.h"
#include "portsDef.h"

/**********************************************************************************************************/
/*      Function Pre Processors                                                                           */
/**********************************************************************************************************/


void delay(uint16 delayit);
void MCU_init(void);

uint8 CharToPrint=0;
uint8 temp; /*dummy storage variable*/


/**********************************************************************************************************/
/*      Main Routine                                                                                     */
/**********************************************************************************************************/

void main(void) {

EnableInterrupts; /* enable interrupts */
MCU_init();

  initialiseLCD();
  cursorAddress(0x00);
 
  for(;:smileywink: {
 
  while (CharToPrint){
    LCDPrint(&SCID,1);
    CharToPrint=0;
   
  } /*end while */
  } /* end for loop forever */
  /* please make sure that you never leave main */
}

/**********************************************************************************************************/
/*      Delay Routine                                                                                     */
/**********************************************************************************************************/

void delay(uint16 delayit) {
 
  uint16 i;
  i=0;

    for (i=0;i<delayit;i++){ /*delayit value based on 4Mhz clock and this instruction 25clk cycles per run*/
    }
}

void MCU_init(void)
{
  /* ### MC9S08QG8_16_QFN "Cpu" init code ... */
  /*  PE initialization code after reset */
  /* Common initialization of the write once registers */
  /* SOPT1: COPE=0,COPT=1,STOPE=0,BKGDPE=1,RSTPE=0 */
  SOPT1 = 0x52;                                     
  /* SPMSC1: LVDF=0,LVDACK=0,LVDIE=0,LVDRE=1,LVDSE=1,LVDE=1,BGBE=0 */
  SPMSC1 = 0x1C;                                     
  /* SPMSC2: PDF=0,PPDF=0,PPDACK=0,PDC=0,PPDC=0 */
  SPMSC2 = 0x00;                                     
  /* SPMSC3: LVDV=0,LVWV=0 */
  SPMSC3 &= (unsigned char)~0x30;                    
  /*  System clock initialization */
  ICSTRM = *(unsigned char*far)0xFFAF; /* Initialize ICSTRM register from a non volatile memory */
  ICSSC = *(unsigned char*far)0xFFAE;  /* Initialize ICSSC register from a non volatile memory */
  /* ICSC1: CLKS=0,RDIV=0,IREFS=1,IRCLKEN=0,IREFSTEN=0 */
  ICSC1 = 0x04;                        /* Initialization of the ICS control register 1 */
  /* ICSC2: BDIV=1,RANGE=0,HGO=0,LP=0,EREFS=0,ERCLKEN=0,EREFSTEN=0 */
  ICSC2 = 0x40;                        /* Initialization of the ICS control register 2 */
  /* Common initialization of the CPU registers */
  /* ### Init_SCI init code */
  /* SCIC2: TIE=0,TCIE=0,RIE=0,ILIE=0,TE=0,RE=0,RWU=0,SBK=0 */
  SCIC2 = 0x00;                        /* Disable the SCI module */
  (void)(SCIS1 == 0);                  /* Dummy read of the SCIS1 registr to clear flags */
  (void)(SCID == 0);                   /* Dummy read of the SCID registr to clear flags */
  /* SCIBD: SBR12=0,SBR11=0,SBR10=0,SBR9=0,SBR8=0,SBR7=1,SBR6=1,SBR5=0,SBR4=1,SBR3=1,SBR2=0,SBR1=1,SBR0=0 */
  SCIBD = 0xDA;                                     
  /* SCIC1: LOOPS=0,SCISWAI=0,Rsrc=0,M=0,WAKE=0,ILT=0,PE=0,PT=0 */
  SCIC1 = 0x00;                                     
  /* SCIC2: TIE=0,TCIE=0,RIE=1,ILIE=0,TE=0,RE=1,RWU=0,SBK=0 */
  SCIC2 = 0x2C;                                     
  /* SCIC3: R8=0,T8=0,TXDIR=1,TXINV=0,ORIE=0,NEIE=0,FEIE=0,PEIE=0 */
  SCIC3 = 0x00;                                     
  /* ### */
  PTADD = 0x0F;   /*PTA0-PTA3 output*/
  PTBDD |= 0x08;  /*LED Display*/
                          
} /*MCU_init*/


/**********************************************************************************************************/
/*      Interrupt Routines                                                                                */
/**********************************************************************************************************/


void interrupt 15 ReceiveBufferFull(void){

  if (ReceiverFull()==1){  /* 2 step process in order to clear RDRF flag i.e. this is always true*/
    temp=SCID;
  } 
  CharToPrint = 1;
}  
0 Kudos
Reply

1,212 Views
bigmac
Specialist III
Hello,
 
I still find your code a little unusual in one respect.  You are using the SCI receive interrupt to clear the flag, but do not read the character value until the LCDPrint() function is called, but this cannot occur until the previous character write is completed.  I realize your serial rate is only 1200 bits per second, but LCD displays can be notoriously slow, so it may be possible that a new character arrives before the previous one can be read.
 
With your present code, there seems little point in using the receive interrupt - simply poll the flag from within the main loop, and if set, send the character to the display.  An overrun is still possible, but at least the SCI overrun flag will become set, and if necessary, can be tested during debug.
 
   if (SCIS1_RDRF) {
      /* Test for overrun here, if necessary */
      LCDPrint( &SCID,1);
   }
 
However, to minimize potential overruns you would need to use the receive interrupt, and from within the ISR, the character value would be read and stored in a circular (FIFO) buffer.  From within the main loop, the next character can then be fetched from the buffer and sent to the display.  This is probably the traditional approach, but is more complex than polled operation.
 
Regards,
Mac
 
0 Kudos
Reply

1,212 Views
peg
Senior Contributor IV
Hello and welcome Viking,

Can you give us a list of what character changes into what wrong character, just a few examples.
Maybe this will provide some clues.
Also some samples of characters that always work.

0 Kudos
Reply

1,212 Views
PeterHouse
Contributor I
I do not use CW.

I am thinking you may have an issue where it runs a little bit slower with the debugger since it is taking time to read memory and do its thing.  When the debugger is not present, you are writing to the LCD to quickly and this is where character are getting lost.

You could try toggling an output pin for the reception of each character and check with a 'scope to make sure every character is received.

You could put in a large delay, around 100ms, after each write to the LCD and see if it makes any difference.

Good Luck,

Peter House
0 Kudos
Reply