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 
     25 void cdc_task(void);
     26 
     27 static void
     28 unassigned_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 
     44 int
     45 main(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 
     78 void
     79 tud_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 
     89 void
     90 tud_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 
    100 void
    101 tud_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 
    111 void
    112 tud_resume_cb(void)
    113 {
    114 	led_rgb = SOFT_PURPLE;
    115 	led_mode = LED_ON;
    116 	led_reset = true;
    117 }
    118 
    119 void
    120 tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts)
    121 {
    122 }
    123 
    124 void
    125 tud_cdc_rx_cb(uint8_t itf)
    126 {
    127 }
    128 
    129 uint16_t
    130 tud_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 
    136 void
    137 tud_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 
    142 void
    143 process_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 
    198 void
    199 cdc_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 }