140 lines
2.6 KiB
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);
|
|
}
|
|
}
|