From 6ee4233c2fd877bf14fe8ba53d841e227e226ddc Mon Sep 17 00:00:00 2001 From: true Date: Wed, 23 Oct 2024 04:19:13 -0700 Subject: [PATCH] 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. --- gat_stand_fw/user/main.c | 42 ++++++++++++++++++++-- gat_stand_fw/user/src/adc.c | 60 +++++++++----------------------- gat_stand_fw/user/src/adc.h | 18 +++++----- gat_stand_fw/user/src/btn.c | 10 +++--- gat_stand_fw/user/src/btn.h | 5 +++ gat_stand_fw/user/src/port_pwr.c | 12 +++---- gat_stand_fw/user/src/rgbled.c | 48 ++++++++++++++++++++----- 7 files changed, 121 insertions(+), 74 deletions(-) diff --git a/gat_stand_fw/user/main.c b/gat_stand_fw/user/main.c index 79b9f23..45f0ce0 100644 --- a/gat_stand_fw/user/main.c +++ b/gat_stand_fw/user/main.c @@ -23,12 +23,20 @@ void btn_top_push_cb(uint8_t idx) { - gat_toggle(); + // 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) { - usb2_toggle(); + // 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(); diff --git a/gat_stand_fw/user/src/adc.c b/gat_stand_fw/user/src/adc.c index da7b477..16cf873 100644 --- a/gat_stand_fw/user/src/adc.c +++ b/gat_stand_fw/user/src/adc.c @@ -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]; -} diff --git a/gat_stand_fw/user/src/adc.h b/gat_stand_fw/user/src/adc.h index ae554ac..3ae244f 100644 --- a/gat_stand_fw/user/src/adc.h +++ b/gat_stand_fw/user/src/adc.h @@ -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_ */ diff --git a/gat_stand_fw/user/src/btn.c b/gat_stand_fw/user/src/btn.c index 8525cce..3a4fed0 100644 --- a/gat_stand_fw/user/src/btn.c +++ b/gat_stand_fw/user/src/btn.c @@ -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; diff --git a/gat_stand_fw/user/src/btn.h b/gat_stand_fw/user/src/btn.h index 22ba6c6..1078158 100644 --- a/gat_stand_fw/user/src/btn.h +++ b/gat_stand_fw/user/src/btn.h @@ -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 diff --git a/gat_stand_fw/user/src/port_pwr.c b/gat_stand_fw/user/src/port_pwr.c index dc300aa..e34ad0e 100644 --- a/gat_stand_fw/user/src/port_pwr.c +++ b/gat_stand_fw/user/src/port_pwr.c @@ -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(); diff --git a/gat_stand_fw/user/src/rgbled.c b/gat_stand_fw/user/src/rgbled.c index 4cc6498..5ab8f5c 100644 --- a/gat_stand_fw/user/src/rgbled.c +++ b/gat_stand_fw/user/src/rgbled.c @@ -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 #include +#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; } } + */ - flash_timeout[GRN] = gat_pwr_state() ? 0 : 0xff; - flash_timeout[RED] = gat_oc_state() ? 16 : 0xff; + // 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] = 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; }