]> rtime.felk.cvut.cz Git - pes-rpp/rpp-lib.git/blobdiff - rpp/src/drv/adc.c
Trigger context switch after ADC interrupts
[pes-rpp/rpp-lib.git] / rpp / src / drv / adc.c
index 5289d5c98bb835d4fdf3ffc40c4666330dcc5419..e2ecd3bb77f9c54bc4409e557b115e733829ede8 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2012-2013 Czech Technical University in Prague
+/* Copyright (C) 2012-2013, 2015 Czech Technical University in Prague
  *
  * Authors:
  *     - Michal Horn
  */
 
 
-#include "drv/adc.h"
+#include "drv/drv.h"
+#include "drv/port.h"
+#include "os/portmacro.h"
 
-// Binary semaphore for ADC1 GRP1 conversion (AIN)
-xSemaphoreHandle adcSemaphore_ADC1GRP1;
-// Binary semaphore for ADC2 GRP1 conversion (HOUT-IFBK)
-xSemaphoreHandle adcSemaphore_ADC2GRP1;
+// Binary semaphores for finish notifications
+static xSemaphoreHandle sem[2][2];
 
-// Mutex for AIN read control
-xSemaphoreHandle adcMutex_ADC;
-// Mutex for HOUTIFBK control
-xSemaphoreHandle adcMutex_HOUTIFBK;
+// Mutex for two ADCs
+xSemaphoreHandle mutex[2];
 
 void drv_adc_init()
 {
-       // Create semaphores
-       vSemaphoreCreateBinary(adcSemaphore_ADC1GRP1);
-       xSemaphoreTake(adcSemaphore_ADC1GRP1, 0);
-       vSemaphoreCreateBinary(adcSemaphore_ADC2GRP1);
-       xSemaphoreTake(adcSemaphore_ADC2GRP1, 0);
-
-       adcMutex_ADC       = xSemaphoreCreateMutex();
-       adcMutex_HOUTIFBK  = xSemaphoreCreateMutex();
+       int adc, grp;
 
+       for (adc = 0; adc < 2; adc++) {
+               for (grp = 0; grp < 2; grp++) {
+                       vSemaphoreCreateBinary(sem[adc][grp]);
+                       xSemaphoreTake(sem[adc][grp], 0);
+               }
+               mutex[adc] = xSemaphoreCreateMutex();
+       }
        // Low level init
        adcInit();
 }
@@ -59,55 +57,24 @@ void drv_adc_init()
  *              - adcGROUP1: ADC group 1
  *              - adcGROUP2: ADC group 2
  */
-void adcNotification(adcBASE_t *adc, uint32_t group)
+void adcNotification(adcBASE_t *adc, uint32_t group, portBASE_TYPE* xHigherPriorityTaskWoken)
 {
        if (adcIsConversionComplete(adc, group) == ADC_CONVERSION_IS_FINISHED) {
-
-               // ADC1
-               if (adc == adcREG1) {
-                       switch (group) {
-                       case adcGROUP0:
-                               // Group0 is unused on RPP
-                               break;
-                       case adcGROUP1:
-                               // According to FreeRTOS documentation second parameter is
-                               // optional (and can be set to NULL) from FreeRTOS
-                               // V7.3.0. We are using 7.0.2. I confirmed this in the
-                               // source code: src/os/queue.c line 821. - Carlos
-                       {
-                               signed portBASE_TYPE dummy;
-                               xSemaphoreGiveFromISR(adcSemaphore_ADC1GRP1, &dummy);
-                       }
-                       break;
-                       default:
-                               // Group2 is unused on RPP
-                               break;
-                       }
-                       // ADC2
-               }
-               else {
-                       switch (group) {
-                       case adcGROUP0:
-                               // Group0 is unused on RPP
-                               break;
-                       case adcGROUP1:
-                       {
-                               signed portBASE_TYPE dummy;
-                               xSemaphoreGiveFromISR(adcSemaphore_ADC2GRP1, &dummy);
-                       }
-                       break;
-                       default:
-                               // Group2 is unused on RPP
-                               break;
-                       }
-               }
+               int adc_idx = (adc == adcREG1) ? 0 : 1;
+               int grp_idx = (group == adcGROUP1) ? 0 : 1;
+               xSemaphoreGiveFromISR(sem[adc_idx][grp_idx], xHigherPriorityTaskWoken);
        }
 }
 
 
 uint32_t drv_adc_generic_read(adcBASE_t *adc, uint32_t group,
-                                                         xSemaphoreHandle adcSemaphore, adcData_t *data)
+                                                         adcData_t *data)
 {
+       int adc_idx = (adc == adcREG1) ? 0 : 1;
+       int grp_idx = (group == adcGROUP1) ? 0 : 1;
+
+       xSemaphoreTake(mutex[adc_idx], portMAX_DELAY);
+
        // Calibrate
        adcCalibration(adc);
        adcMidPointCalibration(adc);
@@ -117,7 +84,7 @@ uint32_t drv_adc_generic_read(adcBASE_t *adc, uint32_t group,
        adcStartConversion(adc, group);
 
        // Wait for conversion to complete
-       xSemaphoreTake(adcSemaphore, portMAX_DELAY);
+       xSemaphoreTake(sem[adc_idx][grp_idx], portMAX_DELAY);
        adcDisableNotification(adc, group);
 
        // Get data
@@ -128,56 +95,31 @@ uint32_t drv_adc_generic_read(adcBASE_t *adc, uint32_t group,
                // FIXME Should report somehow.
                adcResetFiFo(adc, group);
 
-       return channels;
-}
-
+       xSemaphoreGive(mutex[adc_idx]);
 
-uint32_t drv_adc_read_adc(adcData_t *data)
-{
-       xSemaphoreTake(adcMutex_ADC, portMAX_DELAY);
-       uint32_t result = drv_adc_generic_read(
-               adcREG1,
-               adcGROUP1,
-               adcSemaphore_ADC1GRP1,
-               data
-               );
-       xSemaphoreGive(adcMutex_ADC);
-       return result;
+       return channels;
 }
 
-uint32_t drv_adc_read_houtifbk(adcData_t *data)
-{
-       xSemaphoreTake(adcMutex_HOUTIFBK, portMAX_DELAY);
-       uint32_t result = drv_adc_generic_read(
-               adcREG2,
-               adcGROUP1,
-               adcSemaphore_ADC2GRP1,
-               data
-               );
-       xSemaphoreGive(adcMutex_HOUTIFBK);
-       return result;
-}
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
 
-uint32_t adc_get_port_val(uint32_t *config, uint32_t num_channels,
-                                                 uint32_t *values)
+int8_t port_adc_get(const struct port_desc *port, void *values, size_t size)
 {
        uint32_t i;
-       adcBASE_t *adcReg = (adcBASE_t*)config[0];
-       uint32_t adcGroup = config[1];
-       uint32_t adcSemaphore = config[2];
        adcData_t data[ADC_MAX_CHANNELS];
+       int count = MIN(port->numchn, size/sizeof(uint16_t));
+       uint16_t *adcval = values;
+
+       assert(port->bpch == 16);
+       assert(size % sizeof(uint16_t) == 0);
 
        drv_adc_generic_read(
-               adcReg,
-               adcGroup,
-               (adcSemaphore == 1) ? adcSemaphore_ADC1GRP1 : adcSemaphore_ADC2GRP1,
+               port->cfg.adc.reg,
+               port->cfg.adc.group,
                data
                );
 
-       for (i = 0; i < num_channels; i++) {
-               values[i] = data[i].value;
-               values[i+num_channels] = data[i].id;
-       }
+       for (i = 0; i < count; i++)
+               adcval[i] = data[i].value;
 
        return 0;
 }