uint8_t matrix_scan(void) { uint8_t mchanged; uint8_t row; uint8_t col; uint32_t scans[2]; //PA PB if (timer_read64() < mdebouncing) return 1; //mdebouncing == 0 when no debouncing active memset(mlatest, 0, MATRIX_ROWS * sizeof(matrix_row_t)); //Zero the result buffer for (col = 0; col < MATRIX_COLS; col++) { PORT->Group[col_ports[col]].OUTSET.reg = 1 << col_pins[col]; //Set col output wait_us(1); //Delay for output scans[PA] = PORT->Group[PA].IN.reg & row_masks[PA]; //Read PA row pins data scans[PB] = PORT->Group[PB].IN.reg & row_masks[PB]; //Read PB row pins data PORT->Group[col_ports[col]].OUTCLR.reg = 1 << col_pins[col]; //Clear col output for (row = 0; row < MATRIX_ROWS; row++) { //Move scan bits from scans array into proper row bit locations if (scans[row_ports[row]] & (1 << row_pins[row])) mlatest[row] |= 1 << col; } } mchanged = 0; //Default to no matrix change since last for (row = 0; row < MATRIX_ROWS; row++) { if (mlast[row] != mlatest[row]) mchanged = 1; mlast[row] = mlatest[row]; } if (!mchanged) { for (row = 0; row < MATRIX_ROWS; row++) mdebounced[row] = mlatest[row]; mdebouncing = 0; } else { //Begin or extend debounce on change mdebouncing = timer_read64() + DEBOUNCING_DELAY; } matrix_scan_quantum(); return 1; }
void main_subtask_usb_extra_device(void) { static uint64_t next_usb_checkup = 0; if (timer_read64() > next_usb_checkup) { next_usb_checkup = timer_read64() + 10; USB_HandleExtraDevice(); } }
void main_subtask_power_check(void) { static uint64_t next_5v_checkup = 0; if (timer_read64() > next_5v_checkup) { next_5v_checkup = timer_read64() + 5; v_5v = adc_get(ADC_5V); v_5v_avg = 0.9 * v_5v_avg + 0.1 * v_5v; #ifdef RGB_MATRIX_ENABLE gcr_compute(); #endif } }
void main_subtask_usb_state(void) { static uint64_t fsmstate_on_delay = 0; //Delay timer to be sure USB is actually operating before bringing up hardware uint8_t fsmstate_now = USB->DEVICE.FSMSTATUS.reg; //Current state from hardware register if (fsmstate_now == USB_FSMSTATUS_FSMSTATE_SUSPEND_Val) //If USB SUSPENDED { fsmstate_on_delay = 0; //Clear ON delay timer if (g_usb_state != USB_FSMSTATUS_FSMSTATE_SUSPEND_Val) //If previously not SUSPENDED { suspend_power_down(); //Run suspend routine g_usb_state = fsmstate_now; //Save current USB state } } else if (fsmstate_now == USB_FSMSTATUS_FSMSTATE_SLEEP_Val) //Else if USB SLEEPING { fsmstate_on_delay = 0; //Clear ON delay timer if (g_usb_state != USB_FSMSTATUS_FSMSTATE_SLEEP_Val) //If previously not SLEEPING { suspend_power_down(); //Run suspend routine g_usb_state = fsmstate_now; //Save current USB state } } else if (fsmstate_now == USB_FSMSTATUS_FSMSTATE_ON_Val) //Else if USB ON { if (g_usb_state != USB_FSMSTATUS_FSMSTATE_ON_Val) //If previously not ON { if (fsmstate_on_delay == 0) //If ON delay timer is cleared { fsmstate_on_delay = timer_read64() + 250; //Set ON delay timer } else if (timer_read64() > fsmstate_on_delay) //Else if ON delay timer is active and timed out { suspend_wakeup_init(); //Run wakeup routine g_usb_state = fsmstate_now; //Save current USB state } } } else //Else if USB is in a state not being tracked { fsmstate_on_delay = 0; //Clear ON delay timer } }
uint32_t timer_elapsed64(uint32_t tlast) { uint64_t tnow = timer_read64(); return (tnow >= tlast ? tnow - tlast : UINT64_MAX - tlast + tnow); }
int main(void) { DBG_LED_ENA; DBG_1_ENA; DBG_1_OFF; DBG_2_ENA; DBG_2_OFF; DBG_3_ENA; DBG_3_OFF; debug_code_init(); CLK_init(); ADC0_init(); SR_EXP_Init(); #ifdef RGB_MATRIX_ENABLE i2c1_init(); #endif // RGB_MATRIX_ENABLE matrix_init(); USB2422_init(); DBGC(DC_MAIN_UDC_START_BEGIN); udc_start(); DBGC(DC_MAIN_UDC_START_COMPLETE); DBGC(DC_MAIN_CDC_INIT_BEGIN); CDC_init(); DBGC(DC_MAIN_CDC_INIT_COMPLETE); while (USB2422_Port_Detect_Init() == 0) {} DBG_LED_OFF; #ifdef RGB_MATRIX_ENABLE while (I2C3733_Init_Control() != 1) {} while (I2C3733_Init_Drivers() != 1) {} I2C_DMAC_LED_Init(); i2c_led_q_init(); for (uint8_t drvid = 0; drvid < ISSI3733_DRIVER_COUNT; drvid++) I2C_LED_Q_ONOFF(drvid); //Queue data #endif // RGB_MATRIX_ENABLE keyboard_setup(); keyboard_init(); host_set_driver(&arm_atsam_driver); #ifdef CONSOLE_ENABLE uint64_t next_print = 0; #endif //CONSOLE_ENABLE v_5v_avg = adc_get(ADC_5V); debug_code_disable(); while (1) { main_subtasks(); //Note these tasks will also be run while waiting for USB keyboard polling intervals if (g_usb_state == USB_FSMSTATUS_FSMSTATE_SUSPEND_Val || g_usb_state == USB_FSMSTATUS_FSMSTATE_SLEEP_Val) { if (suspend_wakeup_condition()) { udc_remotewakeup(); //Send remote wakeup signal wait_ms(50); } continue; } keyboard_task(); #ifdef CONSOLE_ENABLE if (timer_read64() > next_print) { next_print = timer_read64() + 250; //Add any debug information here that you want to see very often //dprintf("5v=%u 5vu=%u dlow=%u dhi=%u gca=%u gcd=%u\r\n", v_5v, v_5v_avg, v_5v_avg - V5_LOW, v_5v_avg - V5_HIGH, gcr_actual, gcr_desired); } #endif //CONSOLE_ENABLE } return 1; }