LNSC-2420-Firmware/src/led_chplex.c

108 lines
2.3 KiB
C

#include <libopencm3/stm32/gpio.h>
#include "pinout.h"
#include "led_chplex.h"
#define NUM_LEDs 6
static uint8_t led_index;
static uint8_t led_mask;
void led_chplex_init(void)
{
// set up required GPIOs
gpio_clear(LED_PORT, LED_ALL_PINS);
gpio_mode_setup(LED_PORT, GPIO_MODE_INPUT, GPIO_PUPD_NONE, LED_ALL_PINS);
// initialize charlieplex stepping
led_index = 0;
// all LEDs off by default
led_mask = 0;
}
void led_chplex_periodic(void)
{
// set all GPIOs to input to ensure the LEDs are properly switched off
gpio_mode_setup(LED_PORT, GPIO_MODE_INPUT, GPIO_PUPD_NONE, LED_ALL_PINS);
// apply the proper signals depending on LED index
if(led_mask & (1 << led_index)) {
switch(led_index)
{
case LED_CHPLEX_IDX_SOLAR_ON:
gpio_set(LED_PORT, LED_A_PIN);
gpio_clear(LED_PORT, LED_B_PIN);
gpio_mode_setup(LED_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED_A_PIN | LED_B_PIN);
break;
case LED_CHPLEX_IDX_LOAD_ON:
gpio_set(LED_PORT, LED_B_PIN);
gpio_clear(LED_PORT, LED_C_PIN);
gpio_mode_setup(LED_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED_B_PIN | LED_C_PIN);
break;
case LED_CHPLEX_IDX_ERR_TEMP:
gpio_set(LED_PORT, LED_B_PIN);
gpio_clear(LED_PORT, LED_A_PIN);
gpio_mode_setup(LED_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED_A_PIN | LED_B_PIN);
break;
case LED_CHPLEX_IDX_ERR_LOAD:
gpio_set(LED_PORT, LED_C_PIN);
gpio_clear(LED_PORT, LED_B_PIN);
gpio_mode_setup(LED_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED_B_PIN | LED_C_PIN);
break;
case LED_CHPLEX_IDX_CHARGE_PULSE:
gpio_set(LED_PORT, LED_A_PIN);
gpio_clear(LED_PORT, LED_C_PIN);
gpio_mode_setup(LED_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED_A_PIN | LED_C_PIN);
break;
case LED_CHPLEX_IDX_DISCHARGE_PULSE:
gpio_set(LED_PORT, LED_C_PIN);
gpio_clear(LED_PORT, LED_A_PIN);
gpio_mode_setup(LED_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED_A_PIN | LED_C_PIN);
break;
default:
// unknown index => do nothing and reset index
led_index = 0;
break;
}
}
led_index++;
if(led_index >= NUM_LEDs) {
led_index = 0;
}
}
void led_chplex_on(uint8_t idx)
{
led_mask |= (1 << idx);
}
void led_chplex_off(uint8_t idx)
{
led_mask &= ~(1 << idx);
}
void led_chplex_toggle(uint8_t idx)
{
led_mask ^= (1 << idx);
}
void led_chplex_mask(uint8_t mask)
{
led_mask = mask;
}