aboutsummaryrefslogtreecommitdiff
path: root/fw/adc.c
diff options
context:
space:
mode:
Diffstat (limited to 'fw/adc.c')
-rw-r--r--fw/adc.c302
1 files changed, 138 insertions, 164 deletions
diff --git a/fw/adc.c b/fw/adc.c
index 06cf027..ddc2640 100644
--- a/fw/adc.c
+++ b/fw/adc.c
@@ -85,8 +85,8 @@ void adc_configure_monitor_mode(int oversampling, int ivl_us, int mean_aggregate
/* keep track of current mode in global variable */
st.adc_mode = ADC_MONITOR;
- st.adc_oversampling = oversampling;
- st.ovs_count = 0;
+ //st.adc_oversampling = oversampling;
+ //st.ovs_count = 0;
for (int i=0; i<NCH; i++)
st.adc_aggregate[i] = 0;
st.mean_aggregator[0] = st.mean_aggregator[1] = st.mean_aggregator[2] = 0;
@@ -96,7 +96,10 @@ void adc_configure_monitor_mode(int oversampling, int ivl_us, int mean_aggregate
st.detector.debounce_cycles = 0;
st.detector.base_interval_cycles = 10;
- st.detector.symbol = -1;
+ st.detector.sync = 0;
+ st.receiver.rxpos = -1;
+ st.receiver.address = 5; /* FIXME debug code */
+ st.receiver.global_brightness = 0xff;
st.detector.bit = 0;
st.detector.committed_len_ctr = st.detector.len_ctr = 0;
st.detector.debounce_ctr = 0;
@@ -165,13 +168,106 @@ static void adc_timer_init(int psc, int ivl) {
TIM1->CR1 |= TIM_CR1_CEN;
}
-/* FIXME DEBUG */
+/* This acts as a no-op that provides a convenient point to set a breakpoint for the debug scope logic */
static void gdb_dump(void) {
}
+int payload_len[PKT_TYPE_MAX] = {
+ [PKT_TYPE_RESERVED] = 0,
+ [PKT_TYPE_SET_OUTPUTS_BINARY] = 1,
+ [PKT_TYPE_SET_GLOBAL_BRIGHTNESS] = 1,
+ [PKT_TYPE_SET_OUTPUTS] = 8 };
+
+void handle_command(int command, uint8_t *args) {
+ switch (command) {
+ case PKT_TYPE_SET_OUTPUTS_BINARY:
+ set_outputs_binary(args[0], st.receiver.global_brightness);
+ break;
+
+ case PKT_TYPE_SET_GLOBAL_BRIGHTNESS:
+ st.receiver.global_brightness = args[0];
+ break;
+
+ case PKT_TYPE_SET_OUTPUTS:
+ set_outputs(args);
+ break;
+ }
+}
+
+void receive_symbol(int symbol) {
+ if (symbol == -K28_1) { /* Comma/frame delimiter */
+ st.receiver.rxpos = 0;
+ /* Fall through and return and just ignore incomplete packets */
+
+ } else if (symbol == -DECODING_ERROR) {
+ st.receiver.rxpos = -1;
+
+ } else if (symbol < 0) { /* Unknown comma symbol or error */
+ st.receiver.rxpos = -1;
+
+ } else if (st.receiver.rxpos == -1) {
+ return;
+
+ } else if (st.receiver.rxpos == 0) { /* First data symbol, and not an error or comma symbol */
+ st.receiver.packet_type = symbol & ~PKT_TYPE_BULK_FLAG;
+ if (st.receiver.packet_type >= PKT_TYPE_MAX) {
+ st.receiver.rxpos = -1;
+ return;
+ }
+
+ st.receiver.is_bulk = symbol & PKT_TYPE_BULK_FLAG;
+ st.receiver.offset = (st.receiver.is_bulk) ? st.receiver.address*payload_len[st.receiver.packet_type]+1 : 2;
+ st.receiver.rxpos++;
+
+ } else if (!st.receiver.is_bulk && st.receiver.rxpos == 1) {
+ st.receiver.rxpos = (symbol == st.receiver.address) ? 2 : -1;
+
+ } else {
+ st.receiver.argbuf[st.receiver.rxpos - st.receiver.offset] = symbol;
+ st.receiver.rxpos++;
+
+ if (st.receiver.rxpos - st.receiver.offset == payload_len[st.receiver.packet_type]) {
+ handle_command(st.receiver.packet_type, (uint8_t *)st.receiver.argbuf);
+ st.receiver.rxpos = -1;
+ }
+ }
+}
+
+void receive_bit(int bit) {
+ int symbol = xfr_8b10b_feed_bit((struct state_8b10b_dec *)&st.detector.rx8b10b, bit);
+ if (symbol == -K28_1)
+ st.detector.sync = 1;
+
+ if (symbol == -DECODING_IN_PROGRESS)
+ return;
+
+ if (symbol == -DECODING_ERROR)
+ st.detector.sync = 0;
+ /* Fall through so we also pass the error to receive_symbol */
+
+ receive_symbol(symbol);
+
+ /* Debug scope logic */
+ static int debug_buf_pos = 0;
+ if (st.detector.sync && symbol != -DECODING_IN_PROGRESS) {
+ if (debug_buf_pos < NCH) {
+ debug_buf_pos = NCH;
+ } else {
+ adc_buf[debug_buf_pos++] = symbol;
+
+ if (debug_buf_pos >= sizeof(adc_buf)/sizeof(adc_buf[0])) {
+ debug_buf_pos = 0;
+ st.detector.sync = 0;
+ gdb_dump();
+ for (int i=0; i<sizeof(adc_buf)/sizeof(adc_buf[0]); i++)
+ adc_buf[i] = -255;
+ }
+ }
+ }
+}
+
void DMA1_Channel1_IRQHandler(void) {
int start = SysTick->VAL;
- static int debug_buf_pos = 0;
/* Clear the interrupt flag */
DMA1->IFCR |= DMA_IFCR_CGIF1;
@@ -179,171 +275,49 @@ void DMA1_Channel1_IRQHandler(void) {
if (st.adc_mode == ADC_SCOPE)
return;
- //for (int i=0; i<NCH; i++)
- // st.adc_aggregate[i] += adc_buf[i];
-
- //if (++st.ovs_count == (1<<st.adc_oversampling)) {
- /* FIXME DEBUG
- for (int i=0; i<NCH; i++)
- st.adc_aggregate[i] >>= st.adc_oversampling;
- */
- /* This has been copied from the code examples to section 12.9 ADC>"Temperature sensor and internal reference
- * voltage" in the reference manual with the extension that we actually measure the supply voltage instead of
- * hardcoding it. This is not strictly necessary since we're running off a bored little LDO but it's free and
- * the current supply voltage is a nice health value.
- */
- // FIXME DEBUG adc_data.adc_vcc_mv = (3300 * VREFINT_CAL)/(st.adc_aggregate[VREF_CH]);
-
- int64_t vcc = 3300;
- /* FIXME debug
- int64_t vcc = adc_data.adc_vcc_mv;
- int64_t read = st.adc_aggregate[TEMP_CH] * 10 * 10000;
- int64_t cal = TS_CAL1 * 10 * 10000;
- adc_data.adc_temp_celsius_tenths = 300 + ((read/4096 * vcc) - (cal/4096 * 3300))/43000;
- */
-
- const long vmeas_r_total = VMEAS_R_HIGH + VMEAS_R_LOW;
- //int a = adc_data.adc_vmeas_a_mv = (st.adc_aggregate[VMEAS_A]*(vmeas_r_total * vcc / VMEAS_R_LOW)) >> 12;
- int a = adc_data.adc_vmeas_a_mv = (adc_buf[VMEAS_A]*13300) >> 12;
- //FIXME debug int b = adc_data.adc_vmeas_b_mv = (st.adc_aggregate[VMEAS_B]*vmeas_r_total)/4096 * vcc / VMEAS_R_LOW;
-
- /* FIXME debug
- st.mean_aggregator[0] += a;
- st.mean_aggregator[1] += b;
- st.mean_aggregator[2] += abs(b-a);
- if (++st.mean_aggregate_ctr == st.mean_aggregate_len) {
- adc_data.adc_mean_a_mv = st.mean_aggregator[0] / st.mean_aggregate_len;
- adc_data.adc_mean_b_mv = st.mean_aggregator[1] / st.mean_aggregate_len;
- adc_data.adc_mean_diff_mv = st.mean_aggregator[2] / st.mean_aggregate_len;
-
- st.mean_aggregate_ctr = 0;
- st.mean_aggregator[0] = st.mean_aggregator[1] = st.mean_aggregator[2] = 0;
- }
- */
-
- //if (st.detector.debounce_ctr == 0) {
- int old_bit = st.detector.bit;
- int new_bit = old_bit;
- //FIXME debug int diff = (int)b - (int)a;
- int diff = a-5500;
-
- /*
- if (debug_buf_pos < NCH || debug_buf_pos >= sizeof(adc_buf)/sizeof(adc_buf[0])) {
- debug_buf_pos = NCH;
- gdb_dump();
- }
- adc_buf[debug_buf_pos++] = diff;
- */
-
- if (diff < - st.detector.hysteresis_mv/2)
- new_bit = 0;
- else if (diff > st.detector.hysteresis_mv/2)
- new_bit = 1;
+ /* This has been copied from the code examples to section 12.9 ADC>"Temperature sensor and internal reference
+ * voltage" in the reference manual with the extension that we actually measure the supply voltage instead of
+ * hardcoding it. This is not strictly necessary since we're running off a bored little LDO but it's free and
+ * the current supply voltage is a nice health value.
+ */
+ // FIXME DEBUG adc_data.adc_vcc_mv = (3300 * VREFINT_CAL)/(st.adc_aggregate[VREF_CH]);
+
+ int64_t vcc = 3300;
+ /* FIXME debug
+ int64_t vcc = adc_data.adc_vcc_mv;
+ int64_t read = st.adc_aggregate[TEMP_CH] * 10 * 10000;
+ int64_t cal = TS_CAL1 * 10 * 10000;
+ adc_data.adc_temp_celsius_tenths = 300 + ((read/4096 * vcc) - (cal/4096 * 3300))/43000;
+ */
- /*
- if (debug_buf_pos < NCH || debug_buf_pos >= sizeof(adc_buf)/sizeof(adc_buf[0])) {
- debug_buf_pos = NCH;
- gdb_dump();
- }
- adc_buf[debug_buf_pos++] = new_bit;
- */
-
- if (new_bit != old_bit) {
- st.detector.bit = new_bit;
- //st.detector.debounce_ctr = st.detector.debounce_cycles;
- st.detector.len_ctr = 0;
- st.detector.committed_len_ctr = st.detector.base_interval_cycles>>1;
- }
- //} else {
- // st.detector.debounce_ctr--;
- //}
-
- /*
- if (debug_buf_pos < NCH || debug_buf_pos >= sizeof(adc_buf)/sizeof(adc_buf[0])) {
- debug_buf_pos = NCH;
- gdb_dump();
- }
- adc_buf[debug_buf_pos++] = st.detector.len_ctr;
- adc_buf[debug_buf_pos++] = st.detector.committed_len_ctr;
- adc_buf[debug_buf_pos++] = diff;
- int foo = 0;
- */
-
- if (st.detector.len_ctr >= st.detector.committed_len_ctr) {
- /*
- if (debug_buf_pos < NCH || debug_buf_pos >= sizeof(adc_buf)/sizeof(adc_buf[0])) {
- debug_buf_pos = NCH;
- gdb_dump();
- }
- adc_buf[debug_buf_pos++] = st.detector.bit;
- int foo = st.detector.symbol;
- if (foo < 0 && foo != K28_1)
- foo = 0;
- adc_buf[debug_buf_pos++] = foo;
- */
-
- if (st.detector.symbol != -DECODING_IN_PROGRESS) {
- static int trig = 0;
- if (st.detector.symbol == -K28_1) {
- if (trig == 10) {
- gdb_dump();
- for (int i=0; i<sizeof(adc_buf)/sizeof(adc_buf[0]); i++)
- adc_buf[i] = -255;
- trig = 0;
- } else if (trig == 1) {
- debug_buf_pos = NCH;
- }
- trig++;
- }
- if (debug_buf_pos >= sizeof(adc_buf)/sizeof(adc_buf[0])) {
- debug_buf_pos = 0;
- }
- if (debug_buf_pos >= NCH) {
- adc_buf[debug_buf_pos++] = st.detector.symbol;
- }
- }
- /*
- if (debug_buf_pos < NCH || debug_buf_pos >= sizeof(adc_buf)/sizeof(adc_buf[0])) {
- debug_buf_pos = NCH;
- gdb_dump();
- }
- adc_buf[debug_buf_pos++] = st.detector.bit;
- */
- //foo = st.detector.bit ? 1 : -1;
-
- st.detector.committed_len_ctr += st.detector.base_interval_cycles;
- st.detector.symbol = xfr_8b10b_feed_bit((struct state_8b10b_dec *)&st.detector.rx8b10b, st.detector.bit);
- /*
- if (st.detector.symbol != -DECODING_IN_PROGRESS) {
- if (debug_buf_pos < NCH || debug_buf_pos >= sizeof(adc_buf)/sizeof(adc_buf[0])) {
- debug_buf_pos = NCH;
- gdb_dump();
- }
- adc_buf[debug_buf_pos++] = st.detector.symbol;
- adc_buf[debug_buf_pos++] = st.detector.symbol == -DECODING_ERROR;
- adc_buf[debug_buf_pos++] = st.detector.symbol == -K28_1;
- adc_buf[debug_buf_pos++] = 0;
- }
- */
- }
+ const long vmeas_r_total = VMEAS_R_HIGH + VMEAS_R_LOW;
+ //int a = adc_data.adc_vmeas_a_mv = (st.adc_aggregate[VMEAS_A]*(vmeas_r_total * vcc / VMEAS_R_LOW)) >> 12;
+ int a = adc_data.adc_vmeas_a_mv = (adc_buf[VMEAS_A]*13300) >> 12;
+
+ int new_bit = st.detector.bit;
+ int diff = a-5500;
+ if (diff < - st.detector.hysteresis_mv/2)
+ new_bit = 0;
+ else if (diff > st.detector.hysteresis_mv/2)
+ new_bit = 1;
+
+ if (new_bit != st.detector.bit) {
+ st.detector.bit = new_bit;
+ st.detector.len_ctr = 0;
+ st.detector.committed_len_ctr = st.detector.base_interval_cycles>>1;
+
+ } else if (st.detector.len_ctr >= st.detector.committed_len_ctr) {
+ st.detector.committed_len_ctr += st.detector.base_interval_cycles;
+ receive_bit(st.detector.bit);
+ }
- //adc_buf[debug_buf_pos++] = foo;
- st.detector.len_ctr++;
+ st.detector.len_ctr++;
- st.ovs_count = 0;
- for (int i=0; i<NCH; i++)
- st.adc_aggregate[i] = 0;
- //}
+ /* ISR timing measurement for debugging */
int end = SysTick->VAL;
- /*
- if (debug_buf_pos < NCH || debug_buf_pos >= sizeof(adc_buf)/sizeof(adc_buf[0])) {
- debug_buf_pos = NCH;
- gdb_dump();
- }
int tdiff = start - end;
if (tdiff < 0)
tdiff += SysTick->LOAD;
- adc_buf[debug_buf_pos++] = tdiff;
- */
+ st.detector.dma_isr_duration = tdiff;
}