/*! \brief Initializes the ports used by LEDs \param void \return void */ void hal_init_ports_leds(void) { LED2_DIR = OUTPUT; LED3_DIR = OUTPUT; LED_TURN_OFF(LED2); LED_TURN_OFF(LED3); } // init_ports_leds //
static void pnx0106_leds_event (led_event_t ledevt) { if (ledevt == led_idle_end) LED_TURN_ON(GPIO_LED_ACTIVITY); else if (ledevt == led_idle_start) LED_TURN_OFF(GPIO_LED_ACTIVITY); else if (ledevt == led_timer) gpio_toggle_output (GPIO_LED_HEARTBEAT); }
usbFunctionSetup(uchar data[8]) { // {{{ usbRequest_t *rq = (void *)data; if ((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS) { // class request type if (rq->bRequest == USBRQ_HID_GET_REPORT){ // wValue: ReportType (highbyte), ReportID (lowbyte) // we only have one report type, so don't look at wValue // This seems to be called as one of the final initialization // steps of the device, after the ReportDescriptor has been sent. // Returns the initial state of the device. LED_TURN_OFF(GREEN_LED); #if ENABLE_KEYBOARD if (rq->wValue.bytes[0] == 1) { // Keyboard report // Not needed as I the struct already has sane values // build_report_from_char('\0'); usbMsgPtr = (void*) &keyboard_report; return sizeof(keyboard_report); } #endif #if ENABLE_MOUSE if (rq->wValue.bytes[0] == 2) { // Mouse report usbMsgPtr = (void*) &mouse_report; return sizeof(mouse_report); } #endif #if ENABLE_IDLE_RATE } else if (rq->bRequest == USBRQ_HID_GET_IDLE) { usbMsgPtr = &idle_rate; return 1; } else if (rq->bRequest == USBRQ_HID_SET_IDLE) { idle_rate = rq->wValue.bytes[1]; #endif } } else { /* no vendor specific requests implemented */ } return 0; } // }}}
main(void) { // {{{ uchar sensor_probe_counter = 0; uchar timer_overflow = 0; #if ENABLE_IDLE_RATE int idle_counter = 0; #endif cli(); hardware_init(); #if ENABLE_KEYBOARD init_keyboard_emulation(); init_ui_system(); #endif #if ENABLE_MOUSE init_mouse_emulation(); #endif TWI_Master_Initialise(); usbInit(); init_int_eeprom(); init_button_state(); wdt_reset(); sei(); // Sensor initialization must be done with interrupts enabled! // It uses I2C (TWI) to configure the sensor. sensor_init_configuration(); LED_TURN_ON(GREEN_LED); for (;;) { // main event loop wdt_reset(); usbPoll(); if (TIFR & (1<<TOV0)) { timer_overflow = 1; // Resetting the Timer0 // Setting this bit to one will clear it. TIFR = 1<<TOV0; } else { timer_overflow = 0; } update_button_state(timer_overflow); // Red LED lights up if there is any kind of error in I2C communication if ( TWI_statusReg.lastTransOK ) { LED_TURN_OFF(RED_LED); } else { LED_TURN_ON(RED_LED); } // Handling the state change of the main switch if (ON_KEY_UP(BUTTON_SWITCH)) { // Upon releasing the switch, stop the continuous reading. sensor_stop_continuous_reading(); #if ENABLE_KEYBOARD // And also reset the menu system. init_ui_system(); #endif } else if (ON_KEY_DOWN(BUTTON_SWITCH)) { // Upon pressing the switch, start the continuous reading for // mouse emulation code. sensor_start_continuous_reading(); } // Continuous reading of sensor data if (sensor.continuous_reading) { // {{{ // Timer is set to 1.365ms if (timer_overflow) { // The sensor is configured for 75Hz measurements. // I'm using this timer to read the values twice that rate. // 5 * 1.365ms = 6.827ms ~= 146Hz if (sensor_probe_counter > 0){ // Waiting... sensor_probe_counter--; } } if (sensor_probe_counter == 0) { // Time for reading new data! uchar return_code; return_code = sensor_read_data_registers(); if (return_code == SENSOR_FUNC_DONE || return_code == SENSOR_FUNC_ERROR) { // Restart the counter+timer sensor_probe_counter = 5; } } } // }}} #if ENABLE_IDLE_RATE // Timer is set to 1.365ms if (timer_overflow) { // {{{ // Implementing the idle rate... if (idle_rate != 0) { if (idle_counter > 0){ idle_counter--; } else { // idle_counter counts how many Timer0 overflows are // required before sending another report. // The exact formula is: // idle_counter = (idle_rate * 4)/1.365; // But it's better to avoid floating point math. // 4/1.365 = 2.93, so let's just multiply it by 3. idle_counter = idle_rate * 3; //keyDidChange = 1; LED_TOGGLE(YELLOW_LED); // TODO: Actually implement idle rate... Should re-send // the current status. } } } // }}} #endif // MAIN code. Code that emulates the mouse or implements the menu // system. if (button.state & BUTTON_SWITCH) { // Code for when the switch is held down // Should read data and do things #if ENABLE_MOUSE // nothing here #endif } else { // Code for when the switch is "off" // Basically, this is the menu system (implemented as keyboard) #if ENABLE_KEYBOARD ui_main_code(); #endif } // Sending USB Interrupt-in report if(usbInterruptIsReady()) { if (0) { // This useless "if" is here to make all the following // conditionals an "else if", and thus making it a lot // easier to add/remove them using preprocessor directives. } #if ENABLE_KEYBOARD else if(string_output_pointer != NULL){ // Automatically send keyboard report if there is something // in the buffer send_next_char(); usbSetInterrupt((void*) &keyboard_report, sizeof(keyboard_report)); } #endif #if ENABLE_MOUSE else if (button.state & BUTTON_SWITCH) { if (mouse_prepare_next_report()) { usbSetInterrupt((void*) &mouse_report, sizeof(mouse_report)); } } #endif } } } // }}}