void port1Init (void) { // Port 1 and it's pins are used for the Power LED, ADC10 and the USCI. // P1.0 = Power LED (Pin 2) (Eventually nothing) // P1.1 = SPI SOMI USCI (Pin 3) // P1.2 = SPI SIMO USCI (Pin 4) // P1.3 = Unconnected (Pin 5) // P1.4 = SPI Clock USCI (Pin 6) // P1.5 = TA0.0 (OUT0 of Timer0A) used in toggle mode to capture the Yaw Angle on the ADC input A5 (Pin 7). See timer0AInit and adc10Init for more. // P1.6 = TA0.1 (OUT1 of Timer0A) used in reset/set mode to turn on power to the pot. (Pin 14) // P1.7 = Unconnected (Pin 15) P1OUT = 0; // This initializes P1OUT to all zeros. Same as 0b00000000 P1SEL = BIT6; // This sets P1.6 (Pin 14) to OUT1. Note: OUT0 for the ADC input is set in the ADC10 init method. P1DIR = BIT0 + BIT1 + BIT6; // This is used to set the corresponding pin (2) to an output for the power // LED signal. This also sets Pin 14 to an output for Reset/Set Mode in the Timer1A OUT1. P1OUT = BIT0; // This sets the output to 1, turning on the LED } /*-------------------------------------------------------------------------------------------------------*/ void port2Init (void) { // Port 2 and it's pins are used for the wind and rider speed inputs and the LCD control. // P2.0 = Unconnected (Pin 8) // P2.1 = TA1.1 CCI1A Capture Input Rider Speed (Pin 9) // P2.2 = LCD RS (Pin 10) // P2.3 = LCD E (Pin 11) // P2.4 = LCD Data 4 (Pin 12) // P2.5 = LCD Data 5 (Pin 13) // P2.6 = LCD Data 6 (Pin 19) // P2.7 = LCD Data 7 (Pin 18) P2OUT = 0; // This initializes the P2OUT to all zeros. Same as 0b00000000 P2SEL = 0; // P2SEL must first be cleared so we can use P2.6 & P2.7 as IO pins. P2SEL2 = 0; // They are XIN & XOUT by default. // Pin P2.1 is used initially as an input. When the pin in P1DIR is 0 the pin is set as an input. // The default is to have P1DIR = 0. Below we clear any potential flags for interrupts on the pin // and then enable interrupts. When the interrupt is called we will set up the pin to act as a // capture input for TimerA. We do this because in LPM4 everything is asleep. If we were to set // up the pin as a capture right away we would not be able to set the SCS bit in TimerA which I do // not like. This way we are able to wake up the MCU and change everything in the Port2 ISR. P2IFG &= ~BIT1; P2IE |= BIT1; P2DIR = MASK; // This sets the corresponding pins for the LCD control to outputs } /*-------------------------------------------------------------------------------------------------------*/ void timer0AInit (void) { // Select ACLK (VLO), Division 0, Up Mode to TACCRO, (NOTE: Interrupts do not need to // enabled. We will enable interrupts in the ADC10 which handles everything. TA0CTL = TASSEL_1 + ID_0 + MC_1 + TACLR; // Set the top in Up Mode to 5,999 which is half of the 12Khz clock. I want a reading // every second and since toggle mode works on the rising edge only I cut the frequency // in half to trigger the ADC once a second. Using toggle mode starts the conversion // in the ADC automatically when it "toggles" to the rising edge. Once the conversion is // complete the ADC ISR is called and the value is handled. TA0CCR0 = 5999; // We are using Pin 14 in Reset/Set mode (OUT1) to turn the pot on and off. When TAR // (the counter) returns to 0, the output it set to 1 (high). When the TAR counts to // TAOCCR1 the output is reset to 0. Since we need 16 clock cycles to sample, we set // TA0CCR1 to 16. Not that the Sample from the toggle mode below actually turns on // when TAR counts to TA0CCR0 which is one clock cycle before we turn the pot on // when TAR = 0. As long as we sample long enough this is ok. TA0CCR1 = 16; // Enable Toggle Mode for Pin. Remember Toggle mode has to be used with an OUT0 TA0CCTL0 = OUTMOD_4; // Enable Reset/Set mode for Pin. Remember Reset/Set mode has to be used with an OUT1 TA0CCTL1 = OUTMOD_7; } /*-------------------------------------------------------------------------------------------------------*/ void timer1AInit (void) { TA1CTL = TASSEL_1 + MC_2 + TACLR; // Selects ACLK (VLO), Continuous Mode and clears the timer. // This simple enables the interrupts on channel 0 of TimerA1 so that when TAR hits 65k in continuous mode // the ISR is called. This is where I will put the unit back in LMP4 when this is hit. TA1CCTL0 = CCIE; // Set up Channel 1 to capture the input of the reed switch for rider speed. Every time the magnet breaks its // connection we capture the value of TAR in TA1CCR1 and raise the interrupt flag. The following // set up sets Captures on a Falling Edge, Puts the Capture on Pin 8 also known as P2.1, Synschronizes // the capture with the clock, puts Channel 1 in Capture Mode and Enables Interrupts. TA1CCTL1 = CM_2 + CCIS_0 + SCS + CAP + CCIE; } void adc10Init (void) { // I am using pin 7 for the input to the ADC10. This is A5. OUT0 is also associated with pin 7 so I am // able to drive the conversions by toggling OUT0 in OUTMOD_4. This is set up in timer0AInit();. // Vcc - Vss, 16 clock cycles (with 2kOhm Pot) for the sample, turn on ADC10, enable interrupts ADC10CTL0 = SREF_0 + ADC10SHT_2 + ADC10ON + ADC10IE; // Select input on Channel 5, sample and hold source OUT0, clock division 0, use ADC10SC clock, repeat single conversion ADC10CTL1 = INCH_5 + SHS_2 + ADC10DIV_0 + ADC10SSEL_0 + CONSEQ_2; // Enable ADC10 on input channel A5. ADC10AE0 = BIT5; // Enable conversions. This only needs to be done once since we selected CONSEQ_2 ADC10CTL0 |= ENC; }