/** Task to read in and processes the next report from the attached device, displaying the report * contents on the board LEDs and via the serial port. */ void KeyboardHost_Task(void) { if (USB_HostState != HOST_STATE_Configured) return; /* Select keyboard data pipe */ Pipe_SelectPipe(KEYBOARD_DATA_IN_PIPE); /* Unfreeze keyboard data pipe */ Pipe_Unfreeze(); /* Check to see if a packet has been received */ if (!(Pipe_IsINReceived())) { /* Refreeze HID data IN pipe */ Pipe_Freeze(); return; } /* Ensure pipe contains data before trying to read from it */ if (Pipe_IsReadWriteAllowed()) { USB_KeyboardReport_Data_t KeyboardReport; /* Read in keyboard report data */ Pipe_Read_Stream_LE(&KeyboardReport, sizeof(KeyboardReport), NULL); /* Indicate if the modifier byte is non-zero (special key such as shift is being pressed) */ LEDs_ChangeLEDs(LEDS_LED1, (KeyboardReport.Modifier) ? LEDS_LED1 : 0); uint8_t KeyCode = KeyboardReport.KeyCode[0]; /* Check if a key has been pressed */ if (KeyCode) { /* Toggle status LED to indicate keypress */ LEDs_ToggleLEDs(LEDS_LED2); char PressedKey = 0; /* Retrieve pressed key character if alphanumeric */ if ((KeyCode >= HID_KEYBOARD_SC_A) && (KeyCode <= HID_KEYBOARD_SC_Z)) { PressedKey = (KeyCode - HID_KEYBOARD_SC_A) + 'A'; } else if ((KeyCode >= HID_KEYBOARD_SC_1_AND_EXCLAMATION) & (KeyCode < HID_KEYBOARD_SC_0_AND_CLOSING_PARENTHESIS)) { PressedKey = (KeyCode - HID_KEYBOARD_SC_1_AND_EXCLAMATION) + '1'; } else if (KeyCode == HID_KEYBOARD_SC_0_AND_CLOSING_PARENTHESIS) { PressedKey = '0'; } else if (KeyCode == HID_KEYBOARD_SC_SPACE) { PressedKey = ' '; } else if (KeyCode == HID_KEYBOARD_SC_ENTER) { PressedKey = '\n'; } /* Print the pressed key character out through the serial port if valid */ if (PressedKey) putchar(PressedKey); } } /* Clear the IN endpoint, ready for next data packet */ Pipe_ClearIN(); /* Refreeze keyboard data pipe */ Pipe_Freeze(); }
/** Task to manage an enumerated USB keyboard once connected, to display key state * data as it is received. */ void KeyboardHost_Task(void) { if (USB_HostState != HOST_STATE_Configured) return; if (HID_Host_IsReportReceived(&Keyboard_HID_Interface)) { uint8_t KeyboardReport[Keyboard_HID_Interface.State.LargestReportSize]; HID_Host_ReceiveReport(&Keyboard_HID_Interface, &KeyboardReport); for (uint8_t ReportNumber = 0; ReportNumber < HIDReportInfo.TotalReportItems; ReportNumber++) { HID_ReportItem_t* ReportItem = &HIDReportInfo.ReportItems[ReportNumber]; /* Update the report item value if it is contained within the current report */ if (!(USB_GetHIDReportItemInfo(KeyboardReport, ReportItem))) continue; /* Determine what report item is being tested, process updated value as needed */ if ((ReportItem->Attributes.Usage.Page == USAGE_PAGE_KEYBOARD) && (ReportItem->Attributes.BitSize == 8) && (ReportItem->Attributes.Logical.Maximum > 1) && (ReportItem->ItemType == HID_REPORT_ITEM_In)) { /* Key code is an unsigned char in length, cast to the appropriate type */ uint8_t KeyCode = (uint8_t)ReportItem->Value; /* If scan-code is non-zero, a key is being pressed */ if (KeyCode) { /* Toggle status LED to indicate keypress */ LEDs_ToggleLEDs(LEDS_LED2); char PressedKey = 0; /* Convert scan-code to printable character if alphanumeric */ if ((KeyCode >= HID_KEYBOARD_SC_A) && (KeyCode <= HID_KEYBOARD_SC_Z)) { PressedKey = (KeyCode - HID_KEYBOARD_SC_A) + 'A'; } else if ((KeyCode >= HID_KEYBOARD_SC_1_AND_EXCLAMATION) & (KeyCode < HID_KEYBOARD_SC_0_AND_CLOSING_PARENTHESIS)) { PressedKey = (KeyCode - HID_KEYBOARD_SC_1_AND_EXCLAMATION) + '1'; } else if (KeyCode == HID_KEYBOARD_SC_0_AND_CLOSING_PARENTHESIS) { PressedKey = '0'; } else if (KeyCode == HID_KEYBOARD_SC_SPACE) { PressedKey = ' '; } else if (KeyCode == HID_KEYBOARD_SC_ENTER) { PressedKey = '\n'; } /* Print the pressed key character out through the serial port if valid */ if (PressedKey) putchar(PressedKey); } /* Once a scan-code is found, stop scanning through the report items */ break; } } } }
/** ISR to periodically toggle the LEDs on the board to indicate that the bootloader is active. */ ISR(TIMER1_OVF_vect, ISR_BLOCK) { LEDs_ToggleLEDs(LEDS_LED1 | LEDS_LED2); }
/** Main program entry point. This routine contains the overall program flow, including initial * setup of all components and the main program loop. */ int main(void) { SetupHardware(); RingBuffer_InitBuffer(&USARTtoUSB_Buffer, USARTtoUSB_Buffer_Data, sizeof(USARTtoUSB_Buffer_Data)); sei(); for (;;) { /* Echo bytes from the host to the target via the hardware USART */ if ((UCSR1A & (1 << UDRE1)) && CDC_Device_BytesReceived(&VirtualSerial_CDC_Interface)) { UDR1 = CDC_Device_ReceiveByte(&VirtualSerial_CDC_Interface); LEDs_TurnOnLEDs(LEDMASK_TX); PulseMSRemaining.TxLEDPulse = TX_RX_LED_PULSE_MS; } /* Check if the millisecond timer has elapsed */ if (TIFR0 & (1 << OCF0A)) { /* Clear flush timer expiry flag */ TIFR0 |= (1 << TOV0); /* Check if the reset pulse period has elapsed, if so tristate the target reset line */ if (PulseMSRemaining.ResetPulse && !(--PulseMSRemaining.ResetPulse)) { LEDs_TurnOffLEDs(LEDMASK_BUSY); AVR_RESET_LINE_DDR &= ~AVR_RESET_LINE_MASK; } /* Check if the LEDs should be ping-ponging (during enumeration) */ if (PulseMSRemaining.PingPongLEDPulse && !(--PulseMSRemaining.PingPongLEDPulse)) { LEDs_ToggleLEDs(LEDMASK_TX | LEDMASK_RX); PulseMSRemaining.PingPongLEDPulse = PING_PONG_LED_PULSE_MS; } /* Turn off TX LED(s) once the TX pulse period has elapsed */ if (PulseMSRemaining.TxLEDPulse && !(--PulseMSRemaining.TxLEDPulse)) LEDs_TurnOffLEDs(LEDMASK_TX); /* Turn off RX LED(s) once the RX pulse period has elapsed */ if (PulseMSRemaining.RxLEDPulse && !(--PulseMSRemaining.RxLEDPulse)) LEDs_TurnOffLEDs(LEDMASK_RX); /* Check if the receive buffer flush period has expired */ uint16_t BufferCount = RingBuffer_GetCount(&USARTtoUSB_Buffer); if (!(--FlushPeriodRemaining) || (BufferCount > 200)) { FlushPeriodRemaining = RECEIVE_BUFFER_FLUSH_MS; /* Start RX LED indicator pulse */ if (BufferCount) { LEDs_TurnOnLEDs(LEDMASK_RX); PulseMSRemaining.RxLEDPulse = TX_RX_LED_PULSE_MS; } /* Echo bytes from the target to the host via the virtual serial port */ while (BufferCount--) { /* Try to send the next byte of data to the host, abort if there is an error without dequeuing */ if (CDC_Device_SendByte(&VirtualSerial_CDC_Interface, RingBuffer_Peek(&USARTtoUSB_Buffer)) != ENDPOINT_READYWAIT_NoError) { break; } /* Dequeue the already sent byte from the buffer now we have confirmed that no transmission error occurred */ RingBuffer_Remove(&USARTtoUSB_Buffer); } } } CDC_Device_USBTask(&VirtualSerial_CDC_Interface); USB_USBTask(); } }
/** Main program entry point. This routine configures the hardware required by the application, then * enters a loop to run the application tasks in sequence. */ int main(void) { SetupHardware(); puts_P(PSTR(ESC_FG_CYAN "Keyboard Host Demo running.\r\n" ESC_FG_WHITE)); LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY); sei(); for (;;) { switch (USB_HostState) { case HOST_STATE_Addressed: LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING); uint16_t ConfigDescriptorSize; uint8_t ConfigDescriptorData[512]; if (USB_Host_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData, sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful) { puts_P(PSTR("Error Retrieving Configuration Descriptor.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } if (HID_Host_ConfigurePipes(&Keyboard_HID_Interface, ConfigDescriptorSize, ConfigDescriptorData) != HID_ENUMERROR_NoError) { puts_P(PSTR("Attached Device Not a Valid Keyboard.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful) { puts_P(PSTR("Error Setting Device Configuration.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } if (HID_Host_SetBootProtocol(&Keyboard_HID_Interface) != 0) { puts_P(PSTR("Could not Set Boot Protocol Mode.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } puts_P(PSTR("Keyboard Enumerated.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_READY); USB_HostState = HOST_STATE_Configured; break; case HOST_STATE_Configured: if (HID_Host_IsReportReceived(&Keyboard_HID_Interface)) { USB_KeyboardReport_Data_t KeyboardReport; HID_Host_ReceiveReport(&Keyboard_HID_Interface, &KeyboardReport); LEDs_ChangeLEDs(LEDS_LED1, (KeyboardReport.Modifier) ? LEDS_LED1 : 0); uint8_t KeyCode = KeyboardReport.KeyCode[0]; if (KeyCode) { char PressedKey = 0; LEDs_ToggleLEDs(LEDS_LED2); /* Retrieve pressed key character if alphanumeric */ if ((KeyCode >= HID_KEYBOARD_SC_A) && (KeyCode <= HID_KEYBOARD_SC_Z)) { PressedKey = (KeyCode - HID_KEYBOARD_SC_A) + 'A'; } else if ((KeyCode >= HID_KEYBOARD_SC_1_AND_EXCLAMATION) & (KeyCode < HID_KEYBOARD_SC_0_AND_CLOSING_PARENTHESIS)) { PressedKey = (KeyCode - HID_KEYBOARD_SC_1_AND_EXCLAMATION) + '1'; } else if (KeyCode == HID_KEYBOARD_SC_0_AND_CLOSING_PARENTHESIS) { PressedKey = '0'; } else if (KeyCode == HID_KEYBOARD_SC_SPACE) { PressedKey = ' '; } else if (KeyCode == HID_KEYBOARD_SC_ENTER) { PressedKey = '\n'; } if (PressedKey) putchar(PressedKey); } } break; } HID_Host_USBTask(&Keyboard_HID_Interface); USB_USBTask(); } }
/** Main program entry point. This routine configures the hardware required by the application, then * enters a loop to run the application tasks in sequence. */ int main(void) { SetupHardware(); puts_P(PSTR(ESC_FG_CYAN "Keyboard Host Demo running.\r\n" ESC_FG_WHITE)); LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY); sei(); for (;;) { switch (USB_HostState) { case HOST_STATE_Addressed: LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING); uint16_t ConfigDescriptorSize; uint8_t ConfigDescriptorData[512]; if (USB_Host_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData, sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful) { puts_P(PSTR("Error Retrieving Configuration Descriptor.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } if (HID_Host_ConfigurePipes(&Keyboard_HID_Interface, ConfigDescriptorSize, ConfigDescriptorData) != HID_ENUMERROR_NoError) { puts_P(PSTR("Attached Device Not a Valid Keyboard.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful) { puts_P(PSTR("Error Setting Device Configuration.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } if (HID_Host_SetReportProtocol(&Keyboard_HID_Interface) != 0) { puts_P(PSTR("Error Setting Report Protocol Mode or Not a Valid Keyboard.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } puts_P(PSTR("Keyboard Enumerated.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_READY); USB_HostState = HOST_STATE_Configured; break; case HOST_STATE_Configured: if (HID_Host_IsReportReceived(&Keyboard_HID_Interface)) { uint8_t KeyboardReport[Keyboard_HID_Interface.State.LargestReportSize]; HID_Host_ReceiveReport(&Keyboard_HID_Interface, &KeyboardReport); for (uint8_t ReportNumber = 0; ReportNumber < HIDReportInfo.TotalReportItems; ReportNumber++) { HID_ReportItem_t* ReportItem = &HIDReportInfo.ReportItems[ReportNumber]; /* Update the report item value if it is contained within the current report */ if (!(USB_GetHIDReportItemInfo(KeyboardReport, ReportItem))) continue; /* Determine what report item is being tested, process updated value as needed */ if ((ReportItem->Attributes.Usage.Page == USAGE_PAGE_KEYBOARD) && (ReportItem->Attributes.BitSize == 8) && (ReportItem->Attributes.Logical.Maximum > 1) && (ReportItem->ItemType == REPORT_ITEM_TYPE_In)) { /* Key code is an unsigned char in length, cast to the appropriate type */ uint8_t KeyCode = (uint8_t)ReportItem->Value; /* If scan-code is non-zero, a key is being pressed */ if (KeyCode) { /* Toggle status LED to indicate keypress */ LEDs_ToggleLEDs(LEDS_LED2); char PressedKey = 0; /* Convert scan-code to printable character if alphanumeric */ if ((KeyCode >= 0x04) && (KeyCode <= 0x1D)) PressedKey = (KeyCode - 0x04) + 'A'; else if ((KeyCode >= 0x1E) && (KeyCode <= 0x27)) PressedKey = (KeyCode - 0x1E) + '0'; else if (KeyCode == 0x2C) PressedKey = ' '; else if (KeyCode == 0x28) PressedKey = '\n'; /* Print the pressed key character out through the serial port if valid */ if (PressedKey) putchar(PressedKey); } /* Once a scan-code is found, stop scanning through the report items */ break; } } } break; } HID_Host_USBTask(&Keyboard_HID_Interface); USB_USBTask(); } }
//------------------------------------------------------------------------------ static uint8_t serialProcess(Application *app) { uint16_t count = RingBuffer_GetCount(&app->buffer_); if(count == 0) return true; uint8_t cmd = RingBuffer_Peek(&app->buffer_); switch(cmd) { case 'L': RingBuffer_Remove(&app->buffer_); LEDs_ToggleLEDs(LEDS_LED1); break; case 'R': RingBuffer_Remove(&app->buffer_); asicReset(); asicResetSpi(); app->state.state = STATE_RESET; sendCmdReply(app, cmd, (uint8_t *)&app->state, sizeof(State)); break; case 'I': RingBuffer_Remove(&app->buffer_); sendCmdReply(app, cmd, (uint8_t *)&ID, sizeof(ID)); break; case 'A': RingBuffer_Remove(&app->buffer_); app->state.state = STATE_RESET; asicStop(); sendCmdReply(app, cmd, (uint8_t *)&app->state, sizeof(State)); break; case 'S': RingBuffer_Remove(&app->buffer_); sendCmdReply(app, cmd, (uint8_t *)&app->state, sizeof(State)); break; case 'W': if(count > 44) // 32 bytes midstate + 12 bytes data { RingBuffer_Remove(&app->buffer_); uint8_t i = 0; uint8_t *midstate = (uint8_t *)app->worktask.midstate; uint8_t *data = (uint8_t *)app->worktask.data; for(i=0; i<32; i++) { midstate[i] = RingBuffer_Remove(&app->buffer_); } for(i=0; i<12; i++) { data[i] = RingBuffer_Remove(&app->buffer_); } asicPrecalc(app->worktask.midstate, app->worktask.data, app->worktask.precalc); app->state.state = STATE_WORKING; app->state.nonce_valid = 0; app->state.nonce = 0; asicReset(); asicResetSpi(); pushWork(app, &app->worktask); timerSet(&app->work_timer, 16000); sendCmdReply(app, cmd, (uint8_t *)&app->state, sizeof(State)); } break; default: RingBuffer_Remove(&app->buffer_); break; } return true; }
/** Event handler for the library USB Unhandled Control Packet event. */ void EVENT_USB_Device_UnhandledControlRequest(void) { const uint8_t SerialNumber[5] = { 0, 0, 0, 0, 1 }; uint8_t ControlData[2] = { 0, 0 }; switch (USB_ControlRequest.bRequest) { case 0x09: if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) { LEDs_ToggleLEDs(LEDS_LED1); Endpoint_ClearSETUP(); Endpoint_Read_Control_Stream_LE(ControlData, sizeof(ControlData)); Endpoint_ClearIN(); switch (USB_ControlRequest.wValue) { case 0x303: if (ControlData[1]) PORTC &= ~RELAY1; else PORTC |= RELAY1; break; case 0x306: if (ControlData[1]) PORTC &= ~RELAY2; else PORTC |= RELAY2; break; case 0x309: if (ControlData[1]) PORTC &= ~RELAY3; else PORTC |= RELAY3; break; case 0x30c: if (ControlData[1]) PORTC &= ~RELAY4; else PORTC |= RELAY4; break; } } break; case 0x01: if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) { LEDs_ToggleLEDs(LEDS_LED1); Endpoint_ClearSETUP(); switch (USB_ControlRequest.wValue) { case 0x301: Endpoint_Write_Control_Stream_LE(SerialNumber, sizeof(SerialNumber)); break; case 0x303: ControlData[1] = (PORTC & RELAY1) ? 2 : 3; break; case 0x306: ControlData[1] = (PORTC & RELAY2) ? 2 : 3; break; case 0x309: ControlData[1] = (PORTC & RELAY3) ? 2 : 3; break; case 0x30c: ControlData[1] = (PORTC & RELAY4) ? 2 : 3; break; } if (ControlData[1]) Endpoint_Write_Control_Stream_LE(ControlData, sizeof(ControlData)); Endpoint_ClearOUT(); } break; } }
/** Task to read in AVR109 commands from the CDC data OUT endpoint, process them, perform the required actions * and send the appropriate response back to the host. */ static void CDC_Task(void) { /* Select the OUT endpoint */ Endpoint_SelectEndpoint(CDC_RX_EPADDR); /* Check if endpoint has a command in it sent from the host */ if (!(Endpoint_IsOUTReceived())) return; /* LED feedback */ LEDs_ToggleLEDs(LEDS_LED1 | LEDS_LED2); /* Read in the bootloader command (first byte sent from host) */ uint8_t Command = CDC_FetchNextCommandByte(); if (Command == AVR109_COMMAND_ExitBootloader) { /* Exit the bootloader */ RunBootloader = false; /* Send confirmation byte back to the host */ CDC_WriteNextResponseByte('\r'); } else if (Command == AVR109_COMMAND_SelectDeviceType) { /* Just flush this byte... */ CDC_FetchNextCommandByte(); /* Send confirmation byte back to the host */ CDC_WriteNextResponseByte('\r'); } else if ((Command == AVR109_COMMAND_EnterProgrammingMode) || (Command == AVR109_COMMAND_LeaveProgrammingMode)) { /* Send confirmation byte back to the host */ CDC_WriteNextResponseByte('\r'); } else if (Command == AVR109_COMMAND_ReadPartCode) { /* Return ATMEGA128 part code - this is only to allow AVRProg to use the bootloader */ CDC_WriteNextResponseByte(0x44); CDC_WriteNextResponseByte(0x00); } else if (Command == AVR109_COMMAND_ReadAutoAddressIncrement) { /* Indicate auto-address increment is supported */ CDC_WriteNextResponseByte('Y'); } else if (Command == AVR109_COMMAND_SetCurrentAddress) { /* Set the current address to that given by the host (translate 16-bit word address to byte address) */ CurrAddress = (CDC_FetchNextCommandByte() << 9); CurrAddress |= (CDC_FetchNextCommandByte() << 1); /* Send confirmation byte back to the host */ CDC_WriteNextResponseByte('\r'); } else if (Command == AVR109_COMMAND_ReadBootloaderInterface) { /* Indicate serial programmer back to the host */ CDC_WriteNextResponseByte('S'); } else if (Command == AVR109_COMMAND_ReadBootloaderIdentifier) { /* Write the 7-byte software identifier to the endpoint */ CDC_WriteNextResponseByte(SOFTWARE_IDENTIFIER[0]); CDC_WriteNextResponseByte(SOFTWARE_IDENTIFIER[1]); CDC_WriteNextResponseByte(SOFTWARE_IDENTIFIER[2]); CDC_WriteNextResponseByte(SOFTWARE_IDENTIFIER[3]); CDC_WriteNextResponseByte(SOFTWARE_IDENTIFIER[4]); CDC_WriteNextResponseByte(SOFTWARE_IDENTIFIER[5]); CDC_WriteNextResponseByte(SOFTWARE_IDENTIFIER[6]); } else if (Command == AVR109_COMMAND_ReadBootloaderSWVersion) { CDC_WriteNextResponseByte('0' + BOOTLOADER_VERSION_MAJOR); CDC_WriteNextResponseByte('0' + BOOTLOADER_VERSION_MINOR); } else if (Command == AVR109_COMMAND_ReadSignature) { CDC_WriteNextResponseByte(AVR_SIGNATURE_3); CDC_WriteNextResponseByte(AVR_SIGNATURE_2); CDC_WriteNextResponseByte(AVR_SIGNATURE_1); } else if (Command == AVR109_COMMAND_GetBlockWriteSupport) { CDC_WriteNextResponseByte('Y'); /* Send block size to the host */ CDC_WriteNextResponseByte(SPM_PAGESIZE >> 8); CDC_WriteNextResponseByte(SPM_PAGESIZE & 0xFF); }
/** Processes a read HID report from an attached keyboard, extracting out elements via the HID parser results * as required and prints pressed characters to the serial port. Each time a key is typed, a board LED is toggled. * * \param[in] KeyboardReport Pointer to a HID report from an attached keyboard device */ void ProcessKeyboardReport(uint8_t* KeyboardReport) { /* Check each HID report item in turn, looking for keyboard scan code reports */ for (uint8_t ReportNumber = 0; ReportNumber < HIDReportInfo.TotalReportItems; ReportNumber++) { /* Create a temporary item pointer to the next report item */ HID_ReportItem_t* ReportItem = &HIDReportInfo.ReportItems[ReportNumber]; /* Check if the current report item is a keyboard scan-code */ if ((ReportItem->Attributes.Usage.Page == USAGE_PAGE_KEYBOARD) && (ReportItem->Attributes.BitSize == 8) && (ReportItem->Attributes.Logical.Maximum > 1) && (ReportItem->ItemType == HID_REPORT_ITEM_In)) { /* Retrieve the keyboard scan-code from the report data retrieved from the device */ bool FoundData = USB_GetHIDReportItemInfo(KeyboardReport, ReportItem); /* For multi-report devices - if the requested data was not in the issued report, continue */ if (!(FoundData)) continue; /* Key code is an unsigned char in length, cast to the appropriate type */ uint8_t KeyCode = (uint8_t)ReportItem->Value; /* If scan-code is non-zero, a key is being pressed */ if (KeyCode) { /* Toggle status LED to indicate keypress */ LEDs_ToggleLEDs(LEDS_LED2); char PressedKey = 0; /* Retrieve pressed key character if alphanumeric */ if ((KeyCode >= HID_KEYBOARD_SC_A) && (KeyCode <= HID_KEYBOARD_SC_Z)) { PressedKey = (KeyCode - HID_KEYBOARD_SC_A) + 'A'; } else if ((KeyCode >= HID_KEYBOARD_SC_1_AND_EXCLAMATION) & (KeyCode < HID_KEYBOARD_SC_0_AND_CLOSING_PARENTHESIS)) { PressedKey = (KeyCode - HID_KEYBOARD_SC_1_AND_EXCLAMATION) + '1'; } else if (KeyCode == HID_KEYBOARD_SC_0_AND_CLOSING_PARENTHESIS) { PressedKey = '0'; } else if (KeyCode == HID_KEYBOARD_SC_SPACE) { PressedKey = ' '; } else if (KeyCode == HID_KEYBOARD_SC_ENTER) { PressedKey = '\n'; } /* Print the pressed key character out through the serial port if valid */ if (PressedKey) putchar(PressedKey); } /* Once a scan-code is found, stop scanning through the report items */ break; } } }
void usb_update_led() { LEDs_ToggleLEDs(LEDS_ALL_LEDS); }
//------------------------------------------------------------------------------ uint8_t serialProcess(void) { uint8_t cmd = RingBuffer_Remove(&buffer_); uint8_t size = RingBuffer_Remove(&buffer_); if(cmd == SERIAL_START_CONFIG) { return xilinxSetupConfiguration(); } else if(cmd == SERIAL_DOWNLOAD_DATA) { uint8_t i=0; LEDs_ToggleLEDs(LEDS_LED1); for(i=0; i<size; i++) { xilinxSend(RingBuffer_Remove(&buffer_)); } if(isSetDone()) { return true; } if(!isSetInitB()) { return false; } } else if(cmd == SERIAL_USE_SPI) { SPI_Init(SPI_SPEED_FCPU_DIV_8 | SPI_SCK_LEAD_RISING | SPI_SAMPLE_LEADING | SPI_ORDER_MSB_FIRST | SPI_MODE_MASTER); DDRB |= (1 << 0); PORTB |= (1 << 0); } else if(cmd == SERIAL_SPI_DATA) { uint8_t i=0; LEDs_ToggleLEDs(LEDS_LED2); for(i=0; i<size; i++) { SPI_SendByte(RingBuffer_Remove(&buffer_)); } } else if(cmd == SERIAL_SPI_SELECT) { uint8_t prop = RingBuffer_Remove(&buffer_); if(prop) { PORTD &= ~_BV(PD3); } else { PORTD |= _BV(PD3); } } else if(cmd == SERIAL_USE_USART) { SPI_Disable(); PORTB &= ~((1 << 1) | (1 << 2)); DDRB |= (1 << 1) | (1 << 2); } else if(cmd == SERIAL_USART_DATA) { uint8_t i=0; for(i=0; i<size; i++) { Serial_SendByte(RingBuffer_Remove(&buffer_)); } } else if(cmd == SERIAL_FPGA_RESET) { PORTB |= _BV(PB1); _delay_us(5); PORTB &= ~_BV(PB1); } else if(cmd == SERIAL_FPGA_START) { PORTB |= _BV(PB2); _delay_us(5); PORTB &= ~_BV(PB2); } else { uint8_t i=0; for(i=0; i<size; i++) RingBuffer_Remove(&buffer_); return false; } return true; }
/** Main program entry point. This routine contains the overall program flow, including initial * setup of all components and the main program loop. */ int main(void) { SetupHardware(); RingBuffer_InitBuffer(&Tx_Buffer); sei(); for (;;) { /* Echo bytes from the host to the target via the hardware USART */ int16_t ReceivedByte = CDC_Device_ReceiveByte(&VirtualSerial_CDC_Interface); if (!(ReceivedByte < 0) && (UCSR1A & (1 << UDRE1))) { UDR1 = ReceivedByte; LEDs_TurnOnLEDs(LEDMASK_TX); PulseMSRemaining.TxLEDPulse = TX_RX_LED_PULSE_MS; } /* Check if the millisecond timer has elapsed */ if (TIFR0 & (1 << OCF0A)) { /* Check if the reset pulse period has elapsed, if so tristate the target reset line */ if (PulseMSRemaining.ResetPulse && !(--PulseMSRemaining.ResetPulse)) { LEDs_TurnOffLEDs(LEDMASK_BUSY); AVR_RESET_LINE_DDR &= ~AVR_RESET_LINE_MASK; } /* Check if the LEDs should be ping-ponging (during enumeration) */ if (PulseMSRemaining.PingPongLEDPulse && !(--PulseMSRemaining.PingPongLEDPulse)) { LEDs_ToggleLEDs(LEDMASK_TX | LEDMASK_RX); PulseMSRemaining.PingPongLEDPulse = PING_PONG_LED_PULSE_MS; } /* Turn off TX LED(s) once the TX pulse period has elapsed */ if (PulseMSRemaining.TxLEDPulse && !(--PulseMSRemaining.TxLEDPulse)) LEDs_TurnOffLEDs(LEDMASK_TX); /* Turn off RX LED(s) once the RX pulse period has elapsed */ if (PulseMSRemaining.RxLEDPulse && !(--PulseMSRemaining.RxLEDPulse)) LEDs_TurnOffLEDs(LEDMASK_RX); /* Check if the receive buffer flush period has expired */ RingBuff_Count_t BufferCount = RingBuffer_GetCount(&Tx_Buffer); if (!(--FlushPeriodRemaining) || (BufferCount > 200)) { /* Echo bytes from the target to the host via the virtual serial port */ if (BufferCount) { while (BufferCount--) CDC_Device_SendByte(&VirtualSerial_CDC_Interface, RingBuffer_Remove(&Tx_Buffer)); LEDs_TurnOnLEDs(LEDMASK_RX); PulseMSRemaining.RxLEDPulse = TX_RX_LED_PULSE_MS; } FlushPeriodRemaining = RECEIVE_BUFFER_FLUSH_MS; } /* Clear the millisecond timer CTC flag (cleared by writing logic one to the register) */ TIFR0 |= (1 << OCF0A); } CDC_Device_USBTask(&VirtualSerial_CDC_Interface); USB_USBTask(); } }