Skip to content

Commit

Permalink
Unflickerify LEDs
Browse files Browse the repository at this point in the history
This includes a bunch of efforts to fix the issue where the same data
being output to the LEDs over and over, instead of keeping a steady
image, makes for a flickery mess.

1) Swap timer instances used to TIM1, previously TIM3.
   This could potentially be higher resolution by feeding it a PLL
   clock, but it seems to work as-is

2) Tinkering with how ADC is disabled prior to an LED transmission
   Of note is addition of a nop(), and also very much reducing just how
   much de-initialization was being done just to stop the ADC DMA.

3) Restructure how and what LED data is processed
   Previously, we updated the led_data array, which is used in DMA
   requests to clock the data out to GPIO pins, whenever a new segment
   of LED data arrived. It's quite possible we were writing to this
   array while it was also used by DMA at the same time, leading to more
   instability.

   It's now reworked to stick incoming data as-is into an array until we
   do led_send_buffer, at which time the lot of it is processed into
   led_data, and then clocked out with a DMA request. A flag also
   ensures we don't start any of this if it was already in progress.

There are also some optimizations done to the algorithm that populates
led_data, to make it faster. Especially important since we're now doing
it all at once at led_send_buffer time.
  • Loading branch information
michd committed Nov 15, 2020
1 parent 88852b6 commit afe72cc
Show file tree
Hide file tree
Showing 5 changed files with 274 additions and 115 deletions.
8 changes: 2 additions & 6 deletions Inc/led.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,8 @@

#include "stm32f3xx_hal.h"


void DMA1_Channel2_IRQHandler(void);

void led_send_buffer();
void led_init();
void led_prepare_input(uint8_t* led_buffer);
void transfer_complete_handler(DMA_HandleTypeDef *dma_handle);
void led_stage_buffer(uint8_t * led_buffer);
void led_send_buffer();

#endif
11 changes: 6 additions & 5 deletions Src/adc.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ void adc_init(){
init_adc_gpio();
init_adc_channels();
init_adc_dma();
HAL_ADC_Start_DMA(&hadc1, (uint32_t*)adc_read_buffer, NUM_SENSORS);
}

void adc_read_into(uint8_t * destination) {
Expand All @@ -39,13 +38,15 @@ void adc_read_into(uint8_t * destination) {
output_data.beingRead = false;
}

void adc_start(){
adc_init();
// Note: ADC is first started after finishing an LED commit.
// Such a commit is done on startup, so this will always start the ADC.
// However, starting it in adc_init() makes LED flickery.
void adc_start() {
HAL_ADC_Start_DMA(&hadc1, (uint32_t*)adc_read_buffer, NUM_SENSORS);
}

void adc_stop(){
HAL_DMA_Abort(&hdma_adc1);
HAL_ADC_DeInit(&hadc1);
HAL_ADC_Stop_DMA(&hadc1);
}

// "Private" functions
Expand Down
Loading

0 comments on commit afe72cc

Please sign in to comment.