Hey all,
Gotta be a stupid thing but I cannot get an interrupt to go to the ISR. Here's the short version:
- ADC14 on S3DK. Using the input the Pot is connected to. Using AD framework, no RTOS.
- AD function works in single scan or continuous. Plan is to do continuous.
- I get AD callback OK and conversion is good.
- Setting up Window compare function. Not supported by framework. Just Channel 13 (the pot) comparing with Window A, arbitrary values of 2000 and 7000.
- If I check the window compare status bit after AD complete, it indeed works. I turn on an LED based on inside the window or out. All is well.
- Now try to generate interrupt from window compare. Followed instructions in section section 39.3.5.2 of S3 manual. I get nada.
- Interrupts enabled in ICU. ISR names are same as weak defined names. Still nothing.
- It is NOT going to the default ISR routine, so this is good.
Here is code. I can post project if desired. General question: Is there a set of instructions or something for setting up an interrupt when it's not part of the configurator?
Specific question: How do I get the interrupt to do something.
void hal_entry(void) {
/* Calculate the delay in terms of bsp_delay_units */
const uint32_t delay = bsp_delay_units/freq_in_hz;
/* Get LED information for this board */
R_BSP_LedsGet(&leds);
/* If this board has no LEDs then trap here */
if (0 == leds.led_count)
{
while(1); // There are no LEDs on this board
}
// setup the ADC14 to convert channel 13 per the Synergy Configurator
// Ch 13 is the one with the pot on the S3DK over by the display
err = g_adc0.p_api->open(g_adc0.p_ctrl, g_adc0.p_cfg);
err = g_adc0.p_api->scanCfg(g_adc0.p_ctrl, g_adc0.p_channel_cfg);
// the following is per the instructions in the User Manual, section 39.3.5.2
// now setup the window compare A function
R_S14ADC->ADCMPDR0 = 2000; // set the lower level. Just an arbitrary value
R_S14ADC->ADCMPDR1 = 7000; // set the upper level. Just an arbitrary value
R_S14ADC->ADCMPANSR0 = 0; // make sure all other channels are off
R_S14ADC->ADCMPANSR0_b.CMPCHA13 = 1; // now make window A look at channel 13
R_S14ADC->ADCMPLR0_b.CMPLCHA13 = 1; // trigger if ADCMPDR0 < AD ch 13 < ADCMPDR1
// disable window b
R_S14ADC->ADWINLLB = 0; // disable window for b by setting both upper and lower to 0
R_S14ADC->ADWINULB = 0; // disable window for b by setting both upper and lower to 0
R_S14ADC->ADCMPBNSR_b.CMPCHB = 0x3f;
R_S14ADC->ADCMPCR_b.CMPAB = 00; // output on a match with either window A or window B
R_S14ADC->ADCMPCR_b.CMPAE = 1; // enable window a
R_S14ADC->ADCMPCR_b.CMPBE = 1; // enable window b // seems odd but per the instructions
R_S14ADC->ADCMPCR_b.CMPBIE = 1; // disable interrupt on b
R_S14ADC->ADCMPCR_b.CMPAIE = 1; // interrupt on window a
R_S14ADC->ADCMPANSR1 = 0; // don't look at the upper channels
R_S14ADC->ADCMPANSER = 0; // exclude the temperature sensor and the internal voltage reference
R_S14ADC->ADCSR_b.ADST = 0;
R_S14ADC->ADCMPCR_b.WCMPE = 1; // enable window a
while(1)
{
/* toggle the LED */
g_ioport.p_api->pinWrite(leds.p_leds[0], (level = !level));
ad_done = 0;
err = g_adc0.p_api->scanStart(g_adc0.p_ctrl); // start the A/D - single scan mode
while(ad_done == 0);
err = g_adc0.p_api->read(g_adc0.p_ctrl, ADC_REG_CHANNEL_13, &my_result); // get the result
//
//
//
// This all works, just no interrupt for window compare function.
//
//
//
// turn the pot and the LED goes on at the right time and off at the right time.
// if the conditions are met, turn on the LED. If not, turn it off.
if(R_S14ADC->ADCMPSR0_b.CMPSTCHA13 == 1){
err = g_ioport.p_api->pinWrite(leds.p_leds[2], IOPORT_LEVEL_HIGH);
R_S14ADC->ADCMPSR0_b.CMPSTCHA13 = 0; // clear the bit that says we got a match.
}
else{
err = g_ioport.p_api->pinWrite(leds.p_leds[2], IOPORT_LEVEL_LOW); // use this LED to indicate A/D done
R_S14ADC->ADCMPSR0_b.CMPSTCHA13 = 0; // clear the bit that says we got a match.
}
}
}
//// this callback works fine...
void adc14_callback(adc_callback_args_t *p_args)
{
ad_done = 1;
}
////// we never get to either of these.
void adc0_window_a_isr(void)
{
R_BSP_IrqStatusClear (ADC0_WINDOW_A_IRQn) ;
R_BSP_SoftwareDelay(10, bsp_delay_units);
}
void adc0_compare_match_isr(void)
{
R_BSP_IrqStatusClear (ADC0_COMPARE_MATCH_IRQn) ;
R_BSP_SoftwareDelay(10, bsp_delay_units);
}