more parts of adc fixed
This commit is contained in:
+18
-6
@@ -12,21 +12,26 @@ bool EventReport_Start(EventReport *report)
|
||||
{
|
||||
assert_param(report->timestamp != 0);
|
||||
|
||||
TF_Msg msg;
|
||||
TF_ClearMsg(&msg);
|
||||
msg.len = (TF_LEN) (report->length + 1 /*callsign*/ + 1 /*type*/ + 8 /*checksum*/);
|
||||
msg.type = MSG_UNIT_REPORT;
|
||||
const uint8_t len_overhead = 1 /*callsign*/ + 1 /*type*/ + 8 /*timestamp u64*/;
|
||||
|
||||
TF_Msg msg = {
|
||||
.len = (TF_LEN) (report->length + len_overhead),
|
||||
.type = MSG_UNIT_REPORT,
|
||||
};
|
||||
|
||||
if (!TF_Send_Multipart(comm, &msg)) {
|
||||
dbg("!! Err sending event");
|
||||
return false;
|
||||
}
|
||||
|
||||
PayloadBuilder pb = pb_start(evt_buf, 10, NULL);
|
||||
report->sent_msg_id = msg.frame_id;
|
||||
|
||||
PayloadBuilder pb = pb_start(evt_buf, len_overhead, NULL);
|
||||
pb_u8(&pb, report->unit->callsign);
|
||||
pb_u8(&pb, report->type);
|
||||
pb_u64(&pb, report->timestamp);
|
||||
assert_param(pb.ok);
|
||||
TF_Multipart_Payload(comm, evt_buf, 10);
|
||||
TF_Multipart_Payload(comm, evt_buf, len_overhead);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -36,6 +41,13 @@ void EventReport_Data(const uint8_t *buff, uint16_t len)
|
||||
TF_Multipart_Payload(comm, buff, len);
|
||||
}
|
||||
|
||||
void EventReport_PB(PayloadBuilder *pb)
|
||||
{
|
||||
uint32_t len;
|
||||
uint8_t *buf = pb_close(pb, &len);
|
||||
TF_Multipart_Payload(comm, buf, len);
|
||||
}
|
||||
|
||||
void EventReport_End(void)
|
||||
{
|
||||
TF_Multipart_Close(comm);
|
||||
|
||||
@@ -21,12 +21,14 @@ typedef struct event_report_ {
|
||||
uint64_t timestamp; //!< Microsecond timestamp of the event, captured as close as possible to the IRQ
|
||||
uint16_t length; //!< Payload length
|
||||
uint8_t *data; //!< Data if using the EventReport_Send() function, otherwise NULL and data is sent using EventReport_Data()
|
||||
TF_ID sent_msg_id;
|
||||
} EventReport;
|
||||
|
||||
bool EventReport_Send(EventReport *report);
|
||||
|
||||
bool EventReport_Start(EventReport *report);
|
||||
void EventReport_Data(const uint8_t *buff, uint16_t len);
|
||||
void EventReport_PB(PayloadBuilder *pb);
|
||||
void EventReport_End(void);
|
||||
|
||||
#endif //GEX_F072_EVENT_REPORTS_H
|
||||
|
||||
@@ -57,10 +57,9 @@ void com_send_pb(TF_TYPE type, PayloadBuilder *pb)
|
||||
void com_send_buf(TF_TYPE type, const uint8_t *buf, uint32_t len)
|
||||
{
|
||||
TF_Msg msg = {
|
||||
.type = MSG_UNIT_REPORT,
|
||||
.type = type,
|
||||
.data = buf,
|
||||
.len = (TF_LEN) len,
|
||||
.type = type,
|
||||
};
|
||||
|
||||
TF_Send(comm, &msg); // no listener
|
||||
|
||||
+1
-1
@@ -56,7 +56,7 @@ void TaskMain(void const * argument)
|
||||
// Periodically check stacks for overrun
|
||||
stackmon_check_canaries();
|
||||
// Periodically dump all stacks - for checking levels before critical (to reduce size if not needed)
|
||||
if ((cnt%75)==0) stackmon_dump();
|
||||
if ((cnt%150)==0) stackmon_dump();
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
+96
-20
@@ -39,6 +39,75 @@ static void UADC_JobSendBlockChunk(Job *job)
|
||||
priv->stream_serial++;
|
||||
}
|
||||
|
||||
static void UADC_JobSendTriggerCaptureHeader(Job *job)
|
||||
{
|
||||
Unit *unit = job->unit;
|
||||
assert_param(unit);
|
||||
struct priv *priv = unit->data;
|
||||
assert_param(priv);
|
||||
|
||||
EventReport er = {
|
||||
.unit = unit,
|
||||
.type = EVT_CAPT_START,
|
||||
.timestamp = job->timestamp,
|
||||
.length = (priv->pretrig_len+1)*priv->nb_channels*sizeof(uint16_t) + 2 /*pretrig len*/ + 1 /*edge*/ + 1 /* seq */
|
||||
};
|
||||
|
||||
uint16_t index_trigd = (uint16_t) job->data1;
|
||||
uint8_t edge = (uint8_t) job->data2;
|
||||
|
||||
EventReport_Start(&er);
|
||||
priv->stream_frame_id = er.sent_msg_id;
|
||||
dbg("Sending TRIG HEADER with id %d (idx %d)", (int)er.sent_msg_id, (int)index_trigd);
|
||||
{
|
||||
// preamble
|
||||
uint8_t buf[4];
|
||||
PayloadBuilder pb = pb_start(buf, 4, NULL);
|
||||
pb_u16(&pb, priv->pretrig_len);
|
||||
pb_u8(&pb, edge);
|
||||
pb_u8(&pb, priv->stream_serial++); // This is the serial counter for the first chunk
|
||||
// (containing the pre-trigger, or empty if no pretrig configured)
|
||||
EventReport_PB(&pb);
|
||||
|
||||
if (priv->pretrig_len > 0) {
|
||||
// pretrig
|
||||
uint16_t pretrig_remain = (uint16_t) ((priv->pretrig_len + 1) * priv->nb_channels); // +1 because we want pretrig 0 to exactly start with the triggering sample
|
||||
|
||||
assert_param(index_trigd <= priv->dma_buffer_itemcount);
|
||||
|
||||
// this is one past the last entry of the triggering capture group
|
||||
if (pretrig_remain > index_trigd) {
|
||||
// used items in the wrap-around part of the buffer
|
||||
uint16_t items_from_end = pretrig_remain - index_trigd;
|
||||
assert_param(priv->dma_buffer_itemcount - items_from_end >= index_trigd);
|
||||
|
||||
dbg("Pretrig wraparound part: start %d, len %d",
|
||||
(int) (priv->dma_buffer_itemcount - items_from_end),
|
||||
(int) items_from_end
|
||||
);
|
||||
|
||||
EventReport_Data(
|
||||
(uint8_t *) &priv->dma_buffer[priv->dma_buffer_itemcount -
|
||||
items_from_end],
|
||||
items_from_end * sizeof(uint16_t));
|
||||
|
||||
assert_param(items_from_end <= pretrig_remain);
|
||||
pretrig_remain -= items_from_end;
|
||||
}
|
||||
|
||||
dbg("Pretrig front part: start %d, len %d",
|
||||
(int) (index_trigd - pretrig_remain),
|
||||
(int) pretrig_remain
|
||||
);
|
||||
|
||||
assert_param(pretrig_remain <= index_trigd);
|
||||
EventReport_Data((uint8_t *) &priv->dma_buffer[index_trigd - pretrig_remain],
|
||||
pretrig_remain * sizeof(uint16_t));
|
||||
}
|
||||
}
|
||||
EventReport_End();
|
||||
}
|
||||
|
||||
static void UADC_JobSendEndOfStreamMsg(Job *job)
|
||||
{
|
||||
Unit *unit = job->unit;
|
||||
@@ -93,17 +162,17 @@ void UADC_DMA_Handler(void *arg)
|
||||
uint16_t end;
|
||||
|
||||
if (ht) {
|
||||
dbg("HT");
|
||||
// dbg("HT");
|
||||
end = (uint16_t) (priv->dma_buffer_itemcount / 2);
|
||||
LL_DMA_ClearFlag_HT(priv->DMAx, priv->dma_chnum);
|
||||
}
|
||||
else {
|
||||
dbg("TC");
|
||||
// dbg("TC");
|
||||
end = (uint16_t) priv->dma_buffer_itemcount;
|
||||
LL_DMA_ClearFlag_TC(priv->DMAx, priv->dma_chnum);
|
||||
}
|
||||
|
||||
dbg("start %d, end %d", (int)start, (int)end);
|
||||
// dbg("start %d, end %d", (int)start, (int)end);
|
||||
assert_param(start <= end);
|
||||
|
||||
if (start != end) {
|
||||
@@ -126,7 +195,7 @@ void UADC_DMA_Handler(void *arg)
|
||||
scheduleJob(&j);
|
||||
|
||||
if (close) {
|
||||
dbg("End of capture");
|
||||
// dbg("End of capture");
|
||||
// If auto-arm enabled, we need to re-arm again.
|
||||
// However, EOS irq is disabled during the capture.
|
||||
// We have to wait for the next EOS interrupt to occur.
|
||||
@@ -134,7 +203,7 @@ void UADC_DMA_Handler(void *arg)
|
||||
UADC_SwitchMode(unit, (priv->auto_rearm && m_trigd) ? ADC_OPMODE_REARM_PENDING : ADC_OPMODE_IDLE);
|
||||
}
|
||||
} else {
|
||||
dbg("start==end, skip this irq");
|
||||
// dbg("start==end, skip this irq");
|
||||
}
|
||||
|
||||
if (tc) {
|
||||
@@ -201,18 +270,18 @@ void UADC_ADC_EOS_Handler(void *arg)
|
||||
|
||||
if (i == priv->trigger_source) {
|
||||
if (priv->opmode == ADC_OPMODE_ARMED) {
|
||||
dbg("Trig line level %d", (int)val);
|
||||
// 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) {
|
||||
dbg("******** Rising edge");
|
||||
// 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");
|
||||
// dbg("******** Falling edge");
|
||||
// Falling edge
|
||||
trigd = (bool) (priv->trig_edge & 0b10);
|
||||
edge_type = 2;
|
||||
@@ -246,7 +315,7 @@ void UADC_HandleTrigger(Unit *unit, uint8_t edge_type, uint64_t timestamp)
|
||||
assert_param(priv);
|
||||
|
||||
if (priv->trig_holdoff != 0 && priv->trig_holdoff_remain > 0) {
|
||||
dbg("Trig discarded due to holdoff.");
|
||||
// dbg("Trig discarded due to holdoff.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -261,9 +330,16 @@ void UADC_HandleTrigger(Unit *unit, uint8_t edge_type, uint64_t timestamp)
|
||||
priv->trig_stream_remain = priv->trig_len;
|
||||
priv->stream_serial = 0;
|
||||
|
||||
// TODO Send pre-trigger
|
||||
// dbg("Trigger condition hit, edge=%d, startpos %d", edge_type, (int)priv->stream_startpos);
|
||||
|
||||
dbg("Trigger condition hit, edge=%d, startpos %d", edge_type, (int)priv->stream_startpos);
|
||||
Job j = {
|
||||
.unit = unit,
|
||||
.timestamp = timestamp,
|
||||
.data1 = priv->stream_startpos,
|
||||
.data2 = edge_type,
|
||||
.cb = UADC_JobSendTriggerCaptureHeader
|
||||
};
|
||||
scheduleJob(&j);
|
||||
|
||||
UADC_SwitchMode(unit, ADC_OPMODE_TRIGD);
|
||||
}
|
||||
@@ -291,7 +367,7 @@ void UADC_StartStream(Unit *unit, TF_ID frame_id)
|
||||
priv->stream_frame_id = frame_id;
|
||||
priv->stream_startpos = (uint16_t) DMA_POS(priv);
|
||||
priv->stream_serial = 0;
|
||||
dbg("Start streaming.");
|
||||
// dbg("Start streaming.");
|
||||
UADC_SwitchMode(unit, ADC_OPMODE_STREAM);
|
||||
}
|
||||
|
||||
@@ -302,7 +378,7 @@ void UADC_StopStream(Unit *unit)
|
||||
struct priv *priv = unit->data;
|
||||
assert_param(priv);
|
||||
|
||||
dbg("Stop stream.");
|
||||
// dbg("Stop stream.");
|
||||
UADC_ReportEndOfStream(unit);
|
||||
UADC_SwitchMode(unit, ADC_OPMODE_IDLE);
|
||||
}
|
||||
@@ -336,7 +412,7 @@ void UADC_SwitchMode(Unit *unit, enum uadc_opmode new_mode)
|
||||
assert_param((priv->opmode != ADC_OPMODE_UNINIT) || (new_mode == ADC_OPMODE_IDLE));
|
||||
|
||||
if (new_mode == ADC_OPMODE_UNINIT) {
|
||||
dbg("ADC switch -> UNINIT");
|
||||
// dbg("ADC switch -> UNINIT");
|
||||
// Stop the DMA, timer and disable ADC - this is called before tearing down the unit
|
||||
LL_TIM_DisableCounter(priv->TIMx);
|
||||
|
||||
@@ -344,23 +420,23 @@ void UADC_SwitchMode(Unit *unit, enum uadc_opmode new_mode)
|
||||
if (LL_ADC_IsEnabled(priv->ADCx)) {
|
||||
// Cancel ongoing conversion
|
||||
if (LL_ADC_REG_IsConversionOngoing(priv->ADCx)) {
|
||||
dbg("Stopping ADC conv");
|
||||
// dbg("Stopping ADC conv");
|
||||
LL_ADC_REG_StopConversion(priv->ADCx);
|
||||
hw_wait_while(LL_ADC_REG_IsStopConversionOngoing(priv->ADCx), 100);
|
||||
}
|
||||
|
||||
LL_ADC_Disable(priv->ADCx);
|
||||
dbg("Disabling ADC");
|
||||
// dbg("Disabling ADC");
|
||||
hw_wait_while(LL_ADC_IsDisableOngoing(priv->ADCx), 100);
|
||||
}
|
||||
|
||||
dbg("Disabling DMA");
|
||||
// dbg("Disabling DMA");
|
||||
LL_DMA_DisableChannel(priv->DMAx, priv->dma_chnum);
|
||||
LL_DMA_DisableIT_HT(priv->DMAx, priv->dma_chnum);
|
||||
LL_DMA_DisableIT_TC(priv->DMAx, priv->dma_chnum);
|
||||
}
|
||||
else if (new_mode == ADC_OPMODE_IDLE || new_mode == ADC_OPMODE_REARM_PENDING) {
|
||||
dbg("ADC switch -> IDLE or IDLE/REARM_PENDING");
|
||||
// dbg("ADC switch -> IDLE or IDLE/REARM_PENDING");
|
||||
// IDLE and ARMED are identical with the exception that the trigger condition is not checked
|
||||
// ARMED can be only entered from IDLE, thus we do the init only here.
|
||||
|
||||
@@ -382,7 +458,7 @@ void UADC_SwitchMode(Unit *unit, enum uadc_opmode new_mode)
|
||||
}
|
||||
}
|
||||
else if (new_mode == ADC_OPMODE_ARMED) {
|
||||
dbg("ADC switch -> ARMED");
|
||||
// dbg("ADC switch -> ARMED");
|
||||
assert_param(priv->opmode == ADC_OPMODE_IDLE || priv->opmode == ADC_OPMODE_REARM_PENDING);
|
||||
|
||||
// avoid firing immediately by the value jumping across the scale
|
||||
@@ -392,7 +468,7 @@ void UADC_SwitchMode(Unit *unit, enum uadc_opmode new_mode)
|
||||
new_mode == ADC_OPMODE_STREAM ||
|
||||
new_mode == ADC_OPMODE_BLCAP) {
|
||||
|
||||
dbg("ADC switch -> TRIG'D / STREAM / BLOCK");
|
||||
// dbg("ADC switch -> TRIG'D / STREAM / BLOCK");
|
||||
assert_param(priv->opmode == ADC_OPMODE_ARMED || priv->opmode == ADC_OPMODE_IDLE);
|
||||
|
||||
// during the capture, we disallow direct readout and averaging to reduce overhead
|
||||
|
||||
Reference in New Issue
Block a user