#include #include enum indicator_index { IND_TLR, // 0 IND_TLY, // 1 IND_TLG, // 2 IND_B1, // 3 IND_B2, // 4 IND_S3, // 5 IND_S1, // 6 IND_S2, // 7 IND_R2, // 8 IND_S4, // 9 IND_R1, // 10 }; enum andon_index { AND_G, AND_B, AND_Y, AND_R, }; uint32_t xorshift32() { /* https://en.wikipedia.org/wiki/Xorshift */ static uint32_t x = 1; x ^= x << 13; x ^= x >> 17; x ^= x << 5; return x; } void set_indicators(int val) { int tlr = !!(val & (1<<0)); int tly = !!(val & (1<<1)); int tlg = !!(val & (1<<2)); int b1 = !!(val & (1<<3)); int b2 = !!(val & (1<<4)); int r1 = !!(val & (1<<5)); int r2 = !!(val & (1<<6)); int s1 = !!(val & (1<<7)); int s2 = !!(val & (1<<8)); int s3 = !!(val & (1<<9)); int s4 = !!(val & (1<<10)); GPIOB->BRR = (1 << 12) | (1 << 13) | (1 << 14) | (1 << 15) | (1 << 0) | (1 << 1) | (1 << 10) | (1 << 11) | (1 << 5) | (1 << 6) | (1 << 7); GPIOB->BSRR = (tlr << 12) | (tly << 13) | (tlg << 14) | ( b1 << 15) | ( b2 << 0) | ( r1 << 1) | ( r2 << 10) | ( s1 << 11) | ( s2 << 5) | ( s3 << 6) | ( s4 << 7); } void set_andon(int val) { int a = !!(val & (1<<0)); int b = !!(val & (1<<1)); int c = !!(val & (1<<2)); int d = !!(val & (1<<3)); GPIOB->BRR = (1<<8) | (1<<9) | (1<<4) | (1<<3); GPIOB->BSRR = (a<<3) | (b<<4) | (c<<8) | (d<<9); } void buzz(int val) { GPIOA->BRR = 1; GPIOA->BSRR = !!val; } ssize_t uart_pos = 0; ssize_t uart_nb = 0; struct ch9329_packet { uint8_t header[2]; uint8_t addr; uint8_t cmd; uint8_t len; uint8_t data[9]; } uart_buf; uint8_t *uart_p = (uint8_t *)&uart_buf; void uart_tx(bool keyboard, bool press) { if (uart_nb > 0) { return; } memset(&uart_buf, 0, sizeof(uart_buf)); uart_buf.header[0] = 0x57; uart_buf.header[1] = 0xab; int dlen = sizeof(uart_buf); if (keyboard) { uart_buf.len = 8; uart_buf.cmd = 2; uart_buf.data[0] = 0; uart_buf.data[1] = 0; uart_buf.data[2] = press ? 0x28 : 0; /* Enter */ } else { uart_buf.len = 7; uart_buf.cmd = 4; dlen -= 1; uart_buf.data[0] = 2; uart_buf.data[1] = press ? 1 : 0; uart_buf.data[2] = 0; } int checksum = 0; for (size_t i=0; iIDR & (1<<6)); } int get_trig_button() { return !(GPIOA->IDR & (1<<7)); } int main(void) { RCC->CFGR = (0x7 << RCC_CFGR_PLLMULL_Pos); RCC->CR |= RCC_CR_PLLON; while (!(RCC->CR & RCC_CR_PLLRDY)) { /* Do nothing. */ } FLASH->ACR |= (1<CFGR |= (2<CFGR >> RCC_CFGR_SWS_Pos) & 0x3) != 2) { /* Do nothing. */ } /* Enable peripheral clocks */ RCC->APB2ENR |= RCC_APB2ENR_USART1EN | RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | RCC_APB2ENR_IOPCEN | RCC_APB2ENR_AFIOEN; /* Disable JTAG NJTRST pin to free up GPIOB4*/ AFIO->MAPR = (2<CRL = 0x88444443; /* 111111 * 54321098 */ GPIOA->CRH = 0x444444b4; GPIOA->BSRR = (1<<6) | (1<<7); /* Enable button pull-ups */ /* * 76543210 */ GPIOB->CRL = 0x33333433; /* 111111 * 54321098 */ GPIOB->CRH = 0x33333333; /* 111111 * 54321098 */ GPIOC->CRH = 0x44344444; USART1->CR1 = USART_CR1_UE | USART_CR1_TE; USART1->BRR = 0xea6; /* 9600 Bd, matches default baud rate of CH9329 */ SystemCoreClockUpdate(); set_indicators(0xffff); set_andon(0xf); buzz(1); for (int i=0; i<3000000; i++) { asm volatile ("nop"); } buzz(0); int n = 0; int tl = 0; int spin = 0; int andr = 0; int blk = 0; int uart_ct = 0; while (23) { if ((uart_nb > 0) && (USART1->SR & USART_SR_TXE)) { USART1->DR = uart_p[uart_pos]; uart_pos += 1; if (uart_pos == uart_nb) { uart_pos = 0; uart_nb = 0; } } if (uart_ct == 0) { uart_tx(get_config_button(), get_trig_button()); uart_ct = 1<<12; } else { uart_ct -= 1; } n++; if (n&(1<<16)) { tl = (tl+1)%3; spin = (spin+1)%4; int r = xorshift32(); int ind = 0; ind |= (tl == 0 ? (1< 12) ? (1< 16) ? (1<ODR ^= 1<<13; } } } void HardFault_Handler() { asm volatile ("bkpt"); } void delay_us(int duration_us) { while (duration_us--) { for (int i=0; i<3; i++) { asm volatile ("nop"); } } } void *memcpy(void *restrict dest, const void *restrict src, size_t n) { unsigned char *d = dest; const unsigned char *s = src; for (; n; n--) { *d++ = *s++; } return dest; } void *memmove(void *dest, const void *src, size_t n) { return memcpy(dest, src, n); } void *memset(void *dest, int c, size_t n) { unsigned char *d = dest; while (n--) { *d++ = c; } return dest; } size_t strlen(const char *s) { const char *start = s; while (*s) { s++; } return s - start; } void __libc_init_array (void) __attribute__((weak)); void __libc_init_array () { }