diff --git a/FreeRTOSConfig.h b/FreeRTOSConfig.h index 2be418b..4b9bfd9 100644 --- a/FreeRTOSConfig.h +++ b/FreeRTOSConfig.h @@ -111,7 +111,7 @@ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY 4 // above normal -#define configTIMER_TASK_STACK_DEPTH 128 +#define configTIMER_TASK_STACK_DEPTH TSK_STACK_TIMERS //128 #define configTIMER_QUEUE_LENGTH 4 #define configTOTAL_HEAP_SIZE 4096 diff --git a/freertos.c b/freertos.c index 3c69f35..da8accd 100644 --- a/freertos.c +++ b/freertos.c @@ -114,13 +114,13 @@ __weak void vApplicationStackOverflowHook(TaskHandle_t xTask, signed char *pcTas /* USER CODE BEGIN GET_IDLE_TASK_MEMORY */ static StaticTask_t xIdleTaskTCBBuffer; -static StackType_t xIdleStack[configMINIMAL_STACK_SIZE]; +static StackType_t xIdleStack[TSK_STACK_IDLE]; void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize ) { *ppxIdleTaskTCBBuffer = &xIdleTaskTCBBuffer; *ppxIdleTaskStackBuffer = &xIdleStack[0]; - *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE; + *pulIdleTaskStackSize = TSK_STACK_IDLE; /* place for user code */ } /* USER CODE END GET_IDLE_TASK_MEMORY */ @@ -128,13 +128,13 @@ void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackTy /* USER CODE BEGIN GET_IDLE_TASK_MEMORY */ static StaticTask_t xTimersTaskTCBBuffer; -static StackType_t xTimersStack[configTIMER_TASK_STACK_DEPTH]; +static StackType_t xTimersStack[TSK_STACK_TIMERS]; void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimersTaskTCBBuffer, StackType_t **ppxTimersTaskStackBuffer, uint32_t *pulTimersTaskStackSize ) { *ppxTimersTaskTCBBuffer = &xTimersTaskTCBBuffer; *ppxTimersTaskStackBuffer = &xTimersStack[0]; - *pulTimersTaskStackSize = configTIMER_TASK_STACK_DEPTH; + *pulTimersTaskStackSize = TSK_STACK_TIMERS; /* place for user code */ } /* USER CODE END GET_IDLE_TASK_MEMORY */ diff --git a/platform/plat_compat.h b/platform/plat_compat.h index 994fe3e..03b1a1f 100644 --- a/platform/plat_compat.h +++ b/platform/plat_compat.h @@ -18,13 +18,17 @@ // 180 is normally enough if not doing extensive debug logging #define TSK_STACK_MSG 200 // TF message handler task stack size (all unit commands run on this thread) +#define TSK_STACK_IDLE 64 //configMINIMAL_STACK_SIZE +#define TSK_STACK_TIMERS 64 //configTIMER_TASK_STACK_DEPTH + + #define BULK_READ_BUF_LEN 256 // Buffer for TF bulk reads #define UNIT_TMP_LEN 512 // Buffer for internal unit operations #define FLASH_SAVE_BUF_LEN 128 // Malloc'd buffer for saving to flash #define MSG_QUE_SLOT_SIZE 64 // FIXME this should be possible to lower, but there's some bug with bulk transfer / INI parser -#define RX_QUE_CAPACITY 32 // TinyFrame rx queue size (64 bytes each) +#define RX_QUE_CAPACITY 36 // TinyFrame rx queue size (64 bytes each) #define TF_MAX_PAYLOAD_RX 512 // TF max Rx payload #define TF_SENDBUF_LEN 64 // TF transmit buffer (can be less than a full frame) diff --git a/units/adc/_adc_core.c b/units/adc/_adc_core.c index d101831..64a6698 100644 --- a/units/adc/_adc_core.c +++ b/units/adc/_adc_core.c @@ -183,7 +183,9 @@ void UADC_DMA_Handler(void *arg) LL_DMA_ClearFlag_TC(priv->DMAx, priv->dma_chnum); } -// dbg("start %d, end %d", (int)start, (int)end); + if (start > end) { + dbg("start %d, end %d", (int) start, (int) end); + } assert_param(start <= end); if (start != end) { @@ -252,19 +254,25 @@ void UADC_DMA_Handler(void *arg) void UADC_ADC_EOS_Handler(void *arg) { - uint64_t timestamp = PTIM_GetMicrotime(); Unit *unit = arg; - assert_param(unit); struct priv *priv = unit->data; assert_param(priv); + const bool trig_ready4_rising = (priv->trig_prev_level < priv->trig_level) && (bool) (priv->trig_edge & 0b01); + const bool trig_ready4_falling = (priv->trig_prev_level > priv->trig_level) && (bool) (priv->trig_edge & 0b10); + const bool armed = (trig_ready4_rising && trig_ready4_falling) && priv->opmode == ADC_OPMODE_ARMED; + + // Normally + uint64_t timestamp = 0; + if (armed) timestamp = PTIM_GetMicrotime(); + LL_ADC_ClearFlag_EOS(priv->ADCx); if (priv->opmode == ADC_OPMODE_UNINIT) return; // Wait for the DMA to complete copying the last sample uint16_t dmapos; - hw_wait_while((dmapos = (uint16_t) DMA_POS(priv)) % priv->nb_channels != 0, 100); + hw_wait_while((dmapos = (uint16_t) DMA_POS(priv)) % priv->nb_channels != 0, 100); // XXX this could be changed to reading it from the DR instead uint32_t sample_pos; if (dmapos == 0) { @@ -275,55 +283,52 @@ void UADC_ADC_EOS_Handler(void *arg) sample_pos -= priv->nb_channels; int cnt = 0; // index of the sample within the group - for (uint32_t i = 0; i < 18; i++) { - if (priv->extended_channels_mask & (1 << i)) { - uint16_t val = priv->dma_buffer[sample_pos+cnt]; + + const uint8_t trig_source = priv->trigger_source; + const bool can_average = priv->real_frequency_int < UADC_MAX_FREQ_FOR_AVERAGING; + const uint16_t *dma_buffer = priv->dma_buffer; + const uint32_t channels_mask = priv->extended_channels_mask; + + for (uint8_t i = 0; i < 18; i++) { + if (channels_mask & (1 << i)) { + uint16_t val = dma_buffer[sample_pos+cnt]; cnt++; - priv->averaging_bins[i] = - priv->averaging_bins[i] * (1.0f - priv->avg_factor_as_float) + - ((float) val) * priv->avg_factor_as_float; + if (can_average) { + priv->averaging_bins[i] = + priv->averaging_bins[i] * (1.0f - priv->avg_factor_as_float) + + ((float) val) * priv->avg_factor_as_float; + } priv->last_samples[i] = val; - if (i == priv->trigger_source) { - if (priv->opmode == ADC_OPMODE_ARMED) { + if (armed && i == trig_source) { // dbg("Trig line level %d", (int)val); - - bool trigd = false; - uint8_t edge_type = 0; - if (priv->trig_prev_level < priv->trig_level && val >= priv->trig_level) { + if (trig_ready4_rising && val >= priv->trig_level) { // dbg("******** Rising edge"); - // Rising edge - trigd = (bool) (priv->trig_edge & 0b01); - edge_type = 1; - } - else if (priv->trig_prev_level > priv->trig_level && val <= priv->trig_level) { -// dbg("******** Falling edge"); - // Falling edge - trigd = (bool) (priv->trig_edge & 0b10); - edge_type = 2; - } - - if (trigd) { - UADC_HandleTrigger(unit, edge_type, timestamp); - } + // Rising edge + UADC_HandleTrigger(unit, 1, timestamp); } - else if (priv->opmode == ADC_OPMODE_REARM_PENDING) { - if (!priv->auto_rearm) { - // It looks like the flag was cleared by DISARM before we got a new sample. - // Let's just switch to IDLE - UADC_SwitchMode(unit, ADC_OPMODE_IDLE); - } else { - // Re-arming for a new trigger - UADC_SwitchMode(unit, ADC_OPMODE_ARMED); - } + else if (trig_ready4_falling && val <= priv->trig_level) { +// dbg("******** Falling edge"); + // Falling edge + UADC_HandleTrigger(unit, 2, timestamp); } - priv->trig_prev_level = val; } } } + + if (priv->opmode == ADC_OPMODE_REARM_PENDING) { + if (!priv->auto_rearm) { + // It looks like the flag was cleared by DISARM before we got a new sample. + // Let's just switch to IDLE + UADC_SwitchMode(unit, ADC_OPMODE_IDLE); + } else { + // Re-arming for a new trigger + UADC_SwitchMode(unit, ADC_OPMODE_ARMED); + } + } } void UADC_HandleTrigger(Unit *unit, uint8_t edge_type, uint64_t timestamp) @@ -538,6 +543,5 @@ void UADC_SwitchMode(Unit *unit, enum uadc_opmode new_mode) LL_DMA_EnableIT_TC(priv->DMAx, priv->dma_chnum); } - dbg("Now setting the new opmode"); priv->opmode = new_mode; } diff --git a/units/adc/_adc_init.c b/units/adc/_adc_init.c index 1de3f4f..8fd1e47 100644 --- a/units/adc/_adc_init.c +++ b/units/adc/_adc_init.c @@ -49,6 +49,8 @@ error_t UADC_SetSampleRate(Unit *unit, uint32_t hertz) LL_TIM_SetPrescaler(priv->TIMx, (uint32_t) (presc - 1)); LL_TIM_SetAutoReload(priv->TIMx, count - 1); + priv->real_frequency_int = hertz; + return E_SUCCESS; } diff --git a/units/adc/_adc_internal.h b/units/adc/_adc_internal.h index fe00843..8972fff 100644 --- a/units/adc/_adc_internal.h +++ b/units/adc/_adc_internal.h @@ -11,6 +11,8 @@ #include "unit_base.h" +#define UADC_MAX_FREQ_FOR_AVERAGING 20000 + enum uadc_opmode { ADC_OPMODE_UNINIT, //!< Not yet switched to any mode ADC_OPMODE_IDLE, //!< Idle. Allows immediate value readout and averaging. @@ -42,6 +44,7 @@ struct priv { // internal state float real_frequency; + uint32_t real_frequency_int; uint32_t extended_channels_mask; //!< channels bitfield including tsense and vref float avg_factor_as_float; ADC_TypeDef *ADCx; //!< The ADC peripheral used diff --git a/units/adc/_adc_settings.c b/units/adc/_adc_settings.c index e19811e..e723c19 100644 --- a/units/adc/_adc_settings.c +++ b/units/adc/_adc_settings.c @@ -98,7 +98,7 @@ void UADC_writeIni(Unit *unit, IniWriter *iw) iw_entry(iw, "enable_tsense", str_yn(priv->enable_tsense)); iw_comment(iw, "Enable Vref channel (#17)"); - iw_entry(iw, "enable_vref", str_yn(priv->enable_tsense)); + iw_entry(iw, "enable_vref", str_yn(priv->enable_vref)); iw_cmt_newline(iw); iw_comment(iw, "Sampling time (0-7)"); diff --git a/units/adc/unit_adc.c b/units/adc/unit_adc.c index 0f8cb83..715b7bc 100644 --- a/units/adc/unit_adc.c +++ b/units/adc/unit_adc.c @@ -64,6 +64,7 @@ static error_t UADC_handleRequest(Unit *unit, TF_ID frame_id, uint8_t command, P * May differ from the configured or requested value due to prescaller limitations. */ case CMD_GET_SAMPLE_RATE: + pb_u32(&pb, priv->real_frequency_int); pb_float(&pb, priv->real_frequency); com_respond_pb(frame_id, MSG_SUCCESS, &pb); return E_SUCCESS; @@ -106,6 +107,11 @@ static error_t UADC_handleRequest(Unit *unit, TF_ID frame_id, uint8_t command, P return E_BUSY; } + if (priv->real_frequency_int > UADC_MAX_FREQ_FOR_AVERAGING) { + com_respond_str(MSG_ERROR, frame_id, "Too fast for smoothing"); + return E_FAILURE; + } + for (uint8_t i = 0; i < 18; i++) { if (priv->extended_channels_mask & (1 << i)) { pb_float(&pb, priv->averaging_bins[i]);