sxkbd

Firmware for RP2040-based corne split keyboard
git clone https://git.sinitax.com/sinitax/sxkbd
Log | Files | Refs | Submodules | README | LICENSE | sfeed.txt

main.c (4133B)


      1#include "board.h"
      2#include "usb_stdio.h"
      3#include "keymat.h"
      4#include "keysym.h"
      5#include "split.h"
      6#include "led.h"
      7#include "hid.h"
      8#include "keymap.h"
      9#include "ws2812.h"
     10#include "util.h"
     11
     12#include "hardware/gpio.h"
     13#include "class/cdc/cdc_device.h"
     14#include "class/hid/hid.h"
     15#include "device/usbd.h"
     16#include "pico/stdlib.h"
     17#include "bsp/board.h"
     18#include "pico/time.h"
     19#include "tusb.h"
     20
     21#include <stdlib.h>
     22#include <stdio.h>
     23#include <string.h>
     24
     25void cdc_task(void);
     26
     27static void
     28unassigned_init(void)
     29{
     30#ifdef BAD_GPIO_MITIGATION
     31#pragma message("Enabled bad gpio mitigation to swap gpio pins 5 & 9")
     32	const uint unassigned[] = { 8, 5, 23, 21 };
     33#else
     34	const uint unassigned[] = { 8, 9, 23, 21 };
     35#endif
     36	uint i;
     37
     38	for (i = 0; i < ARRLEN(unassigned); i++) {
     39		gpio_init(unassigned[i]);
     40		gpio_set_dir(unassigned[i], GPIO_IN);
     41	}
     42}
     43
     44int
     45main(void)
     46{
     47	uint32_t start, stop;
     48
     49	board_init();
     50	tud_init(BOARD_TUD_RHPORT);
     51	usb_stdio_init();
     52	led_init();
     53	keymat_init();
     54	split_init();
     55	hid_init();
     56	unassigned_init();
     57
     58	led_start_blip(HARD_WHITE, 500);
     59
     60	start = board_millis();
     61	while (true) {
     62		tud_task();
     63		led_task();
     64		split_task();
     65		if (split_role == MASTER) {
     66			cdc_task();
     67			hid_task();
     68		}
     69
     70		stop = board_millis();
     71		DEBUG(LOG_TIMING, "Main loop: %i ms", stop - start);
     72		start = stop;
     73	}
     74
     75	return 0;
     76}
     77
     78void
     79tud_mount_cb(void)
     80{
     81#ifndef SPLIT_ROLE
     82	split_role = MASTER;
     83#endif
     84	led_rgb = SOFT_PURPLE;
     85	led_mode = LED_ON;
     86	led_reset = true;
     87}
     88
     89void
     90tud_umount_cb(void)
     91{
     92	led_blink_ms = 500;
     93	led_rgb = SOFT_WHITE;
     94	led_mode = LED_BLINK;
     95	led_reset = true;
     96
     97	led_start_blip(HARD_WHITE, 500);
     98}
     99
    100void
    101tud_suspend_cb(bool remote_wakeup_en)
    102{
    103#ifndef SPLIT_ROLE
    104	split_role = SLAVE;
    105#endif
    106	led_rgb = SOFT_WHITE;
    107	led_mode = LED_ON;
    108	led_reset = true;
    109}
    110
    111void
    112tud_resume_cb(void)
    113{
    114	led_rgb = SOFT_PURPLE;
    115	led_mode = LED_ON;
    116	led_reset = true;
    117}
    118
    119void
    120tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts)
    121{
    122}
    123
    124void
    125tud_cdc_rx_cb(uint8_t itf)
    126{
    127}
    128
    129uint16_t
    130tud_hid_get_report_cb(uint8_t itf, uint8_t report_id,
    131	hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen)
    132{
    133	return 0;
    134}
    135
    136void
    137tud_hid_set_report_cb(uint8_t itf, uint8_t report_id,
    138	hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize)
    139{
    140}
    141
    142void
    143process_cmd(char *cmd)
    144{
    145	char *arg, *tok;
    146
    147	tok = strchr(cmd, ' ');
    148	if (tok) {
    149		*tok = '\0';
    150		arg = tok + 1;
    151	} else {
    152		arg = cmd + strlen(cmd);
    153	}
    154
    155	if (!strcmp(cmd, "log-level")) {
    156		if (!strcmp(arg, "")) {
    157			printf("Levels: debug, info, warn, err\n");
    158		} else if (!strcmp(arg, "debug")) {
    159			log_level_min = LOG_DEBUG;
    160		} else if (!strcmp(arg, "info")) {
    161			log_level_min = LOG_INFO;
    162		} else if (!strcmp(arg, "warn")) {
    163			log_level_min = LOG_WARN;
    164		} else {
    165			printf("Invalid log level: %s\n", arg);
    166		}
    167	} else if (!strcmp(cmd, "log-groups")) {
    168		log_group_mask = 0;
    169		while (1) {
    170			tok = strchr(arg, ',');
    171			if (tok) *tok = '\0';
    172			if (!strcmp(arg, "all")) {
    173				log_group_mask |= LOG_ALL;
    174			} else if (!strcmp(arg, "keymat")) {
    175				log_group_mask |= LOG_KEYMAT;
    176			} else if (!strcmp(arg, "timing")) {
    177				log_group_mask |= LOG_TIMING;
    178			} else if (strspn(arg, "\t ") == strlen(arg)) {
    179				/* ignore */
    180			} else {
    181				printf("Invalid log facility: %s\n", arg);
    182			}
    183			if (!tok) break;
    184			arg = tok + 1;
    185		}
    186	} else if (!strcmp(cmd, "warn")) {
    187		if (*warnlog) {
    188			printf("Warning: %s\n", warnlog);
    189			*warnlog = '\0';
    190		} else {
    191			printf("No warnings logged\n");
    192		}
    193	} else {
    194		printf("Invalid command: %s\n", cmd);
    195	}
    196}
    197
    198void
    199cdc_task(void)
    200{
    201	static char cmdbuf[256];
    202	static int cmdlen = 0;
    203	char c;
    204
    205	do {
    206		if (cmdlen)
    207			tud_task();
    208
    209		if (tud_cdc_connected() && tud_cdc_available()
    210				&& tud_cdc_read(&c, 1)) {
    211			if (c == '\r' || c == '\n') {
    212				printf("\n");
    213				tud_cdc_write_flush();
    214				if (cmdlen) {
    215					cmdbuf[cmdlen] = 0;
    216					process_cmd(cmdbuf);
    217					cmdlen = 0;
    218				}
    219			} else if (c == 4) {
    220				printf("ALIVE!\n");
    221			} else if (cmdlen == ARRLEN(cmdbuf)) {
    222				printf("\n--- cmd too long ---\n");
    223				cmdlen = 0;
    224			} else {
    225				printf("%c", c);
    226				tud_cdc_write_flush();
    227				cmdbuf[cmdlen++] = c;
    228			}
    229		}
    230	} while (cmdlen);
    231}