Add power-down mode for LED driver

This commit is contained in:
fruchti 2020-07-16 23:48:48 +02:00
parent ee5a5b9f6c
commit 38d3a3846b
5 changed files with 62 additions and 1 deletions

View file

@ -1 +1 @@
375
389

View file

@ -3,6 +3,7 @@
LED_Colour_t LED_PixelData[LED_COUNT] = {{0}};
volatile bool LED_FrameFlag = false;
volatile bool LED_SuspendFlag = false;
#define LED_ODR_MASK ((1 << PIN_LED_R_0) | (1 << PIN_LED_G_0) \
| (1 << PIN_LED_B_0) | (1 << PIN_LED_R_1) \
@ -215,6 +216,7 @@ void LED_Init(void)
RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
// Fill both DMA buffers
LED_QueuePageFlip = false;
LED_Commit();
LED_PageFlip();
LED_Commit();
@ -244,6 +246,39 @@ void LED_Init(void)
LED_StartBCM(0);
}
void LED_Suspend(void)
{
LED_SuspendFlag = true;
while(LED_SuspendFlag);
// Disable timer and DMA channels
TIM3->CR1 = 0x0000;
TIM3->DIER = 0x0000;
TIM3->CNT = 0;
DMA1->IFCR = DMA_IFCR_CTCIF3;
DMA1_Channel3->CCR = 0x0000;
DMA1_Channel4->CCR = 0x0000;
NVIC_DisableIRQ(DMA1_Channel2_3_IRQn);
NVIC_ClearPendingIRQ(DMA1_Channel2_3_IRQn);
// Deactivate all rows and columns
GPIOA->BSRR = LED_ODR_MASK;
GPIOF->BSRR = (1 << PIN_ROW_DATA);
for(int i = 0; i < LED_ROWS + 1; i++)
{
LED_PulseRowClock();
}
// Disable timer and DMA clocks
RCC->AHBENR &= ~RCC_AHBENR_DMA1EN;
RCC->APB1ENR &= ~RCC_APB1ENR_TIM3EN;
}
void LED_WakeUp(void)
{
LED_Init();
}
void DMA1_Channel2_3_IRQHandler(void)
{
// Interrupt when all bits have been sent
@ -268,6 +303,12 @@ void DMA1_Channel2_3_IRQHandler(void)
LED_PulseRowClock();
}
if(LED_SuspendFlag)
{
LED_SuspendFlag = false;
return;
}
// Start sending bits out again. The row offset caused by the shift
// register "lagging" one clock cycle behind because RCK and SCK are
// connected to the same signal doesn't matter here: we're not paying much

View file

@ -27,6 +27,12 @@ extern volatile bool LED_FrameFlag;
void LED_InitShiftRegister(void);
void LED_Init(void);
// Enter power-saving mode (LEDs off)
void LED_Suspend(void);
// Leave power-saving mode
void LED_WakeUp(void);
// Display LED_PixelData, starting with the next frame
void LED_Commit(void);

View file

@ -5,6 +5,8 @@ int main(void)
LED_InitShiftRegister();
LightSensor_Init();
bool powered_down = false;
// Delay a bit to make programming easier
for(unsigned int i = 0; i < 1000; i++)
{
@ -18,6 +20,17 @@ int main(void)
__WFI();
LightSensor_Poll();
Animation_Poll();
if(LightSensor_RelativeBrightness == 0 && !powered_down)
{
LED_Suspend();
powered_down = true;
}
if(powered_down && LightSensor_RelativeBrightness > 0)
{
LED_WakeUp();
powered_down = false;
}
}
return 0;

View file

@ -1,6 +1,7 @@
#pragma once
#include <string.h>
#include <stdbool.h>
#include "stm32f030x6.h"
#include "buildid.h"