]> rtime.felk.cvut.cz Git - pes-rpp/rpp-lib.git/blobdiff - rpp/src/drv/adc.c
port_adc_get: Do not leak data
[pes-rpp/rpp-lib.git] / rpp / src / drv / adc.c
index 7089cfa56144662b232e707e29eac12a0f1e965b..3951dae7b2c1ff692ef94d515bff233982121d58 100644 (file)
@@ -20,6 +20,7 @@
 
 #include "drv/drv.h"
 #include "drv/port.h"
+#include "os/portmacro.h"
 
 // Binary semaphores for finish notifications
 static xSemaphoreHandle sem[2][2];
@@ -59,10 +60,12 @@ void drv_adc_init()
 void adcNotification(adcBASE_t *adc, uint32_t group)
 {
        if (adcIsConversionComplete(adc, group) == ADC_CONVERSION_IS_FINISHED) {
-               signed portBASE_TYPE dummy;
                int adc_idx = (adc == adcREG1) ? 0 : 1;
                int grp_idx = (group == adcGROUP1) ? 0 : 1;
-               xSemaphoreGiveFromISR(sem[adc_idx][grp_idx], &dummy);
+               portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
+
+               xSemaphoreGiveFromISR(sem[adc_idx][grp_idx], &xHigherPriorityTaskWoken);
+               portYIELD_FROM_ISR(xHigherPriorityTaskWoken); /* Cause context switch after return from interrupt */
        }
 }
 
@@ -73,6 +76,7 @@ uint32_t drv_adc_generic_read(adcBASE_t *adc, uint32_t group,
        int adc_idx = (adc == adcREG1) ? 0 : 1;
        int grp_idx = (group == adcGROUP1) ? 0 : 1;
 
+       /* Note: Thread safety of rpp_adc_update depends on this! */
        xSemaphoreTake(mutex[adc_idx], portMAX_DELAY);
 
        // Calibrate
@@ -106,20 +110,24 @@ int8_t port_adc_get(const struct port_desc *port, void *values, size_t size)
 {
        uint32_t i;
        adcData_t data[ADC_MAX_CHANNELS];
-       int count = MIN(port->numchn, size/sizeof(uint16_t));
+       uint32_t count = MIN(port->numchn, size/sizeof(uint16_t));
+       uint32_t ret;
        uint16_t *adcval = values;
 
        assert(port->bpch == 16);
+       assert(port->numchn <= ADC_MAX_CHANNELS);
        assert(size % sizeof(uint16_t) == 0);
 
-       drv_adc_generic_read(
+       ret = drv_adc_generic_read(
                port->cfg.adc.reg,
                port->cfg.adc.group,
                data
                );
 
-       for (i = 0; i < count; i++)
+       for (i = 0; i < ret; i++)
                adcval[i] = data[i].value;
+       for (i = ret; i < count; i++)
+               adcval[i] = 0;
 
        return 0;
 }