/** Handler for the CMD_SET_PARAMETER and CMD_GET_PARAMETER commands from the host, setting or * getting a device parameter's value from the parameter table. * * \param[in] V2Command Issued V2 Protocol command byte from the host */ static void V2Protocol_GetSetParam(const uint8_t V2Command) { uint8_t ParamID = Endpoint_Read_Byte(); uint8_t ParamValue; if (V2Command == CMD_SET_PARAMETER) ParamValue = Endpoint_Read_Byte(); Endpoint_ClearOUT(); Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPNUM); Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN); Endpoint_Write_Byte(V2Command); uint8_t ParamPrivs = V2Params_GetParameterPrivileges(ParamID); if ((V2Command == CMD_SET_PARAMETER) && (ParamPrivs & PARAM_PRIV_WRITE)) { Endpoint_Write_Byte(STATUS_CMD_OK); V2Params_SetParameterValue(ParamID, ParamValue); } else if ((V2Command == CMD_GET_PARAMETER) && (ParamPrivs & PARAM_PRIV_READ)) { Endpoint_Write_Byte(STATUS_CMD_OK); Endpoint_Write_Byte(V2Params_GetParameterValue(ParamID)); } else { Endpoint_Write_Byte(STATUS_CMD_FAILED); } Endpoint_ClearIN(); }
/** Handler for the CMD_LEAVE_ISP command, which releases the target from programming mode. */ void ISPProtocol_LeaveISPMode(void) { struct { uint8_t PreDelayMS; uint8_t PostDelayMS; } Leave_ISP_Params; Endpoint_Read_Stream_LE(&Leave_ISP_Params, sizeof(Leave_ISP_Params), NO_STREAM_CALLBACK); Endpoint_ClearOUT(); Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPNUM); Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN); /* Perform pre-exit delay, release the target /RESET, disable the SPI bus and perform the post-exit delay */ ISPProtocol_DelayMS(Leave_ISP_Params.PreDelayMS); ISPTarget_ChangeTargetResetLine(false); ISPTarget_ShutDown(); ISPProtocol_DelayMS(Leave_ISP_Params.PostDelayMS); /* Turn off the synchronous USART to terminate the recovery clock on XCK pin */ UBRR1 = (F_CPU / 500000UL); UCSR1B = (1 << TXEN1); UCSR1C = (1 << UMSEL10) | (1 << UPM11) | (1 << USBS1) | (1 << UCSZ11) | (1 << UCSZ10) | (1 << UCPOL1); DDRD &= ~(1 << 5); Endpoint_Write_Byte(CMD_LEAVE_PROGMODE_ISP); Endpoint_Write_Byte(STATUS_CMD_OK); Endpoint_ClearIN(); }
/** Handler for the CMD_RESET_PROTECTION command, implemented as a dummy ACK function as * no target short-circuit protection is currently implemented. */ static void V2Protocol_ResetProtection(void) { Endpoint_ClearOUT(); Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPNUM); Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN); Endpoint_Write_Byte(CMD_RESET_PROTECTION); Endpoint_Write_Byte(STATUS_CMD_OK); Endpoint_ClearIN(); }
/** Handler for the XPROG CRC command to read a specific memory space's CRC value for comparison between the * attached device's memory and a data set on the host. */ static void XPROGProtocol_ReadCRC(void) { uint8_t ReturnStatus = XPRG_ERR_OK; struct { uint8_t CRCType; } ReadCRC_XPROG_Params; Endpoint_Read_Stream_LE(&ReadCRC_XPROG_Params, sizeof(ReadCRC_XPROG_Params), NO_STREAM_CALLBACK); Endpoint_ClearOUT(); Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPNUM); Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN); uint32_t MemoryCRC; if (XPROG_SelectedProtocol == XPRG_PROTOCOL_PDI) { uint8_t CRCCommand; /* Determine which NVM command to send to the device depending on the memory to CRC */ switch (ReadCRC_XPROG_Params.CRCType) { case XPRG_CRC_APP: CRCCommand = XMEGA_NVM_CMD_APPCRC; break; case XPRG_CRC_BOOT: CRCCommand = XMEGA_NVM_CMD_BOOTCRC; break; default: CRCCommand = XMEGA_NVM_CMD_FLASHCRC; break; } /* Perform and retrieve the memory CRC, indicate timeout if occurred */ if (!(XMEGANVM_GetMemoryCRC(CRCCommand, &MemoryCRC))) ReturnStatus = XPRG_ERR_TIMEOUT; } else { /* TPI does not support memory CRC */ ReturnStatus = XPRG_ERR_FAILED; } Endpoint_Write_Byte(CMD_XPROG); Endpoint_Write_Byte(XPRG_CMD_CRC); Endpoint_Write_Byte(ReturnStatus); if (ReturnStatus == XPRG_ERR_OK) { Endpoint_Write_Byte(MemoryCRC >> 16); Endpoint_Write_Word_LE(MemoryCRC & 0xFFFF); }
/** Handler for the CMD_SIGN_ON command, returning the programmer ID string to the host. */ static void V2Protocol_SignOn(void) { Endpoint_ClearOUT(); Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPNUM); Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN); Endpoint_Write_Byte(CMD_SIGN_ON); Endpoint_Write_Byte(STATUS_CMD_OK); Endpoint_Write_Byte(sizeof(PROGRAMMER_ID) - 1); Endpoint_Write_Stream_LE(PROGRAMMER_ID, (sizeof(PROGRAMMER_ID) - 1), NO_STREAM_CALLBACK); Endpoint_ClearIN(); }
/** Handler for the XPROG ENTER_PROGMODE command to establish a connection with the attached device. */ static void XPROGProtocol_EnterXPROGMode(void) { Endpoint_ClearOUT(); Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPNUM); Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN); bool NVMBusEnabled = false; if (XPROG_SelectedProtocol == XPRG_PROTOCOL_PDI) { /* Enable PDI programming mode with the attached target */ XPROGTarget_EnableTargetPDI(); /* Store the RESET key into the RESET PDI register to keep the XMEGA in reset */ XPROGTarget_SendByte(PDI_CMD_STCS | PDI_RESET_REG); XPROGTarget_SendByte(PDI_RESET_KEY); /* Lower direction change guard time to 0 USART bits */ XPROGTarget_SendByte(PDI_CMD_STCS | PDI_CTRL_REG); XPROGTarget_SendByte(0x07); /* Enable access to the XPROG NVM bus by sending the documented NVM access key to the device */ XPROGTarget_SendByte(PDI_CMD_KEY); for (uint8_t i = sizeof(PDI_NVMENABLE_KEY); i > 0; i--) XPROGTarget_SendByte(PDI_NVMENABLE_KEY[i - 1]); /* Wait until the NVM bus becomes active */ NVMBusEnabled = XMEGANVM_WaitWhileNVMBusBusy(); } else if (XPROG_SelectedProtocol == XPRG_PROTOCOL_TPI) { /* Enable TPI programming mode with the attached target */ XPROGTarget_EnableTargetTPI(); /* Lower direction change guard time to 0 USART bits */ XPROGTarget_SendByte(TPI_CMD_SSTCS | TPI_CTRL_REG); XPROGTarget_SendByte(0x07); /* Enable access to the XPROG NVM bus by sending the documented NVM access key to the device */ XPROGTarget_SendByte(TPI_CMD_SKEY); for (uint8_t i = sizeof(TPI_NVMENABLE_KEY); i > 0; i--) XPROGTarget_SendByte(TPI_NVMENABLE_KEY[i - 1]); /* Wait until the NVM bus becomes active */ NVMBusEnabled = TINYNVM_WaitWhileNVMBusBusy(); } Endpoint_Write_Byte(CMD_XPROG); Endpoint_Write_Byte(XPRG_CMD_ENTER_PROGMODE); Endpoint_Write_Byte(NVMBusEnabled ? XPRG_ERR_OK : XPRG_ERR_FAILED); Endpoint_ClearIN(); }
/** Command processing for an issued SCSI MODE SENSE (6) command. This command returns various informational pages about * the SCSI device, as well as the device's Write Protect status. * * \return Boolean true if the command completed successfully, false otherwise. */ static bool SCSI_Command_ModeSense_6(void) { /* Send an empty header response with the Write Protect flag status */ Endpoint_Write_Byte(0x00); Endpoint_Write_Byte(0x00); Endpoint_Write_Byte(DISK_READ_ONLY ? 0x80 : 0x00); Endpoint_Write_Byte(0x00); Endpoint_ClearIN(); /* Update the bytes transferred counter and succeed the command */ CommandBlock.DataTransferLength -= 4; return true; }
/** Handler for the CMD_LOAD_ADDRESS command, loading the given device address into a * global storage variable for later use, and issuing LOAD EXTENDED ADDRESS commands * to the attached device as required. */ static void V2Protocol_LoadAddress(void) { Endpoint_Read_Stream_BE(&CurrentAddress, sizeof(CurrentAddress), NO_STREAM_CALLBACK); Endpoint_ClearOUT(); Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPNUM); Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN); if (CurrentAddress & (1UL << 31)) MustLoadExtendedAddress = true; Endpoint_Write_Byte(CMD_LOAD_ADDRESS); Endpoint_Write_Byte(STATUS_CMD_OK); Endpoint_ClearIN(); }
void ecmd_lufa_tx(void) { /* Select the Serial Tx Endpoint */ Endpoint_SelectEndpoint(CDC_TX_EPNUM); /* Wait until Serial Tx Endpoint Ready for Read/Write */ Endpoint_WaitUntilReady(); /* Write the bytes from the buffer to the endpoint while space is available */ while (write_len && Endpoint_IsReadWriteAllowed()) { /* Write each byte retreived from the buffer to the endpoint */ Endpoint_Write_Byte(write_buffer[0]); write_len--; memcpy( write_buffer, &write_buffer[1], write_len ); } /* Remember if the packet to send completely fills the endpoint */ bool IsFull = (Endpoint_BytesInEndpoint() == CDC_TXRX_EPSIZE); /* Send the data */ Endpoint_ClearIN(); /* If no more data to send and the last packet filled the endpoint, send an empty packet to release * the buffer on the receiver (otherwise all data will be cached until a non-full packet is received) */ if (IsFull && !write_len) { /* Wait until Serial Tx Endpoint Ready for Read/Write */ Endpoint_WaitUntilReady(); /* Send an empty packet to terminate the transfer */ Endpoint_ClearIN(); } }
uint8_t Endpoint_Write_Control_Stream_LE(const void* Buffer, uint16_t Length) { uint8_t* DataStream = (uint8_t*)Buffer; bool LastPacketFull = false; if (Length > USB_ControlRequest.wLength) Length = USB_ControlRequest.wLength; while (Length && !(Endpoint_IsOUTReceived())) { while (!(Endpoint_IsINReady())); while (Length && (Endpoint_BytesInEndpoint() < USB_ControlEndpointSize)) { Endpoint_Write_Byte(*(DataStream++)); Length--; } LastPacketFull = (Endpoint_BytesInEndpoint() == USB_ControlEndpointSize); Endpoint_ClearIN(); } if (Endpoint_IsOUTReceived()) return ENDPOINT_RWCSTREAM_HostAborted; if (LastPacketFull) { while (!(Endpoint_IsINReady())); Endpoint_ClearIN(); } while (!(Endpoint_IsOUTReceived())); return ENDPOINT_RWCSTREAM_NoError; }
uint8_t Endpoint_Write_Stream_LE(const void* Buffer, uint16_t Length #if !defined(NO_STREAM_CALLBACKS) , uint8_t (* const Callback)(void) #endif ) { uint8_t* DataStream = (uint8_t*)Buffer; uint8_t ErrorCode; if ((ErrorCode = Endpoint_WaitUntilReady())) return ErrorCode; while (Length) { if (!(Endpoint_IsReadWriteAllowed())) { Endpoint_ClearIN(); #if !defined(NO_STREAM_CALLBACKS) if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort)) return ENDPOINT_RWSTREAM_CallbackAborted; #endif if ((ErrorCode = Endpoint_WaitUntilReady())) return ErrorCode; } else { Endpoint_Write_Byte(*(DataStream++)); Length--; } } return ENDPOINT_RWSTREAM_NoError; }
int8_t usbSendByte(uint8_t data) { #ifdef DEBUG if (usbDataDir != ENDPOINT_DIR_IN) { DEBUGF(DBG_ERROR, "ERR: usbSendByte when dir was %d\n", usbDataDir); return -1; } #endif // Write data back to the host buffer for USB transfer Endpoint_Write_Byte(data); usbDataLen--; // If the endpoint is now full, flush the block to the host if (!Endpoint_IsReadWriteAllowed()) { Endpoint_ClearIN(); while (!Endpoint_IsReadWriteAllowed() && !doDeviceReset) ; } // Check if the current command is being aborted by the host if (doDeviceReset) { DEBUGF(DBG_ERROR, "sndrst\n"); return -1; } return 0; }
/** Event handler for the USB_UnhandledControlPacket event. This is used to catch standard and class specific * control requests that are not handled internally by the USB library (including the Mass Storage class-specific * requests) so that they can be handled appropriately for the application. */ void EVENT_USB_Device_UnhandledControlRequest(void) { /* Process UFI specific control requests */ switch (USB_ControlRequest.bRequest) { case REQ_MassStorageReset: if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) { Endpoint_ClearSETUP(); Endpoint_ClearStatusStage(); /* Indicate that the current transfer should be aborted */ IsMassStoreReset = true; } break; case REQ_GetMaxLUN: if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) { Endpoint_ClearSETUP(); /* Indicate to the host the number of supported LUNs (virtual disks) on the device */ Endpoint_Write_Byte(TOTAL_LUNS - 1); Endpoint_ClearIN(); Endpoint_ClearStatusStage(); } break; } }
void Audio_Device_WriteSample8(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo, const int8_t Sample) { Endpoint_Write_Byte(Sample); if (Endpoint_BytesInEndpoint() == AudioInterfaceInfo->Config.DataINEndpointSize) Endpoint_ClearIN(); }
void MS_Device_ProcessControlRequest(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) { if (!(Endpoint_IsSETUPReceived())) return; if (USB_ControlRequest.wIndex != MSInterfaceInfo->Config.InterfaceNumber) return; switch (USB_ControlRequest.bRequest) { case MS_REQ_MassStorageReset: if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) { Endpoint_ClearSETUP(); Endpoint_ClearStatusStage(); MSInterfaceInfo->State.IsMassStoreReset = true; } break; case MS_REQ_GetMaxLUN: if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) { Endpoint_ClearSETUP(); Endpoint_Write_Byte(MSInterfaceInfo->Config.TotalLUNs - 1); Endpoint_ClearIN(); Endpoint_ClearStatusStage(); } break; } }
uint8_t Endpoint_Write_Stream_BE(const void* Buffer, uint16_t Length #if !defined(NO_STREAM_CALLBACKS) , uint8_t (* const Callback)(void) #endif ) { uint8_t* DataStream = (uint8_t*)(Buffer + Length - 1); uint8_t ErrorCode; if ((ErrorCode = Endpoint_WaitUntilReady())) return ErrorCode; while (Length--) { if (!(Endpoint_ReadWriteAllowed())) { Endpoint_ClearCurrentBank(); #if !defined(NO_STREAM_CALLBACKS) if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort)) return ENDPOINT_RWSTREAM_ERROR_CallbackAborted; #endif if ((ErrorCode = Endpoint_WaitUntilReady())) return ErrorCode; } Endpoint_Write_Byte(*(DataStream--)); } return ENDPOINT_RWSTREAM_ERROR_NoError; }
uint8_t Endpoint_Write_Control_Stream_BE(const void* Buffer, uint16_t Length) { uint8_t* DataStream = (uint8_t*)(Buffer + Length - 1); bool SendZLP = true; while (Length && !(Endpoint_IsSetupOUTReceived())) { while (!(Endpoint_IsSetupINReady())); while (Length && (Endpoint_BytesInEndpoint() < USB_ControlEndpointSize)) { Endpoint_Write_Byte(*(DataStream--)); Length--; } SendZLP = (Endpoint_BytesInEndpoint() == USB_ControlEndpointSize); Endpoint_ClearSetupIN(); } if (Endpoint_IsSetupOUTReceived()) return ENDPOINT_RWCSTREAM_ERROR_HostAborted; if (SendZLP) { while (!(Endpoint_IsSetupINReady())); Endpoint_ClearSetupIN(); } while (!(Endpoint_IsSetupOUTReceived())); return ENDPOINT_RWCSTREAM_ERROR_NoError; }
/** Handler for unknown V2 protocol commands. This discards all sent data and returns a * STATUS_CMD_UNKNOWN status back to the host. * * \param[in] V2Command Issued V2 Protocol command byte from the host */ static void V2Protocol_UnknownCommand(const uint8_t V2Command) { /* Discard all incoming data */ while (Endpoint_BytesInEndpoint() == AVRISP_DATA_EPSIZE) { Endpoint_ClearOUT(); Endpoint_WaitUntilReady(); } Endpoint_ClearOUT(); Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPNUM); Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN); Endpoint_Write_Byte(V2Command); Endpoint_Write_Byte(STATUS_CMD_UNKNOWN); Endpoint_ClearIN(); }
static void USB_Device_GetConfiguration(void) { Endpoint_ClearSETUP(); Endpoint_Write_Byte(USB_ConfigurationNumber); Endpoint_ClearIN(); Endpoint_ClearStatusStage(); }
/** Handler for the XPROG ENTER_PROGMODE command to establish a connection with the attached device. */ static void XPROGProtocol_EnterXPROGMode(void) { Endpoint_ClearOUT(); Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPNUM); Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN); bool NVMBusEnabled = false; if (XPROG_SelectedProtocol == XPRG_PROTOCOL_PDI) NVMBusEnabled = XMEGANVM_EnablePDI(); else if (XPROG_SelectedProtocol == XPRG_PROTOCOL_TPI) NVMBusEnabled = TINYNVM_EnableTPI(); Endpoint_Write_Byte(CMD_XPROG); Endpoint_Write_Byte(XPRG_CMD_ENTER_PROGMODE); Endpoint_Write_Byte(NVMBusEnabled ? XPRG_ERR_OK : XPRG_ERR_FAILED); Endpoint_ClearIN(); }
/** Handler for the XPROG READ_MEMORY command to read data from a specific address space within the * attached device. */ static void XPROGProtocol_ReadMemory(void) { uint8_t ReturnStatus = XPRG_ERR_OK; struct { uint8_t MemoryType; uint32_t Address; uint16_t Length; } ReadMemory_XPROG_Params; Endpoint_Read_Stream_LE(&ReadMemory_XPROG_Params, sizeof(ReadMemory_XPROG_Params), NO_STREAM_CALLBACK); ReadMemory_XPROG_Params.Address = SwapEndian_32(ReadMemory_XPROG_Params.Address); ReadMemory_XPROG_Params.Length = SwapEndian_16(ReadMemory_XPROG_Params.Length); Endpoint_ClearOUT(); Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPNUM); Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN); uint8_t ReadBuffer[256]; if (XPROG_SelectedProtocol == XPRG_PROTOCOL_PDI) { /* Read the PDI target's memory, indicate timeout if occurred */ if (!(XMEGANVM_ReadMemory(ReadMemory_XPROG_Params.Address, ReadBuffer, ReadMemory_XPROG_Params.Length))) ReturnStatus = XPRG_ERR_TIMEOUT; } else { /* Read the TPI target's memory, indicate timeout if occurred */ if (!(TINYNVM_ReadMemory(ReadMemory_XPROG_Params.Address, ReadBuffer, ReadMemory_XPROG_Params.Length))) ReturnStatus = XPRG_ERR_TIMEOUT; } Endpoint_Write_Byte(CMD_XPROG); Endpoint_Write_Byte(XPRG_CMD_READ_MEM); Endpoint_Write_Byte(ReturnStatus); if (ReturnStatus == XPRG_ERR_OK) Endpoint_Write_Stream_LE(ReadBuffer, ReadMemory_XPROG_Params.Length, NO_STREAM_CALLBACK); Endpoint_ClearIN(); }
/** Handler for the CMD_XPROG_SETMODE command, which sets the programmer-to-target protocol used for PDI/TPI * programming. */ void XPROGProtocol_SetMode(void) { struct { uint8_t Protocol; } SetMode_XPROG_Params; Endpoint_Read_Stream_LE(&SetMode_XPROG_Params, sizeof(SetMode_XPROG_Params), NO_STREAM_CALLBACK); Endpoint_ClearOUT(); Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPNUM); Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN); XPROG_SelectedProtocol = SetMode_XPROG_Params.Protocol; Endpoint_Write_Byte(CMD_XPROG_SETMODE); Endpoint_Write_Byte((SetMode_XPROG_Params.Protocol != XPRG_PROTOCOL_JTAG) ? STATUS_CMD_OK : STATUS_CMD_FAILED); Endpoint_ClearIN(); }
/** Event handler for the USB_UnhandledControlRequest event. This is used to catch standard and class specific * control requests that are not handled internally by the USB library, so that they can be handled appropriately * for the application. */ void EVENT_USB_Device_UnhandledControlRequest(void) { uint8_t* LineCodingData = (uint8_t*)&LineCoding; /* Process CDC specific control requests */ switch (USB_ControlRequest.bRequest) { case REQ_GetLineEncoding: if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) { Endpoint_ClearSETUP(); for (uint8_t i = 0; i < sizeof(LineCoding); i++) Endpoint_Write_Byte(*(LineCodingData++)); Endpoint_ClearIN(); Endpoint_ClearStatusStage(); } break; case REQ_SetLineEncoding: if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) { Endpoint_ClearSETUP(); while (!(Endpoint_IsOUTReceived())) { if (USB_DeviceState == DEVICE_STATE_Unattached) return; } for (uint8_t i = 0; i < sizeof(LineCoding); i++) *(LineCodingData++) = Endpoint_Read_Byte(); Endpoint_ClearOUT(); Endpoint_ClearStatusStage(); } break; case REQ_SetControlLineState: if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) { Endpoint_ClearSETUP(); Endpoint_ClearStatusStage(); } break; } }
/** Handler for the XPROG LEAVE_PROGMODE command to terminate the PDI programming connection with * the attached device. */ static void XPROGProtocol_LeaveXPROGMode(void) { Endpoint_ClearOUT(); Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPNUM); Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN); if (XPROG_SelectedProtocol == XPRG_PROTOCOL_PDI) XMEGANVM_DisablePDI(); else TINYNVM_DisableTPI(); #if defined(XCK_RESCUE_CLOCK_ENABLE) && defined(ENABLE_ISP_PROTOCOL) /* If the XCK rescue clock option is enabled, we need to restart it once the * XPROG mode has been exited, since the XPROG protocol stops it after use. */ ISPTarget_ConfigureRescueClock(); #endif Endpoint_Write_Byte(CMD_XPROG); Endpoint_Write_Byte(XPRG_CMD_LEAVE_PROGMODE); Endpoint_Write_Byte(XPRG_ERR_OK); Endpoint_ClearIN(); }
/** Handler for the XPROG LEAVE_PROGMODE command to terminate the PDI programming connection with * the attached device. */ static void XPROGProtocol_LeaveXPROGMode(void) { Endpoint_ClearOUT(); Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPNUM); Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN); if (XPROG_SelectedProtocol == XPRG_PROTOCOL_PDI) { XMEGANVM_WaitWhileNVMBusBusy(); /* Clear the RESET key in the RESET PDI register to allow the XMEGA to run */ XPROGTarget_SendByte(PDI_CMD_STCS | PDI_RESET_REG); XPROGTarget_SendByte(0x00); /* Do it twice to make sure it takes affect (silicon bug?) */ XPROGTarget_SendByte(PDI_CMD_STCS | PDI_RESET_REG); XPROGTarget_SendByte(0x00); XPROGTarget_DisableTargetPDI(); } else { TINYNVM_WaitWhileNVMBusBusy(); /* Clear the NVMEN bit in the TPI CONTROL register to disable TPI mode */ XPROGTarget_SendByte(TPI_CMD_SSTCS | TPI_CTRL_REG); XPROGTarget_SendByte(0x00); XPROGTarget_DisableTargetTPI(); } Endpoint_Write_Byte(CMD_XPROG); Endpoint_Write_Byte(XPRG_CMD_LEAVE_PROGMODE); Endpoint_Write_Byte(XPRG_ERR_OK); Endpoint_ClearIN(); }
void uart_send(uint8_t d) { do { if (usb_txpacket_leftb) { Endpoint_SelectEndpoint(CDC_TX_EPNUM); Endpoint_Write_Byte(d); usb_txpacket_leftb--; if (usb_txpacket_leftb == 1) { Endpoint_ClearIN(); /* Go data, GO. */ usb_txpacket_leftb = 0; } return; } usb_process(); if (CDC_Device_SendByte_Prep(&VirtualSerial_CDC_Interface) == 0) usb_txpacket_leftb = CDC_IN_EPSIZE; } while (1); }
void HUB_Task(void) { Endpoint_SelectEndpoint(1); if (Endpoint_IsReadWriteAllowed()) { if (hub_int_response) { if (hub_int_force_data0) { Endpoint_ResetDataToggle(); hub_int_force_data0 = 0; } Endpoint_Write_Byte(hub_int_response); Endpoint_ClearIN(); hub_int_response = 0x00; } } }
uint8_t CDC_Device_SendByte(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, const uint8_t Data) { if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS)) return ENDPOINT_RWSTREAM_DeviceDisconnected; Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataINEndpointNumber); if (!(Endpoint_IsReadWriteAllowed())) { Endpoint_ClearIN(); uint8_t ErrorCode; if ((ErrorCode = Endpoint_WaitUntilReady()) != ENDPOINT_READYWAIT_NoError) return ErrorCode; } Endpoint_Write_Byte(Data); return ENDPOINT_READYWAIT_NoError; }
uint8_t Endpoint_Null_Stream(uint16_t Length, uint16_t* const BytesProcessed) { uint8_t ErrorCode; uint16_t BytesInTransfer = 0; if ((ErrorCode = Endpoint_WaitUntilReady())) return ErrorCode; if (BytesProcessed != NULL) Length -= *BytesProcessed; while (Length) { if (!(Endpoint_IsReadWriteAllowed())) { Endpoint_ClearIN(); if (BytesProcessed != NULL) { *BytesProcessed += BytesInTransfer; return ENDPOINT_RWSTREAM_IncompleteTransfer; } if ((ErrorCode = Endpoint_WaitUntilReady())) return ErrorCode; } else { Endpoint_Write_Byte(0); Length--; BytesInTransfer++; } } return ENDPOINT_RWSTREAM_NoError; }
/** Handler for the XPROG WRITE_MEMORY command to write to a specific memory space within the attached device. */ static void XPROGProtocol_WriteMemory(void) { uint8_t ReturnStatus = XPRG_ERR_OK; struct { uint8_t MemoryType; uint8_t PageMode; uint32_t Address; uint16_t Length; uint8_t ProgData[256]; } WriteMemory_XPROG_Params; Endpoint_Read_Stream_LE(&WriteMemory_XPROG_Params, (sizeof(WriteMemory_XPROG_Params) - sizeof(WriteMemory_XPROG_Params).ProgData), NO_STREAM_CALLBACK); WriteMemory_XPROG_Params.Address = SwapEndian_32(WriteMemory_XPROG_Params.Address); WriteMemory_XPROG_Params.Length = SwapEndian_16(WriteMemory_XPROG_Params.Length); Endpoint_Read_Stream_LE(&WriteMemory_XPROG_Params.ProgData, WriteMemory_XPROG_Params.Length, NO_STREAM_CALLBACK); Endpoint_ClearOUT(); Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPNUM); Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN); if (XPROG_SelectedProtocol == XPRG_PROTOCOL_PDI) { /* Assume FLASH page programming by default, as it is the common case */ uint8_t WriteCommand = XMEGA_NVM_CMD_WRITEFLASHPAGE; uint8_t WriteBuffCommand = XMEGA_NVM_CMD_LOADFLASHPAGEBUFF; uint8_t EraseBuffCommand = XMEGA_NVM_CMD_ERASEFLASHPAGEBUFF; bool PagedMemory = true; switch (WriteMemory_XPROG_Params.MemoryType) { case XPRG_MEM_TYPE_APPL: WriteCommand = XMEGA_NVM_CMD_WRITEAPPSECPAGE; break; case XPRG_MEM_TYPE_BOOT: WriteCommand = XMEGA_NVM_CMD_WRITEBOOTSECPAGE; break; case XPRG_MEM_TYPE_EEPROM: WriteCommand = XMEGA_NVM_CMD_ERASEWRITEEEPROMPAGE; WriteBuffCommand = XMEGA_NVM_CMD_LOADEEPROMPAGEBUFF; EraseBuffCommand = XMEGA_NVM_CMD_ERASEEEPROMPAGEBUFF; break; case XPRG_MEM_TYPE_USERSIG: /* User signature is paged, but needs us to manually indicate the mode bits since the host doesn't set them */ WriteMemory_XPROG_Params.PageMode = (XPRG_PAGEMODE_ERASE | XPRG_PAGEMODE_WRITE); WriteCommand = XMEGA_NVM_CMD_WRITEUSERSIG; break; case XPRG_MEM_TYPE_FUSE: WriteCommand = XMEGA_NVM_CMD_WRITEFUSE; PagedMemory = false; break; case XPRG_MEM_TYPE_LOCKBITS: WriteCommand = XMEGA_NVM_CMD_WRITELOCK; PagedMemory = false; break; } /* Send the appropriate memory write commands to the device, indicate timeout if occurred */ if ((PagedMemory && !(XMEGANVM_WritePageMemory(WriteBuffCommand, EraseBuffCommand, WriteCommand, WriteMemory_XPROG_Params.PageMode, WriteMemory_XPROG_Params.Address, WriteMemory_XPROG_Params.ProgData, WriteMemory_XPROG_Params.Length))) || (!PagedMemory && !(XMEGANVM_WriteByteMemory(WriteCommand, WriteMemory_XPROG_Params.Address, WriteMemory_XPROG_Params.ProgData[0])))) { ReturnStatus = XPRG_ERR_TIMEOUT; } } else { /* Send write command to the TPI device, indicate timeout if occurred */ if (!(TINYNVM_WriteMemory(WriteMemory_XPROG_Params.Address, WriteMemory_XPROG_Params.ProgData, WriteMemory_XPROG_Params.Length))) { ReturnStatus = XPRG_ERR_TIMEOUT; } } Endpoint_Write_Byte(CMD_XPROG); Endpoint_Write_Byte(XPRG_CMD_WRITE_MEM); Endpoint_Write_Byte(ReturnStatus); Endpoint_ClearIN(); }