diff options
Diffstat (limited to 'center_fw/src')
-rw-r--r-- | center_fw/src/main.c | 165 |
1 files changed, 47 insertions, 118 deletions
diff --git a/center_fw/src/main.c b/center_fw/src/main.c index 4df1db5..53b6aae 100644 --- a/center_fw/src/main.c +++ b/center_fw/src/main.c @@ -16,10 +16,10 @@ */ #include "global.h" +#include "8b10b.h" -uint16_t adc_data[192*2]; - -const int nominal_period = 125*16*32/2; +static uint16_t adc_data[64*2]; +static volatile struct state_8b10b_dec st_8b10b_dec; static void quicksort(uint16_t *head, uint16_t *tail); @@ -64,11 +64,13 @@ int main(void) { NVIC_SetPriority(TIM1_CC_IRQn, 0); */ + xfr_8b10b_reset((struct state_8b10b_dec *)&st_8b10b_dec); + TIM3->CR1 = TIM_CR1_ARPE; TIM3->CR2 = (2<<TIM_CR2_MMS_Pos); /* Update event on TRGO */ TIM3->PSC = 0; /* We sample 32 times per 1 kHz AC cycle, and use 32 times oversampling. */ - TIM3->ARR = 125*32; /* Output 64 MHz / 125 = 512 kHz signal */ + TIM3->ARR = 125*16; /* Output 64 MHz / 125 = 512 kHz signal */ TIM3->CR1 |= TIM_CR1_CEN; DMAMUX1[0].CCR = 5; /* ADC */ @@ -121,131 +123,58 @@ void TIM1_CC_IRQHandler(void) { TIM1->SR &= ~TIM_SR_CC1IF; } */ +static size_t received_symbols = 0; +static int symbol_buf[32]; +static size_t received_bits = 0; +static int16_t bit_buf[256]; +size_t adc_reduced_pos = 0; +static uint8_t adc_reduced[4096]; void DMA1_Channel1_IRQHandler(void) { - static int32_t bottom = -1; - static int32_t top = -1; + static int sampling_phase = 0; + static int last_sample = 0; + + uint16_t *buf = (DMA1->ISR & DMA_ISR_HTIF1) ? &adc_data[0] : &adc_data[COUNT_OF(adc_data)/2]; DMA1->IFCR = DMA_IFCR_CGIF1; - int phase_correction = 0; GPIOB->BSRR = (1<<7); - uint16_t *data = DMA1->ISR & DMA_ISR_HTIF1 ? &adc_data[0] : &adc_data[192]; - - if (bottom >= 0) { - uint32_t amplitude = top - bottom; - uint32_t middle = bottom + amplitude / 2; - - const uint32_t lower_thr = bottom + amplitude / 4; - const uint32_t upper_thr = top - amplitude / 4; - const uint32_t adc_clockdiv = 125 * 32; - - int num_edges = 0; - int edge_indices[24]; - - int state = 0; - ssize_t run_start = -1; - int last_v = -1; - for (ssize_t i=0; i<192-1; i++) { - uint32_t a = data[i], b = data[i+1]; - - if (state == 0) { - if (a < lower_thr && b > lower_thr) { - state = 1; - run_start = i+1; - } else if (a > upper_thr && b < upper_thr) { - state = -1; - run_start = i+1; - } - - } else if (state == 1) { - if (b < a) { - state = 0; - } else if (a < upper_thr && b > upper_thr) { - /* run from run_start (incl.) to i (incl.) */ - uint32_t v0 = data[run_start]; - int d = a - v0; - int c = i - run_start; - size_t intercept = run_start * adc_clockdiv + (middle - v0) * adc_clockdiv * c / d; - if (num_edges < COUNT_OF(edge_indices)) { - edge_indices[num_edges] = intercept; - num_edges++; - } - state = 0; - } - - } else if (state == -1) { - if (b > a) { - state = 0; - } else if (a > lower_thr && b < lower_thr) { - uint32_t v0 = data[run_start]; - int d = a - v0; - int c = i - run_start; - size_t intercept = run_start * adc_clockdiv + (middle - v0) * adc_clockdiv * c / d; - if (num_edges < COUNT_OF(edge_indices)) { - edge_indices[num_edges] = intercept; - num_edges++; - } - state = 0; - } - } + + const int threshold_adc_counts = 28500; + const int sample_per_baud = 16; + + for (size_t i=0; i<COUNT_OF(adc_data)/2; i++) { + int sample = buf[i]; + + adc_reduced[adc_reduced_pos] = (sample & 0xffff)>>9; + if (adc_reduced_pos == 0) { + asm volatile ("bkpt"); } - if (num_edges > 1) { - const int approx_cycle = 32*16*125/2; - int delta_avg = 0; - for (size_t i=0; i<num_edges-1; i++) { - int delta = edge_indices[i+1] - edge_indices[i]; - if (delta > approx_cycle/2 * 50) { - asm volatile ("bkpt"); - } - while (delta > approx_cycle/2) { - delta -= approx_cycle; - } - delta_avg += delta; - } - delta_avg /= num_edges-1; - - int cycle = approx_cycle + delta_avg; - int offset = 0; - int phase_avg = 0; - for (size_t i=0; i<num_edges; i++) { - int remainder = edge_indices[i] - offset; - while (remainder > cycle/2) { - remainder -= cycle; - offset += cycle; - } - phase_avg += remainder; - } - phase_avg /= num_edges; - phase_correction = phase_avg >= 0 ? cycle/2 - phase_avg : cycle/2 + phase_avg; - phase_correction /= 125 * 4; - - const int deadzone = 3; - const int max_correction = 40; - if (phase_correction < -deadzone || phase_correction > deadzone) { - if (phase_correction < -max_correction) { - phase_correction = -max_correction; - } else if (phase_correction > max_correction) { - phase_correction = max_correction; - } + if ((last_sample <= threshold_adc_counts && sample >= threshold_adc_counts) || + (last_sample >= threshold_adc_counts && sample <= threshold_adc_counts)){ + sampling_phase = sample_per_baud / 4; /* /2 for half baud sampling point, /2 for sinusoidal edge shape */ + + } else if (sampling_phase == 0) { + int bit = sample < threshold_adc_counts; + adc_reduced[adc_reduced_pos] |= 0x80; + + bit_buf[received_bits] = bit; + received_bits = (received_bits+1) % COUNT_OF(bit_buf); + + int rc = xfr_8b10b_feed_bit((struct state_8b10b_dec *)&st_8b10b_dec, bit); + if (rc > -K_CODES_LAST) { + symbol_buf[received_symbols] = rc; + received_symbols = (received_symbols+1) % COUNT_OF(symbol_buf); } - } - } + sampling_phase = sample_per_baud; - const int discard = 5; - const int keep = 32; + } else { + sampling_phase--; + } - bottom = 0; - top = 0; - quicksort(data, &data[192-1]); - for (size_t i=0; i<keep; i++) { - bottom += data[discard + i]; - top += data[COUNT_OF(data)/2 - 1 - discard - i]; + adc_reduced_pos = (adc_reduced_pos+1) % COUNT_OF(adc_reduced); + last_sample = sample; } - bottom /= keep; - top /= keep; - - TIM3->ARR = 125*32 + phase_correction; GPIOB->BRR = (1<<7); } |