dsPIC33EP32GS502 context saving problem
Im trying to write ADC oversampling filter ISR with context saving, ADC is triggered in every 100us so I really need this context saving optimalization.
At begining I used MCC code configurator, it generates most of ADC code but unfortunly it didnt generate too much code for oversampling filter, it ignore ADFLTR ISR, so I wrote missing code according to data sheet or just copy some examples.
According to xc16 Compiler Users Guide, chapter 14.5 "INTERRUPT SERVICE ROUTINE CONTEXT SAVING" if context switchin is desired CTXT1 should be set equal to ADFLTR0 interrupt priotity, so I set both to priority 5 via MCC. Next step is add attribute "context" to ISR declaration, in chapter 14.5 example there was no "no_auto_psv" in ISR, but even after remove it, problem persist.
Unfortunlly context save is not working, when run code with simulator or with tagret device via PICKIT3 I cannot see any CTXTSTAT change (I roll over SFR view to let it refresh). Also in disassembly I cannot find any CTXTSWP instruction generated by compiler, ofcourse if change any working register (via asm code) in ISR it cause address trap error at exit, any C code adds just PUSH/POP instructions. So Im pretty sure context is not saved/switched.
Also attempted to manually switch context by typing asm("CTXTSWP #1"); at ISR first line of code, it made CTXTSTAT change but, according to device data sheet RETFIE should restore also CTXTSWP to default value 0, unfortunlly not in this case, maybe it was only about C code. When add asm("CTXTSWP #0"); at ISR end it wont trigger ADC anymore.
Have no idea what I missed, In errata found only information about CTXT issue with interrupt nesting thats why I turn off timer to avoid this problem during tests.
ADC initialize code, mostly MCC/code examples:
void ADC1_Initialize (void)
// Configure the I/O pins to be used as analog inputs.
ANSELAbits.ANSA0 = 1; TRISAbits.TRISA0 = 1; // AN0/RA0 connected the dedicated core 0
// Configure the common ADC clock.
ADCON3Hbits.CLKSEL = 3; // clock from AUXclk = 117 964 800 Hz
ADCON3Hbits.CLKDIV = 0; // no clock divider (1:1) TCORE = 8.48ns
// Configure the cores ADC clock.
ADCORE0Hbits.ADCS = 0; // clock divider (1:2) Tadcore = 16.96 ns > 14.3 ns
// Configure the ADC reference sources.
ADCON3Lbits.REFSEL = 0; // AVdd as voltage reference
// Configure the integer of fractional output format.
ADCON1Hbits.FORM = 0; // integer format
// Select single-ended input configuration and unsigned output format.
ADMOD0Lbits.SIGN0 = 0; // AN0/RA0
ADMOD0Lbits.DIFF0 = 0; // AN0/RA1
// Set initialization time to maximum
ADCON5Hbits.WARMTIME = 15;
// Turn on ADC module
ADCON1Lbits.ADON = 1;
// Enable and calibrate cores
// Set software common trigger as AN0 input Egde sensitive trigger source.
ADTRIG0Lbits.TRGSRC0 = 1;
ADLVLTRGLbits.LVLEN0 = 0;
// OVERSAMPLING FILTER INITIALIZATION.
ADFL0CONbits.FLCHSEL = 0; // Select the AN0 input for the filter.
ADFL0CONbits.MODE = 3; // Averaging, 12-bit result.
ADFL0CONbits.OVRSAM = 6; // x256
// Enable delay between trigger and the conversion start (SAMC bits).
ADCON4Lbits.SAMC0EN = 1;
// Set sampling time (26x Tad) = 26 * 16,96 = 440.96ns
ADCORE0Lbits.SAMC = 26;
// Filter Interrupts
ADFL0CONbits.IE = 1;
_ADFLTR0IF = 0;
_ADFLTR0IE = 1;
// Enable the filter.
ADFL0CONbits.FLEN = 1;
void ADC1_Core0PowerEnable (void)
ADCON5Lbits.C0PWR = 1;
while(ADCON5Lbits.C0RDY == 0);
ADCON3Hbits.C0EN = 1;
void ADC1_Core0Calibration (void)
ADCAL0Lbits.CAL0EN = 1;
ADCAL0Lbits.CAL0DIFF = 0;
ADCAL0Lbits.CAL0RUN = 1;
while(ADCAL0Lbits.CAL0RDY == 0);
ADCAL0Lbits.CAL0EN = 0;
When try to add more code i got forum crash:
You don't have permission to access "http://www.microchip.com/forums/post.aspx?" on this server.
What a day....
post edited by abel11 - 2019/11/13 05:33:31