Add power-down mode for LED driver
This commit is contained in:
parent
ee5a5b9f6c
commit
38d3a3846b
|
@ -1 +1 @@
|
|||
375
|
||||
389
|
||||
|
|
41
src/led.c
41
src/led.c
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
13
src/main.c
13
src/main.c
|
@ -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;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "stm32f030x6.h"
|
||||
#include "buildid.h"
|
||||
|
|
Loading…
Reference in a new issue