110 lines
2.6 KiB
C
Raw Normal View History

2022-04-07 18:46:57 +02:00
#include"msp.h"
#define UNLOCK_CS CS->KEY = CS_KEY_VAL
#define LOCK_CS CS->KEY = 0
#define DISABLE_WATCHDOG() WDT_A->CTL= WDT_A_CTL_PW | WDT_A_CTL_HOLD
#define TIMER_PERIOD 20 // ms
#define TIMER_DIV (8)
#define TIMER_FCLK 3000000
#define TIMER_PERIOD_TICKS (((TIMER_FCLK / TIMER_DIV) * TIMER_PERIOD) / 1000)
//#define FULLRANGE
#ifdef FULLRANGE
#define DC_MIN 0.75
#define DC_MAX 2.25
#else
#define DC_MIN 1
#define DC_MAX 2
#endif
#define PERIOD TIMER_PERIOD_TICKS //20 ms
#define DUTY_MAX ((unsigned int)(TIMER_PERIOD_TICKS/TIMER_PERIOD)*(DC_MAX)) //2 ms
#define DUTY_MIN ((unsigned int)(TIMER_PERIOD_TICKS/TIMER_PERIOD)*(DC_MIN)) //1 ms
#define DUTY_RANGE (DUTY_MAX - DUTY_MIN)
#define ADC_MAX ((1 << 14) - 1)
#define ADC_MIN 0
#define ADC_RANGE ((ADC_MAX-ADC_MIN))
#define ADC_TO_T(v) (DUTY_MIN + ((v - ADC_MIN)*DUTY_RANGE)/ADC_RANGE)
void setup_pins(){
// J4 - P2.4
P2->DIR |= 0x10; //2.4
P2->SEL0 |= 0x10; //2.4 SELECT TA0 MODULE
P2->SEL1 &= ~0x10;//2.4 SELECT TA0 MODULE
// J3 - P4.0
P4->SEL0 |= 0x01; //4.0 SELECT ADC MODULE
P4->SEL1 |= 0x01; //4.0 SELECT ADC MODULE
}
void setup_clock(){
UNLOCK_CS;
CS->CTL0 |= CS_CTL0_DCORSEL_1; // 3 MHz
CS->CTL1 |= CS_CTL1_DIVS__8 | CS_CTL1_SELS__DCOCLK ; // SMCLOCK = DCLOCK/8
CS->CTL0 |= CS_CTL0_DCOEN; //Enable
LOCK_CS;
}
void setup_timer_a0(){
TIMER_A0->CCR[0] = PERIOD; //base period
TIMER_A0->CCR[1] = DUTY_MIN; //COMPARE to duty cycle
TIMER_A0->CCTL[1] = OUTMOD_7; //RESET/SET
TIMER_A0->EX0 = TAIDEX__1; // divide by 1
TIMER_A0->CTL = TASSEL__SMCLK | ID__1 | MC__UP;//DOWN; //SMCLK, /1, UP
}
void setup_adc(){
ADC14->CTL0 &= ~ADC14_CTL0_ENC; //ADC Disable
ADC14->CTL0 = ADC14_CTL0_ON; //ADC ON
ADC14->CTL0 |= ADC14_CTL0_SSEL__SMCLK; //USE SMCLK
ADC14->CTL0 |= ADC14_CTL0_CONSEQ_2; //ADC14 Repeat Channel Sampling
ADC14->CTL0 |= ADC14_CTL0_SHS_1; //USE TA0.1
ADC14->CTL1 = ADC14_CTL1_RES__14BIT; //14 bit, 16 clk conversion
ADC14->MCTL[0] = ADC14_MCTLN_VRSEL_0 | ADC14_MCTLN_INCH_13; // A13 ADC & V(R+) = AVCC, V(R-) = AVSS
ADC14->IER0 |= ADC14_IER0_IE0; //ADC Interrupt
ADC14->CTL0 |= ADC14_CTL0_ENC; //ADC Enable
}
void main(void){
DISABLE_WATCHDOG();
setup_pins();
setup_clock();
setup_timer_a0();
setup_adc();
SCB->SCR |= SCB_SCR_SLEEPONEXIT_Msk; // Enable sleep on exit from ISR
__DSB(); // Ensures SLEEPONEXIT takes effect immediately
__enable_irq(); // Enable global interrupt
NVIC_EnableIRQ(ADC14_IRQn); //ENABLE IRQ ADC14
__sleep(); //Sleep
}
void ADC14_IRQHandler(void) {
TIMER_A0->CCR[1] = ADC_TO_T(ADC14->MEM[0]);
}