Part Number: MSP430FR2311
Ok, so I thought this would be easy, but apparently I'm doing something wrong and it isn't quite coming to me what the root cause of the issue is. I started with the Out_of_box example. I can easily read just one channel. So then I tried to set it up to read a sequence of channels P1.1 and then P1.0. My understanding is that you pick your highest channel and the sequencer just counts down through the channels, so I should get two readings. I don't have the logic yet to parse out the readings which is fine for now. I can deal with that. It seems to not work because I would expect to get alternating ADC reading values which isn't the case. There must be some detail I am missing here. Note: The extra stuff in the ADC interrupt routine is just leftovers from the out of box example where they were writing the adc result to FRAM.
/*
* main.c
*/
int main(void) {
//Stop WDT
WDT_A_hold(WDT_A_BASE);
initClockTo16MHz();
initUART();
/* Initialize peripherals */
initGPIO();
initPWM();
initI2C();
//Toggle LED1 during start-up
GPIO_setOutputHighOnPin(GPIO_PORT_P1, GPIO_PIN0);
__delay_cycles(10000);
GPIO_setOutputLowOnPin(GPIO_PORT_P1, GPIO_PIN0);
EUSCI_A_UART_enable(EUSCI_A0_BASE);
initSleepTimer(TIMER_RATE); // 128Hz
while(1){
//lightSample();
n0Sample();
uintoa( buf, ADC_Conversion_Result );
transmitString( buf );
__bis_SR_register(LPM3_bits + GIE);
}
}
void initSleepTimer(uint16_t period){
//Start timer
Timer_B_clearTimerInterrupt(TIMER_B0_BASE);
Timer_B_initUpModeParam param = {0};
param.clockSource = TIMER_B_CLOCKSOURCE_ACLK;
param.clockSourceDivider = TIMER_B_CLOCKSOURCE_DIVIDER_1;
param.timerPeriod = period;
param.timerInterruptEnable_TBIE = TIMER_B_TBIE_INTERRUPT_DISABLE;
param.captureCompareInterruptEnable_CCR0_CCIE = TIMER_B_CAPTURECOMPARE_INTERRUPT_ENABLE;
param.timerClear = TIMER_B_DO_CLEAR;
param.startTimer = true;
Timer_B_initUpMode(TIMER_B0_BASE, ¶m);
}
void enable_ADC10(uint8_t adc_channel){
//Initialize the ADC Module
/*
* Base Address for the ADC Module
* Use internal ADC bit as sample/hold signal to start conversion
* USE MODOSC 5MHZ Digital Oscillator as clock source
* Use default clock divider of 1
*/
ADC_init(ADC_BASE, ADC_SAMPLEHOLDSOURCE_SC, ADC_CLOCKSOURCE_ADCOSC, ADC_CLOCKDIVIDER_1);
ADC_setDataReadBackFormat(ADC_BASE, ADC_UNSIGNED_BINARY); //AP
ADC_enable(ADC_BASE);
/*
* Base Address for the ADC Module
* Sample/hold for 16 clock cycles
* Do not enable Multiple Sampling
*/
ADC_setupSamplingTimer(ADC_BASE, ADC_CYCLEHOLD_16_CYCLES, ADC_MULTIPLESAMPLESENABLE);
//ADC_setupSamplingTimer(ADC_BASE, ADC_CYCLEHOLD_16_CYCLES, ADC_MULTIPLESAMPLESDISABLE);
ADC_configureMemory(ADC_BASE, adc_channel, ADC_VREFPOS_AVCC, ADC_VREFNEG_AVSS); // channel mis-map for A1 in driverlib?
ADC_clearInterrupt(ADC_BASE, ADC_COMPLETED_INTERRUPT);
//Enable the Memory Buffer Interrupt
ADC_enableInterrupt(ADC_BASE, ADC_COMPLETED_INTERRUPT);
}
void disable_ADC10(void){
ADC_disableConversions(ADC_BASE,0);
ADC_disable(ADC_BASE);
}
void n0Sample(void)
{
enable_ADC10(ADC_INPUT_VEREF_N);
__delay_cycles(15);
//Enable and Start the conversion
//in Single-Channel, Single Conversion Mode
//ADC_startConversion(ADC_BASE, ADC_SINGLECHANNEL);
ADC_startConversion(ADC_BASE, ADC_SEQOFCHANNELS); // Changing this to single sequence did not work with ADC_SEQOFCHANNELS
//LPM3, ADC conversion complete will force exit
__bis_SR_register(LPM3_bits + GIE);
disable_ADC10();
}
void initGPIO(void){
//Set Px.x to output direction
//P1DIR |= 0xFF; // outputs
//P1OUT = 0x00;
P1DIR |= 0x00; // inputs
//P2DIR |= 0xFF;
P2DIR |= 0b00000011;
P2OUT = 0x00;
// Select P2.0 as PWM Timer output function
GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P2,GPIO_PIN0,GPIO_PRIMARY_MODULE_FUNCTION);
// AP Configure GPIO
P1SEL1 &= ~(BIT6 | BIT7); // USCI_A0 UART operation
P1SEL0 |= BIT6 | BIT7;
GPIO_setAsOutputPin(GPIO_PORT_P1, GPIO_PIN0);
// I2C pins
P1SEL0 |= BIT2 | BIT3;
P1SEL1 &= ~(BIT2 | BIT3);
//ADC Pins
P1SEL0 |= BIT0 | BIT1;
P1SEL1 |= BIT0 | BIT1;
/*
* Disable the GPIO power-on default high-impedance mode to activate
* previously configured port settings
*/
PMM_unlockLPM5();
}
// ADC interrupt service routine
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=ADC_VECTOR
__interrupt void ADC_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(ADC_VECTOR))) ADC_ISR (void)
#else
#error Compiler not supported!
#endif
{
//Get previous write protection setting
uint8_t state = HWREG8(SYS_BASE + OFS_SYSCFG0_L);
#ifdef DFWP
uint8_t wp = DFWP | PFWP;
#else
uint8_t wp = PFWP;
#endif
#ifdef FRWPPW
HWREG16(SYS_BASE + OFS_SYSCFG0) = FWPW | (state & ~wp);
#else
HWREG8(SYS_BASE + OFS_SYSCFG0_L) &= ~wp;
#endif
ADC_Conversion_Result = ADCMEM0;
//Restore previous write protection setting
#ifdef FRWPPW
HWREG16(SYS_BASE + OFS_SYSCFG0) = FWPW | state;
#else
HWREG8(SYS_BASE + OFS_SYSCFG0_L) = state;
#endif
__bic_SR_register_on_exit(LPM3_bits); // Sleep Timer Exits LPM3
}