/** 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(); }
/** Initializes the appropriate SPI driver (hardware or software, depending on the selected ISP speed) ready for * communication with the attached target. */ void ISPTarget_EnableTargetISP(void) { uint8_t SCKDuration = V2Params_GetParameterValue(PARAM_SCK_DURATION); if (SCKDuration < sizeof(SPIMaskFromSCKDuration)) { HardwareSPIMode = true; SPI_Init(pgm_read_byte(&SPIMaskFromSCKDuration[SCKDuration]) | SPI_ORDER_MSB_FIRST | SPI_SCK_LEAD_RISING | SPI_SAMPLE_LEADING | SPI_MODE_MASTER); } else { HardwareSPIMode = false; DDRB |= ((1 << 1) | (1 << 2)); PORTB |= ((1 << 0) | (1 << 3)); ISPTarget_ConfigureSoftwareSPI(SCKDuration); } #ifdef SELECT_TPI_MASK SELECT_TPI_DDR |= SELECT_TPI_MASK; SELECT_TPI_PORT &= ~SELECT_TPI_PORT; #endif }
/** Asserts or deasserts the target's reset line, using the correct polarity as set by the host using a SET PARAM command. * When not asserted, the line is tristated so as not to interfere with normal device operation. * * \param[in] ResetTarget Boolean true when the target should be held in reset, false otherwise */ void ISPTarget_ChangeTargetResetLine(const bool ResetTarget) { if (ResetTarget) { AUX_LINE_DDR |= AUX_LINE_MASK; if (!(V2Params_GetParameterValue(PARAM_RESET_POLARITY))) AUX_LINE_PORT |= AUX_LINE_MASK; } else { AUX_LINE_DDR &= ~AUX_LINE_MASK; AUX_LINE_PORT &= ~AUX_LINE_MASK; } }
/** Asserts or deasserts the target's reset line, using the correct polarity as set by the host using a SET PARAM command. * When not asserted, the line is tristated so as not to interfere with normal device operation. * * \param[in] ResetTarget Boolean true when the target should be held in reset, \c false otherwise */ void ISPTarget_ChangeTargetResetLine(const bool ResetTarget) { if (ResetTarget) { AUX_LINE_DDR |= AUX_LINE_MASK; if (!(V2Params_GetParameterValue(PARAM_RESET_POLARITY))) AUX_LINE_PORT |= AUX_LINE_MASK; else AUX_LINE_PORT &= ~AUX_LINE_MASK; minimizer_set_power(true); } else { minimizer_set_power(false); AUX_LINE_DDR &= ~AUX_LINE_MASK; AUX_LINE_PORT &= ~AUX_LINE_MASK; } }
/** Initialises the appropriate SPI driver (hardware or software, depending on the selected ISP speed) ready for * communication with the attached target. */ void ISPTarget_Init(void) { uint8_t SCKDuration = V2Params_GetParameterValue(PARAM_SCK_DURATION); if (SCKDuration < sizeof(SPIMaskFromSCKDuration)) { HardwareSPIMode = true; SPI_Init(pgm_read_byte(&SPIMaskFromSCKDuration[SCKDuration]) | SPI_ORDER_MSB_FIRST | SPI_SCK_LEAD_RISING | SPI_SAMPLE_LEADING | SPI_MODE_MASTER); } else { HardwareSPIMode = false; DDRB |= ((1 << 1) | (1 << 2)); PORTB |= ((1 << 0) | (1 << 3)); TIMSK1 = (1 << OCIE1A); OCR1A = pgm_read_word(&TimerCompareFromSCKDuration[SCKDuration - sizeof(SPIMaskFromSCKDuration)]); } }