Other Parts Discussed in Thread: CC1310
Hi All!
So here is my problem.
I am using the adcbuf driver on the cc1310.
I modified the adcbufcontinuous No RTOS CCS compiler example from here: https://dev.ti.com/
This is the modified adcBufContinuousSampling.c file:
#include <stdint.h> #include <stdio.h> /* For sleep() */ #include <unistd.h> /* Driver Header files */ #include <ti/drivers/ADCBuf.h> #include <ti/drivers/dpl/HwiP.h> /* Example/Board Header files */ #include "Board.h" #define ADCBUFFERSIZE (50) uint16_t sampleBufferOne[ADCBUFFERSIZE]; uint16_t sampleBufferTwo[ADCBUFFERSIZE]; /* * This function is called whenever an ADC buffer is full. */ volatile uint32_t foo; void adcBufCallback(ADCBuf_Handle handle, ADCBuf_Conversion *conversion, void *completedADCBuffer, uint32_t completedChannel) { foo++; } /* * ======== mainThread ======== */ void *mainThread(void *arg0) { ADCBuf_Handle adcBuf; ADCBuf_Params adcBufParams; ADCBuf_Conversion continuousConversion; /* Call driver init functions */ ADCBuf_init(); /* Set up an ADCBuf peripheral in ADCBuf_RECURRENCE_MODE_CONTINUOUS */ ADCBuf_Params_init(&adcBufParams); adcBufParams.callbackFxn = adcBufCallback; adcBufParams.recurrenceMode = ADCBuf_RECURRENCE_MODE_CONTINUOUS; adcBufParams.returnMode = ADCBuf_RETURN_MODE_CALLBACK; adcBufParams.samplingFrequency = 2000; adcBuf = ADCBuf_open(Board_ADCBUF0, &adcBufParams); /* Configure the conversion struct */ continuousConversion.arg = NULL; continuousConversion.adcChannel = Board_ADCBUF0CHANNEL0; continuousConversion.sampleBuffer = sampleBufferOne; continuousConversion.sampleBufferTwo = sampleBufferTwo; continuousConversion.samplesRequestedCount = 20; if (adcBuf == NULL){ /* ADCBuf failed to open. */ while(1); } /* Start converting. */ if (ADCBuf_convert(adcBuf, &continuousConversion, 1) != ADCBuf_STATUS_SUCCESS) { /* Did not start conversion process correctly. */ while(1); } uintptr_t key = HwiP_disable(); volatile uint32_t foobar; // long isr disable to emulate flash write // counting up 100000 times corrupts the adcbuf as it will spin in its interrupt forever // counting up 100 times is still safe int i; for (i = 0 ; i < 100000; i++) { foobar++; } HwiP_restore(key); /* * Go to sleep in the foreground thread forever. The ADC hardware will * perform conversions and invoke the callback function when a buffer is * full. */ while(1) { sleep(1); } }
What it does is basically setting up the adcbuf in callback interrupt mode, and the simulating a long interrupt disabling, which might happen when the internal flash is being written.
If the interrupt disabling takes more time then the adcbuf would take to fill both buffers, then it gets stuck forever in the ADCBufCC26XX_hwiFxn ISR.
By stuck I mean that it just seems to reenter the ADCBufCC26XX_hwiFxn forever, and nothing else gets run anymore.
When might this happen:
In our application we use the internal flash as an emulated eeprom. This gets written every once in a while. An erase and write cycle takes up to ~10ms (whenever the flash is written or erased all interrupts are to be disabled), which is more than enough to crash the adcbuf as demonstrated in this example.
A possible workaround for me would be to disable the adcbuf before writing to the flash.
I was wondering if you did knew about this, because I don't seem to find any warning in the documentation that it might get locked.
The only thing I found is this:
If the ADCBUF driver is setup in ADCBuf_RECURRENCE_MODE_CONTINUOUS mode, the user must assure that the provided callback function is completed before the next conversion completes. If the next conversion completes before the callback function finishes, the DMA will clobber the previous buffer with new data.
For me this only means an overwritten data, but nut an ISR which deadlocks itself.
Obviously I would be thrilled if you had any inputs on how to solve this issue.
Maybe this is even a bugreport?
Thanks for your help!
Cheers!