Basic command comm works

This commit is contained in:
jaseg 2019-01-11 22:02:14 +09:00
parent 528d653bde
commit c6547c6e6f
7 changed files with 221 additions and 222 deletions

View file

@ -9,7 +9,7 @@ OBJCOPY := arm-none-eabi-objcopy
OBJDUMP := arm-none-eabi-objdump
SIZE := arm-none-eabi-size
CFLAGS = -g -Wall -std=gnu11 -O1 -fdump-rtl-expand -Wno-discarded-qualifiers
CFLAGS = -g -Wall -std=gnu11 -O0 -fdump-rtl-expand -Wno-discarded-qualifiers
CFLAGS += -mlittle-endian -mcpu=cortex-m3 -mthumb
#CFLAGS += -ffunction-sections -fdata-sections
LDFLAGS = -nostartfiles

View file

@ -79,12 +79,24 @@ int main(void) {
NVIC_EnableIRQ(TIM1_UP_IRQn);
NVIC_SetPriority(TIM1_UP_IRQn, 3<<4);
uint8_t txbuf[128];
unsigned char x, a, b, c;
unsigned char random() {
x++; //x is incremented every round and is not affected by any other variable
a = (a ^ c ^ x); //note the mix of addition and XOR
b = (b + a); //And the use of very few instructions
c = ((c + (b >> 1) ^ a)); // the AES S-Box Operation ensures an even distributon of entropy
return (c);
}
uint8_t txbuf[3] = {0x01, 0x05, 0x01};
int txpos = -1;
/* FIXME test code */
for (int i=0; i<sizeof(txbuf)/sizeof(txbuf[0]); i++)
txbuf[i] = i;
//for (int i=0; i<sizeof(txbuf)/sizeof(txbuf[0]); i++)
// txbuf[i] = i;
/* FIXME end test code */
int i = 0;
while (42) {
if (txstate.next_symbol == -NO_SYMBOL) {
if (txpos == -1)
@ -93,8 +105,18 @@ int main(void) {
txstate.next_symbol = xfr_8b10b_encode(&txstate.st, txbuf[txpos]);
txpos++;
if (txpos >= sizeof(txbuf)/sizeof(txbuf[0]))
if (txpos >= sizeof(txbuf)/sizeof(txbuf[0])) {
txpos = -1;
i++;
if (i == 2) {
//txbuf[2] = random();
//txbuf[2] <<= 1;
//if (!txbuf[2] & 0xff)
// txbuf[2] = 0x01;
i = 0;
}
}
}
}
}

File diff suppressed because one or more lines are too long

298
fw/adc.c
View file

@ -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];
/* 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]);
//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;
*/
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;
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;
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;
/* 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;
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;
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;
/*
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;
}
*/
}
//adc_buf[debug_buf_pos++] = foo;
st.detector.len_ctr++;
st.ovs_count = 0;
for (int i=0; i<NCH; i++)
st.adc_aggregate[i] = 0;
//}
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();
} 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++;
/* ISR timing measurement for debugging */
int end = SysTick->VAL;
int tdiff = start - end;
if (tdiff < 0)
tdiff += SysTick->LOAD;
adc_buf[debug_buf_pos++] = tdiff;
*/
st.detector.dma_isr_duration = tdiff;
}

View file

@ -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__*/

View file

@ -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<<i;
out_state = x;
}
void set_outputs_binary(int mask, int global_brightness) {
uint8_t val[8];
for (int i=0; i<8; i++)
val[i] = (mask & (1<<i)) ? global_brightness : 0;
set_outputs(val);
}
int main(void) {
RCC->CR |= RCC_CR_HSEON;
while (!(RCC->CR&RCC_CR_HSERDY));
@ -62,64 +79,35 @@ int main(void) {
| (2<<GPIO_OSPEEDR_OSPEEDR6_Pos) /* CH2 */
| (2<<GPIO_OSPEEDR_OSPEEDR7_Pos); /* CH1 */
void set_outputs(uint8_t val) {
void set_drv_gpios(uint8_t val) {
int a=!!(val&1), b=!!(val&2), c=!!(val&4), d=!!(val&8);
GPIOA->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);
set_drv_gpios(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;
}
}
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; i<FOO; i++) ;
set_outputs(0x1);
for (int i=0; i<FOO; i++) ;
set_outputs(0x2);
for (int i=0; i<FOO; i++) ;
set_outputs(0x4);
for (int i=0; i<FOO; i++) ;
set_outputs(0x8);
*/
//for (int i=0; i<8*FOO; i++) ;
//GPIOA->ODR ^= 4;
}
}

View file

@ -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