diff options
Diffstat (limited to 'fw/adc.c')
-rw-r--r-- | fw/adc.c | 302 |
1 files changed, 138 insertions, 164 deletions
@@ -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; } |