From c6547c6e6fa381a7811d0c47603291d82be7e440 Mon Sep 17 00:00:00 2001 From: jaseg Date: Fri, 11 Jan 2019 22:02:14 +0900 Subject: Basic command comm works --- fw/Scope.ipynb | 19 ++-- fw/adc.c | 302 ++++++++++++++++++++++++++------------------------------- fw/adc.h | 24 ++++- fw/main.c | 70 ++++++------- fw/scope.gdb | 2 +- 5 files changed, 197 insertions(+), 220 deletions(-) (limited to 'fw') diff --git a/fw/Scope.ipynb b/fw/Scope.ipynb index 33596a0..12d39ac 100644 --- a/fw/Scope.ipynb +++ b/fw/Scope.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 208, + "execution_count": 5, "metadata": {}, "outputs": [], "source": [ @@ -14,7 +14,7 @@ }, { "cell_type": "code", - "execution_count": 207, + "execution_count": 11, "metadata": {}, "outputs": [], "source": [ @@ -33,7 +33,7 @@ }, { "cell_type": "code", - "execution_count": 213, + "execution_count": 46, "metadata": { "scrolled": false }, @@ -821,7 +821,7 @@ { "data": { "text/html": [ - "" + "" ], "text/plain": [ "" @@ -832,16 +832,9 @@ } ], "source": [ - "data = plot_data(offx=4, signed=True, channels=1)\n", + " data = plot_data(offx=4, signed=True, channels=1)\n", "#print(''.join(str(x) for x in data[4:][3::4]))" ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": { @@ -860,7 +853,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.6.6" + "version": "3.6.7" } }, "nbformat": 4, 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; iCR1 |= 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; iVAL; - 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>= 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])) { - 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; iVAL; - /* - 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; } diff --git a/fw/adc.h b/fw/adc.h index 1f6d868..bf62156 100644 --- a/fw/adc.h +++ b/fw/adc.h @@ -56,6 +56,15 @@ enum adc_channels { NCH }; +enum packet_type { + PKT_TYPE_RESERVED = 0, + PKT_TYPE_SET_OUTPUTS_BINARY = 1, + PKT_TYPE_SET_GLOBAL_BRIGHTNESS = 2, + PKT_TYPE_SET_OUTPUTS = 3, + PKT_TYPE_MAX, + PKT_TYPE_BULK_FLAG = 0x80 +}; + struct adc_state { enum adc_mode adc_mode; int adc_oversampling; @@ -63,7 +72,7 @@ struct adc_state { struct { int hysteresis_mv; int debounce_cycles; - int symbol; + int sync; int base_interval_cycles; /* private stuff */ int bit; @@ -71,7 +80,17 @@ struct adc_state { int committed_len_ctr; int debounce_ctr; struct state_8b10b_dec rx8b10b; + int dma_isr_duration; } detector; + struct { + int packet_type; + int is_bulk; + int rxpos; + int global_brightness; + int address; + uint8_t argbuf[8]; + int offset; + } receiver; /* private stuff */ int ovs_count; /* oversampling accumulator sample count */ @@ -88,4 +107,7 @@ void adc_init(void); void adc_configure_scope_mode(uint8_t channel_mask, int sampling_interval_ns); void adc_configure_monitor_mode(int oversampling, int ivl_us, int mean_aggregate_len); +void set_outputs(uint8_t val[8]); +void set_outputs_binary(int mask, int global_brightness); + #endif/*__ADC_H__*/ diff --git a/fw/main.c b/fw/main.c index 75a7350..cc07245 100644 --- a/fw/main.c +++ b/fw/main.c @@ -26,6 +26,23 @@ void TIM1_BRK_UP_TRG_COM_Handler() { TIM1->SR &= ~TIM_SR_UIF_Msk; } +uint8_t out_state = 0x01; +void set_outputs(uint8_t val[8]) { + /* TODO implement BCM for digital brightness control */ + int x = 0; + for (int i=0; i<8; i++) + if (val[i] > 127) + x |= 1<CR |= RCC_CR_HSEON; while (!(RCC->CR&RCC_CR_HSERDY)); @@ -62,64 +79,35 @@ int main(void) { | (2<ODR &= ~(!a<<3 | !b<<7 | c<<6 | d<<4); GPIOA->ODR |= a<<3 | b<<7 | !c<<6 | !d<<4; } - set_outputs(0); + set_drv_gpios(0); adc_configure_monitor_mode(0 /*no oversampling*/, 50 /*us*/, 10000/20 /*mean window size*/); /* FIXME DEBUG */ //adc_configure_scope_mode(MASK_VMEAS_A, 50000); - uint8_t out_state = 0x01; -#define DEBOUNCE 100 int debounce_ctr = 0; int val_last = 0; - int ctr = 0; -#define RESET 1000 int reset_ctr = 0; while (42) { -#define FOO 500000 if (reset_ctr) reset_ctr--; else - set_outputs(0); - - if (debounce_ctr) { - debounce_ctr--; - } else { - int val = !!(GPIOA->IDR & 1); - debounce_ctr = DEBOUNCE; - - if (val != val_last) { - if (val) - set_outputs(out_state & 0xf); - else - set_outputs(out_state >> 4); - reset_ctr = RESET; - val_last = val; - ctr++; - - if (ctr == 100) { - ctr = 0; - out_state = out_state<<1 | out_state>>7; - } - } + set_drv_gpios(0); + + int val = adc_state.detector.bit; + if (val != val_last) { + if (val) + set_drv_gpios(out_state & 0xf); + else + set_drv_gpios(out_state >> 4); + reset_ctr = 500; + val_last = val; } - /* - for (int i=0; iODR ^= 4; } } diff --git a/fw/scope.gdb b/fw/scope.gdb index 8e4bb99..bb685e7 100644 --- a/fw/scope.gdb +++ b/fw/scope.gdb @@ -3,7 +3,7 @@ set pagination off file main.elf load -break DMA1_Channel1_IRQHandler +break gdb_dump command 1 dump binary value /tmp/scope_dump.bin adc_buf continue -- cgit