Some optimizations to make it better work at higher speeds. Triggers don't work
This commit is contained in:
+1
-1
@@ -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
|
||||
|
||||
+4
-4
@@ -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 */
|
||||
|
||||
@@ -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)
|
||||
|
||||
+45
-41
@@ -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) {
|
||||
// Rising edge
|
||||
UADC_HandleTrigger(unit, 1, timestamp);
|
||||
}
|
||||
else if (trig_ready4_falling && 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);
|
||||
}
|
||||
// Falling edge
|
||||
UADC_HandleTrigger(unit, 2, 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);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)");
|
||||
|
||||
@@ -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]);
|
||||
|
||||
Reference in New Issue
Block a user