/** Removes access to the target's NVM controller and physically disables the target's physical TPI interface. */ void TINYNVM_DisableTPI(void) { TINYNVM_WaitWhileNVMBusBusy(); /* Clear the NVMEN bit in the TPI STATUS register to disable TPI mode */ XPROGTarget_SendByte(TPI_CMD_SSTCS | TPI_STATUS_REG); XPROGTarget_SendByte(0x00); XPROGTarget_DisableTargetTPI(); }
/** 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(); }
/** Removes access to the target's NVM controller and physically disables the target's physical TPI interface. */ void TINYNVM_DisableTPI(void) { TINYNVM_WaitWhileNVMBusBusy(); do { /* Clear the NVMEN bit in the TPI STATUS register to disable TPI mode */ XPROGTarget_SendByte(TPI_CMD_SSTCS | TPI_STATUS_REG); XPROGTarget_SendByte(0x00); /* Read back the STATUS register, check to see if it took effect */ XPROGTarget_SendByte(TPI_CMD_SLDCS | PDI_RESET_REG); } while (XPROGTarget_ReceiveByte() != 0x00); XPROGTarget_DisableTargetTPI(); }
/** Enables the physical TPI interface on the target and enables access to the internal NVM controller. * * \return Boolean true if the TPI interface was enabled successfully, false otherwise */ bool TINYNVM_EnableTPI(void) { /* Enable TPI programming mode with the attached target */ XPROGTarget_EnableTargetTPI(); /* Lower direction change guard time to 32 USART bits */ XPROGTarget_SendByte(TPI_CMD_SSTCS | TPI_CTRL_REG); XPROGTarget_SendByte(0x02); /* 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 */ return TINYNVM_WaitWhileNVMBusBusy(); }
/** 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(); }