add fixed auto brightness control option, led brightness options
jumper 1 will set LEDs to a dimmer level. jumper 2 will disable LEDs entirely. jumper 3 will turn the addon and USB ports on and off depending on ambient light level. the levels decided are arbitrary and may be updated with further testing.
This commit is contained in:
parent
5829bc190d
commit
6ee4233c2f
|
@ -23,12 +23,20 @@
|
|||
|
||||
void btn_top_push_cb(uint8_t idx)
|
||||
{
|
||||
// jumper 3, if set, will manage power by brightness automatically
|
||||
// only respect the button if this switch isn't set
|
||||
if (!(btn[DIP3]._mask & BTN_PUSH)) {
|
||||
gat_toggle();
|
||||
}
|
||||
}
|
||||
|
||||
void btn_bot_push_cb(uint8_t idx)
|
||||
{
|
||||
// jumper 3, if set, will manage power by brightness automatically
|
||||
// only respect the button if this switch isn't set
|
||||
if (!(btn[DIP3]._mask & BTN_PUSH)) {
|
||||
usb2_toggle();
|
||||
}
|
||||
}
|
||||
|
||||
static inline void systick_init(void)
|
||||
|
@ -76,6 +84,16 @@ static void gpio_init()
|
|||
gpio.GPIO_Pin = GAT_EN_PIN;
|
||||
GPIO_Init(GAT_EN_PORT, &gpio);
|
||||
|
||||
// lightsense anode (PA5)
|
||||
LSENS_A_PORT->BCR = LSENS_A_PIN;
|
||||
gpio.GPIO_Pin = LSENS_A_PIN;
|
||||
GPIO_Init(LSENS_A_PORT, &gpio);
|
||||
|
||||
// lightsense cathode (PB0)
|
||||
LSENS_K_PORT->BCR = LSENS_K_PIN;
|
||||
gpio.GPIO_Pin = LSENS_K_PIN;
|
||||
GPIO_Init(LSENS_K_PORT, &gpio);
|
||||
|
||||
// USB2 power enable (PB4)
|
||||
USB2_EN_PORT->BCR = USB2_EN_PIN;
|
||||
gpio.GPIO_Pin = USB2_EN_PIN;
|
||||
|
@ -86,6 +104,7 @@ static void gpio_init()
|
|||
gpio.GPIO_Pin = GAT_OC_PIN;
|
||||
GPIO_Init(GAT_EN_PORT, &gpio);
|
||||
|
||||
|
||||
// buttons (PB10, PB11) and DIP switches (PB12, PB13, PB14)
|
||||
gpio.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14;
|
||||
GPIO_Init(GPIOB, &gpio);
|
||||
|
@ -167,7 +186,24 @@ __attribute__((interrupt("WCH-Interrupt-fast")))
|
|||
void SysTick_Handler(void)
|
||||
{
|
||||
st_tick++;
|
||||
if (!st_tick) uptime++;
|
||||
if (!st_tick) {
|
||||
uptime++;
|
||||
|
||||
// jumper 3, if set, will manage power by brightness automatically
|
||||
if (btn[DIP3]._mask & BTN_PUSH) {
|
||||
if (adc_get_lsens_coarse() > LSENS_DARK) {
|
||||
gat_off();
|
||||
usb2_off();
|
||||
}
|
||||
if (adc_get_lsens_coarse() <= LSENS_BRIGHT) {
|
||||
gat_on();
|
||||
usb2_on();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// light sensor updating at ~4ms
|
||||
adc_process_lsens();
|
||||
|
||||
// update buttons
|
||||
btn_poll();
|
||||
|
|
|
@ -13,25 +13,9 @@
|
|||
|
||||
|
||||
|
||||
|
||||
static const uint8_t led_brightness_map[] = {
|
||||
47, 44, 42, 41,
|
||||
40, 38, 36, 34,
|
||||
32, 31, 30, 29,
|
||||
27, 25, 21, 19,
|
||||
17, 16, 15, 15, // indoors normal brightness
|
||||
14, 14, 13, 13,
|
||||
12, 12, 12, 11,
|
||||
11, 11, 10, 10,
|
||||
10, 9, 9, 9,
|
||||
8, 8, 8, 8,
|
||||
7, 7, 7, 7,
|
||||
7, 6, 6, 6
|
||||
};
|
||||
|
||||
static GPIO_InitTypeDef lsens_gpio = {
|
||||
.GPIO_Mode = GPIO_Mode_Out_PP,
|
||||
.GPIO_Pin = LSENS_A_PIN | LSENS_K_PIN,
|
||||
.GPIO_Pin = LSENS_A_PIN,
|
||||
.GPIO_Speed = GPIO_Speed_2MHz
|
||||
};
|
||||
|
||||
|
@ -42,6 +26,8 @@ static uint8_t lsens_mode = LSENS_READING_IDLE;
|
|||
uint8_t lsens_wait;
|
||||
uint8_t lsens_coarse = 1;
|
||||
|
||||
uint16_t lsens_timeout;
|
||||
|
||||
|
||||
|
||||
void adc_init()
|
||||
|
@ -82,9 +68,11 @@ void adc_set_mode_lsens(uint8_t mode)
|
|||
lsens_mode = mode;
|
||||
|
||||
if (mode == LSENS_OUTPUT) {
|
||||
lsens_gpio.GPIO_Pin = LSENS_A_PIN | LSENS_K_PIN;
|
||||
lsens_gpio.GPIO_Mode = GPIO_Mode_Out_PP;
|
||||
GPIO_Init(LSENS_PORT, &lsens_gpio);
|
||||
lsens_gpio.GPIO_Pin = LSENS_A_PIN;
|
||||
GPIO_Init(LSENS_A_PORT, &lsens_gpio);
|
||||
lsens_gpio.GPIO_Pin = LSENS_K_PIN;
|
||||
GPIO_Init(LSENS_K_PORT, &lsens_gpio);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -96,29 +84,32 @@ uint8_t adc_get_mode_lsens()
|
|||
static void lsens_start()
|
||||
{
|
||||
// set anode and cathode low
|
||||
LSENS_PORT->BCR = LSENS_A_PIN | LSENS_K_PIN;
|
||||
LSENS_A_PORT->BCR = LSENS_A_PIN;
|
||||
LSENS_K_PORT->BCR = LSENS_K_PIN;
|
||||
|
||||
adc_set_mode_lsens(LSENS_READING_START);
|
||||
|
||||
// set cathode high, let it charge
|
||||
LSENS_PORT->BSHR = LSENS_K_PIN;
|
||||
LSENS_K_PORT->BSHR = LSENS_K_PIN;
|
||||
|
||||
// set anode low
|
||||
lsens_gpio.GPIO_Pin = LSENS_A_PIN;
|
||||
lsens_gpio.GPIO_Mode = GPIO_Mode_IPD;
|
||||
GPIO_Init(LSENS_PORT, &lsens_gpio);
|
||||
GPIO_Init(LSENS_A_PORT, &lsens_gpio);
|
||||
|
||||
// set cathode as analog input
|
||||
lsens_gpio.GPIO_Pin = LSENS_K_PIN;
|
||||
lsens_gpio.GPIO_Mode = GPIO_Mode_AIN;
|
||||
GPIO_Init(LSENS_PORT, &lsens_gpio);
|
||||
GPIO_Init(LSENS_K_PORT, &lsens_gpio);
|
||||
}
|
||||
|
||||
static void lsens_stop()
|
||||
{
|
||||
lsens_gpio.GPIO_Pin = LSENS_A_PIN | LSENS_K_PIN;
|
||||
lsens_gpio.GPIO_Mode = GPIO_Mode_Out_PP;
|
||||
GPIO_Init(LSENS_PORT, &lsens_gpio);
|
||||
lsens_gpio.GPIO_Pin = LSENS_A_PIN;
|
||||
GPIO_Init(LSENS_A_PORT, &lsens_gpio);
|
||||
lsens_gpio.GPIO_Pin = LSENS_K_PIN;
|
||||
GPIO_Init(LSENS_K_PORT, &lsens_gpio);
|
||||
|
||||
lsens_mode = LSENS_READING_IDLE;
|
||||
}
|
||||
|
@ -190,22 +181,3 @@ uint8_t adc_get_lsens_coarse()
|
|||
{
|
||||
return lsens_coarse;
|
||||
}
|
||||
|
||||
uint8_t adc_get_brightness(uint8_t level)
|
||||
{
|
||||
if (!level) {
|
||||
// are you outside? why? it's too fucking hot
|
||||
// we'll shut down when in the presence of big nuclear fire
|
||||
if (adc_get_lsens() < 400) {
|
||||
// yup, outside or in a spotlight at 3ft away or something
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (level >= sizeof(led_brightness_map)) {
|
||||
return led_brightness_map[sizeof(led_brightness_map) - 1];
|
||||
|
||||
}
|
||||
|
||||
return led_brightness_map[level];
|
||||
}
|
||||
|
|
|
@ -12,13 +12,17 @@
|
|||
|
||||
#define LSENS_DARK_THRESHOLD 0x7ff // baseline minimum value reading achieved in darkness
|
||||
|
||||
#define LSENS_PORT GPIOA
|
||||
#define LSENS_A_PIN GPIO_Pin_2
|
||||
#define LSENS_K_PIN GPIO_Pin_3
|
||||
#define LSENS_ADC_CH ADC_Channel_3
|
||||
#define LSENS_A_PORT GPIOA
|
||||
#define LSENS_A_PIN GPIO_Pin_5
|
||||
#define LSENS_K_PORT GPIOB
|
||||
#define LSENS_K_PIN GPIO_Pin_0
|
||||
#define LSENS_ADC_CH ADC_Channel_8
|
||||
|
||||
#define LSENS_COARSE_UP 0x690 // counts higher than this increase lsens_coarse, maximum 64
|
||||
#define LSENS_COARSE_DOWN 0x5a0 // counts lower than this decrease lsens_coarse, minimum 1
|
||||
#define LSENS_COARSE_UP 0x990 // counts higher than this increase lsens_coarse, maximum 64
|
||||
#define LSENS_COARSE_DOWN 0x890 // counts lower than this decrease lsens_coarse, minimum 1
|
||||
|
||||
#define LSENS_DARK 48
|
||||
#define LSENS_BRIGHT 32
|
||||
|
||||
enum lsens_mode {
|
||||
LSENS_READING_IDLE = 0,
|
||||
|
@ -43,8 +47,6 @@ void adc_process_lsens();
|
|||
uint16_t adc_get_lsens();
|
||||
uint8_t adc_get_lsens_coarse();
|
||||
|
||||
uint8_t adc_get_brightness(uint8_t level);
|
||||
|
||||
|
||||
|
||||
#endif /* USER_SRC_ADC_H_ */
|
||||
|
|
|
@ -23,12 +23,12 @@ void btn_init()
|
|||
// this function assumes GPIO has been configured already
|
||||
|
||||
// initialize default setup
|
||||
btn[0]._pintype = BTN1_PIN;
|
||||
btn[1]._pintype = BTN2_PIN;
|
||||
btn[BTN1]._pintype = BTN1_PIN;
|
||||
btn[BTN2]._pintype = BTN2_PIN;
|
||||
|
||||
btn[2]._pintype = DIP1_PIN;
|
||||
btn[3]._pintype = DIP2_PIN;
|
||||
btn[4]._pintype = DIP3_PIN;
|
||||
btn[DIP1]._pintype = DIP1_PIN;
|
||||
btn[DIP2]._pintype = DIP2_PIN;
|
||||
btn[DIP3]._pintype = DIP3_PIN;
|
||||
|
||||
for (i = 0; i < BTN_COUNT; i++) {
|
||||
btn[i]._mask = BTN_RELEASE;
|
||||
|
|
|
@ -16,11 +16,16 @@
|
|||
|
||||
#define BTN_PORT GPIOB
|
||||
|
||||
#define BTN1 0
|
||||
#define BTN1_PIN 10
|
||||
#define BTN2 1
|
||||
#define BTN2_PIN 11
|
||||
|
||||
#define DIP1 2
|
||||
#define DIP1_PIN 12
|
||||
#define DIP2 3
|
||||
#define DIP2_PIN 13
|
||||
#define DIP3 4
|
||||
#define DIP3_PIN 14
|
||||
|
||||
#define BTN_PIN_MASK 0xf
|
||||
|
|
|
@ -26,7 +26,7 @@ static uint8_t gat_oc_state_latch = 0;
|
|||
|
||||
|
||||
|
||||
void port_pwr_commit_bkp()
|
||||
void port_pwr_state_commit_bkp()
|
||||
{
|
||||
BKP_WriteBackupRegister(PORT_PWR_STATE_DR, port_pwr_state);
|
||||
RTC_WaitForLastTask();
|
||||
|
@ -39,7 +39,7 @@ void gat_on()
|
|||
GAT_EN_PORT->BSHR = GAT_EN_PIN;
|
||||
|
||||
port_pwr_state |= GAT_ON_FLAG;
|
||||
port_pwr_commit_bkp();
|
||||
port_pwr_state_commit_bkp();
|
||||
}
|
||||
|
||||
void gat_off()
|
||||
|
@ -47,7 +47,7 @@ void gat_off()
|
|||
GAT_EN_PORT->BCR = GAT_EN_PIN;
|
||||
|
||||
port_pwr_state &= ~GAT_ON_FLAG;
|
||||
port_pwr_commit_bkp();
|
||||
port_pwr_state_commit_bkp();
|
||||
}
|
||||
|
||||
uint8_t gat_pwr_state()
|
||||
|
@ -77,7 +77,7 @@ void usb2_on()
|
|||
USB2_EN_PORT->BSHR = USB2_EN_PIN;
|
||||
|
||||
port_pwr_state |= USB2_ON_FLAG;
|
||||
port_pwr_commit_bkp();
|
||||
port_pwr_state_commit_bkp();
|
||||
}
|
||||
|
||||
void usb2_off()
|
||||
|
@ -85,7 +85,7 @@ void usb2_off()
|
|||
USB2_EN_PORT->BCR = USB2_EN_PIN;
|
||||
|
||||
port_pwr_state &= ~USB2_ON_FLAG;
|
||||
port_pwr_commit_bkp();
|
||||
port_pwr_state_commit_bkp();
|
||||
}
|
||||
|
||||
uint8_t usb2_pwr_state()
|
||||
|
@ -111,7 +111,7 @@ void port_pwr_init()
|
|||
port_pwr_state = INIT_FLAG | USB2_ON_FLAG | GAT_ON_FLAG;
|
||||
|
||||
// and commit state flags
|
||||
port_pwr_commit_bkp();
|
||||
port_pwr_state_commit_bkp();
|
||||
}
|
||||
|
||||
if (port_pwr_state & GAT_ON_FLAG) gat_on();
|
||||
|
|
|
@ -2,14 +2,21 @@
|
|||
* rgbled.c
|
||||
*
|
||||
* using TIM2 CH1-CH3
|
||||
*
|
||||
* * errata:
|
||||
* - board design makes overcurrent on GAT port practically impossible.
|
||||
* overcurrent condition may either trip low voltage condition due to
|
||||
* decoupling or voltage output limit on LDO. as such, displaying
|
||||
* any overcurrent state is meaningless.
|
||||
*/
|
||||
|
||||
#include <ch32v20x.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "btn.h"
|
||||
#include "port_pwr.h"
|
||||
#include "rtc.h"
|
||||
|
||||
#include "port_pwr.h"
|
||||
|
||||
|
||||
|
||||
|
@ -17,7 +24,7 @@
|
|||
#define GRN 1
|
||||
#define BLU 2
|
||||
|
||||
#define BRT_RED 80
|
||||
#define BRT_RED 40
|
||||
#define BRT_GRN 32
|
||||
#define BRT_BLU 36
|
||||
#define BRT_OFF 0
|
||||
|
@ -34,7 +41,8 @@ static uint8_t state[3] = {0};
|
|||
|
||||
void rgbled_set()
|
||||
{
|
||||
uint8_t i;
|
||||
int8_t i;
|
||||
uint16_t out[3];
|
||||
|
||||
// flash counters
|
||||
for (i = 0; i < 3; i++) {
|
||||
|
@ -64,14 +72,31 @@ void rgbled_set()
|
|||
}
|
||||
}
|
||||
|
||||
RGBLED_TIM->CH1CVR = state[BLU] ? BRT_BLU : BRT_OFF;
|
||||
RGBLED_TIM->CH2CVR = state[GRN] ? BRT_GRN : BRT_OFF;
|
||||
RGBLED_TIM->CH3CVR = state[RED] ? BRT_RED : BRT_OFF;
|
||||
out[BLU] = BRT_BLU;
|
||||
out[GRN] = BRT_GRN;
|
||||
out[RED] = BRT_RED;
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
// jumper 1 will reduce brightness
|
||||
if (btn[DIP1]._mask & BTN_PUSH) {
|
||||
out[i] >>= 2;
|
||||
}
|
||||
|
||||
// jumper 2 will turn off LEDs entirely
|
||||
if (btn[DIP2]._mask & BTN_PUSH) {
|
||||
out[i] = BRT_OFF;
|
||||
}
|
||||
}
|
||||
|
||||
RGBLED_TIM->CH1CVR = state[BLU] ? out[BLU] : BRT_OFF;
|
||||
RGBLED_TIM->CH2CVR = state[GRN] ? out[GRN] : BRT_OFF;
|
||||
RGBLED_TIM->CH3CVR = state[RED] ? out[RED] : BRT_OFF;
|
||||
}
|
||||
|
||||
void rgbled_update()
|
||||
{
|
||||
// VCR flash if clock isn't set
|
||||
/*
|
||||
switch (rtc_state) {
|
||||
case RTC_STATE_CLOCK_NOT_SET: {
|
||||
flash_timeout[BLU] = 48;
|
||||
|
@ -82,9 +107,14 @@ void rgbled_update()
|
|||
break;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// see errata on why we aren't showing overcurrent status anymore
|
||||
// flash_timeout[RED] = gat_oc_state() ? 16 : 0xff;
|
||||
|
||||
// power output state
|
||||
flash_timeout[GRN] = gat_pwr_state() ? 0 : 0xff;
|
||||
flash_timeout[RED] = gat_oc_state() ? 16 : 0xff;
|
||||
flash_timeout[RED] = usb2_pwr_state() ? 0 : 0xff;
|
||||
|
||||
rgbled_set();
|
||||
}
|
||||
|
@ -117,4 +147,6 @@ void rgbled_init()
|
|||
|
||||
RGBLED_TIM->CNT = 0;
|
||||
TIM_Cmd(RGBLED_TIM, ENABLE);
|
||||
|
||||
flash_timeout[BLU] = flash_timeout[GRN] = flash_timeout[RED] = 0xff;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue