Monday, January 16, 2006

Interrupts, timer, LED code

Fun time figuring out flags and interrupts to get this work on my M68DEMO908GB60.
-------------------------------
/* File: M68DEMO908GB60.h*/
/* include peripheral declarations */
#include <MC9S08GB60.h>
/*define value for led's when on and off*/
#define ON 0
#define OFF 1
/*define value for switches when up (not pressed) and down (pressed)*/
#define UP 1
#define DOWN 0
/*define led's*/
#define LED1 PTFD_PTFD0
#define LED2 PTFD_PTFD1
#define LED3 PTFD_PTFD2
#define LED4 PTFD_PTFD3
#define LED5 PTDD_PTDD0

/*define switches*/
#define SWITCH1 PTAD_PTAD4
#define SWITCH2 PTAD_PTAD5
#define SWITCH3 PTAD_PTAD6
#define SWITCH4 PTAD_PTAD7

#define Vspi 15
#define Vkeyboard 22
//define Timer1 interrupts
#define VTimer1Overflow 8
#define VTimer1Chnl2 7
#define VTimer1Chnl1 6
#define VTimer1Chnl0 5

//define Timer2 interrupts
#define VTimer2Overflow 14
#define VTimer2Chnl4 13
#define VTimer2Chnl3 12
#define VTimer2Chnl2 11
#define VTimer2Chnl1 10
#define VTimer2Chnl0 9

#define Vatd 23
#define Viic 24
-------------------------------


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

#define PRESCALAR 7
#define MODULUS 32768
#define DUTY75 (MODULUS-(MODULUS/4))
#define DUTY25 (MODULUS/4)
int sequenceNumber = 0;

void resetLEDs(){
 LED1 = OFF;
 LED2 = OFF;
 LED3 = OFF;
 LED4 = OFF;
 LED5 = OFF;
}

void interrupt Vkeyboard intSWITCH1(){
  resetLEDs();
  if(SWITCH1 == DOWN){
    sequenceNumber = 1;
  }else if(SWITCH2 == DOWN){
    sequenceNumber = 2;
  }else if(SWITCH3 == DOWN){
    sequenceNumber = 3;
  }else if(SWITCH4 == DOWN){
    sequenceNumber = 0;
  }
   
  KBI1SC_KBACK = 1;//ack
}

/*
* Reset all LEDs
*/
int ledsAreReset(){
 return ((LED1 == OFF) && (LED2 == OFF)&&(LED3 == OFF)&&(LED4 == OFF)&&(LED5 == OFF));
}

/*
* Light up the LEDs in sequence
*/
void ledLightInSeq(){
  if(((LED1 == OFF) && (LED5 == ON)) || (ledsAreReset())){
     resetLEDs();
     LED1 = ON;
   }else if((LED2 == OFF) && (LED1 == ON)){
     resetLEDs();
     LED2 = ON;
   }else if((LED3 == OFF) && (LED2 == ON)){
     resetLEDs();
     LED3 = ON;
   }else if((LED4 == OFF) && (LED3 == ON)){
     resetLEDs();
     LED4 = ON;
   }else if((LED5 == OFF) && (LED4 == ON)){
     resetLEDs();
     LED5 = ON;
   }
}
/*
* Light up the LEDs in reverse sequence
*/
void ledLightRevSeq(){
  if(((LED5 == OFF) && (LED1 == ON)) || (ledsAreReset())){
     resetLEDs();
     LED5 = ON;
   }else if((LED4 == OFF) && (LED5 == ON)){
     resetLEDs();
     LED4 = ON;
   }else if((LED3 == OFF) && (LED4 == ON)){
     resetLEDs();
     LED3 = ON;
   }else if((LED2 == OFF) && (LED3 == ON)){
     resetLEDs();
     LED2 = ON;
   }else if((LED1 == OFF) && (LED2 == ON)){
     resetLEDs();
     LED1 = ON;
   }
}

/*
* Light LEDs from middle going out
*/
void ledLightMidOut(){
  if(((LED5 == ON) && (LED1 == ON)) || (ledsAreReset())){
    resetLEDs();
    LED3 = ON;
  }else if((LED3 == ON)){
    resetLEDs();
    LED2 = ON;
    LED4 = ON;
  }else if((LED2 == ON) && (LED4 == ON)){
    resetLEDs();
    LED1 = ON;
    LED5 = ON;
  }
}

/*
* Interrupt handler for controlling light sequence based on Timer2 clock overflow
*/
void interrupt VTimer2Overflow intTimer2Ovf(){
 if(sequenceNumber ==1 ){
   ledLightInSeq();  
  
 } else if(sequenceNumber == 2){
   ledLightRevSeq();
 } else if(sequenceNumber == 3){
   ledLightMidOut();
 } else {
   LED1 = ~LED1;
   LED5 = ~LED5;
 }

 TPM2SC_TOF = 0;//ack, change overflow bit
}

/*
* Initialize TPM2
*/
void initTimer2(){
  TPM2SC_TOIE = 1;
  /*Initialize timer TPM1 channel, assumes not touched since reset!*/
  TPM2SC_CLKSA = 1;/*Select BUS clock*/
  TPM2SC_CLKSB = 0;
  TPM2SC_PS = PRESCALAR;/*clock source divided by prescalar*/
  TPM2MOD = MODULUS;/*set Counter modulus*/
  /*configure PWM mode and pulse*/
  TPM2C0SC_MS0B = 1; /*MS0B=1, MS0A=0; << Edge align PWM*/
  TPM2C0SC_ELS0A = 1; /*Select low as true*/
 

  TPM2C0V = DUTY75;//sets number that if matched by counter, will set channel flag

}

void initLedStuff(){
  PTADD = 0; //initialize as input (Data Direction Register)
  PTAPE = 0xf0; //Pullups on upper 4 bits
  /*initialize bits 0-3 of Port D&F as outputs (connected to led's)*/
  PTFDD = 0x0f;
  PTDDD = 0x0f;
  resetLEDs();
}

void initKeyboardInterrupt(){
  KBI1SC_KBIE = 1;  //KBIE =>Keyboard Interrupt Enable
  KBI1PE_KBIPE4 = 1; //Keyboard Interrupt Port Enable 4 (switch1)
  KBI1PE_KBIPE5 = 1; //Keyboard Interrupt Port Enable 5 (switch2)
  KBI1PE_KBIPE6 = 1; //Keyboard Interrupt Port Enable 6 (switch3)
  KBI1PE_KBIPE7 = 1; //Keyboard Interrupt Port Enable 7 (switch4)
}

/*
* Sample code from docs
*/
void manageDuty(){
   if(SWITCH3==DOWN){
      /*Switch pressed*/
      if(SWITCH4==DOWN){/**/
        TPM1C0V = DUTY75;/**/
        LED3 = ON;/**/
        LED4 = OFF;/**/
      }else{
        TPM1C0V = DUTY25;/**/
        LED3 = OFF;/**/
        LED4 = ON;/**/
      }
    }
}



void MCU_init(void); /* Device initialization function declaration */

void main(void) {

  /* Uncomment this function call after using Device Initialization
     to use the generated code */
  /* MCU_init(); */

  EnableInterrupts; /* enable interrupts */
  initLedStuff();
  initTimer2();
  initKeyboardInterrupt();
 
 
  for(;;) {
    __RESET_WATCHDOG(); /* feeds the dog */
   
    
  } /* loop forever */
 
}

No comments: