diff --git a/driver_fw/main.c b/driver_fw/main.c
index df2eaa7..324ca11 100644
--- a/driver_fw/main.c
+++ b/driver_fw/main.c
@@ -109,7 +109,7 @@ unsigned char random() {
txpos = -1;
i++;
- if (i == 2) {
+ if (i == 5) {
//txbuf[2] = random();
//txbuf[2] <<= 1;
//if (!txbuf[2] & 0xff)
diff --git a/fw/Makefile b/fw/Makefile
index cb2f244..3050fd1 100644
--- a/fw/Makefile
+++ b/fw/Makefile
@@ -76,7 +76,7 @@ sources.tar.xz.zip: sources.tar.xz
sources.c: sources.tar.xz.zip
xxd -i $< | head -n -1 | sed 's/=/__attribute__((section(".source_tarball"))) =/' > $@
-main.elf: main.o startup_stm32f030x6.o system_stm32f0xx.o $(HAL_PATH)/Src/stm32f0xx_ll_utils.o base.o cmsis_exports.o ../common/8b10b.o adc.o
+main.elf: main.o startup_stm32f030x6.o system_stm32f0xx.o $(HAL_PATH)/Src/stm32f0xx_ll_utils.o base.o cmsis_exports.o ../common/8b10b.o adc.o protocol.o
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS)
$(OBJCOPY) -O ihex $@ $(@:.elf=.hex)
$(OBJCOPY) -O binary $@ $(@:.elf=.bin)
diff --git a/fw/Scope.ipynb b/fw/Scope.ipynb
index 12d39ac..b7ac077 100644
--- a/fw/Scope.ipynb
+++ b/fw/Scope.ipynb
@@ -33,7 +33,7 @@
},
{
"cell_type": "code",
- "execution_count": 46,
+ "execution_count": 47,
"metadata": {
"scrolled": false
},
@@ -821,7 +821,7 @@
{
"data": {
"text/html": [
- "
"
+ "
"
],
"text/plain": [
""
diff --git a/fw/adc.c b/fw/adc.c
index ddc2640..5a1dea2 100644
--- a/fw/adc.c
+++ b/fw/adc.c
@@ -31,6 +31,7 @@ static void adc_dma_init(int burstlen, bool enable_interrupt);
static void adc_timer_init(int psc, int ivl);
+/* Mode that can be used for debugging */
void adc_configure_scope_mode(uint8_t channel_mask, int sampling_interval_ns) {
/* The constant SAMPLE_FAST (0) when passed in as sampling_interval_ns is handled specially in that we turn the ADC
to continuous mode to get the highest possible sampling rate. */
@@ -76,7 +77,8 @@ void adc_configure_scope_mode(uint8_t channel_mask, int sampling_interval_ns) {
adc_timer_init(12/*250ns/tick*/, cycles);
}
-void adc_configure_monitor_mode(int oversampling, int ivl_us, int mean_aggregate_len) {
+/* Regular operation receiver mode */
+void adc_configure_monitor_mode(struct command_if_def *cmd_if, int ivl_us) {
/* First, disable trigger timer, DMA and ADC in case we're reconfiguring on the fly. */
TIM1->CR1 &= ~TIM_CR1_CEN;
ADC1->CR &= ~ADC_CR_ADSTART;
@@ -85,25 +87,21 @@ 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;
for (int i=0; i= 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);
+void receive_bit(struct bit_detector_st *st, int bit) {
+ int symbol = xfr_8b10b_feed_bit((struct state_8b10b_dec *)&st->rx8b10b, bit);
if (symbol == -K28_1)
- st.detector.sync = 1;
+ st->sync = 1;
if (symbol == -DECODING_IN_PROGRESS)
return;
if (symbol == -DECODING_ERROR)
- st.detector.sync = 0;
+ st->sync = 0;
/* Fall through so we also pass the error to receive_symbol */
- receive_symbol(symbol);
+ receive_symbol(&st->rx_st, symbol);
/* Debug scope logic */
static int debug_buf_pos = 0;
- if (st.detector.sync && symbol != -DECODING_IN_PROGRESS) {
+ if (st->sync) {
if (debug_buf_pos < NCH) {
debug_buf_pos = NCH;
} else {
@@ -257,7 +194,7 @@ void receive_bit(int bit) {
if (debug_buf_pos >= sizeof(adc_buf)/sizeof(adc_buf[0])) {
debug_buf_pos = 0;
- st.detector.sync = 0;
+ st->sync = 0;
gdb_dump();
for (int i=0; ilast_bit;
+ int diff = a-5500;
+ if (diff < - st->hysteresis_mv/2)
+ new_bit = 0;
+ else if (diff > st->hysteresis_mv/2)
+ new_bit = 1;
+
+ st->len_ctr++;
+ if (new_bit != st->last_bit) {
+ st->last_bit = new_bit;
+ st->len_ctr = 0;
+ st->committed_len_ctr = st->base_interval_cycles>>1;
+
+ } else if (st->len_ctr >= st->committed_len_ctr) {
+ st->committed_len_ctr += st->base_interval_cycles;
+ receive_bit(&st->rx_st, st->last_bit);
+ }
+}
+
void DMA1_Channel1_IRQHandler(void) {
+ /* ISR timing measurement for debugging */
int start = SysTick->VAL;
/* Clear the interrupt flag */
@@ -293,31 +251,13 @@ void DMA1_Channel1_IRQHandler(void) {
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);
- }
-
- st.detector.len_ctr++;
+ bit_detector(&st.det_st, a);
/* ISR timing measurement for debugging */
int end = SysTick->VAL;
int tdiff = start - end;
if (tdiff < 0)
tdiff += SysTick->LOAD;
- st.detector.dma_isr_duration = tdiff;
+ st.dma_isr_duration = tdiff;
}
diff --git a/fw/adc.h b/fw/adc.h
index bf62156..1358f62 100644
--- a/fw/adc.h
+++ b/fw/adc.h
@@ -20,6 +20,7 @@
#include "global.h"
#include "8b10b.h"
+#include "protocol.h"
struct adc_measurements {
int16_t adc_vcc_mv;
@@ -56,44 +57,23 @@ 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 bit_detector_st {
+ int hysteresis_mv;
+ int sync;
+ int base_interval_cycles;
+ struct proto_rx_st rx_st;
+ /* private stuff */
+ int last_bit;
+ int len_ctr;
+ int committed_len_ctr;
+ struct state_8b10b_dec rx8b10b;
};
struct adc_state {
enum adc_mode adc_mode;
- int adc_oversampling;
- int mean_aggregate_len;
- struct {
- int hysteresis_mv;
- int debounce_cycles;
- int sync;
- int base_interval_cycles;
- /* private stuff */
- int bit;
- int len_ctr;
- 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;
-
+ int dma_isr_duration;
+ struct bit_detector_st det_st;
/* private stuff */
- int ovs_count; /* oversampling accumulator sample count */
uint32_t adc_aggregate[NCH]; /* oversampling accumulator */
uint32_t mean_aggregate_ctr;
uint32_t mean_aggregator[3];
@@ -105,9 +85,9 @@ extern volatile struct adc_measurements adc_data;
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 adc_configure_monitor_mode(struct command_if_def *cmd_if, int ivl_us);
-void set_outputs(uint8_t val[8]);
-void set_outputs_binary(int mask, int global_brightness);
+void bit_detector(struct bit_detector_st *st, int a);
+void receive_bit(struct bit_detector_st *st, int bit);
#endif/*__ADC_H__*/
diff --git a/fw/main.c b/fw/main.c
index cc07245..3eb08af 100644
--- a/fw/main.c
+++ b/fw/main.c
@@ -26,6 +26,24 @@ void TIM1_BRK_UP_TRG_COM_Handler() {
TIM1->SR &= ~TIM_SR_UIF_Msk;
}
+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
+};
+
+struct {
+ struct command_if_def cmd_if;
+ int payload_len[PKT_TYPE_MAX];
+} cmd_if = {{PKT_TYPE_MAX}, {
+ [PKT_TYPE_RESERVED] = 0,
+ [PKT_TYPE_SET_OUTPUTS_BINARY] = 1,
+ [PKT_TYPE_SET_GLOBAL_BRIGHTNESS] = 1,
+ [PKT_TYPE_SET_OUTPUTS] = 8 }
+};
+
uint8_t out_state = 0x01;
void set_outputs(uint8_t val[8]) {
/* TODO implement BCM for digital brightness control */
@@ -43,6 +61,23 @@ void set_outputs_binary(int mask, int global_brightness) {
set_outputs(val);
}
+void handle_command(int command, uint8_t *args) {
+ static int global_brightness = 0xff;
+ switch (command) {
+ case PKT_TYPE_SET_OUTPUTS_BINARY:
+ set_outputs_binary(args[0], global_brightness);
+ break;
+
+ case PKT_TYPE_SET_GLOBAL_BRIGHTNESS:
+ global_brightness = args[0];
+ break;
+
+ case PKT_TYPE_SET_OUTPUTS:
+ set_outputs(args);
+ break;
+ }
+}
+
int main(void) {
RCC->CR |= RCC_CR_HSEON;
while (!(RCC->CR&RCC_CR_HSERDY));
@@ -60,8 +95,8 @@ int main(void) {
RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
GPIOA->MODER |=
- (3<rxpos = 0;
+ /* Fall through and return and just ignore incomplete packets */
+
+ } else if (symbol == -DECODING_ERROR) {
+ st->rxpos = -1;
+
+ } else if (symbol < 0) { /* Unknown comma symbol or error */
+ st->rxpos = -1;
+
+ } else if (st->rxpos == -1) {
+ return;
+
+ } else if (st->rxpos == 0) { /* First data symbol, and not an error or comma symbol */
+ st->packet_type = symbol & ~PKT_TYPE_BULK_FLAG;
+ if (st->packet_type >= st->cmd_if->packet_type_max) {
+ st->rxpos = -1;
+ return;
+ }
+
+ st->is_bulk = symbol & PKT_TYPE_BULK_FLAG;
+ st->offset = (st->is_bulk) ? st->address*st->cmd_if->payload_len[st->packet_type]+1 : 2;
+ st->rxpos++;
+
+ } else if (!st->is_bulk && st->rxpos == 1) {
+ st->rxpos = (symbol == st->address) ? 2 : -1;
+
+ } else {
+ st->argbuf[st->rxpos - st->offset] = symbol;
+ st->rxpos++;
+
+ if (st->rxpos - st->offset == st->cmd_if->payload_len[st->packet_type]) {
+ handle_command(st->packet_type, (uint8_t *)st->argbuf);
+ st->rxpos = -1;
+ }
+ }
+}
+
diff --git a/fw/protocol.h b/fw/protocol.h
new file mode 100644
index 0000000..508cfdd
--- /dev/null
+++ b/fw/protocol.h
@@ -0,0 +1,28 @@
+#ifndef __PROTOCOL_H__
+#define __PROTOCOL_H__
+
+#include "global.h"
+
+#define PKT_TYPE_BULK_FLAG 0x80
+
+struct proto_rx_st {
+ int packet_type;
+ int is_bulk;
+ int rxpos;
+ int address;
+ uint8_t argbuf[8];
+ int offset;
+ struct command_if_def *cmd_if;
+};
+
+struct command_if_def {
+ int packet_type_max;
+ int payload_len[0];
+};
+
+/* Callback */
+void handle_command(int command, uint8_t *args);
+
+void receive_symbol(struct proto_rx_st *st, int symbol);
+
+#endif