Thomas Kolb
df3211333e
This is most important for the LEDs and the RS485 interface. If any LED is on when deep sleep is entered, it will stay on the whole sleep time, drawing about 10 mA on the 3,3V rail. The RS485 transceiver must be switched to RX mode, as it consumes about 30 mA from the 5V rail in TX mode.
122 lines
2.6 KiB
C
122 lines
2.6 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;
|
|
}
|
|
|
|
|
|
|
|
void led_chplex_deepsleep_prepare(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);
|
|
}
|
|
|
|
|
|
void led_chplex_deepsleep_resume(void)
|
|
{
|
|
// nothing to do here
|
|
}
|