Esempio n. 1
0
/** 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();
}
Esempio n. 2
0
/** 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();
}
Esempio n. 3
0
/** 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), NULL);

    Endpoint_ClearOUT();
    Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPADDR);
    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_DisableTargetISP();
    ISPProtocol_DelayMS(Leave_ISP_Params.PostDelayMS);

    Endpoint_Write_8(CMD_LEAVE_PROGMODE_ISP);
    Endpoint_Write_8(STATUS_CMD_OK);
    Endpoint_ClearIN();

    ISPActive = false;
}
Esempio n. 4
0
/** 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();
}
Esempio n. 5
0
/** 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 = XPROG_ERR_OK;

	struct
	{
		uint8_t CRCType;
	} ReadCRC_XPROG_Params;

	Endpoint_Read_Stream_LE(&ReadCRC_XPROG_Params, sizeof(ReadCRC_XPROG_Params), NULL);

	Endpoint_ClearOUT();
	Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPADDR);
	Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);

	uint32_t MemoryCRC;

	if (XPROG_SelectedProtocol == XPROG_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 XPROG_CRC_APP:
				CRCCommand = XMEGA_NVM_CMD_APPCRC;
				break;
			case XPROG_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 = XPROG_ERR_TIMEOUT;
	}
	else
	{
		/* TPI does not support memory CRC */
		ReturnStatus = XPROG_ERR_FAILED;
	}

	Endpoint_Write_8(CMD_XPROG);
	Endpoint_Write_8(XPROG_CMD_CRC);
	Endpoint_Write_8(ReturnStatus);

	if (ReturnStatus == XPROG_ERR_OK)
	{
		Endpoint_Write_8(MemoryCRC >> 16);
		Endpoint_Write_16_LE(MemoryCRC & 0xFFFF);
	}
Esempio n. 6
0
/** 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 CMD_SIGN_ON command, returning the programmer ID string to the host. */
static void V2Protocol_SignOn(void)
{
    Endpoint_ClearOUT();
    Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPADDR);
    Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);

    Endpoint_Write_8(CMD_SIGN_ON);
    Endpoint_Write_8(STATUS_CMD_OK);
    Endpoint_Write_8(sizeof(PROGRAMMER_ID) - 1);
    Endpoint_Write_Stream_LE(PROGRAMMER_ID, (sizeof(PROGRAMMER_ID) - 1), NULL);
    Endpoint_ClearIN();
}
Esempio n. 8
0
/** 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();
}
Esempio n. 9
0
/** 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();
}
Esempio n. 10
0
/** 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();

	if ( use_libusb == true ) {
		Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPNUM__LIBUSB);

	} else {
		Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPNUM__DEFAULT);
	}

	Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);

	Endpoint_Write_8(CMD_RESET_PROTECTION);
	Endpoint_Write_8(STATUS_CMD_OK);
	Endpoint_ClearIN();
}
Esempio n. 11
0
/** 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();
}
Esempio n. 12
0
/** 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_EPADDR);
	Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);

	bool NVMBusEnabled = false;

	if (XPROG_SelectedProtocol == XPROG_PROTOCOL_PDI)
	  NVMBusEnabled = XMEGANVM_EnablePDI();
	else if (XPROG_SelectedProtocol == XPROG_PROTOCOL_TPI)
	  NVMBusEnabled = TINYNVM_EnableTPI();

	Endpoint_Write_8(CMD_XPROG);
	Endpoint_Write_8(XPROG_CMD_ENTER_PROGMODE);
	Endpoint_Write_8(NVMBusEnabled ? XPROG_ERR_OK : XPROG_ERR_FAILED);
	Endpoint_ClearIN();
}
Esempio n. 13
0
/** Handler for the CMD_SIGN_ON command, returning the programmer ID string to the host. */
static void V2Protocol_SignOn(void)
{
	Endpoint_ClearOUT();

	if ( use_libusb == true ) {
		Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPNUM__LIBUSB);

	} else {
		Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPNUM__DEFAULT);
	}

	Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);

	Endpoint_Write_8(CMD_SIGN_ON);
	Endpoint_Write_8(STATUS_CMD_OK);
	Endpoint_Write_8(sizeof(PROGRAMMER_ID) - 1);
	Endpoint_Write_Stream_LE(PROGRAMMER_ID, (sizeof(PROGRAMMER_ID) - 1), NULL);
	Endpoint_ClearIN();
}
Esempio n. 14
0
/** 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 = XPROG_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), NULL);
	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_EPADDR);
	Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);

	uint8_t ReadBuffer[256];

	if (XPROG_SelectedProtocol == XPROG_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 = XPROG_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 = XPROG_ERR_TIMEOUT;
	}

	Endpoint_Write_8(CMD_XPROG);
	Endpoint_Write_8(XPROG_CMD_READ_MEM);
	Endpoint_Write_8(ReturnStatus);

	if (ReturnStatus == XPROG_ERR_OK)
	  Endpoint_Write_Stream_LE(ReadBuffer, ReadMemory_XPROG_Params.Length, NULL);

	Endpoint_ClearIN();
}
Esempio n. 15
0
/** 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), NULL);

	Endpoint_ClearOUT();
	Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPADDR);
	Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);

	XPROG_SelectedProtocol = SetMode_XPROG_Params.Protocol;

	Endpoint_Write_8(CMD_XPROG_SETMODE);
	Endpoint_Write_8((SetMode_XPROG_Params.Protocol != XPROG_PROTOCOL_JTAG) ? STATUS_CMD_OK : STATUS_CMD_FAILED);
	Endpoint_ClearIN();
}
Esempio n. 16
0
/** 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), NULL);

	Endpoint_ClearOUT();

	if ( use_libusb == true ) {
		Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPNUM__LIBUSB);
	} else {
		Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPNUM__DEFAULT);
	}

	Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);

	if (CurrentAddress & (1UL << 31))
	  MustLoadExtendedAddress = true;

	Endpoint_Write_8(CMD_LOAD_ADDRESS);
	Endpoint_Write_8(STATUS_CMD_OK);
	Endpoint_ClearIN();
}
Esempio n. 17
0
/** 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_EPADDR);
	Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);

	if (XPROG_SelectedProtocol == XPROG_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_8(CMD_XPROG);
	Endpoint_Write_8(XPROG_CMD_LEAVE_PROGMODE);
	Endpoint_Write_8(XPROG_ERR_OK);
	Endpoint_ClearIN();
}
Esempio n. 18
0
/** 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();
}
/** Handler for the CMD_PROGRAM_FLASH_ISP and CMD_PROGRAM_EEPROM_ISP commands, writing out bytes,
 *  words or pages of data to the attached device.
 *
 *  \param[in] V2Command  Issued V2 Protocol command byte from the host
 */
void ISPProtocol_ProgramMemory(uint8_t V2Command)
{
	struct
	{
		uint16_t BytesToWrite;
		uint8_t  ProgrammingMode;
		uint8_t  DelayMS;
		uint8_t  ProgrammingCommands[3];
		uint8_t  PollValue1;
		uint8_t  PollValue2;
		uint8_t  ProgData[256]; // Note, the Jungo driver has a very short ACK timeout period, need to buffer the
	} Write_Memory_Params;      // whole page and ACK the packet as fast as possible to prevent it from aborting

	Endpoint_Read_Stream_LE(&Write_Memory_Params, (sizeof(Write_Memory_Params) -
	                                               sizeof(Write_Memory_Params.ProgData)), NULL);
	Write_Memory_Params.BytesToWrite = SwapEndian_16(Write_Memory_Params.BytesToWrite);

	if (Write_Memory_Params.BytesToWrite > sizeof(Write_Memory_Params.ProgData))
	{
		Endpoint_ClearOUT();
		Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPADDR);
		Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);

		Endpoint_Write_8(V2Command);
		Endpoint_Write_8(STATUS_CMD_FAILED);
		Endpoint_ClearIN();
		return;
	}

	Endpoint_Read_Stream_LE(&Write_Memory_Params.ProgData, Write_Memory_Params.BytesToWrite, NULL);

	// The driver will terminate transfers that are a round multiple of the endpoint bank in size with a ZLP, need
	// to catch this and discard it before continuing on with packet processing to prevent communication issues
	if (((sizeof(uint8_t) + sizeof(Write_Memory_Params) - sizeof(Write_Memory_Params.ProgData)) +
	    Write_Memory_Params.BytesToWrite) % AVRISP_DATA_EPSIZE == 0)
	{
		Endpoint_ClearOUT();
		Endpoint_WaitUntilReady();
	}

	Endpoint_ClearOUT();
	Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPADDR);
	Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);

	uint8_t  ProgrammingStatus = STATUS_CMD_OK;
	uint8_t  PollValue         = (V2Command == CMD_PROGRAM_FLASH_ISP) ? Write_Memory_Params.PollValue1 :
	                                                                    Write_Memory_Params.PollValue2;
	uint16_t PollAddress       = 0;
	uint8_t* NextWriteByte     = Write_Memory_Params.ProgData;
	uint16_t PageStartAddress  = (CurrentAddress & 0xFFFF);

	for (uint16_t CurrentByte = 0; CurrentByte < Write_Memory_Params.BytesToWrite; CurrentByte++)
	{
		uint8_t ByteToWrite     = *(NextWriteByte++);
		uint8_t ProgrammingMode = Write_Memory_Params.ProgrammingMode;

		/* Check to see if we need to send a LOAD EXTENDED ADDRESS command to the target */
		if (MustLoadExtendedAddress)
		{
			ISPTarget_LoadExtendedAddress();
			MustLoadExtendedAddress = false;
		}

		ISPTarget_SendByte(Write_Memory_Params.ProgrammingCommands[0]);
		ISPTarget_SendByte(CurrentAddress >> 8);
		ISPTarget_SendByte(CurrentAddress & 0xFF);
		ISPTarget_SendByte(ByteToWrite);

		/* AVR FLASH addressing requires us to modify the write command based on if we are writing a high
		 * or low byte at the current word address */
		if (V2Command == CMD_PROGRAM_FLASH_ISP)
		  Write_Memory_Params.ProgrammingCommands[0] ^= READ_WRITE_HIGH_BYTE_MASK;

		/* Check to see if we have a valid polling address */
		if (!(PollAddress) && (ByteToWrite != PollValue))
		{
			if ((CurrentByte & 0x01) && (V2Command == CMD_PROGRAM_FLASH_ISP))
			  Write_Memory_Params.ProgrammingCommands[2] |=  READ_WRITE_HIGH_BYTE_MASK;
			else
			  Write_Memory_Params.ProgrammingCommands[2] &= ~READ_WRITE_HIGH_BYTE_MASK;

			PollAddress = (CurrentAddress & 0xFFFF);
		}

		/* If in word programming mode, commit the byte to the target's memory */
		if (!(ProgrammingMode & PROG_MODE_PAGED_WRITES_MASK))
		{
			/* If the current polling address is invalid, switch to timed delay write completion mode */
			if (!(PollAddress) && !(ProgrammingMode & PROG_MODE_WORD_READYBUSY_MASK))
			  ProgrammingMode = (ProgrammingMode & ~PROG_MODE_WORD_VALUE_MASK) | PROG_MODE_WORD_TIMEDELAY_MASK;

			ProgrammingStatus = ISPTarget_WaitForProgComplete(ProgrammingMode, PollAddress, PollValue,
			                                                  Write_Memory_Params.DelayMS,
			                                                  Write_Memory_Params.ProgrammingCommands[2]);

			/* Abort the programming loop early if the byte/word programming failed */
			if (ProgrammingStatus != STATUS_CMD_OK)
			  break;

			/* Must reset the polling address afterwards, so it is not erroneously used for the next byte */
			PollAddress = 0;
		}

		/* EEPROM just increments the address each byte, flash needs to increment on each word and
		 * also check to ensure that a LOAD EXTENDED ADDRESS command is issued each time the extended
		 * address boundary has been crossed during FLASH memory programming */
		if ((CurrentByte & 0x01) || (V2Command == CMD_PROGRAM_EEPROM_ISP))
		{
			CurrentAddress++;

			if ((V2Command == CMD_PROGRAM_FLASH_ISP) && !(CurrentAddress & 0xFFFF))
			  MustLoadExtendedAddress = true;
		}
	}

	/* If the current page must be committed, send the PROGRAM PAGE command to the target */
	if (Write_Memory_Params.ProgrammingMode & PROG_MODE_COMMIT_PAGE_MASK)
	{
		ISPTarget_SendByte(Write_Memory_Params.ProgrammingCommands[1]);
		ISPTarget_SendByte(PageStartAddress >> 8);
		ISPTarget_SendByte(PageStartAddress & 0xFF);
		ISPTarget_SendByte(0x00);

		/* Check if polling is enabled and possible, if not switch to timed delay mode */
		if ((Write_Memory_Params.ProgrammingMode & PROG_MODE_PAGED_VALUE_MASK) && !(PollAddress))
		{
			Write_Memory_Params.ProgrammingMode = (Write_Memory_Params.ProgrammingMode & ~PROG_MODE_PAGED_VALUE_MASK) |
												   PROG_MODE_PAGED_TIMEDELAY_MASK;
		}

		ProgrammingStatus = ISPTarget_WaitForProgComplete(Write_Memory_Params.ProgrammingMode, PollAddress, PollValue,
		                                                  Write_Memory_Params.DelayMS,
		                                                  Write_Memory_Params.ProgrammingCommands[2]);

		/* Check to see if the FLASH address has crossed the extended address boundary */
		if ((V2Command == CMD_PROGRAM_FLASH_ISP) && !(CurrentAddress & 0xFFFF))
		  MustLoadExtendedAddress = true;
	}
Esempio n. 20
0
/** Master V2 Protocol packet handler, for received V2 Protocol packets from a connected host.
 *  This routine decodes the issued command and passes off the handling of the command to the
 *  appropriate function.
 */
void V2Protocol_ProcessCommand(void)
{
	uint8_t V2Command = Endpoint_Read_8();

	/* Start the watchdog with timeout interrupt enabled to manage the timeout */
	TimeoutExpired = false;
	wdt_enable(WDTO_1S);
	WDTCSR |= (1 << WDIE);

	switch (V2Command)
	{
		case CMD_SIGN_ON:
			V2Protocol_SignOn();
			break;
		case CMD_SET_PARAMETER:
		case CMD_GET_PARAMETER:
			V2Protocol_GetSetParam(V2Command);
			break;
		case CMD_LOAD_ADDRESS:
			V2Protocol_LoadAddress();
			break;
		case CMD_RESET_PROTECTION:
			V2Protocol_ResetProtection();
			break;
#if defined(ENABLE_ISP_PROTOCOL)
		case CMD_ENTER_PROGMODE_ISP:
			ISPProtocol_EnterISPMode();
			break;
		case CMD_LEAVE_PROGMODE_ISP:
			ISPProtocol_LeaveISPMode();
			break;
		case CMD_PROGRAM_FLASH_ISP:
		case CMD_PROGRAM_EEPROM_ISP:
			ISPProtocol_ProgramMemory(V2Command);
			break;
		case CMD_READ_FLASH_ISP:
		case CMD_READ_EEPROM_ISP:
			ISPProtocol_ReadMemory(V2Command);
			break;
		case CMD_CHIP_ERASE_ISP:
			ISPProtocol_ChipErase();
			break;
		case CMD_READ_FUSE_ISP:
		case CMD_READ_LOCK_ISP:
		case CMD_READ_SIGNATURE_ISP:
		case CMD_READ_OSCCAL_ISP:
			ISPProtocol_ReadFuseLockSigOSCCAL(V2Command);
			break;
		case CMD_PROGRAM_FUSE_ISP:
		case CMD_PROGRAM_LOCK_ISP:
			ISPProtocol_WriteFuseLock(V2Command);
			break;
		case CMD_SPI_MULTI:
			ISPProtocol_SPIMulti();
			break;
#endif
#if defined(ENABLE_XPROG_PROTOCOL)
		case CMD_XPROG_SETMODE:
			XPROGProtocol_SetMode();
			break;
		case CMD_XPROG:
			XPROGProtocol_Command();
			break;
#endif
		default:
			V2Protocol_UnknownCommand(V2Command);
			break;
	}

	/* Disable the timeout management watchdog timer */
	wdt_disable();

	Endpoint_WaitUntilReady();
	Endpoint_SelectEndpoint(AVRISP_DATA_OUT_EPNUM);
	Endpoint_SetEndpointDirection(ENDPOINT_DIR_OUT);
}
Esempio n. 21
0
void OnyxWalker_Task(void) {

    unsigned short now = MY_GetTicks();
    if (now < lastTicks) {
        ++numWraps;
        LCD_DrawUint(numWraps, WIDTH-7, 3);
    }
    if (now - lastVolts > 15000) {
        lastVolts = now;
        ++voltBlink;
        if ((power_cvolts > 1320 && !power_failure) || (voltBlink & 1)) {
            LCD_DrawFrac(power_cvolts, 2, 0, 3);
            LCD_DrawChar(' ', 6, 3);
            LCD_DrawChar('V', 7, 3);
            PORTC &= ~(1 << 6);
        }
        else {
            LCD_DrawChar(' ', 0, 3);
            for (unsigned char i = 1; i != 8; ++i) {
                LCD_DrawChar('-', i, 3);
            }
            if (!(voltBlink & 15) && power_cvolts > 0) {
                PORTC |= (1 << 6);
            }
            else {
                PORTC &= ~(1 << 6);
            }
        }
    }
    lastTicks = now;
    LCD_Flush();
    if (lastTicks - last_cvolts > 10000) {
        power_tick();
        last_cvolts = lastTicks;
    }

    if (USB_DeviceState != DEVICE_STATE_Configured) {
        return;
    }

    /* see if host has requested data */
    Endpoint_SelectEndpoint(DATA_RX_EPNUM);
    Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
    epic = Endpoint_IsConfigured();
    epiir = epic && Endpoint_IsINReady();
    epirwa = epiir && Endpoint_IsReadWriteAllowed();
    if (epirwa && (in_packet_ptr || (now - last_flush > FLUSH_TICK_INTERVAL))) {
        last_flush = now;
        if (in_packet_ptr == 0) {
            in_packet_ptr = 1;  //  repeat the last received serial
        }
        //  send packet in
        for (unsigned char ch = 0; ch < in_packet_ptr; ++ch) {
            Endpoint_Write_8(in_packet[ch]);
        }
        Endpoint_ClearIN();
        in_packet_ptr = 0;
    }

    /* see if there's data from the host */
    Endpoint_SelectEndpoint(DATA_TX_EPNUM);
    Endpoint_SetEndpointDirection(ENDPOINT_DIR_OUT);
    MY_SetLed(LED_act, false);
    if (Endpoint_IsConfigured() && 
        Endpoint_IsOUTReceived() && 
        Endpoint_IsReadWriteAllowed()) {
        uint8_t n = Endpoint_BytesInEndpoint();
        if (n > sizeof(out_packet)) {
            MY_Failure("OUT too big", n, sizeof(out_packet));
        }
        out_packet_ptr = 0;
        MY_SetLed(LED_act, true);
        while (n > 0) {
            epic = Endpoint_Read_8();
            out_packet[out_packet_ptr++] = epic;
            --n;
        }
        Endpoint_ClearOUT();
        dispatch_out();
    }
}
Esempio n. 22
0
/** Handler for the CMD_PROGRAM_FLASH_ISP and CMD_PROGRAM_EEPROM_ISP commands, writing out bytes,
 *  words or pages of data to the attached device.
 *
 *  \param[in] V2Command  Issued V2 Protocol command byte from the host
 */
void ISPProtocol_ProgramMemory(uint8_t V2Command)
{
	struct
	{
		uint16_t BytesToWrite;
		uint8_t  ProgrammingMode;
		uint8_t  DelayMS;
		uint8_t  ProgrammingCommands[3];
		uint8_t  PollValue1;
		uint8_t  PollValue2;
		uint8_t  ProgData[256]; // Note, the Jungo driver has a very short ACK timeout period, need to buffer the
	} Write_Memory_Params;      // whole page and ACK the packet as fast as possible to prevent it from aborting
	
	Endpoint_Read_Stream_LE(&Write_Memory_Params, (sizeof(Write_Memory_Params) -
	                                               sizeof(Write_Memory_Params.ProgData)), NO_STREAM_CALLBACK);


	Write_Memory_Params.BytesToWrite = SwapEndian_16(Write_Memory_Params.BytesToWrite);
	
	if (Write_Memory_Params.BytesToWrite > sizeof(Write_Memory_Params.ProgData))
	{
		Endpoint_ClearOUT();
		Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPNUM);
		Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);

		Endpoint_Write_Byte(V2Command);
		Endpoint_Write_Byte(STATUS_CMD_FAILED);
		Endpoint_ClearIN();
		return;
	}
	
	Endpoint_Read_Stream_LE(&Write_Memory_Params.ProgData, Write_Memory_Params.BytesToWrite, NO_STREAM_CALLBACK);

	Endpoint_ClearOUT();
	Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPNUM);
	Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);

	uint8_t  ProgrammingStatus = STATUS_CMD_OK;	
	uint16_t PollAddress       = 0;
	uint8_t  PollValue         = (V2Command == CMD_PROGRAM_FLASH_ISP) ? Write_Memory_Params.PollValue1 :
	                                                                    Write_Memory_Params.PollValue2;
	uint8_t* NextWriteByte     = Write_Memory_Params.ProgData;

	/* Check the programming mode desired by the host, either Paged or Word memory writes */
	if (Write_Memory_Params.ProgrammingMode & PROG_MODE_PAGED_WRITES_MASK)
	{
		uint16_t StartAddress = (CurrentAddress & 0xFFFF);
	
		/* Check to see if we need to send a LOAD EXTENDED ADDRESS command to the target */
		if (MustLoadExtendedAddress)
		{
			ISPTarget_LoadExtendedAddress();
			MustLoadExtendedAddress = false;
		}

		/* Paged mode memory programming */
		for (uint16_t CurrentByte = 0; CurrentByte < Write_Memory_Params.BytesToWrite; CurrentByte++)
		{
			bool    IsOddByte   = (CurrentByte & 0x01);
			uint8_t ByteToWrite = *(NextWriteByte++);
		
			ISPTarget_SendByte(Write_Memory_Params.ProgrammingCommands[0]);
			ISPTarget_SendByte(CurrentAddress >> 8);
			ISPTarget_SendByte(CurrentAddress & 0xFF);
			ISPTarget_SendByte(ByteToWrite);
			
			/* AVR FLASH addressing requires us to modify the write command based on if we are writing a high
			 * or low byte at the current word address */
			if (V2Command == CMD_PROGRAM_FLASH_ISP)
			  Write_Memory_Params.ProgrammingCommands[0] ^= READ_WRITE_HIGH_BYTE_MASK;

			/* Check to see the write completion method, to see if we have a valid polling address */
			if (!(PollAddress) && (ByteToWrite != PollValue))
			{
				if (IsOddByte && (V2Command == CMD_PROGRAM_FLASH_ISP))
				  Write_Memory_Params.ProgrammingCommands[2] |= READ_WRITE_HIGH_BYTE_MASK;

				PollAddress = (CurrentAddress & 0xFFFF);				
			}		

			/* EEPROM increments the address on each byte, flash needs to increment on each word */
			if (IsOddByte || (V2Command == CMD_PROGRAM_EEPROM_ISP))
			  CurrentAddress++;
		}
		
		/* If the current page must be committed, send the PROGRAM PAGE command to the target */
		if (Write_Memory_Params.ProgrammingMode & PROG_MODE_COMMIT_PAGE_MASK)
		{
			ISPTarget_SendByte(Write_Memory_Params.ProgrammingCommands[1]);
			ISPTarget_SendByte(StartAddress >> 8);
			ISPTarget_SendByte(StartAddress & 0xFF);
			ISPTarget_SendByte(0x00);
			
			/* Check if polling is possible and enabled, if not switch to timed delay mode */
			if (!(PollAddress) && (Write_Memory_Params.ProgrammingMode & PROG_MODE_PAGED_VALUE_MASK))
			{
				Write_Memory_Params.ProgrammingMode &= ~PROG_MODE_PAGED_VALUE_MASK;
				Write_Memory_Params.ProgrammingMode |=  PROG_MODE_PAGED_TIMEDELAY_MASK;				
			}

			ProgrammingStatus = ISPTarget_WaitForProgComplete(Write_Memory_Params.ProgrammingMode, PollAddress, PollValue,
			                                                  Write_Memory_Params.DelayMS, Write_Memory_Params.ProgrammingCommands[2]);

			/* Check to see if the FLASH address has crossed the extended address boundary */
			if ((V2Command == CMD_PROGRAM_FLASH_ISP) && !(CurrentAddress & 0xFFFF))
			  MustLoadExtendedAddress = true;			
		}
Esempio n. 23
0
/** 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 = XPROG_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), NULL);
	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, NULL);

	// The driver will terminate transfers that are a round multiple of the endpoint bank in size with a ZLP, need
	// to catch this and discard it before continuing on with packet processing to prevent communication issues
	if (((sizeof(uint8_t) + sizeof(WriteMemory_XPROG_Params) - sizeof(WriteMemory_XPROG_Params.ProgData)) +
	    WriteMemory_XPROG_Params.Length) % AVRISP_DATA_EPSIZE == 0)
	{
		Endpoint_ClearOUT();
		Endpoint_WaitUntilReady();
	}

	Endpoint_ClearOUT();
	Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPADDR);
	Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);

	if (XPROG_SelectedProtocol == XPROG_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 XPROG_MEM_TYPE_APPL:
				WriteCommand     = XMEGA_NVM_CMD_WRITEAPPSECPAGE;
				break;
			case XPROG_MEM_TYPE_BOOT:
				WriteCommand     = XMEGA_NVM_CMD_WRITEBOOTSECPAGE;
				break;
			case XPROG_MEM_TYPE_EEPROM:
				WriteCommand     = XMEGA_NVM_CMD_ERASEWRITEEEPROMPAGE;
				WriteBuffCommand = XMEGA_NVM_CMD_LOADEEPROMPAGEBUFF;
				EraseBuffCommand = XMEGA_NVM_CMD_ERASEEEPROMPAGEBUFF;
				break;
			case XPROG_MEM_TYPE_USERSIG:
				WriteCommand     = XMEGA_NVM_CMD_WRITEUSERSIG;
				break;
			case XPROG_MEM_TYPE_FUSE:
				WriteCommand     = XMEGA_NVM_CMD_WRITEFUSE;
				PagedMemory      = false;
				break;
			case XPROG_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 = XPROG_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 = XPROG_ERR_TIMEOUT;
		}
	}

	Endpoint_Write_8(CMD_XPROG);
	Endpoint_Write_8(XPROG_CMD_WRITE_MEM);
	Endpoint_Write_8(ReturnStatus);
	Endpoint_ClearIN();
}
Esempio n. 24
0
/** Handler for the XPRG ERASE command to erase a specific memory address space in the attached device. */
static void XPROGProtocol_Erase(void)
{
	uint8_t ReturnStatus = XPROG_ERR_OK;

	struct
	{
		uint8_t  MemoryType;
		uint32_t Address;
	} Erase_XPROG_Params;

	Endpoint_Read_Stream_LE(&Erase_XPROG_Params, sizeof(Erase_XPROG_Params), NULL);
	Erase_XPROG_Params.Address = SwapEndian_32(Erase_XPROG_Params.Address);

	Endpoint_ClearOUT();
	Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPADDR);
	Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);

	uint8_t EraseCommand;

	if (XPROG_SelectedProtocol == XPROG_PROTOCOL_PDI)
	{
		/* Determine which NVM command to send to the device depending on the memory to erase */
		switch (Erase_XPROG_Params.MemoryType)
		{
			case XPROG_ERASE_CHIP:
				EraseCommand = XMEGA_NVM_CMD_CHIPERASE;
				break;
			case XPROG_ERASE_APP:
				EraseCommand = XMEGA_NVM_CMD_ERASEAPPSEC;
				break;
			case XPROG_ERASE_BOOT:
				EraseCommand = XMEGA_NVM_CMD_ERASEBOOTSEC;
				break;
			case XPROG_ERASE_EEPROM:
				EraseCommand = XMEGA_NVM_CMD_ERASEEEPROM;
				break;
			case XPROG_ERASE_APP_PAGE:
				EraseCommand = XMEGA_NVM_CMD_ERASEAPPSECPAGE;
				break;
			case XPROG_ERASE_BOOT_PAGE:
				EraseCommand = XMEGA_NVM_CMD_ERASEBOOTSECPAGE;
				break;
			case XPROG_ERASE_EEPROM_PAGE:
				EraseCommand = XMEGA_NVM_CMD_ERASEEEPROMPAGE;
				break;
			case XPROG_ERASE_USERSIG:
				EraseCommand = XMEGA_NVM_CMD_ERASEUSERSIG;
				break;
			default:
				EraseCommand = XMEGA_NVM_CMD_NOOP;
				break;
		}

		/* Erase the target memory, indicate timeout if occurred */
		if (!(XMEGANVM_EraseMemory(EraseCommand, Erase_XPROG_Params.Address)))
		  ReturnStatus = XPROG_ERR_TIMEOUT;
	}
	else
	{
		if (Erase_XPROG_Params.MemoryType == XPROG_ERASE_CHIP)
		  EraseCommand = TINY_NVM_CMD_CHIPERASE;
		else
		  EraseCommand = TINY_NVM_CMD_SECTIONERASE;

		/* Erase the target memory, indicate timeout if occurred */
		if (!(TINYNVM_EraseMemory(EraseCommand, Erase_XPROG_Params.Address)))
		  ReturnStatus = XPROG_ERR_TIMEOUT;
	}

	Endpoint_Write_8(CMD_XPROG);
	Endpoint_Write_8(XPROG_CMD_ERASE);
	Endpoint_Write_8(ReturnStatus);
	Endpoint_ClearIN();
}
Esempio n. 25
0
/** Handler for the CMD_ENTER_PROGMODE_ISP command, which attempts to enter programming mode on
 *  the attached device, returning success or failure back to the host.
 */
void ISPProtocol_EnterISPMode(void)
{
	struct
	{
		uint8_t TimeoutMS;
		uint8_t PinStabDelayMS;
		uint8_t ExecutionDelayMS;
		uint8_t SynchLoops;
		uint8_t ByteDelay;
		uint8_t PollValue;
		uint8_t PollIndex;
		uint8_t EnterProgBytes[4];
	} Enter_ISP_Params;
	
	Endpoint_Read_Stream_LE(&Enter_ISP_Params, sizeof(Enter_ISP_Params), NO_STREAM_CALLBACK);

	Endpoint_ClearOUT();
	Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPNUM);
	Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);

	uint8_t ResponseStatus = STATUS_CMD_FAILED;
	
	CurrentAddress = 0;
	
	/* Set up the synchronous USART to generate the .5MHz 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);

	/* Perform execution delay, initialize SPI bus */
	ISPProtocol_DelayMS(Enter_ISP_Params.ExecutionDelayMS); 
	ISPTarget_Init();

	/* Continuously attempt to synchronize with the target until either the number of attempts specified
	 * by the host has exceeded, or the the device sends back the expected response values */
	while (Enter_ISP_Params.SynchLoops-- && (ResponseStatus == STATUS_CMD_FAILED) && TimeoutTicksRemaining)
	{
		uint8_t ResponseBytes[4];

		ISPTarget_ChangeTargetResetLine(true);
		ISPProtocol_DelayMS(Enter_ISP_Params.PinStabDelayMS);

		for (uint8_t RByte = 0; RByte < sizeof(ResponseBytes); RByte++)
		{
			ISPProtocol_DelayMS(Enter_ISP_Params.ByteDelay);
			ResponseBytes[RByte] = ISPTarget_TransferByte(Enter_ISP_Params.EnterProgBytes[RByte]);
		}
		
		/* Check if polling disabled, or if the polled value matches the expected value */
		if (!(Enter_ISP_Params.PollIndex) || (ResponseBytes[Enter_ISP_Params.PollIndex - 1] == Enter_ISP_Params.PollValue))
		{
			ResponseStatus = STATUS_CMD_OK;
		}
		else
		{
			ISPTarget_ChangeTargetResetLine(false);
			ISPProtocol_DelayMS(Enter_ISP_Params.PinStabDelayMS);
		}
	}

	Endpoint_Write_Byte(CMD_ENTER_PROGMODE_ISP);
	Endpoint_Write_Byte(ResponseStatus);
	Endpoint_ClearIN();
}
Esempio n. 26
0
/** 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();
}
Esempio n. 27
0
/** Master V2 Protocol packet handler, for received V2 Protocol packets from a connected host.
 *  This routine decodes the issued command and passes off the handling of the command to the
 *  appropriate function.
 */
void V2Protocol_ProcessCommand(void)
{
	uint8_t V2Command = Endpoint_Read_Byte();

	/* Start the timeout management timer */
	TimeoutTicksRemaining = COMMAND_TIMEOUT_TICKS;
	TCCR0B = ((1 << CS02) | (1 << CS00));

	switch (V2Command)
	{
		case CMD_SIGN_ON:
			V2Protocol_SignOn();
			break;
		case CMD_SET_PARAMETER:
		case CMD_GET_PARAMETER:
			V2Protocol_GetSetParam(V2Command);
			break;
		case CMD_LOAD_ADDRESS:
			V2Protocol_LoadAddress();
			break;
		case CMD_RESET_PROTECTION:
			V2Protocol_ResetProtection();
			break;
#if defined(ENABLE_ISP_PROTOCOL)
		case CMD_ENTER_PROGMODE_ISP:
			ISPProtocol_EnterISPMode();
			break;
		case CMD_LEAVE_PROGMODE_ISP:
			ISPProtocol_LeaveISPMode();
			break;
		case CMD_PROGRAM_FLASH_ISP:
		case CMD_PROGRAM_EEPROM_ISP:
			ISPProtocol_ProgramMemory(V2Command);
			break;
		case CMD_READ_FLASH_ISP:
		case CMD_READ_EEPROM_ISP:
			ISPProtocol_ReadMemory(V2Command);
			break;
		case CMD_CHIP_ERASE_ISP:
			ISPProtocol_ChipErase();
			break;
		case CMD_READ_FUSE_ISP:
		case CMD_READ_LOCK_ISP:
		case CMD_READ_SIGNATURE_ISP:
		case CMD_READ_OSCCAL_ISP:
			ISPProtocol_ReadFuseLockSigOSCCAL(V2Command);
			break;
		case CMD_PROGRAM_FUSE_ISP:
		case CMD_PROGRAM_LOCK_ISP:
			ISPProtocol_WriteFuseLock(V2Command);
			break;
		case CMD_SPI_MULTI:
			ISPProtocol_SPIMulti();
			break;
#endif
#if defined(ENABLE_XPROG_PROTOCOL)
		case CMD_XPROG_SETMODE:
			XPROGProtocol_SetMode();
			break;
		case CMD_XPROG:
			XPROGProtocol_Command();
			break;
#endif
		default:
			V2Protocol_UnknownCommand(V2Command);
			break;
	}

	/* Disable the timeout management timer */
	TCCR0B = 0;

	Endpoint_WaitUntilReady();
	Endpoint_SelectEndpoint(AVRISP_DATA_OUT_EPNUM);
	Endpoint_SetEndpointDirection(ENDPOINT_DIR_OUT);
}
/** Handler for the CMD_ENTER_PROGMODE_ISP command, which attempts to enter programming mode on
 *  the attached device, returning success or failure back to the host.
 */
void ISPProtocol_EnterISPMode(void)
{
	struct
	{
		uint8_t TimeoutMS;
		uint8_t PinStabDelayMS;
		uint8_t ExecutionDelayMS;
		uint8_t SynchLoops;
		uint8_t ByteDelay;
		uint8_t PollValue;
		uint8_t PollIndex;
		uint8_t EnterProgBytes[4];
	} Enter_ISP_Params;

	Endpoint_Read_Stream_LE(&Enter_ISP_Params, sizeof(Enter_ISP_Params), NULL);

	Endpoint_ClearOUT();
	Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPADDR);
	Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);

	uint8_t ResponseStatus = STATUS_CMD_FAILED;

	CurrentAddress = 0;

	/* Perform execution delay, initialize SPI bus */
	ISPProtocol_DelayMS(Enter_ISP_Params.ExecutionDelayMS);
	ISPTarget_EnableTargetISP();

	ISPTarget_ChangeTargetResetLine(true);
	ISPProtocol_DelayMS(Enter_ISP_Params.PinStabDelayMS);

	/* Continuously attempt to synchronize with the target until either the number of attempts specified
	 * by the host has exceeded, or the the device sends back the expected response values */
	while (Enter_ISP_Params.SynchLoops-- && TimeoutTicksRemaining)
	{
		uint8_t ResponseBytes[4];

		for (uint8_t RByte = 0; RByte < sizeof(ResponseBytes); RByte++)
		{
			ISPProtocol_DelayMS(Enter_ISP_Params.ByteDelay);
			ResponseBytes[RByte] = ISPTarget_TransferByte(Enter_ISP_Params.EnterProgBytes[RByte]);
		}

		/* Check if polling disabled, or if the polled value matches the expected value */
		if (!(Enter_ISP_Params.PollIndex) || (ResponseBytes[Enter_ISP_Params.PollIndex - 1] == Enter_ISP_Params.PollValue))
		{
			ResponseStatus = STATUS_CMD_OK;
			break;
		}
		else
		{
			ISPTarget_ChangeTargetResetLine(false);
			ISPProtocol_DelayMS(Enter_ISP_Params.PinStabDelayMS);
			ISPTarget_ChangeTargetResetLine(true);
			ISPProtocol_DelayMS(Enter_ISP_Params.PinStabDelayMS);
		}
	}

	Endpoint_Write_8(CMD_ENTER_PROGMODE_ISP);
	Endpoint_Write_8(ResponseStatus);
	Endpoint_ClearIN();
}