The Analog to Digital Converter (ADC) RTOS driver is intended to use ADC functions in a Real-Time operating system, i.e. is thread safe.
Initialize and deinitialize the driver and associated hardware
Select single shot or free running conversion modes
Configure major ADC properties such as resolution and reference source
Start ADC conversion
Read back conversion results
Selecting which ADC input channels to enable for positive and negative input
Which clock source and prescaler the ADC uses
Various aspects of Event control
Single shot or free running conversion modes
Sampling properties such as resolution, window mode, and reference source
Run in Standby or Debug mode
The convert functions of the ADC RTOS driver are optimized for RTOS support. That is, the convert functions will not work without RTOS. The convert functions should only be called in an RTOS task or thread.
The ADC OS driver use a ring buffer to store ADC sample data. When the ADC raise the sample complete interrupt, a copy of the ADC sample register is stored in the ring buffer at the next free location. This will happen regardless of if the ADC is in one shot mode or in free running mode. When the ring buffer is full, the next sample will overwrite the oldest sample in the ring buffer.
To read the samples from the ring buffer, the function adc_os_read_channel is used. This function reads the number of bytes asked for from the ring buffer, starting from the oldest byte. If the number of bytes asked for are more than currently available in the ring buffer, or more than ringbuf size, the task/thread will be blocked until read done. If the number of bytes asked for is less than the available bytes in the ring buffer, the remaining bytes will be kept until a new call. The adc_os_read_channel function will return the number of bytes that want to read from the buffer back to the caller.
During data conversion, the ADC convert process is not protected, so that a more flexible way can be chosen in the application if multi-task/thread access.
The following shows a simple example of using the ADC. The ADC must have been initialized by adc_os_init. This initialization will configure the operation of the ADC, such as single-shot or continuous mode, etc.
The example creates two tasks for channel 0 of ADC0: convert task and read task, and finally starts the RTOS task scheduler.
/**
* Example convert task of using ADC_0.
*/
void ADC_0_example_convert_task(void *p)
{
(void)p;
adc_os_enable_channel(&ADC_0, 0);
while (1) {
adc_os_start_conversion(&ADC_0);
os_sleep(10);
}
}
/**
* Example read task of using ADC_0.
*/
void ADC_0_example_read_task(void *p)
{
uint8_t adc_values[8];
uint8_t num = 0;
(void)p;
while (1) {
num = adc_os_read_channel(&ADC_0, 0, adc_values, 8);
if (num == 8) {
/* read OK, handle data. */;
} else {
/* error. */;
}
}
}
#define TASK_ADC_CONVERT_STACK_SIZE ( 256/sizeof( portSTACK_TYPE ))
#define TASK_ADC_CONVERT_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define TASK_ADC_READ_STACK_SIZE ( 256/sizeof( portSTACK_TYPE ))
#define TASK_ADC_READ_STACK_PRIORITY ( tskIDLE_PRIORITY + 1 )
static TaskHandle_t xAdcConvertTask;
static TaskHandle_t xAdcReadTask;
int main(void)
{
/* Initializes MCU, drivers and middleware */
atmel_start_init();
/* Create ADC convert task */
if (xTaskCreate(ADC_0_example_convert_task, "ADC convert", TASK_ADC_CONVERT_STACK_SIZE,
NULL,
TASK_ADC_CONVERT_PRIORITY, &xAdcConvertTask) != pdPASS) {
while (1) {
;
}
}
/* Create ADC read task */
if (xTaskCreate(ADC_0_example_read_task, "ADC read", TASK_ADC_READ_STACK_SIZE,
NULL,
TASK_ADC_READ_STACK_PRIORITY, &xAdcReadTask) != pdPASS) {
while (1) {
;
}
}
/* Start RTOS scheduler */
vTaskStartScheduler();
/* Replace with your application code */
while (1) {
}
}
The ADC peripheral and its related I/O lines and clocks
The NVIC must be configured so that ADC interrupt requests are periodically serviced
RTOS