Justin Caselton

illegal_BP abd frequency changes

Discussion created by Justin Caselton on Mar 11, 2009
Latest reply on Mar 12, 2009 by bigmac

I am using an S08DZ16CLC and have designed a program to measure the voltage across two potentiometers and output the data on the CAN bus. 

 

The program seems to work until it enters the calibration function when a push button is pressed.  Upon entering callibration mode an LED is turned on and then off upon exiting the function.  As the program is being run using a 4MHz crystal, the LED should be on for a minimum of approx. 4 seconds, but it is significantly less than this.

 

More seriously, when in this callibration function, the debugger will often complain of a frequency change and an illegal_BP and halt the running of the program.  My code is shown below, any help would be greatly appreciated!

 

//CALIBRATION RESULTS - GLOBAL VARIABLES
static unsigned int brk_cal_max = 0;
static unsigned int brk_cal_min = 255; //set to max range so all values less than initial
static unsigned int brk_cal_result = 0;

static unsigned int ac_cal_max = 0;
static unsigned int ac_cal_min = 255; //set to max range so all values less than initial
static unsigned int ac_cal_result = 0;


//FUNCTION TO PERFORM PEDAL CALIBRATION

unsigned int calibrate_pedals() {
   
    unsigned long int a,n,m,p;           
    /*
    asm{
      NOP
    }
    */
   
    PTCD_PTCD5 = 0;      //light LED1
 
 
  //for(p=0;p<0xFFFFFF;p++){  
  //for(m=0;m<0xFFFFFF;m++){  
    for(n=0;n<0xFFFFFF;n++){      //loop in cal mode
   
        for(a=0;a<5;a++) {
   
            ADCSC1_ADCH=0x0D;   //select rv2
         
            ADCSC1_ADCO=0;        //trigger conversion
            while (!ADCSC1_COCO); //remain idle until conversion comple      
 
            brk_cal_result = (unsigned int)ADCRL;
 
            if(brk_cal_result>brk_cal_max){
                brk_cal_max = brk_cal_result;
            }
            if(brk_cal_result<brk_cal_min){
                brk_cal_min = brk_cal_result;
            }
        }
       
        for(a=0;a<5;a++){
 
            ADCSC1_ADCH=0x0C;     //select rv1
         
            ADCSC1_ADCO=0;        //trigger conversion
            while (!ADCSC1_COCO); //remain idle until conversion complete
 
 
            ac_cal_result = (unsigned int)ADCRL;
 
            if(ac_cal_result>ac_cal_max){
                ac_cal_max = ac_cal_result;
            }
            if(ac_cal_result<ac_cal_min){
                ac_cal_min = ac_cal_result;
            }
        }
    }   
  //}
  //}
 
    PTCD_PTCD5 = 1;   //turn off calibration LED

}


//FUNCTION TO SEND ACCELERATOR AND BRAKE POSITION OVER CAN
static void send_can_data(unsigned long accelpos, unsigned long breakpos) {
   
    int n;
    while (!CANCTL0_SYNCH);   //test if synched to CAN bus
        
    while(!CANTFLG_TXE0);    //test to see which buffers are empty
  
    CANTTBPR = 0x00; 
    CANTIDR0 = 0xD0;     //set CAN id.
    CANTIDR1 = 0x00;


    CANTDSR0 = (unsigned char)accelpos;   
    CANTDSR1 = (unsigned char)breakpos; 

   
    CANTFLG = 0x01;               //clear the buffer, transmit
     
   
    //while(CANTFLG_TXE0);        //wait for flag to clear
   
    CANTFLG = 0x00;
   
      PTBD_PTBD3=0;               //CAN light on
    for(n=0;n<0xFFFF;n++);        //delay
    PTBD_PTBD3=1;                 //CAN light off     
}




void main(void) {

 
    unsigned int accel_result =0;
    unsigned long accel_total = 0;
    unsigned long accel_average = 0;
    unsigned long accelpos =0;
 
    unsigned int break_result =0;
    unsigned long break_total = 0;
    unsigned long break_average = 0;
    unsigned long breakpos =0;
 
    int n;
    int a;
    int b;
 
   
//    MCGC2 = 0x62;                        /* Set MCGC2 register */
  /* MCGC1: CLKS=0,RDIV=7,IREFS=0,IRCLKEN=0,IREFSTEN=0 */
//  MCGC1 = 0x38;                        /* Set MCGC1 register */
  /* MCGC3: LOLIE=0,PLLS=0,CME=0,VDIV=1 */
//  MCGC3 = 0x01;                        /* Set MCGC3 register */
//  while(MCGSC_IREFST) {                /* Wait until external reference is selected */
//  }
//  while(!MCGSC_LOCK) {                 /* Wait until FLL is locked */
//  }
//  while((MCGSC & 0x0C) != 0x00) {      /* Wait until FLL clock is selected as a bus clock reference */
//  }
 
    
    MCGC2_RANGE = 1;            // High freq clock range selected
    MCGC2_EREFS = 1;            // External Ref Clock selected to be Internal Osc
    MCGC2_ERCLKEN = 1;            // Ext Ref Clk Enabled
   
    while(!MCGSC_OSCINIT);        //wait for oscillator to initialize
   
    MCGC1 = 0x00;                //Multi-purpose Clock Generator config register1

    while(MCGSC_CLKST == 3);    //wait until output of PLL is selected as clock
 
 
    //MCGC1=0x80;  //external ref clk selected, divided by 1
    //MCGC2=0x33;
   
     
 
    EnableInterrupts; /* enable interrupts */
 
///////////////////////////////////////////////////////////////////////////// 

  //Initialise CAN     
 
    CANCTL1_CANE = 1;        /* for test: MSCAN enabled, clock = OSC_CLK, listen only disabled, wake-up filter disabled */
    CANCTL0_INITRQ = 1;    /* init mode */
    while(!CANCTL1_INITAK);            /* wait for ack of init mode */
 
 
     CANCTL1 = 0x80;                   /* enable module with osc clk as source */
    CANBTR0 = 0xC1;            /* SJW = 1, SJW = 1, 4Tq jmpwdt  prescaler = 2 */
    CANBTR1 = 0xD8;            /* SAMP = 1, 3 samples/bit, TSEG2 = 5, TSEG1 = 8, 15 Tq per bit */

    CANIDAC = 0x10;      //Initialise for 8bit mask
    CANIDMR0 = 0x00;     //All accemptance masks to 0x00 (accept nothing)
    CANIDMR1 = 0x00;
    CANIDMR2 = 0x00;
    CANIDMR3 = 0x00;

    CANCTL0_INITRQ = 0;    /* leave init mode */
    while(CANCTL1_INITAK);            /* wait for ack of init mode exit */
 
    CANTBSEL = 0x01;    //select transmit buffer TX0
    CANRFLG = 0x40;
    CANRIER = 0;
    CANTARQ = 0;
    CANTIER = 0x00;              /* transmit buffer empty interrupts disabled for TX0*/
 
////////////////////////////////////////////////////////////////////////// 
 
    /*initialise ADC*/
 
    ADCCFG=0x90;  //configured for low power, 8 bit, long samples, bus clk src
    ADCSC2=0x00;  //see log book for value breakdown
    ADCSC1=0x21;  //AIEN disabled, input channel 1
 
    APCTL1=0x02;  //AD1 pin I/O control disabled, all others general I/O
    APCTL2=0x10;  //all other pins general I/O, except adp12
 
    ADCSC1_ADCH=0x0D; //ensure channel 13, rv2 as input
    ADCSC1_ADCH=0x0C;
 
///////////////////////////////////////////////////////////////////////////// 
 
    //PTCPE_PTCPE5 = 1;     //PB1 pull up enable
 
    PTCDD_PTCDD5 = 1;     //set LED1 as calibration output
    PTBDD_PTBDD3 = 1;     //set LED2 as CAN output
    PTBDD_PTBDD6 = 0;     //set PB1 as input
    PTCD_PTCD5 = 1;       //make sure LED1 is initially off
    PTBD_PTBD3 = 1;       //make sure LED2 is initially off
 

    //read the ADC
  
    for(;:smileywink: {   //infinite loop
        //Test button on port B pin 6 for calibration mode
        if (!PTBD_PTBD6) {
            calibrate_pedals();
        }
   
        for(n=0;n<3;n++){

            for(a=0;a<5;a++){
           
              ADCSC1_ADCH=0x0C;
             
              ADCSC1_ADCO=0;        //trigger conversion
              while (!ADCSC1_COCO); //remain idle until conversion complete
        
              break_result = (unsigned int)ADCRL;
              break_total = break_total + break_result;
             
           }
          
           for(a=0;a<5;a++) {    //loop so 10 adc values read CHANGED FOR TEST
         
              ADCSC1_ADCH=0x0D;
             
              ADCSC1_ADCO=0;        //trigger conversion
              while (!ADCSC1_COCO); //remain idle until conversion complete
        
              accel_result = (unsigned int)ADCRL;
              accel_total = accel_total + accel_result;
             
            }
       
        }
       
        
        accel_average = accel_total/10;
        accelpos =((accel_average*256)/(ac_cal_max - ac_cal_min));
       
        break_average = break_total/10;
        breakpos =((break_average*256)/(brk_cal_max - brk_cal_min));
       
        accel_total = 0;
        break_total = 0;
       
        //delay loop provide time for CAN to respond
        //to ADC
        for(n=0;n<0xFFFF;n++);
     
///////////////////////////////////////////////////////////////////////////
      
        //Send over CAN
        send_can_data(accelpos, breakpos);
          
     
        __RESET_WATCHDOG(); /* feeds the dog */  
       
       /* loop forever */
      /* please make sure that you never leave main */
    }
}
 

Any help would be greatly appreciated!!

 

Thank you.

Outcomes