Esempio n. 1
0
/*!
    \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 //
Esempio n. 2
0
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
		}
	}
}  // }}}