xmas-snoopy/firmware/main/main.c

140 lines
2.6 KiB
C

/*
* main.c
*
* Copyright (C) 2022-2023 Sylvain Munaut <tnt@246tNt.com>
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <no2usb/usb.h>
#include <no2usb/usb_dfu_rt.h>
#include "led_ctrl.h"
#include "pmu.h"
#include "spi.h"
#include "utils.h"
#include "usb_dev.h"
/* ------------------------------------------------------------------------ */
/* USB */
/* ------------------------------------------------------------------------ */
extern const struct usb_stack_descriptors app_stack_desc;
static void
usb_serial_no_init(void)
{
uint8_t buf[8];
char *id, *desc;
int i;
/* Get flash ID */
flash_unique_id(buf);
/* Shutdown flash chip */
flash_deep_power_down();
/* Overwrite descriptor string */
/* In theory in rodata ... but nothing is ro here */
id = hexstr(buf, 8, false);
desc = (char*)app_stack_desc.str[1];
for (i=0; i<16; i++)
desc[2 + (i << 1)] = id[i];
}
static bool
usb_run(void)
{
/* Check current power state */
bool powered = pmu_is_vbus_present();
bool usb_running = pmu_usb_state();
/* Power USB on/off accordingly */
if (powered && !usb_running)
{
/* Re-enable USB clock */
pmu_usb_enable();
/* Stack init (got reset) */
usb_init(&app_stack_desc);
usb_dfu_rt_init();
usb_dev_init();
usb_connect();
/* We're up ! */
usb_running = true;
}
else if (!powered & usb_running)
{
/* Shutdown USB clock (and reset USB core) */
pmu_usb_disable();
/* USB not active, don't try to access it */
usb_running = false;
}
/* Run USB if need be */
if (usb_running)
usb_poll();
return usb_running;
}
void
usb_dfu_rt_cb_reboot(void)
{
/* Force re-enumeration */
usb_disconnect();
/* Boot firmware */
pmu_sys_reboot(1);
}
/* ------------------------------------------------------------------------ */
/* Main */
/* ------------------------------------------------------------------------ */
void main()
{
/* SPI */
spi_init();
usb_serial_no_init();
/* Clear events */
pmu_get_buttons();
/* Enable LEDs */
led_init();
led_start();
/* Main loop */
while (1)
{
/* Run USB */
bool usb_running = usb_run();
/* Check buttons */
uint8_t btn = pmu_get_buttons();
if (btn & BTN_1_SHORT) {
led_cycle_speed();
} else if (btn & BTN_1_LONG) {
led_cycle_dim();
}
if (btn & BTN_2_SHORT) {
led_cycle_anim();
} else if (btn & BTN_2_LONG) {
pmu_sys_shutdown();
}
/* LED */
led_poll(!usb_running);
}
}