From 7386afcd846cd07ba7b1c9406e74f1ca4c758668 Mon Sep 17 00:00:00 2001 From: MasterQ Date: Sat, 4 Dec 2021 11:01:07 +0100 Subject: [PATCH 01/28] Endpoint function added --- LUFA/Drivers/USB/Core/XMEGA/Endpoint_XMEGA.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/LUFA/Drivers/USB/Core/XMEGA/Endpoint_XMEGA.h b/LUFA/Drivers/USB/Core/XMEGA/Endpoint_XMEGA.h index 990620eaec..fc33278af9 100644 --- a/LUFA/Drivers/USB/Core/XMEGA/Endpoint_XMEGA.h +++ b/LUFA/Drivers/USB/Core/XMEGA/Endpoint_XMEGA.h @@ -444,6 +444,17 @@ return (USB_Endpoint_SelectedEndpoint & ENDPOINT_DIR_IN); } + /** Sets the direction of the currently selected endpoint. + * + * \param[in] DirectionMask New endpoint direction, as a \c ENDPOINT_DIR_* mask. + */ + static inline void Endpoint_SetEndpointDirection(const uint8_t DirectionMask) ATTR_ALWAYS_INLINE; + static inline void Endpoint_SetEndpointDirection(const uint8_t DirectionMask) + { +// UECFG0X = ((UECFG0X & ~(1 << EPDIR)) | (DirectionMask ? (1 << EPDIR) : 0)); + USB_Endpoint_SelectedEndpoint = (USB_Endpoint_SelectedEndpoint & ~ENDPOINT_DIR_IN) | DirectionMask; + } + /** Reads one byte from the currently selected endpoint's bank, for OUT direction endpoints. * * \ingroup Group_EndpointPrimitiveRW_XMEGA From b2590d1cfa5efda25779c1ee886bfc6088b11050 Mon Sep 17 00:00:00 2001 From: MasterQ Date: Sat, 4 Dec 2021 11:27:03 +0100 Subject: [PATCH 02/28] Ported a lot to xmega, compiling and USB detection works, tested pdi protocol with result: trying to program but not work --- Projects/AVRISP-MKII/AVRISP-MKII.c | 9 ++ Projects/AVRISP-MKII/Config/AppConfig.h | 73 +++++++++-- Projects/AVRISP-MKII/Config/LUFAConfig.h | 33 +++++ Projects/AVRISP-MKII/Lib/ISP/ISPProtocol.c | 16 ++- Projects/AVRISP-MKII/Lib/ISP/ISPTarget.c | 121 ++++++++++++++++++- Projects/AVRISP-MKII/Lib/ISP/ISPTarget.h | 14 ++- Projects/AVRISP-MKII/Lib/V2Protocol.c | 28 ++++- Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c | 114 ++++++++++++++++- Projects/AVRISP-MKII/makefile | 12 +- 9 files changed, 391 insertions(+), 29 deletions(-) diff --git a/Projects/AVRISP-MKII/AVRISP-MKII.c b/Projects/AVRISP-MKII/AVRISP-MKII.c index 4539619f6b..d1cf410d8e 100644 --- a/Projects/AVRISP-MKII/AVRISP-MKII.c +++ b/Projects/AVRISP-MKII/AVRISP-MKII.c @@ -80,6 +80,15 @@ void SetupHardware(void) /* Disable clock division */ clock_prescale_set(clock_div_1); +#elif (ARCH == ARCH_XMEGA) + XMEGACLK_StartPLL(CLOCK_SRC_INT_RC2MHZ, 2000000, F_CPU); + XMEGACLK_SetCPUClockSource(CLOCK_SRC_PLL); + + // Start the 32MHz internal RC oscillator and start the DFLL to increase it to F_USB using the USB SOF as a reference + XMEGACLK_StartInternalOscillator(CLOCK_SRC_INT_RC32MHZ); + XMEGACLK_StartDFLL(CLOCK_SRC_INT_RC32MHZ, DFLL_REF_INT_USBSOF, F_USB); + PMIC.CTRL = PMIC_LOLVLEN_bm | PMIC_MEDLVLEN_bm | PMIC_HILVLEN_bm; + sei(); #endif /* Hardware Initialization */ diff --git a/Projects/AVRISP-MKII/Config/AppConfig.h b/Projects/AVRISP-MKII/Config/AppConfig.h index 245b6ab44d..8bee5f7ad8 100644 --- a/Projects/AVRISP-MKII/Config/AppConfig.h +++ b/Projects/AVRISP-MKII/Config/AppConfig.h @@ -42,27 +42,78 @@ #ifndef _APP_CONFIG_H_ #define _APP_CONFIG_H_ + #if (ARCH == ARCH_AVR8) + #define AUX_LINE_PORT PORTB + #define AUX_LINE_PIN PINB + #define AUX_LINE_DDR DDRB + #if (BOARD == BOARD_U2S) + #define AUX_LINE_MASK (1 << 0) + #else + #define AUX_LINE_MASK (1 << 4) + #endif + #define VTARGET_ADC_CHANNEL 2 + #define VTARGET_REF_VOLTS 5 + #define VTARGET_SCALE_FACTOR 1 +// #define VTARGET_USE_INTERNAL_REF + #elif (ARCH == ARCH_XMEGA) + #define SPI_REG SPIC + #define SPI_PORT PORTC - #define AUX_LINE_PORT PORTB - #define AUX_LINE_PIN PINB - #define AUX_LINE_DDR DDRB - #if (BOARD == BOARD_U2S) + #define SPI_SCK_MASK (1 << 7) + #define SPI_SCK_CTRL PIN7CTRL + + #define SPI_MISO_MASK (1 << 6) + #define SPI_MISO_CTRL PIN6CTRL + + #define SPI_MOSI_MASK (1 << 5) + #define SPI_MOSI_CTRL PIN5CTRL + + #define SPI_RST_MASK (1 << 4) + #define SPI_RST_CTRL PIN4CTRL + + #define RESCUE_PORT PORTD + #define RESCUE_TIMER TCD0 + #define RESCUE_PIN_MASK (1 << 0) + #define RESCUE_TIMER_CMP_EN TC0_CCAEN_bm //A if pin 0, B if pin 1... + #define RESCUE_TIMER_CMP_REG CCA + + #define PDI_USART USARTC0 + #define PDI_PORT PORTC + #define PDI_RX_MASK (1 << 2) + #define PDI_RX_CTRL PIN1CTRL + + #define PDI_TX_MASK (1 << 3) + #define PDI_TX_CTRL PIN3CTRL + + #define PDI_XCK_MASK (1 << 1) + #define PDI_XCK_CTRL PIN1CTRL + + #define AUX_LINE_PORT PORTC #define AUX_LINE_MASK (1 << 0) - #else - #define AUX_LINE_MASK (1 << 4) - #endif + #define AUX_LINE_CTRL PIN0CTRL + + #define DELAY_TIMER TCC0 + #define DELAY_TIMER_OVF_vect TCC0_OVF_vect + #define SW_SPI_TIMER TCC1 + #define SW_SPI_TIMER_CCA_vect TCC1_CCA_vect + #define SW_SPI_TIMER_OVF_vect TCC1_OVF_vect + #define SW_SPI_PIN_IRQ_vect PORTC_INT0_vect + #define VTARGET_ADC_CHANNEL 2 //Unimplemented + #define VTARGET_REF_VOLTS 5 //Unimplemented + #define VTARGET_SCALE_FACTOR 1 //Unimplemented + #endif #define ENABLE_ISP_PROTOCOL #define ENABLE_XPROG_PROTOCOL - #define VTARGET_ADC_CHANNEL 2 - #define VTARGET_REF_VOLTS 5 - #define VTARGET_SCALE_FACTOR 1 -// #define VTARGET_USE_INTERNAL_REF + + #define NO_VTARGET_DETECT // #define XCK_RESCUE_CLOCK_ENABLE // #define INVERTED_ISP_MISO +// #define LIBUSB_DRIVER_COMPAT +// #define RESET_TOGGLES_LIBUSB_COMPAT // #define FIRMWARE_VERSION_MINOR 0x11 #endif diff --git a/Projects/AVRISP-MKII/Config/LUFAConfig.h b/Projects/AVRISP-MKII/Config/LUFAConfig.h index 811d0fd8f6..bb53ba6f78 100644 --- a/Projects/AVRISP-MKII/Config/LUFAConfig.h +++ b/Projects/AVRISP-MKII/Config/LUFAConfig.h @@ -85,6 +85,39 @@ // #define NO_AUTO_VBUS_MANAGEMENT // #define INVERTED_VBUS_ENABLE_LINE + #elif (ARCH == ARCH_XMEGA) + + /* Non-USB Related Configuration Tokens: */ +// #define DISABLE_TERMINAL_CODES + #define ORDERED_EP_CONFIG + /* USB Class Driver Related Tokens: */ +// #define HID_HOST_BOOT_PROTOCOL_ONLY +// #define HID_STATETABLE_STACK_DEPTH {Insert Value Here} +// #define HID_USAGE_STACK_DEPTH {Insert Value Here} +// #define HID_MAX_COLLECTIONS {Insert Value Here} +// #define HID_MAX_REPORTITEMS {Insert Value Here} +// #define HID_MAX_REPORT_IDS {Insert Value Here} +// #define NO_CLASS_DRIVER_AUTOFLUSH + + /* General USB Driver Related Tokens: */ + #define USE_STATIC_OPTIONS (USB_DEVICE_OPT_FULLSPEED | USB_OPT_RC32MCLKSRC | USB_OPT_BUSEVENT_PRIHIGH) +// #define USB_STREAM_TIMEOUT_MS {Insert Value Here} +// #define NO_LIMITED_CONTROLLER_CONNECT + #define NO_SOF_EVENTS + + /* USB Device Mode Driver Related Tokens: */ +// #define USE_RAM_DESCRIPTORS + #define USE_FLASH_DESCRIPTORS +// #define USE_EEPROM_DESCRIPTORS + #define NO_INTERNAL_SERIAL + #define FIXED_CONTROL_ENDPOINT_SIZE 16 + #define DEVICE_STATE_AS_GPIOR 0 + #define FIXED_NUM_CONFIGURATIONS 1 +// #define CONTROL_ONLY_DEVICE + #define MAX_ENDPOINT_INDEX 4 +// #define NO_DEVICE_REMOTE_WAKEUP +// #define NO_DEVICE_SELF_POWER + #else #error Unsupported architecture for this LUFA configuration file. diff --git a/Projects/AVRISP-MKII/Lib/ISP/ISPProtocol.c b/Projects/AVRISP-MKII/Lib/ISP/ISPProtocol.c index 2e93139fb3..f742b29e7e 100644 --- a/Projects/AVRISP-MKII/Lib/ISP/ISPProtocol.c +++ b/Projects/AVRISP-MKII/Lib/ISP/ISPProtocol.c @@ -47,14 +47,26 @@ static volatile uint8_t ISPProtocol_ResponseTogglesRemaining; /** ISR to toggle MOSI pin when TIMER1 overflows */ +#if ARCH == ARCH_AVR8 ISR(TIMER1_OVF_vect, ISR_BLOCK) { PINB |= (1 << PB2); // toggle PB2 (MOSI) by writing 1 to its bit in PINB ISPProtocol_HalfCyclesRemaining--; } +#elif (ARCH == ARCH_XMEGA) +ISR(SW_SPI_TIMER_OVF_vect, ISR_BLOCK) +{ + SPI_PORT.OUTTGL = SPI_MOSI_MASK; + ISPProtocol_HalfCyclesRemaining--; +} +#endif /** ISR to listen for toggles on MISO pin */ +#if ARCH == ARCH_AVR8 ISR(PCINT0_vect, ISR_BLOCK) +#elif (ARCH == ARCH_XMEGA) +ISR(SW_SPI_PIN_IRQ_vect, ISR_BLOCK) +#endif { ISPProtocol_ResponseTogglesRemaining--; } @@ -420,6 +432,8 @@ void ISPProtocol_Calibrate(void) Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPADDR); Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN); + //TODO: Learn it and implement it... +#if ARCH == ARCH_AVR8 /* Enable pull-up on MISO and release ~RESET */ DDRB = ~(1 << PB3); PORTB |= ( (1 << PB4) | (1 << PB3) ); @@ -455,7 +469,7 @@ void ISPProtocol_Calibrate(void) /* Check if device responded with a success message or if we timed out */ if (ISPProtocol_ResponseTogglesRemaining) ResponseStatus = STATUS_CMD_TOUT; - +#endif /* Report back to PC via USB */ Endpoint_Write_8(CMD_OSCCAL); Endpoint_Write_8(ResponseStatus); diff --git a/Projects/AVRISP-MKII/Lib/ISP/ISPTarget.c b/Projects/AVRISP-MKII/Lib/ISP/ISPTarget.c index b6f6369329..d9dcf999ac 100644 --- a/Projects/AVRISP-MKII/Lib/ISP/ISPTarget.c +++ b/Projects/AVRISP-MKII/Lib/ISP/ISPTarget.c @@ -59,6 +59,14 @@ static const uint8_t SPIMaskFromSCKDuration[] PROGMEM = SPI_SPEED_FCPU_DIV_32, // AVRStudio = 500KHz SPI, Actual = 500KHz SPI SPI_SPEED_FCPU_DIV_64, // AVRStudio = 250KHz SPI, Actual = 250KHz SPI SPI_SPEED_FCPU_DIV_128 // AVRStudio = 125KHz SPI, Actual = 125KHz SPI +#elif (F_CPU == 32000000) + SPI_SPEED_FCPU_DIV_4, // AVRStudio = 8MHz SPI, Actual = 8MHz SPI + SPI_SPEED_FCPU_DIV_8, // AVRStudio = 4MHz SPI, Actual = 4MHz SPI + SPI_SPEED_FCPU_DIV_16, // AVRStudio = 2MHz SPI, Actual = 2MHz SPI + SPI_SPEED_FCPU_DIV_32, // AVRStudio = 1MHz SPI, Actual = 1MHz SPI + SPI_SPEED_FCPU_DIV_64, // AVRStudio = 500KHz SPI, Actual = 500KHz SPI + SPI_SPEED_FCPU_DIV_128, // AVRStudio = 250KHz SPI, Actual = 250KHz SPI + SPI_SPEED_FCPU_DIV_128, //TODO: Incomplete table #else #error No SPI prescaler masks for chosen F_CPU speed. #endif @@ -115,6 +123,7 @@ static volatile uint8_t ISPTarget_SoftSPI_BitsRemaining; /** ISR to handle software SPI transmission and reception */ +#if ARCH == ARCH_AVR8 ISR(TIMER1_COMPA_vect, ISR_BLOCK) { /* Check if rising edge (output next bit) or falling edge (read in next bit) */ @@ -142,6 +151,34 @@ ISR(TIMER1_COMPA_vect, ISR_BLOCK) /* Fast toggle of PORTB.1 via the PIN register (see datasheet) */ PINB |= (1 << 1); } +#elif ARCH == ARCH_XMEGA +ISR(TCC1_CCA_vect, ISR_BLOCK) +{ + /* Check if rising edge (output next bit) or falling edge (read in next bit) */ + if (!(SPI_PORT.IN & SPI_SCK_MASK)) + { + if (ISPTarget_SoftSPI_Data & (1 << 7)) + SPI_PORT.OUTSET = SPI_MOSI_MASK; + else + SPI_PORT.OUTCLR = SPI_MOSI_MASK; + } + else + { + ISPTarget_SoftSPI_Data <<= 1; + + if (!(--ISPTarget_SoftSPI_BitsRemaining)) + { + SW_SPI_TIMER.CTRLA = TC_CLKSEL_OFF_gc; + SW_SPI_TIMER.INTCTRLA = TC0_OVFIF_bm; + } + + if (SPI_PORT.IN & SPI_MISO_MASK) + ISPTarget_SoftSPI_Data |= (1 << 0); + } + + SPI_PORT.OUTTGL = SPI_SCK_MASK; +} +#endif /** Initializes the appropriate SPI driver (hardware or software, depending on the selected ISP speed) ready for * communication with the attached target. @@ -153,17 +190,26 @@ void ISPTarget_EnableTargetISP(void) if (SCKDuration < sizeof(SPIMaskFromSCKDuration)) { ISPTarget_HardwareSPIMode = true; - +#if (ARCH == ARCH_AVR8) SPI_Init(pgm_read_byte(&SPIMaskFromSCKDuration[SCKDuration]) | SPI_ORDER_MSB_FIRST | SPI_SCK_LEAD_RISING | SPI_SAMPLE_LEADING | SPI_MODE_MASTER); +#elif (ARCH == XMEGA) + SPI_Init(&SPI_REG, pgm_read_byte(&SPI_PORT, &SPIMaskFromSCKDuration[SCKDuration]) | SPI_ORDER_MSB_FIRST | + SPI_SCK_LEAD_RISING | SPI_SAMPLE_LEADING | SPI_MODE_MASTER); +#endif } else { ISPTarget_HardwareSPIMode = false; - DDRB |= ((1 << 1) | (1 << 2)); - PORTB |= ((1 << 0) | (1 << 3)); - +#if ARCH == ARCH_AVR8 + DDRB |= ((1 << 1) | (1 << 2)); //MOSI and SCK High + PORTB |= ((1 << 0) | (1 << 3)); //Pullup on RST and MISO +#elif (ARCH == ARCH_XMEGA) + SPI_PORT.DIRSET = SPI_SCK_MASK | SPI_MOSI_MASK; + SPI_PORT.SPI_RST_CTRL = PORT_OPC_PULLUP_gc; + SPI_PORT.SPI_MISO_CTRL = PORT_OPC_PULLUP_gc; +#endif ISPTarget_ConfigureSoftwareSPI(SCKDuration); } } @@ -173,6 +219,7 @@ void ISPTarget_EnableTargetISP(void) */ void ISPTarget_DisableTargetISP(void) { +#if (ARCH == ARCH_AVR8) if (ISPTarget_HardwareSPIMode) { SPI_Disable(); @@ -186,6 +233,22 @@ void ISPTarget_DisableTargetISP(void) * re-purposed for software SPI */ ISPTarget_ConfigureRescueClock(); } +#elif (ARCH == ARCH_XMEGA) + if (ISPTarget_HardwareSPIMode) + { + SPI_Disable(&SPI_REG); + } + else + { + SPI_PORT.DIRCLR = SPI_SCK_MASK | SPI_MOSI_MASK; + SPI_PORT.SPI_RST_CTRL &= ~PORT_OPC_PULLUP_gc; + SPI_PORT.SPI_MOSI_CTRL &= ~PORT_OPC_PULLUP_gc; + + /* Must re-enable rescue clock once software ISP has exited, as the timer for the rescue clock is + * re-purposed for software SPI */ + ISPTarget_ConfigureRescueClock(); + } +#endif } /** Configures the AVR to produce a 4MHz rescue clock out of the OCR1A pin of the AVR, so @@ -195,6 +258,7 @@ void ISPTarget_DisableTargetISP(void) */ void ISPTarget_ConfigureRescueClock(void) { +#if (ARCH == ARCH_AVR8) #if defined(XCK_RESCUE_CLOCK_ENABLE) /* Configure XCK as an output for the specified AVR model */ DDRD |= (1 << 5); @@ -218,6 +282,17 @@ void ISPTarget_ConfigureRescueClock(void) TCCR1A = (1 << COM1A0); TCCR1B = ((1 << WGM12) | (1 << CS10)); #endif +#elif (ARCH == ARCH_XMEGA) + #if defined(XCK_RESCUE_CLOCK_ENABLE) + #warning "XCK Rescue clock not implemented for xmega falling back to default" + #endif + RESCUE_PORT.DIRSET = RESCUE_PIN_MASK; + RESCUE_PORT.OUTSET = RESCUE_PIN_MASK; + RESCUE_TIMER.CTRLA = TC_CLKSEL_DIV1_gc; + RESCUE_TIMER.CTRLB = TC_WGMODE_SINGLESLOPE_gc | RESCUE_TIMER_CMP_EN; + RESCUE_TIMER.RESCUE_TIMER_CMP_REG = (F_CPU / 2 / ISP_RESCUE_CLOCK_SPEED); + RESCUE_TIMER.PER = (F_CPU / ISP_RESCUE_CLOCK_SPEED) - 1; +#endif } /** Configures the AVR's timer ready to produce software SPI for the slower ISP speeds that @@ -227,12 +302,20 @@ void ISPTarget_ConfigureRescueClock(void) */ void ISPTarget_ConfigureSoftwareSPI(const uint8_t SCKDuration) { +#if ARCH == ARCH_AVR8 /* Configure Timer 1 for software SPI using the specified SCK duration */ TIMSK1 = (1 << OCIE1A); TCNT1 = 0; OCR1A = pgm_read_word(&TimerCompareFromSCKDuration[SCKDuration - sizeof(SPIMaskFromSCKDuration)]); TCCR1A = 0; TCCR1B = 0; +#elif (ARCH == ARCH_XMEGA) + SW_SPI_TIMER.CTRLA = TC_CLKSEL_OFF_gc; + SW_SPI_TIMER.INTCTRLA = TC_OVFINTLVL_OFF_gc; + SW_SPI_TIMER.CNT = 0; + SW_SPI_TIMER.PER = pgm_read_word(&TimerCompareFromSCKDuration[SCKDuration - sizeof(SPIMaskFromSCKDuration)]); + SW_SPI_TIMER.CTRLB = TC_WGMODE_NORMAL_gc; +#endif } /** Sends and receives a single byte of data to and from the attached target via software SPI. @@ -246,6 +329,7 @@ uint8_t ISPTarget_TransferSoftSPIByte(const uint8_t Byte) ISPTarget_SoftSPI_Data = Byte; ISPTarget_SoftSPI_BitsRemaining = 8; +#if ARCH == ARCH_AVR8 /* Set initial MOSI pin state according to the byte to be transferred */ if (ISPTarget_SoftSPI_Data & (1 << 7)) PORTB |= (1 << 2); @@ -256,7 +340,18 @@ uint8_t ISPTarget_TransferSoftSPIByte(const uint8_t Byte) TCCR1B = ((1 << WGM12) | (1 << CS11)); while (ISPTarget_SoftSPI_BitsRemaining && TimeoutTicksRemaining); TCCR1B = 0; +#elif (ARCH == ARCH_XMEGA) + if (ISPTarget_SoftSPI_Data & (1 << 7)) + SPI_PORT.OUTSET = SPI_MOSI_MASK; + else + SPI_PORT.OUTCLR = SPI_MOSI_MASK; + SW_SPI_TIMER.CTRLA = TC_CLKSEL_OFF_gc; + SW_SPI_TIMER.CNT = 0; + SW_SPI_TIMER.CTRLA = TC_CLKSEL_DIV64_gc; //TODO: Wrong? + while (ISPTarget_SoftSPI_BitsRemaining && TimeoutTicksRemaining); + SW_SPI_TIMER.CTRLA = TC_CLKSEL_OFF_gc; +#endif return ISPTarget_SoftSPI_Data; } @@ -267,6 +362,7 @@ uint8_t ISPTarget_TransferSoftSPIByte(const uint8_t Byte) */ void ISPTarget_ChangeTargetResetLine(const bool ResetTarget) { +#if (ARCH == ARCH_AVR8) if (ResetTarget) { AUX_LINE_DDR |= AUX_LINE_MASK; @@ -281,6 +377,23 @@ void ISPTarget_ChangeTargetResetLine(const bool ResetTarget) AUX_LINE_DDR &= ~AUX_LINE_MASK; AUX_LINE_PORT &= ~AUX_LINE_MASK; } +#elif (ARCH == ARCH_XMEGA) + if (ResetTarget) + { + AUX_LINE_PORT.DIRSET = AUX_LINE_MASK; + + if (!(V2Params_GetParameterValue(PARAM_RESET_POLARITY))) + AUX_LINE_PORT.OUTSET = AUX_LINE_MASK; + else + AUX_LINE_PORT.OUTCLR = AUX_LINE_MASK; + } + else + { + AUX_LINE_PORT.DIRCLR = AUX_LINE_MASK; + AUX_LINE_PORT.OUTCLR = AUX_LINE_MASK; + AUX_LINE_PORT.AUX_LINE_CTRL &= ~PORT_OPC_PULLUP_gc; + } +#endif } /** Waits until the target has completed the last operation, by continuously polling the device's diff --git a/Projects/AVRISP-MKII/Lib/ISP/ISPTarget.h b/Projects/AVRISP-MKII/Lib/ISP/ISPTarget.h index 3b43ef581c..0c99bccbfe 100644 --- a/Projects/AVRISP-MKII/Lib/ISP/ISPTarget.h +++ b/Projects/AVRISP-MKII/Lib/ISP/ISPTarget.h @@ -94,7 +94,11 @@ static inline void ISPTarget_SendByte(const uint8_t Byte) { if (ISPTarget_HardwareSPIMode) + #if (ARCH == ARCH_XMEGA) + SPI_SendByte(&SPI_REG, Byte); + #else SPI_SendByte(Byte); + #endif else ISPTarget_TransferSoftSPIByte(Byte); } @@ -109,7 +113,11 @@ uint8_t ReceivedByte; if (ISPTarget_HardwareSPIMode) + #if (ARCH == ARCH_XMEGA) + ReceivedByte = SPI_ReceiveByte(&SPI_REG); + #else ReceivedByte = SPI_ReceiveByte(); + #endif else ReceivedByte = ISPTarget_TransferSoftSPIByte(0x00); @@ -132,7 +140,11 @@ uint8_t ReceivedByte; if (ISPTarget_HardwareSPIMode) - ReceivedByte = SPI_TransferByte(Byte); + #if (ARCH == ARCH_XMEGA) + ReceivedByte = SPI_ReceiveByte(&SPI_REG); + #else + ReceivedByte = SPI_ReceiveByte(); + #endif else ReceivedByte = ISPTarget_TransferSoftSPIByte(Byte); diff --git a/Projects/AVRISP-MKII/Lib/V2Protocol.c b/Projects/AVRISP-MKII/Lib/V2Protocol.c index 8fee1d63b5..d01249985c 100644 --- a/Projects/AVRISP-MKII/Lib/V2Protocol.c +++ b/Projects/AVRISP-MKII/Lib/V2Protocol.c @@ -42,7 +42,7 @@ uint32_t CurrentAddress; /** Flag to indicate that the next read/write operation must update the device's current extended FLASH address */ bool MustLoadExtendedAddress; - +#if ARCH == ARCH_AVR8 /** ISR to manage timeouts whilst processing a V2Protocol command */ ISR(TIMER0_COMPA_vect, ISR_NOBLOCK) { @@ -51,6 +51,15 @@ ISR(TIMER0_COMPA_vect, ISR_NOBLOCK) else TCCR0B = 0; } +#elif ARCH == ARCH_XMEGA +ISR(DELAY_TIMER_OVF_vect, ISR_NOBLOCK) +{ + if (TimeoutTicksRemaining) + TimeoutTicksRemaining--; + else + DELAY_TIMER.CTRLA = TC_CLKSEL_OFF_gc; +} +#endif /** Initializes the hardware and software associated with the V2 protocol command handling. */ void V2Protocol_Init(void) @@ -63,9 +72,15 @@ void V2Protocol_Init(void) #endif /* Timeout timer initialization (~10ms period) */ +#if ARCH == ARCH_AVR8 OCR0A = (((F_CPU / 1024) / 100) - 1); TCCR0A = (1 << WGM01); TIMSK0 = (1 << OCIE0A); +#elif ARCH == ARCH_XMEGA + DELAY_TIMER.PER = (((F_CPU / 1024) / 100) - 1); + DELAY_TIMER.CTRLB = TC_WGMODE_NORMAL_gc; + DELAY_TIMER.INTCTRLA = TC_OVFINTLVL_MED_gc; +#endif V2Params_LoadNonVolatileParamValues(); @@ -84,8 +99,11 @@ void V2Protocol_ProcessCommand(void) /* Reset timeout counter duration and start the timer */ TimeoutTicksRemaining = COMMAND_TIMEOUT_TICKS; +#if ARCH == ARCH_AVR8 TCCR0B = ((1 << CS02) | (1 << CS00)); - +#elif ARCH == ARCH_XMEGA + TCD0.CTRLA = TC_CLKSEL_DIV1024_gc; +#endif switch (V2Command) { case CMD_SIGN_ON: @@ -150,8 +168,12 @@ void V2Protocol_ProcessCommand(void) } /* Disable the timeout management timer */ +#if ARCH == ARCH_AVR8 TCCR0B = 0; - +#elif ARCH == ARCH_XMEGA + DELAY_TIMER.CTRLA = TC_CLKSEL_OFF_gc; +#endif + Endpoint_WaitUntilReady(); Endpoint_SelectEndpoint(AVRISP_DATA_OUT_EPADDR); Endpoint_SetEndpointDirection(ENDPOINT_DIR_OUT); diff --git a/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c b/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c index ce3d75983c..82427350f2 100644 --- a/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c +++ b/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c @@ -45,7 +45,7 @@ static bool IsSending; void XPROGTarget_EnableTargetPDI(void) { IsSending = false; - +#if (ARCH == ARCH_AVR8) /* Set Tx and XCK as outputs, Rx as input */ DDRD |= (1 << 5) | (1 << 3); DDRD &= ~(1 << 2); @@ -64,6 +64,24 @@ void XPROGTarget_EnableTargetPDI(void) UCSR1B = (1 << TXEN1); UCSR1C = (1 << UMSEL10) | (1 << UPM11) | (1 << USBS1) | (1 << UCSZ11) | (1 << UCSZ10) | (1 << UCPOL1); + +#elif (ARCH == ARCH_XMEGA) + /* Set Tx and XCK as outputs, Rx as input */ + PDI_PORT.DIRSET = PDI_TX_MASK | PDI_XCK_MASK; + PDI_PORT.DIRCLR = PDI_RX_MASK; + _delay_us(100); + + /* Set DATA line high for at least 90ns to disable /RESET functionality */ + PDI_PORT.OUTSET = PDI_TX_MASK; + _delay_us(20); + + /* Set up the synchronous USART for XMEGA communications - 8 data bits, even parity, 2 stop bits */ + PDI_USART.BAUDCTRLA = ((((uint32_t)F_CPU * 2) + XPROG_HARDWARE_SPEED*8)/(XPROG_HARDWARE_SPEED*16) - 1) & 0xFF; + PDI_USART.BAUDCTRLB = ((((uint32_t)F_CPU * 2) + XPROG_HARDWARE_SPEED*8)/(XPROG_HARDWARE_SPEED*16) - 1) >> 8; + PDI_USART.CTRLA = 0; //USART_RXCINTLVL_MED_gc | USART_TXCINTLVL_MED_gc | USART_DREINTLVL_MED_gc //TODO: Enable interrups + PDI_USART.CTRLB = USART_TXEN_bm | USART_CLK2X_bm; + PDI_USART.CTRLC = USART_CMODE_SYNCHRONOUS_gc | USART_PMODE_EVEN_gc | USART_SBMODE_bm | USART_CHSIZE_8BIT_gc; +#endif /* Send two IDLEs of 12 bits each to enable PDI interface (need at least 16 idle bits) */ XPROGTarget_SendIdle(); XPROGTarget_SendIdle(); @@ -74,6 +92,7 @@ void XPROGTarget_EnableTargetTPI(void) { IsSending = false; +#if (ARCH == ARCH_AVR8) /* Set /RESET line low for at least 400ns to enable TPI functionality */ AUX_LINE_DDR |= AUX_LINE_MASK; AUX_LINE_PORT &= ~AUX_LINE_MASK; @@ -87,7 +106,23 @@ void XPROGTarget_EnableTargetTPI(void) UBRR1 = ((F_CPU / 2 / XPROG_HARDWARE_SPEED) - 1); UCSR1B = (1 << TXEN1); UCSR1C = (1 << UMSEL10) | (1 << UPM11) | (1 << USBS1) | (1 << UCSZ11) | (1 << UCSZ10) | (1 << UCPOL1); +#elif (ARCH == ARCH_XMEGA) + /* Set /RESET line low for at least 400ns to enable TPI functionality */ + AUX_LINE_PORT.DIRSET = AUX_LINE_MASK; + AUX_LINE_PORT.OUTCLR = AUX_LINE_MASK; + _delay_us(100); + + /* Set Tx and XCK as outputs, Rx as input */ + PDI_PORT.DIRSET = PDI_TX_MASK | PDI_XCK_MASK; + PDI_PORT.DIRCLR = PDI_RX_MASK; + /* Set up the synchronous USART for TPI communications - 8 data bits, even parity, 2 stop bits */ + PDI_USART.BAUDCTRLA = ((((uint32_t)F_CPU * 2) + XPROG_HARDWARE_SPEED*8)/(XPROG_HARDWARE_SPEED*16) - 1) & 0xFF; + PDI_USART.BAUDCTRLB = ((((uint32_t)F_CPU * 2) + XPROG_HARDWARE_SPEED*8)/(XPROG_HARDWARE_SPEED*16) - 1) >> 8; + PDI_USART.CTRLA = 0; //USART_RXCINTLVL_MED_gc | USART_TXCINTLVL_MED_gc | USART_DREINTLVL_MED_gc //TODO: Enable interrups + PDI_USART.CTRLB = USART_TXEN_bm | USART_CLK2X_bm; + PDI_USART.CTRLC = USART_CMODE_SYNCHRONOUS_gc | USART_PMODE_EVEN_gc | USART_SBMODE_bm | USART_CHSIZE_8BIT_gc; +#endif /* Send two IDLEs of 12 bits each to enable TPI interface (need at least 16 idle bits) */ XPROGTarget_SendIdle(); XPROGTarget_SendIdle(); @@ -100,6 +135,7 @@ void XPROGTarget_DisableTargetPDI(void) if (IsSending) XPROGTarget_SetRxMode(); +#if (ARCH == ARCH_AVR8) /* Turn off receiver and transmitter of the USART, clear settings */ UCSR1A = ((1 << TXC1) | (1 << RXC1)); UCSR1B = 0; @@ -108,6 +144,19 @@ void XPROGTarget_DisableTargetPDI(void) /* Tristate all pins */ DDRD &= ~((1 << 5) | (1 << 3)); PORTD &= ~((1 << 5) | (1 << 3) | (1 << 2)); +#elif (ARCH == ARCH_XMEGA) + /* Turn off receiver and transmitter of the USART, clear settings */ + PDI_USART.STATUS = USART_RXCIF_bm | USART_TXCIF_bm; + PDI_USART.CTRLA = 0; + PDI_USART.CTRLB = 0; + PDI_USART.CTRLC = 0; + + /* Tristate all pins */ + PDI_PORT.DIRCLR = PDI_TX_MASK | PDI_XCK_MASK; + PDI_PORT.PDI_XCK_CTRL &= ~PORT_OPC_PULLUP_gc; + PDI_PORT.PDI_TX_CTRL &= ~PORT_OPC_PULLUP_gc; + PDI_PORT.PDI_RX_CTRL &= ~PORT_OPC_PULLUP_gc; +#endif } /** Disables the target's TPI interface, exits programming mode and starts the target's application. */ @@ -117,6 +166,7 @@ void XPROGTarget_DisableTargetTPI(void) if (IsSending) XPROGTarget_SetRxMode(); +#if (ARCH == ARCH_AVR8) /* Turn off receiver and transmitter of the USART, clear settings */ UCSR1A |= (1 << TXC1) | (1 << RXC1); UCSR1B = 0; @@ -129,6 +179,23 @@ void XPROGTarget_DisableTargetTPI(void) /* Tristate target /RESET line */ AUX_LINE_DDR &= ~AUX_LINE_MASK; AUX_LINE_PORT &= ~AUX_LINE_MASK; +#elif (ARCH == ARCH_XMEGA) + /* Turn off receiver and transmitter of the USART, clear settings */ + PDI_USART.STATUS = USART_RXCIF_bm | USART_TXCIF_bm; + PDI_USART.CTRLA = 0; + PDI_USART.CTRLB = 0; + PDI_USART.CTRLC = 0; + + /* Tristate all pins */ + PDI_PORT.DIRCLR = PDI_TX_MASK | PDI_XCK_MASK; + PDI_PORT.PDI_XCK_CTRL &= ~PORT_OPC_PULLUP_gc; + PDI_PORT.PDI_TX_CTRL &= ~PORT_OPC_PULLUP_gc; + PDI_PORT.PDI_RX_CTRL &= ~PORT_OPC_PULLUP_gc; + + AUX_LINE_PORT.DIRCLR = AUX_LINE_MASK; + AUX_LINE_PORT.OUTCLR = AUX_LINE_MASK; + AUX_LINE_PORT.AUX_LINE_CTRL &= ~PORT_OPC_PULLUP_gc; +#endif } /** Sends a byte via the USART. @@ -142,9 +209,15 @@ void XPROGTarget_SendByte(const uint8_t Byte) XPROGTarget_SetTxMode(); /* Wait until there is space in the hardware Tx buffer before writing */ +#if (ARCH == ARCH_AVR8) while (!(UCSR1A & (1 << UDRE1))); UCSR1A |= (1 << TXC1); UDR1 = Byte; +#elif (ARCH == ARCH_XMEGA) + while(!(PDI_USART.STATUS & USART_DREIF_bm)) + ; + PDI_USART.DATA = Byte; +#endif } /** Receives a byte via the hardware USART, blocking until data is received or timeout expired. @@ -158,9 +231,15 @@ uint8_t XPROGTarget_ReceiveByte(void) XPROGTarget_SetRxMode(); /* Wait until a byte has been received before reading */ - while (!(UCSR1A & (1 << RXC1)) && TimeoutTicksRemaining); - +#if (ARCH == ARCH_AVR8) + while (!(UCSR1A & (1 << RXC1)) && TimeoutTicksRemaining) + ; return UDR1; +#elif (ARCH == ARCH_XMEGA) + while(!(PDI_USART.STATUS & USART_RXCIF_bm)) + ; + return PDI_USART.DATA; +#endif } /** Sends an IDLE via the USART to the attached target, consisting of a full frame of idle bits. */ @@ -173,16 +252,23 @@ void XPROGTarget_SendIdle(void) /* Need to do nothing for a full frame to send an IDLE */ for (uint8_t i = 0; i < BITS_IN_USART_FRAME; i++) { +#if (ARCH == ARCH_AVR8) /* Wait for a full cycle of the clock */ while (PIND & (1 << 5)); while (!(PIND & (1 << 5))); while (PIND & (1 << 5)); +#elif (ARCH == ARCH_XMEGA) + while (PDI_PORT.IN & PDI_XCK_MASK); + while (!(PDI_PORT.IN & PDI_XCK_MASK)); + while (PDI_PORT.IN & PDI_XCK_MASK); +#endif } } static void XPROGTarget_SetTxMode(void) { /* Wait for a full cycle of the clock */ +#if (ARCH == ARCH_AVR8) while (PIND & (1 << 5)); while (!(PIND & (1 << 5))); while (PIND & (1 << 5)); @@ -192,12 +278,23 @@ static void XPROGTarget_SetTxMode(void) UCSR1B &= ~(1 << RXEN1); UCSR1B |= (1 << TXEN1); +#elif (ARCH == ARCH_XMEGA) + while (PDI_PORT.IN & PDI_XCK_MASK); + while (!(PDI_PORT.IN & PDI_XCK_MASK)); + while (PDI_PORT.IN & PDI_XCK_MASK); + + PDI_PORT.OUTSET = PDI_TX_MASK; + PDI_PORT.DIRSET = PDI_TX_MASK; + PDI_USART.CTRLB &= ~USART_RXEN_bm; + PDI_USART.CTRLB |= USART_TXEN_bm; +#endif IsSending = true; } static void XPROGTarget_SetRxMode(void) { +#if (ARCH == ARCH_AVR8) while (!(UCSR1A & (1 << TXC1))); UCSR1A |= (1 << TXC1); @@ -206,7 +303,18 @@ static void XPROGTarget_SetRxMode(void) DDRD &= ~(1 << 3); PORTD &= ~(1 << 3); +#elif (ARCH == ARCH_XMEGA) + while(!(PDI_USART.STATUS & USART_TXCIF_bm)) + ; + + PDI_USART.STATUS = USART_RXCIF_bm; + PDI_USART.CTRLB &= ~USART_TXEN_bm; + PDI_USART.CTRLB |= USART_RXEN_bm; + + PDI_PORT.DIRCLR = PDI_TX_MASK; + PDI_PORT.OUTCLR = PDI_TX_MASK; +#endif IsSending = false; } diff --git a/Projects/AVRISP-MKII/makefile b/Projects/AVRISP-MKII/makefile index 109faad15b..966fc96c81 100644 --- a/Projects/AVRISP-MKII/makefile +++ b/Projects/AVRISP-MKII/makefile @@ -11,12 +11,12 @@ # Run "make help" for target help. -MCU = at90usb1287 -ARCH = AVR8 -BOARD = USBKEY -F_CPU = 8000000 -F_USB = $(F_CPU) -OPTIMIZATION = s +MCU = atxmega128a4u +ARCH = XMEGA +BOARD = NONE +F_CPU = 32000000 +F_USB = 48000000 +OPTIMIZATION = 2 TARGET = AVRISP-MKII SRC = $(TARGET).c AVRISPDescriptors.c Lib/V2Protocol.c Lib/V2ProtocolParams.c Lib/ISP/ISPProtocol.c Lib/ISP/ISPTarget.c Lib/XPROG/XPROGProtocol.c \ Lib/XPROG/XPROGTarget.c Lib/XPROG/XMEGANVM.c Lib/XPROG/TINYNVM.c $(LUFA_SRC_USB) From f5bd6bce76b4fdc2c7cb6e932757eb3c30ad8f13 Mon Sep 17 00:00:00 2001 From: Lars Date: Sun, 5 Dec 2021 01:16:13 +0100 Subject: [PATCH 03/28] pdi reads successfull --- Projects/AVRISP-MKII/.kdev4/AVRISP-MKII.kdev4 | 2 ++ Projects/AVRISP-MKII/AVRISP-MKII.c | 4 ++-- Projects/AVRISP-MKII/AVRISP-MKII.kdev4 | 4 ++++ Projects/AVRISP-MKII/Config/AppConfig.h | 2 +- Projects/AVRISP-MKII/Config/LUFAConfig.h | 4 ++-- Projects/AVRISP-MKII/Lib/V2Protocol.c | 2 +- Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.c | 3 +++ Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c | 3 ++- Projects/AVRISP-MKII/makefile | 2 +- 9 files changed, 18 insertions(+), 8 deletions(-) create mode 100644 Projects/AVRISP-MKII/.kdev4/AVRISP-MKII.kdev4 create mode 100644 Projects/AVRISP-MKII/AVRISP-MKII.kdev4 diff --git a/Projects/AVRISP-MKII/.kdev4/AVRISP-MKII.kdev4 b/Projects/AVRISP-MKII/.kdev4/AVRISP-MKII.kdev4 new file mode 100644 index 0000000000..2ffd5cd5e0 --- /dev/null +++ b/Projects/AVRISP-MKII/.kdev4/AVRISP-MKII.kdev4 @@ -0,0 +1,2 @@ +[Project] +VersionControlSupport=kdevgit diff --git a/Projects/AVRISP-MKII/AVRISP-MKII.c b/Projects/AVRISP-MKII/AVRISP-MKII.c index d1cf410d8e..0fef87da15 100644 --- a/Projects/AVRISP-MKII/AVRISP-MKII.c +++ b/Projects/AVRISP-MKII/AVRISP-MKII.c @@ -96,7 +96,7 @@ void SetupHardware(void) #if defined(RESET_TOGGLES_LIBUSB_COMPAT) UpdateCurrentCompatibilityMode(); #endif - + /* USB Stack Initialization */ USB_Init(); } @@ -122,7 +122,7 @@ void EVENT_USB_Device_ConfigurationChanged(void) ConfigSuccess &= Endpoint_ConfigureEndpoint(AVRISP_DATA_OUT_EPADDR, EP_TYPE_BULK, AVRISP_DATA_EPSIZE, 1); /* Setup AVRISP Data IN endpoint if it is using a physically different endpoint */ - if ((AVRISP_DATA_IN_EPADDR & ENDPOINT_EPNUM_MASK) != (AVRISP_DATA_OUT_EPADDR & ENDPOINT_EPNUM_MASK)) + //if ((AVRISP_DATA_IN_EPADDR & ENDPOINT_EPNUM_MASK) != (AVRISP_DATA_OUT_EPADDR & ENDPOINT_EPNUM_MASK)) ConfigSuccess &= Endpoint_ConfigureEndpoint(AVRISP_DATA_IN_EPADDR, EP_TYPE_BULK, AVRISP_DATA_EPSIZE, 1); /* Indicate endpoint configuration success or failure */ diff --git a/Projects/AVRISP-MKII/AVRISP-MKII.kdev4 b/Projects/AVRISP-MKII/AVRISP-MKII.kdev4 new file mode 100644 index 0000000000..f3d19d1d5d --- /dev/null +++ b/Projects/AVRISP-MKII/AVRISP-MKII.kdev4 @@ -0,0 +1,4 @@ +[Project] +CreatedFrom=makefile +Manager=KDevCustomMakeManager +Name=AVRISP-MKII diff --git a/Projects/AVRISP-MKII/Config/AppConfig.h b/Projects/AVRISP-MKII/Config/AppConfig.h index 8bee5f7ad8..ce10033815 100644 --- a/Projects/AVRISP-MKII/Config/AppConfig.h +++ b/Projects/AVRISP-MKII/Config/AppConfig.h @@ -80,7 +80,7 @@ #define PDI_USART USARTC0 #define PDI_PORT PORTC #define PDI_RX_MASK (1 << 2) - #define PDI_RX_CTRL PIN1CTRL + #define PDI_RX_CTRL PIN2CTRL #define PDI_TX_MASK (1 << 3) #define PDI_TX_CTRL PIN3CTRL diff --git a/Projects/AVRISP-MKII/Config/LUFAConfig.h b/Projects/AVRISP-MKII/Config/LUFAConfig.h index bb53ba6f78..7d78ce3436 100644 --- a/Projects/AVRISP-MKII/Config/LUFAConfig.h +++ b/Projects/AVRISP-MKII/Config/LUFAConfig.h @@ -115,8 +115,8 @@ #define FIXED_NUM_CONFIGURATIONS 1 // #define CONTROL_ONLY_DEVICE #define MAX_ENDPOINT_INDEX 4 -// #define NO_DEVICE_REMOTE_WAKEUP -// #define NO_DEVICE_SELF_POWER + #define NO_DEVICE_REMOTE_WAKEUP + #define NO_DEVICE_SELF_POWER #else diff --git a/Projects/AVRISP-MKII/Lib/V2Protocol.c b/Projects/AVRISP-MKII/Lib/V2Protocol.c index d01249985c..7a501a160d 100644 --- a/Projects/AVRISP-MKII/Lib/V2Protocol.c +++ b/Projects/AVRISP-MKII/Lib/V2Protocol.c @@ -102,7 +102,7 @@ void V2Protocol_ProcessCommand(void) #if ARCH == ARCH_AVR8 TCCR0B = ((1 << CS02) | (1 << CS00)); #elif ARCH == ARCH_XMEGA - TCD0.CTRLA = TC_CLKSEL_DIV1024_gc; + DELAY_TIMER.CTRLA = TC_CLKSEL_DIV1024_gc; #endif switch (V2Command) { diff --git a/Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.c b/Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.c index 246d10bde0..3b071c0861 100644 --- a/Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.c +++ b/Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.c @@ -255,8 +255,11 @@ bool XMEGANVM_ReadMemory(const uint32_t ReadAddress, { /* Send a LDS command with the read address to read out the requested byte */ XPROGTarget_SendByte(PDI_CMD_LDS(PDI_DATASIZE_4BYTES, PDI_DATASIZE_1BYTE)); + XMEGANVM_SendAddress(ReadAddress); + *(ReadBuffer++) = XPROGTarget_ReceiveByte(); + } return (TimeoutTicksRemaining > 0); diff --git a/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c b/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c index 82427350f2..9ad781ad4b 100644 --- a/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c +++ b/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c @@ -216,6 +216,7 @@ void XPROGTarget_SendByte(const uint8_t Byte) #elif (ARCH == ARCH_XMEGA) while(!(PDI_USART.STATUS & USART_DREIF_bm)) ; + PDI_USART.STATUS |= USART_TXCIF_bm; PDI_USART.DATA = Byte; #endif } @@ -236,7 +237,7 @@ uint8_t XPROGTarget_ReceiveByte(void) ; return UDR1; #elif (ARCH == ARCH_XMEGA) - while(!(PDI_USART.STATUS & USART_RXCIF_bm)) + while(!(PDI_USART.STATUS & USART_RXCIF_bm) && TimeoutTicksRemaining) ; return PDI_USART.DATA; #endif diff --git a/Projects/AVRISP-MKII/makefile b/Projects/AVRISP-MKII/makefile index 966fc96c81..cebe7579a0 100644 --- a/Projects/AVRISP-MKII/makefile +++ b/Projects/AVRISP-MKII/makefile @@ -11,7 +11,7 @@ # Run "make help" for target help. -MCU = atxmega128a4u +MCU = atxmega256a3u ARCH = XMEGA BOARD = NONE F_CPU = 32000000 From 2666376af129c072cf70d2bdbd3c7ead3593214b Mon Sep 17 00:00:00 2001 From: Lars Date: Sun, 5 Dec 2021 01:16:13 +0100 Subject: [PATCH 04/28] pdi reads successfull --- LUFA/Drivers/USB/Core/XMEGA/Endpoint_XMEGA.h | 2 +- Projects/AVRISP-MKII/AVRISP-MKII.c | 4 ++-- Projects/AVRISP-MKII/Config/AppConfig.h | 2 +- Projects/AVRISP-MKII/Config/LUFAConfig.h | 4 ++-- Projects/AVRISP-MKII/Lib/V2Protocol.c | 2 +- Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.c | 3 +++ Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c | 3 ++- Projects/AVRISP-MKII/makefile | 2 +- 8 files changed, 13 insertions(+), 9 deletions(-) diff --git a/LUFA/Drivers/USB/Core/XMEGA/Endpoint_XMEGA.h b/LUFA/Drivers/USB/Core/XMEGA/Endpoint_XMEGA.h index fc33278af9..dd7807bcbc 100644 --- a/LUFA/Drivers/USB/Core/XMEGA/Endpoint_XMEGA.h +++ b/LUFA/Drivers/USB/Core/XMEGA/Endpoint_XMEGA.h @@ -452,7 +452,7 @@ static inline void Endpoint_SetEndpointDirection(const uint8_t DirectionMask) { // UECFG0X = ((UECFG0X & ~(1 << EPDIR)) | (DirectionMask ? (1 << EPDIR) : 0)); - USB_Endpoint_SelectedEndpoint = (USB_Endpoint_SelectedEndpoint & ~ENDPOINT_DIR_IN) | DirectionMask; + //USB_Endpoint_SelectedEndpoint = (USB_Endpoint_SelectedEndpoint & ~ENDPOINT_DIR_IN) | DirectionMask; } /** Reads one byte from the currently selected endpoint's bank, for OUT direction endpoints. diff --git a/Projects/AVRISP-MKII/AVRISP-MKII.c b/Projects/AVRISP-MKII/AVRISP-MKII.c index d1cf410d8e..0fef87da15 100644 --- a/Projects/AVRISP-MKII/AVRISP-MKII.c +++ b/Projects/AVRISP-MKII/AVRISP-MKII.c @@ -96,7 +96,7 @@ void SetupHardware(void) #if defined(RESET_TOGGLES_LIBUSB_COMPAT) UpdateCurrentCompatibilityMode(); #endif - + /* USB Stack Initialization */ USB_Init(); } @@ -122,7 +122,7 @@ void EVENT_USB_Device_ConfigurationChanged(void) ConfigSuccess &= Endpoint_ConfigureEndpoint(AVRISP_DATA_OUT_EPADDR, EP_TYPE_BULK, AVRISP_DATA_EPSIZE, 1); /* Setup AVRISP Data IN endpoint if it is using a physically different endpoint */ - if ((AVRISP_DATA_IN_EPADDR & ENDPOINT_EPNUM_MASK) != (AVRISP_DATA_OUT_EPADDR & ENDPOINT_EPNUM_MASK)) + //if ((AVRISP_DATA_IN_EPADDR & ENDPOINT_EPNUM_MASK) != (AVRISP_DATA_OUT_EPADDR & ENDPOINT_EPNUM_MASK)) ConfigSuccess &= Endpoint_ConfigureEndpoint(AVRISP_DATA_IN_EPADDR, EP_TYPE_BULK, AVRISP_DATA_EPSIZE, 1); /* Indicate endpoint configuration success or failure */ diff --git a/Projects/AVRISP-MKII/Config/AppConfig.h b/Projects/AVRISP-MKII/Config/AppConfig.h index 8bee5f7ad8..ce10033815 100644 --- a/Projects/AVRISP-MKII/Config/AppConfig.h +++ b/Projects/AVRISP-MKII/Config/AppConfig.h @@ -80,7 +80,7 @@ #define PDI_USART USARTC0 #define PDI_PORT PORTC #define PDI_RX_MASK (1 << 2) - #define PDI_RX_CTRL PIN1CTRL + #define PDI_RX_CTRL PIN2CTRL #define PDI_TX_MASK (1 << 3) #define PDI_TX_CTRL PIN3CTRL diff --git a/Projects/AVRISP-MKII/Config/LUFAConfig.h b/Projects/AVRISP-MKII/Config/LUFAConfig.h index bb53ba6f78..7d78ce3436 100644 --- a/Projects/AVRISP-MKII/Config/LUFAConfig.h +++ b/Projects/AVRISP-MKII/Config/LUFAConfig.h @@ -115,8 +115,8 @@ #define FIXED_NUM_CONFIGURATIONS 1 // #define CONTROL_ONLY_DEVICE #define MAX_ENDPOINT_INDEX 4 -// #define NO_DEVICE_REMOTE_WAKEUP -// #define NO_DEVICE_SELF_POWER + #define NO_DEVICE_REMOTE_WAKEUP + #define NO_DEVICE_SELF_POWER #else diff --git a/Projects/AVRISP-MKII/Lib/V2Protocol.c b/Projects/AVRISP-MKII/Lib/V2Protocol.c index d01249985c..7a501a160d 100644 --- a/Projects/AVRISP-MKII/Lib/V2Protocol.c +++ b/Projects/AVRISP-MKII/Lib/V2Protocol.c @@ -102,7 +102,7 @@ void V2Protocol_ProcessCommand(void) #if ARCH == ARCH_AVR8 TCCR0B = ((1 << CS02) | (1 << CS00)); #elif ARCH == ARCH_XMEGA - TCD0.CTRLA = TC_CLKSEL_DIV1024_gc; + DELAY_TIMER.CTRLA = TC_CLKSEL_DIV1024_gc; #endif switch (V2Command) { diff --git a/Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.c b/Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.c index 246d10bde0..3b071c0861 100644 --- a/Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.c +++ b/Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.c @@ -255,8 +255,11 @@ bool XMEGANVM_ReadMemory(const uint32_t ReadAddress, { /* Send a LDS command with the read address to read out the requested byte */ XPROGTarget_SendByte(PDI_CMD_LDS(PDI_DATASIZE_4BYTES, PDI_DATASIZE_1BYTE)); + XMEGANVM_SendAddress(ReadAddress); + *(ReadBuffer++) = XPROGTarget_ReceiveByte(); + } return (TimeoutTicksRemaining > 0); diff --git a/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c b/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c index 82427350f2..9ad781ad4b 100644 --- a/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c +++ b/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c @@ -216,6 +216,7 @@ void XPROGTarget_SendByte(const uint8_t Byte) #elif (ARCH == ARCH_XMEGA) while(!(PDI_USART.STATUS & USART_DREIF_bm)) ; + PDI_USART.STATUS |= USART_TXCIF_bm; PDI_USART.DATA = Byte; #endif } @@ -236,7 +237,7 @@ uint8_t XPROGTarget_ReceiveByte(void) ; return UDR1; #elif (ARCH == ARCH_XMEGA) - while(!(PDI_USART.STATUS & USART_RXCIF_bm)) + while(!(PDI_USART.STATUS & USART_RXCIF_bm) && TimeoutTicksRemaining) ; return PDI_USART.DATA; #endif diff --git a/Projects/AVRISP-MKII/makefile b/Projects/AVRISP-MKII/makefile index 966fc96c81..cebe7579a0 100644 --- a/Projects/AVRISP-MKII/makefile +++ b/Projects/AVRISP-MKII/makefile @@ -11,7 +11,7 @@ # Run "make help" for target help. -MCU = atxmega128a4u +MCU = atxmega256a3u ARCH = XMEGA BOARD = NONE F_CPU = 32000000 From dc988596a2a1928e5a5d999f1f66e70563efecfb Mon Sep 17 00:00:00 2001 From: MasterQ Date: Sun, 5 Dec 2021 21:55:52 +0100 Subject: [PATCH 05/28] Formular for baud rate for syncronous devices corrected, inverted clk signal for PDI and TPI, updated comments --- Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c | 43 ++++++++++++-------- 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c b/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c index 9ad781ad4b..bd1109f990 100644 --- a/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c +++ b/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c @@ -66,9 +66,13 @@ void XPROGTarget_EnableTargetPDI(void) #elif (ARCH == ARCH_XMEGA) - /* Set Tx and XCK as outputs, Rx as input */ + /* Set Tx and XCK as outputs, Rx as input, Invert the XCK PIN */ PDI_PORT.DIRSET = PDI_TX_MASK | PDI_XCK_MASK; PDI_PORT.DIRCLR = PDI_RX_MASK; + PDI_PORT.PDI_XCK_CTRL = PORT_INVEN_bm; + + /* Set Tx (PDI CLOCK) high (Set low because its inverted), DATA line low for at least 90ns to disable /RESET functionality */ + PDI_PORT.DIRCLR = PDI_RX_MASK | PDI_XCK_MASK; _delay_us(100); /* Set DATA line high for at least 90ns to disable /RESET functionality */ @@ -76,9 +80,9 @@ void XPROGTarget_EnableTargetPDI(void) _delay_us(20); /* Set up the synchronous USART for XMEGA communications - 8 data bits, even parity, 2 stop bits */ - PDI_USART.BAUDCTRLA = ((((uint32_t)F_CPU * 2) + XPROG_HARDWARE_SPEED*8)/(XPROG_HARDWARE_SPEED*16) - 1) & 0xFF; - PDI_USART.BAUDCTRLB = ((((uint32_t)F_CPU * 2) + XPROG_HARDWARE_SPEED*8)/(XPROG_HARDWARE_SPEED*16) - 1) >> 8; - PDI_USART.CTRLA = 0; //USART_RXCINTLVL_MED_gc | USART_TXCINTLVL_MED_gc | USART_DREINTLVL_MED_gc //TODO: Enable interrups + PDI_USART.BAUDCTRLA = ((((uint32_t)F_CPU + XPROG_HARDWARE_SPEED) /(2*XPROG_HARDWARE_SPEED)) - 1) & 0xFF; + PDI_USART.BAUDCTRLB = ((((uint32_t)F_CPU + XPROG_HARDWARE_SPEED) /(2*XPROG_HARDWARE_SPEED)) - 1) >> 8; + PDI_USART.CTRLA = 0; PDI_USART.CTRLB = USART_TXEN_bm | USART_CLK2X_bm; PDI_USART.CTRLC = USART_CMODE_SYNCHRONOUS_gc | USART_PMODE_EVEN_gc | USART_SBMODE_bm | USART_CHSIZE_8BIT_gc; #endif @@ -112,14 +116,15 @@ void XPROGTarget_EnableTargetTPI(void) AUX_LINE_PORT.OUTCLR = AUX_LINE_MASK; _delay_us(100); - /* Set Tx and XCK as outputs, Rx as input */ + /* Set Tx and XCK as outputs, Rx as input, Invert XCK */ PDI_PORT.DIRSET = PDI_TX_MASK | PDI_XCK_MASK; PDI_PORT.DIRCLR = PDI_RX_MASK; + PDI_PORT.PDI_XCK_CTRL = PORT_INVEN_bm; /* Set up the synchronous USART for TPI communications - 8 data bits, even parity, 2 stop bits */ - PDI_USART.BAUDCTRLA = ((((uint32_t)F_CPU * 2) + XPROG_HARDWARE_SPEED*8)/(XPROG_HARDWARE_SPEED*16) - 1) & 0xFF; - PDI_USART.BAUDCTRLB = ((((uint32_t)F_CPU * 2) + XPROG_HARDWARE_SPEED*8)/(XPROG_HARDWARE_SPEED*16) - 1) >> 8; - PDI_USART.CTRLA = 0; //USART_RXCINTLVL_MED_gc | USART_TXCINTLVL_MED_gc | USART_DREINTLVL_MED_gc //TODO: Enable interrups + PDI_USART.BAUDCTRLA = ((((uint32_t)F_CPU + XPROG_HARDWARE_SPEED) /(2*XPROG_HARDWARE_SPEED)) - 1) & 0xFF; + PDI_USART.BAUDCTRLB = ((((uint32_t)F_CPU + XPROG_HARDWARE_SPEED) /(2*XPROG_HARDWARE_SPEED)) - 1) >> 8; + PDI_USART.CTRLA = 0; PDI_USART.CTRLB = USART_TXEN_bm | USART_CLK2X_bm; PDI_USART.CTRLC = USART_CMODE_SYNCHRONOUS_gc | USART_PMODE_EVEN_gc | USART_SBMODE_bm | USART_CHSIZE_8BIT_gc; #endif @@ -151,11 +156,12 @@ void XPROGTarget_DisableTargetPDI(void) PDI_USART.CTRLB = 0; PDI_USART.CTRLC = 0; - /* Tristate all pins */ + /* Tristate all pins and disable inversion */ PDI_PORT.DIRCLR = PDI_TX_MASK | PDI_XCK_MASK; - PDI_PORT.PDI_XCK_CTRL &= ~PORT_OPC_PULLUP_gc; - PDI_PORT.PDI_TX_CTRL &= ~PORT_OPC_PULLUP_gc; - PDI_PORT.PDI_RX_CTRL &= ~PORT_OPC_PULLUP_gc; + + PDI_PORT.PDI_XCK_CTRL &= ~(PORT_OPC_PULLUP_gc | PORT_OPC_PULLDOWN_gc | PORT_INVEN_bm); + PDI_PORT.PDI_TX_CTRL &= ~(PORT_OPC_PULLUP_gc | PORT_OPC_PULLDOWN_gc); + PDI_PORT.PDI_RX_CTRL &= ~(PORT_OPC_PULLUP_gc | PORT_OPC_PULLDOWN_gc); #endif } @@ -188,13 +194,13 @@ void XPROGTarget_DisableTargetTPI(void) /* Tristate all pins */ PDI_PORT.DIRCLR = PDI_TX_MASK | PDI_XCK_MASK; - PDI_PORT.PDI_XCK_CTRL &= ~PORT_OPC_PULLUP_gc; - PDI_PORT.PDI_TX_CTRL &= ~PORT_OPC_PULLUP_gc; - PDI_PORT.PDI_RX_CTRL &= ~PORT_OPC_PULLUP_gc; + PDI_PORT.PDI_XCK_CTRL &= ~(PORT_OPC_PULLUP_gc | PORT_OPC_PULLDOWN_gc | PORT_INVEN_bm); + PDI_PORT.PDI_TX_CTRL &= ~(PORT_OPC_PULLUP_gc | PORT_OPC_PULLDOWN_gc); + PDI_PORT.PDI_RX_CTRL &= ~(PORT_OPC_PULLUP_gc | PORT_OPC_PULLDOWN_gc); AUX_LINE_PORT.DIRCLR = AUX_LINE_MASK; AUX_LINE_PORT.OUTCLR = AUX_LINE_MASK; - AUX_LINE_PORT.AUX_LINE_CTRL &= ~PORT_OPC_PULLUP_gc; + AUX_LINE_PORT.AUX_LINE_CTRL &= ~(PORT_OPC_PULLUP_gc | PORT_OPC_PULLDOWN_gc); #endif } @@ -259,9 +265,10 @@ void XPROGTarget_SendIdle(void) while (!(PIND & (1 << 5))); while (PIND & (1 << 5)); #elif (ARCH == ARCH_XMEGA) - while (PDI_PORT.IN & PDI_XCK_MASK); + /* As the pin inversion is active we need to wait inverted */ + while (!(PDI_PORT.IN & PDI_XCK_MASK)); + while ((PDI_PORT.IN & PDI_XCK_MASK)); while (!(PDI_PORT.IN & PDI_XCK_MASK)); - while (PDI_PORT.IN & PDI_XCK_MASK); #endif } } From 4c4f1a0dabbcc6188b6696d3eea8eb7c4892a5d2 Mon Sep 17 00:00:00 2001 From: MasterQ Date: Sun, 5 Dec 2021 23:49:42 +0100 Subject: [PATCH 06/28] Clearing correct irq flag. And waiting for the correct pin level --- Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c b/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c index bd1109f990..4eef543955 100644 --- a/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c +++ b/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c @@ -287,9 +287,10 @@ static void XPROGTarget_SetTxMode(void) UCSR1B &= ~(1 << RXEN1); UCSR1B |= (1 << TXEN1); #elif (ARCH == ARCH_XMEGA) - while (PDI_PORT.IN & PDI_XCK_MASK); + /* As the pin is actived, we need to wait inverted */ + while (!(PDI_PORT.IN & PDI_XCK_MASK)); + while ((PDI_PORT.IN & PDI_XCK_MASK)); while (!(PDI_PORT.IN & PDI_XCK_MASK)); - while (PDI_PORT.IN & PDI_XCK_MASK); PDI_PORT.OUTSET = PDI_TX_MASK; PDI_PORT.DIRSET = PDI_TX_MASK; @@ -314,8 +315,7 @@ static void XPROGTarget_SetRxMode(void) #elif (ARCH == ARCH_XMEGA) while(!(PDI_USART.STATUS & USART_TXCIF_bm)) ; - - PDI_USART.STATUS = USART_RXCIF_bm; + PDI_USART.STATUS = USART_TXCIF_bm; PDI_USART.CTRLB &= ~USART_TXEN_bm; PDI_USART.CTRLB |= USART_RXEN_bm; From 43835b2ac7521a48f2609574a5b24d613f07536d Mon Sep 17 00:00:00 2001 From: MasterQ Date: Mon, 6 Dec 2021 00:02:08 +0100 Subject: [PATCH 07/28] void casting unused paramter, but should be checked! --- LUFA/Drivers/USB/Core/XMEGA/Endpoint_XMEGA.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/LUFA/Drivers/USB/Core/XMEGA/Endpoint_XMEGA.h b/LUFA/Drivers/USB/Core/XMEGA/Endpoint_XMEGA.h index dd7807bcbc..4a243b0d68 100644 --- a/LUFA/Drivers/USB/Core/XMEGA/Endpoint_XMEGA.h +++ b/LUFA/Drivers/USB/Core/XMEGA/Endpoint_XMEGA.h @@ -451,6 +451,8 @@ static inline void Endpoint_SetEndpointDirection(const uint8_t DirectionMask) ATTR_ALWAYS_INLINE; static inline void Endpoint_SetEndpointDirection(const uint8_t DirectionMask) { + //TODO: Needs to be completed! + (void) DirectionMask; // UECFG0X = ((UECFG0X & ~(1 << EPDIR)) | (DirectionMask ? (1 << EPDIR) : 0)); //USB_Endpoint_SelectedEndpoint = (USB_Endpoint_SelectedEndpoint & ~ENDPOINT_DIR_IN) | DirectionMask; } From 8c706e241e5287b8ffb916d9d12d2acfb6c77308 Mon Sep 17 00:00:00 2001 From: MasterQ Date: Mon, 6 Dec 2021 00:24:01 +0100 Subject: [PATCH 08/28] Timeouts --- Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c | 28 +++++++++++++++----- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c b/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c index 4eef543955..258c1efc51 100644 --- a/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c +++ b/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c @@ -266,9 +266,13 @@ void XPROGTarget_SendIdle(void) while (PIND & (1 << 5)); #elif (ARCH == ARCH_XMEGA) /* As the pin inversion is active we need to wait inverted */ - while (!(PDI_PORT.IN & PDI_XCK_MASK)); - while ((PDI_PORT.IN & PDI_XCK_MASK)); - while (!(PDI_PORT.IN & PDI_XCK_MASK)); + uint32_t timeout = 100000; + while (timeout && !(PDI_PORT.IN & PDI_XCK_MASK)) + timeout--; + while (timeout && (PDI_PORT.IN & PDI_XCK_MASK)) + timeout--; + while (timeout && !(PDI_PORT.IN & PDI_XCK_MASK)) + timeout--; #endif } } @@ -288,9 +292,21 @@ static void XPROGTarget_SetTxMode(void) UCSR1B |= (1 << TXEN1); #elif (ARCH == ARCH_XMEGA) /* As the pin is actived, we need to wait inverted */ - while (!(PDI_PORT.IN & PDI_XCK_MASK)); - while ((PDI_PORT.IN & PDI_XCK_MASK)); - while (!(PDI_PORT.IN & PDI_XCK_MASK)); + uint32_t timeout = 100000; + while (timeout && !(PDI_PORT.IN & PDI_XCK_MASK)) + { + timeout--; + } + timeout = 100000; + while (timeout && (PDI_PORT.IN & PDI_XCK_MASK)) + { + timeout--; + } + timeout = 100000; + while (timeout && !(PDI_PORT.IN & PDI_XCK_MASK)) + { + timeout--; + } PDI_PORT.OUTSET = PDI_TX_MASK; PDI_PORT.DIRSET = PDI_TX_MASK; From d470313bd6528780de526fa00916cea8f1d68f23 Mon Sep 17 00:00:00 2001 From: MasterQ Date: Mon, 6 Dec 2021 00:25:06 +0100 Subject: [PATCH 09/28] Timeouts --- Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c b/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c index 258c1efc51..58c0f75298 100644 --- a/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c +++ b/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c @@ -269,8 +269,10 @@ void XPROGTarget_SendIdle(void) uint32_t timeout = 100000; while (timeout && !(PDI_PORT.IN & PDI_XCK_MASK)) timeout--; + timeout = 100000; while (timeout && (PDI_PORT.IN & PDI_XCK_MASK)) timeout--; + timeout = 100000; while (timeout && !(PDI_PORT.IN & PDI_XCK_MASK)) timeout--; #endif From 2f71ea528a2c6668576689623fdaa3e16863dbb1 Mon Sep 17 00:00:00 2001 From: MasterQ Date: Mon, 6 Dec 2021 00:39:06 +0100 Subject: [PATCH 10/28] And more fixes for pin level --- Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c b/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c index 58c0f75298..d88a7aabc8 100644 --- a/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c +++ b/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c @@ -72,7 +72,7 @@ void XPROGTarget_EnableTargetPDI(void) PDI_PORT.PDI_XCK_CTRL = PORT_INVEN_bm; /* Set Tx (PDI CLOCK) high (Set low because its inverted), DATA line low for at least 90ns to disable /RESET functionality */ - PDI_PORT.DIRCLR = PDI_RX_MASK | PDI_XCK_MASK; + PDI_PORT.OUTCLR = PDI_TX_MASK | PDI_XCK_MASK; _delay_us(100); /* Set DATA line high for at least 90ns to disable /RESET functionality */ @@ -266,13 +266,15 @@ void XPROGTarget_SendIdle(void) while (PIND & (1 << 5)); #elif (ARCH == ARCH_XMEGA) /* As the pin inversion is active we need to wait inverted */ - uint32_t timeout = 100000; + uint32_t timeout = 10000; while (timeout && !(PDI_PORT.IN & PDI_XCK_MASK)) timeout--; - timeout = 100000; + + timeout = 10000; while (timeout && (PDI_PORT.IN & PDI_XCK_MASK)) timeout--; - timeout = 100000; + + timeout = 10000; while (timeout && !(PDI_PORT.IN & PDI_XCK_MASK)) timeout--; #endif @@ -294,17 +296,17 @@ static void XPROGTarget_SetTxMode(void) UCSR1B |= (1 << TXEN1); #elif (ARCH == ARCH_XMEGA) /* As the pin is actived, we need to wait inverted */ - uint32_t timeout = 100000; + uint32_t timeout = 10000; while (timeout && !(PDI_PORT.IN & PDI_XCK_MASK)) { timeout--; } - timeout = 100000; + timeout = 10000; while (timeout && (PDI_PORT.IN & PDI_XCK_MASK)) { timeout--; } - timeout = 100000; + timeout = 10000; while (timeout && !(PDI_PORT.IN & PDI_XCK_MASK)) { timeout--; From 0fb16777b9b7e5eb7336b3ae892953b4844b59fd Mon Sep 17 00:00:00 2001 From: MasterQ Date: Mon, 6 Dec 2021 00:48:15 +0100 Subject: [PATCH 11/28] No more timeout --- Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c | 36 ++++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c b/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c index d88a7aabc8..2d5d2683c1 100644 --- a/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c +++ b/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c @@ -266,17 +266,17 @@ void XPROGTarget_SendIdle(void) while (PIND & (1 << 5)); #elif (ARCH == ARCH_XMEGA) /* As the pin inversion is active we need to wait inverted */ - uint32_t timeout = 10000; - while (timeout && !(PDI_PORT.IN & PDI_XCK_MASK)) - timeout--; +// uint32_t timeout = 10000; + while (!(PDI_PORT.IN & PDI_XCK_MASK)) + ; - timeout = 10000; - while (timeout && (PDI_PORT.IN & PDI_XCK_MASK)) - timeout--; +// timeout = 10000; + while ((PDI_PORT.IN & PDI_XCK_MASK)) + ; - timeout = 10000; - while (timeout && !(PDI_PORT.IN & PDI_XCK_MASK)) - timeout--; +// timeout = 10000; + while (!(PDI_PORT.IN & PDI_XCK_MASK)) + ; #endif } } @@ -296,20 +296,20 @@ static void XPROGTarget_SetTxMode(void) UCSR1B |= (1 << TXEN1); #elif (ARCH == ARCH_XMEGA) /* As the pin is actived, we need to wait inverted */ - uint32_t timeout = 10000; - while (timeout && !(PDI_PORT.IN & PDI_XCK_MASK)) +// uint32_t timeout = 10000; + while (!(PDI_PORT.IN & PDI_XCK_MASK)) { - timeout--; +// timeout--; } - timeout = 10000; - while (timeout && (PDI_PORT.IN & PDI_XCK_MASK)) +// timeout = 10000; + while ((PDI_PORT.IN & PDI_XCK_MASK)) { - timeout--; +// timeout--; } - timeout = 10000; - while (timeout && !(PDI_PORT.IN & PDI_XCK_MASK)) +// timeout = 10000; + while (!(PDI_PORT.IN & PDI_XCK_MASK)) { - timeout--; +// timeout--; } PDI_PORT.OUTSET = PDI_TX_MASK; From 0a8c79f1db8a40a5287d16809103695bd5efabdd Mon Sep 17 00:00:00 2001 From: MasterQ Date: Mon, 6 Dec 2021 00:54:45 +0100 Subject: [PATCH 12/28] Latest changes for testing --- Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c | 20 +++----------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c b/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c index 2d5d2683c1..3365c87df6 100644 --- a/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c +++ b/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c @@ -266,15 +266,10 @@ void XPROGTarget_SendIdle(void) while (PIND & (1 << 5)); #elif (ARCH == ARCH_XMEGA) /* As the pin inversion is active we need to wait inverted */ -// uint32_t timeout = 10000; while (!(PDI_PORT.IN & PDI_XCK_MASK)) ; - -// timeout = 10000; while ((PDI_PORT.IN & PDI_XCK_MASK)) ; - -// timeout = 10000; while (!(PDI_PORT.IN & PDI_XCK_MASK)) ; #endif @@ -296,21 +291,12 @@ static void XPROGTarget_SetTxMode(void) UCSR1B |= (1 << TXEN1); #elif (ARCH == ARCH_XMEGA) /* As the pin is actived, we need to wait inverted */ -// uint32_t timeout = 10000; while (!(PDI_PORT.IN & PDI_XCK_MASK)) - { -// timeout--; - } -// timeout = 10000; + ; while ((PDI_PORT.IN & PDI_XCK_MASK)) - { -// timeout--; - } -// timeout = 10000; + ; while (!(PDI_PORT.IN & PDI_XCK_MASK)) - { -// timeout--; - } + ; PDI_PORT.OUTSET = PDI_TX_MASK; PDI_PORT.DIRSET = PDI_TX_MASK; From 3fdc8216253df23e7b3c5cb043dadfd15c01d216 Mon Sep 17 00:00:00 2001 From: MasterQ Date: Mon, 20 Dec 2021 02:45:40 +0100 Subject: [PATCH 13/28] Smoother change of PDI TX/RX mode --- Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c b/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c index 3365c87df6..50721112d2 100644 --- a/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c +++ b/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c @@ -72,7 +72,8 @@ void XPROGTarget_EnableTargetPDI(void) PDI_PORT.PDI_XCK_CTRL = PORT_INVEN_bm; /* Set Tx (PDI CLOCK) high (Set low because its inverted), DATA line low for at least 90ns to disable /RESET functionality */ - PDI_PORT.OUTCLR = PDI_TX_MASK | PDI_XCK_MASK; + PDI_PORT.OUTCLR = PDI_TX_MASK; + PDI_PORT.OUTSET = PDI_XCK_MASK; _delay_us(100); /* Set DATA line high for at least 90ns to disable /RESET functionality */ @@ -301,8 +302,7 @@ static void XPROGTarget_SetTxMode(void) PDI_PORT.OUTSET = PDI_TX_MASK; PDI_PORT.DIRSET = PDI_TX_MASK; - PDI_USART.CTRLB &= ~USART_RXEN_bm; - PDI_USART.CTRLB |= USART_TXEN_bm; + PDI_USART.CTRLB = (PDI_USART.CTRLB & ~(USART_TXEN_bm | USART_RXEN_bm)) | USART_TXEN_bm; #endif IsSending = true; } @@ -323,8 +323,7 @@ static void XPROGTarget_SetRxMode(void) ; PDI_USART.STATUS = USART_TXCIF_bm; - PDI_USART.CTRLB &= ~USART_TXEN_bm; - PDI_USART.CTRLB |= USART_RXEN_bm; + PDI_USART.CTRLB = (PDI_USART.CTRLB & ~(USART_TXEN_bm | USART_RXEN_bm)) | USART_RXEN_bm; PDI_PORT.DIRCLR = PDI_TX_MASK; PDI_PORT.OUTCLR = PDI_TX_MASK; From ef1bebd2b90b7efba201c4b1708bc8c5b0435138 Mon Sep 17 00:00:00 2001 From: MasterQ Date: Mon, 20 Dec 2021 02:49:39 +0100 Subject: [PATCH 14/28] Fixed crital bug in length checks! --- Projects/AVRISP-MKII/Lib/XPROG/XPROGProtocol.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Projects/AVRISP-MKII/Lib/XPROG/XPROGProtocol.c b/Projects/AVRISP-MKII/Lib/XPROG/XPROGProtocol.c index b8db41ac91..43a03c20ff 100644 --- a/Projects/AVRISP-MKII/Lib/XPROG/XPROGProtocol.c +++ b/Projects/AVRISP-MKII/Lib/XPROG/XPROGProtocol.c @@ -250,7 +250,7 @@ static void XPROGProtocol_WriteMemory(void) WriteMemory_XPROG_Params.Length = SwapEndian_16(WriteMemory_XPROG_Params.Length); Endpoint_Read_Stream_LE(&WriteMemory_XPROG_Params.ProgData, WriteMemory_XPROG_Params.Length, NULL); - if (WriteMemory_XPROG_Params.Length >= sizeof(WriteMemory_XPROG_Params.ProgData)) + if (WriteMemory_XPROG_Params.Length > sizeof(WriteMemory_XPROG_Params.ProgData)) { Endpoint_StallTransaction(); return; @@ -322,6 +322,7 @@ static void XPROGProtocol_WriteMemory(void) ReturnStatus = XPROG_ERR_TIMEOUT; } } + Endpoint_Write_8(CMD_XPROG); Endpoint_Write_8(XPROG_CMD_WRITE_MEM); @@ -349,7 +350,7 @@ static void XPROGProtocol_ReadMemory(void) ReadMemory_XPROG_Params.Address = SwapEndian_32(ReadMemory_XPROG_Params.Address); ReadMemory_XPROG_Params.Length = SwapEndian_16(ReadMemory_XPROG_Params.Length); - if (ReadMemory_XPROG_Params.Length >= sizeof(ReadBuffer)) + if (ReadMemory_XPROG_Params.Length > sizeof(ReadBuffer)) { Endpoint_StallTransaction(); return; @@ -375,7 +376,7 @@ static void XPROGProtocol_ReadMemory(void) 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); From 93e29eec75ade028b712c0b673de465cc900fb9b Mon Sep 17 00:00:00 2001 From: MasterQ Date: Mon, 20 Dec 2021 03:16:34 +0100 Subject: [PATCH 15/28] Removed IDE file --- Projects/AVRISP-MKII/.kdev4/AVRISP-MKII.kdev4 | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 Projects/AVRISP-MKII/.kdev4/AVRISP-MKII.kdev4 diff --git a/Projects/AVRISP-MKII/.kdev4/AVRISP-MKII.kdev4 b/Projects/AVRISP-MKII/.kdev4/AVRISP-MKII.kdev4 deleted file mode 100644 index 2ffd5cd5e0..0000000000 --- a/Projects/AVRISP-MKII/.kdev4/AVRISP-MKII.kdev4 +++ /dev/null @@ -1,2 +0,0 @@ -[Project] -VersionControlSupport=kdevgit From a6c90b802c344cab57746c7275107d814192e217 Mon Sep 17 00:00:00 2001 From: MasterQ Date: Mon, 20 Dec 2021 03:21:55 +0100 Subject: [PATCH 16/28] Added importand define --- Projects/AVRISP-MKII/AVRISP-MKII.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Projects/AVRISP-MKII/AVRISP-MKII.c b/Projects/AVRISP-MKII/AVRISP-MKII.c index 0fef87da15..62bc6b6aa6 100644 --- a/Projects/AVRISP-MKII/AVRISP-MKII.c +++ b/Projects/AVRISP-MKII/AVRISP-MKII.c @@ -122,7 +122,9 @@ void EVENT_USB_Device_ConfigurationChanged(void) ConfigSuccess &= Endpoint_ConfigureEndpoint(AVRISP_DATA_OUT_EPADDR, EP_TYPE_BULK, AVRISP_DATA_EPSIZE, 1); /* Setup AVRISP Data IN endpoint if it is using a physically different endpoint */ - //if ((AVRISP_DATA_IN_EPADDR & ENDPOINT_EPNUM_MASK) != (AVRISP_DATA_OUT_EPADDR & ENDPOINT_EPNUM_MASK)) +#if (ARCH != ARCH_XMEGA) + if ((AVRISP_DATA_IN_EPADDR & ENDPOINT_EPNUM_MASK) != (AVRISP_DATA_OUT_EPADDR & ENDPOINT_EPNUM_MASK)) +#endif ConfigSuccess &= Endpoint_ConfigureEndpoint(AVRISP_DATA_IN_EPADDR, EP_TYPE_BULK, AVRISP_DATA_EPSIZE, 1); /* Indicate endpoint configuration success or failure */ From d2f21b1cc942509635f8b2b4f303d2b5d436080d Mon Sep 17 00:00:00 2001 From: MasterQ Date: Mon, 20 Dec 2021 03:23:13 +0100 Subject: [PATCH 17/28] Removed another ide file --- Projects/AVRISP-MKII/AVRISP-MKII.kdev4 | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 Projects/AVRISP-MKII/AVRISP-MKII.kdev4 diff --git a/Projects/AVRISP-MKII/AVRISP-MKII.kdev4 b/Projects/AVRISP-MKII/AVRISP-MKII.kdev4 deleted file mode 100644 index f3d19d1d5d..0000000000 --- a/Projects/AVRISP-MKII/AVRISP-MKII.kdev4 +++ /dev/null @@ -1,4 +0,0 @@ -[Project] -CreatedFrom=makefile -Manager=KDevCustomMakeManager -Name=AVRISP-MKII From 394c31f62f47e5613fbf3101a068ab45f5b90453 Mon Sep 17 00:00:00 2001 From: MasterQ Date: Mon, 20 Dec 2021 23:33:31 +0100 Subject: [PATCH 18/28] Fixed SPI for XMega --- Projects/AVRISP-MKII/Lib/ISP/ISPTarget.c | 9 +++++++-- Projects/AVRISP-MKII/Lib/ISP/ISPTarget.h | 4 ++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/Projects/AVRISP-MKII/Lib/ISP/ISPTarget.c b/Projects/AVRISP-MKII/Lib/ISP/ISPTarget.c index d9dcf999ac..e8b21f3c6f 100644 --- a/Projects/AVRISP-MKII/Lib/ISP/ISPTarget.c +++ b/Projects/AVRISP-MKII/Lib/ISP/ISPTarget.c @@ -193,8 +193,11 @@ void ISPTarget_EnableTargetISP(void) #if (ARCH == ARCH_AVR8) SPI_Init(pgm_read_byte(&SPIMaskFromSCKDuration[SCKDuration]) | SPI_ORDER_MSB_FIRST | SPI_SCK_LEAD_RISING | SPI_SAMPLE_LEADING | SPI_MODE_MASTER); -#elif (ARCH == XMEGA) - SPI_Init(&SPI_REG, pgm_read_byte(&SPI_PORT, &SPIMaskFromSCKDuration[SCKDuration]) | SPI_ORDER_MSB_FIRST | +#elif (ARCH == ARCH_XMEGA) + SPI_PORT.DIRSET = SPI_SCK_MASK | SPI_MOSI_MASK | PIN4_bm; + SPI_PORT.DIRCLR = SPI_MISO_MASK; + SPI_PORT.OUTSET = PIN4_bm; + SPI_Init(&SPI_REG, pgm_read_byte(&SPIMaskFromSCKDuration[SCKDuration]) | SPI_ORDER_MSB_FIRST | SPI_SCK_LEAD_RISING | SPI_SAMPLE_LEADING | SPI_MODE_MASTER); #endif } @@ -207,6 +210,7 @@ void ISPTarget_EnableTargetISP(void) PORTB |= ((1 << 0) | (1 << 3)); //Pullup on RST and MISO #elif (ARCH == ARCH_XMEGA) SPI_PORT.DIRSET = SPI_SCK_MASK | SPI_MOSI_MASK; + SPI_PORT.DIRCLR = SPI_MISO_MASK; SPI_PORT.SPI_RST_CTRL = PORT_OPC_PULLUP_gc; SPI_PORT.SPI_MISO_CTRL = PORT_OPC_PULLUP_gc; #endif @@ -237,6 +241,7 @@ void ISPTarget_DisableTargetISP(void) if (ISPTarget_HardwareSPIMode) { SPI_Disable(&SPI_REG); + SPI_PORT.DIRCLR = SPI_SCK_MASK | SPI_MISO_MASK | SPI_MOSI_MASK | PIN4_bm; } else { diff --git a/Projects/AVRISP-MKII/Lib/ISP/ISPTarget.h b/Projects/AVRISP-MKII/Lib/ISP/ISPTarget.h index 0c99bccbfe..f056c93c2f 100644 --- a/Projects/AVRISP-MKII/Lib/ISP/ISPTarget.h +++ b/Projects/AVRISP-MKII/Lib/ISP/ISPTarget.h @@ -141,9 +141,9 @@ if (ISPTarget_HardwareSPIMode) #if (ARCH == ARCH_XMEGA) - ReceivedByte = SPI_ReceiveByte(&SPI_REG); + ReceivedByte = SPI_TransferByte(&SPI_REG, Byte); #else - ReceivedByte = SPI_ReceiveByte(); + ReceivedByte = SPI_TransferByte(Byte); #endif else ReceivedByte = ISPTarget_TransferSoftSPIByte(Byte); From 4781eb7c0ce443bdaa3bfdc56e72ca78e5e4c5c5 Mon Sep 17 00:00:00 2001 From: MasterQ Date: Wed, 22 Dec 2021 22:32:31 +0100 Subject: [PATCH 19/28] Removed reset pin as it is the same as aux --- Projects/AVRISP-MKII/Config/AppConfig.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/Projects/AVRISP-MKII/Config/AppConfig.h b/Projects/AVRISP-MKII/Config/AppConfig.h index ce10033815..d09b3bb7aa 100644 --- a/Projects/AVRISP-MKII/Config/AppConfig.h +++ b/Projects/AVRISP-MKII/Config/AppConfig.h @@ -68,9 +68,6 @@ #define SPI_MOSI_MASK (1 << 5) #define SPI_MOSI_CTRL PIN5CTRL - #define SPI_RST_MASK (1 << 4) - #define SPI_RST_CTRL PIN4CTRL - #define RESCUE_PORT PORTD #define RESCUE_TIMER TCD0 #define RESCUE_PIN_MASK (1 << 0) From e0eed18acf56bda6271db90e5e0e6aec0123cb3e Mon Sep 17 00:00:00 2001 From: MasterQ Date: Wed, 22 Dec 2021 22:33:43 +0100 Subject: [PATCH 20/28] Changed reset pin ctrl to aux pin ctrl --- Projects/AVRISP-MKII/Lib/ISP/ISPTarget.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Projects/AVRISP-MKII/Lib/ISP/ISPTarget.c b/Projects/AVRISP-MKII/Lib/ISP/ISPTarget.c index e8b21f3c6f..4e8e782962 100644 --- a/Projects/AVRISP-MKII/Lib/ISP/ISPTarget.c +++ b/Projects/AVRISP-MKII/Lib/ISP/ISPTarget.c @@ -211,7 +211,7 @@ void ISPTarget_EnableTargetISP(void) #elif (ARCH == ARCH_XMEGA) SPI_PORT.DIRSET = SPI_SCK_MASK | SPI_MOSI_MASK; SPI_PORT.DIRCLR = SPI_MISO_MASK; - SPI_PORT.SPI_RST_CTRL = PORT_OPC_PULLUP_gc; + SPI_PORT.AUX_LINE_CTRL = PORT_OPC_PULLUP_gc; SPI_PORT.SPI_MISO_CTRL = PORT_OPC_PULLUP_gc; #endif ISPTarget_ConfigureSoftwareSPI(SCKDuration); @@ -246,7 +246,7 @@ void ISPTarget_DisableTargetISP(void) else { SPI_PORT.DIRCLR = SPI_SCK_MASK | SPI_MOSI_MASK; - SPI_PORT.SPI_RST_CTRL &= ~PORT_OPC_PULLUP_gc; + SPI_PORT.AUX_LINE_CTRL &= ~PORT_OPC_PULLUP_gc; SPI_PORT.SPI_MOSI_CTRL &= ~PORT_OPC_PULLUP_gc; /* Must re-enable rescue clock once software ISP has exited, as the timer for the rescue clock is From 68d95e89e6ad3b3b0babf863abed038ae96f8878 Mon Sep 17 00:00:00 2001 From: MasterQ Date: Thu, 23 Dec 2021 13:46:38 +0100 Subject: [PATCH 21/28] Avoid overflow --- LUFA/Drivers/Peripheral/XMEGA/SerialSPI_XMEGA.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LUFA/Drivers/Peripheral/XMEGA/SerialSPI_XMEGA.h b/LUFA/Drivers/Peripheral/XMEGA/SerialSPI_XMEGA.h index cb86a9900a..34c7044254 100644 --- a/LUFA/Drivers/Peripheral/XMEGA/SerialSPI_XMEGA.h +++ b/LUFA/Drivers/Peripheral/XMEGA/SerialSPI_XMEGA.h @@ -91,7 +91,7 @@ /* Private Interface - For use in library only: */ #if !defined(__DOXYGEN__) - #define SERIAL_SPI_UBBRVAL(Baud) ((Baud < (F_CPU / 2)) ? ((F_CPU / (2 * Baud)) - 1) : 0) + #define SERIAL_SPI_UBBRVAL(Baud) ((Baud < (F_CPU / 2)) ? ((F_CPU / (2ULL * Baud)) - 1) : 0) #endif /* Public Interface - May be used in end-application: */ From c75241c791af109143f15194d877abe997a57695 Mon Sep 17 00:00:00 2001 From: MasterQ Date: Thu, 23 Dec 2021 13:49:58 +0100 Subject: [PATCH 22/28] Added untested Calibration function for XMega --- Projects/AVRISP-MKII/Lib/ISP/ISPProtocol.c | 43 +++++++++++++++++++++- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/Projects/AVRISP-MKII/Lib/ISP/ISPProtocol.c b/Projects/AVRISP-MKII/Lib/ISP/ISPProtocol.c index f742b29e7e..349d7bf0dc 100644 --- a/Projects/AVRISP-MKII/Lib/ISP/ISPProtocol.c +++ b/Projects/AVRISP-MKII/Lib/ISP/ISPProtocol.c @@ -54,7 +54,7 @@ ISR(TIMER1_OVF_vect, ISR_BLOCK) ISPProtocol_HalfCyclesRemaining--; } #elif (ARCH == ARCH_XMEGA) -ISR(SW_SPI_TIMER_OVF_vect, ISR_BLOCK) +ISR(SW_SPI_TIMER_CCA_vect, ISR_BLOCK) { SPI_PORT.OUTTGL = SPI_MOSI_MASK; ISPProtocol_HalfCyclesRemaining--; @@ -433,7 +433,7 @@ void ISPProtocol_Calibrate(void) Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN); //TODO: Learn it and implement it... -#if ARCH == ARCH_AVR8 +#if (ARCH == ARCH_AVR8) /* Enable pull-up on MISO and release ~RESET */ DDRB = ~(1 << PB3); PORTB |= ( (1 << PB4) | (1 << PB3) ); @@ -466,6 +466,45 @@ void ISPProtocol_Calibrate(void) TIMSK1 = 0; } + /* Check if device responded with a success message or if we timed out */ + if (ISPProtocol_ResponseTogglesRemaining) + ResponseStatus = STATUS_CMD_TOUT; +#elif (ARCH == ARCH_XMEGA) + //TODO: This needs to be tested + /* Enable pull-up on MISO and release ~RESET */ + SPI_PORT.SPI_MISO_CTRL = PORT_OPC_PULLUP_gc; + SPI_PORT.DIRCLR = SPI_MISO_MASK; + AUX_LINE_PORT.DIRCLR = AUX_LINE_MASK; + + /* Set up MISO pin (PCINT3) to listen for toggles */ + SPI_PORT.INT0MASK = SPI_MISO_MASK; + + /* Set up timer that fires at a rate of 65536 Hz - this will drive the MOSI toggle */ + SW_SPI_TIMER.CCA = ISPPROTOCOL_CALIB_TICKS - 1; + SW_SPI_TIMER.PER = ISPPROTOCOL_CALIB_TICKS - 1; + SW_SPI_TIMER.CTRLB = TC_WGMODE_FRQ_gc; // set for fast PWM, TOP = OCR1A + SW_SPI_TIMER.CTRLA = TC_CLKSEL_DIV1_gc; // ... and no clock prescaling + SW_SPI_TIMER.CNT = 0; + + /* Initialize counter variables */ + ISPProtocol_HalfCyclesRemaining = ISPPROTOCOL_CALIB_HALF_CYCLE_LIMIT; + ISPProtocol_ResponseTogglesRemaining = ISPPROTOCOL_CALIB_SUCCESS_TOGGLE_NUM; + + /* Turn on interrupts */ + SW_SPI_TIMER.INTCTRLB = TC_CCAINTLVL_MED_gc; // enable interrupts for PCINT7:0 (don't touch setting for PCINT12:8) + SPI_PORT.INT0MASK |= PORT_INT0LVL_MED_gc; // enable T1 OVF interrupt (and no other T1 interrupts) + + /* Turn on global interrupts for the following block, restoring current state at end */ + NONATOMIC_BLOCK(NONATOMIC_RESTORESTATE) + { + /* Let device do its calibration, wait for response on MISO */ + while (ISPProtocol_HalfCyclesRemaining && ISPProtocol_ResponseTogglesRemaining); + + /* Disable timer and pin change interrupts */ + SW_SPI_TIMER.INTCTRLB &= ~TC_CCAINTLVL_MED_gc; + SPI_PORT.INT0MASK &= ~PORT_INT0LVL_gm; + } + /* Check if device responded with a success message or if we timed out */ if (ISPProtocol_ResponseTogglesRemaining) ResponseStatus = STATUS_CMD_TOUT; From 18cec3c107f7bb00de285d7f64d776881c0932c4 Mon Sep 17 00:00:00 2001 From: MasterQ Date: Thu, 23 Dec 2021 13:51:23 +0100 Subject: [PATCH 23/28] Added hacked, but tested and working ADC init --- Projects/AVRISP-MKII/Lib/V2ProtocolParams.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Projects/AVRISP-MKII/Lib/V2ProtocolParams.c b/Projects/AVRISP-MKII/Lib/V2ProtocolParams.c index c42c6c4bbe..1ba9ff2663 100644 --- a/Projects/AVRISP-MKII/Lib/V2ProtocolParams.c +++ b/Projects/AVRISP-MKII/Lib/V2ProtocolParams.c @@ -139,6 +139,17 @@ void V2Params_UpdateParamValues(void) #if (defined(ADC) && !defined(NO_VTARGET_DETECT)) /* Update VTARGET parameter with the latest ADC conversion of VTARGET on supported AVR models */ V2Params_GetParamFromTable(PARAM_VTARGET)->ParamValue = (((uint16_t)(VTARGET_REF_VOLTS * 10 * VTARGET_SCALE_FACTOR) * ADC_GetResult()) / 1024); + #elif !defined(NO_VTARGET_DETECT) && (ARCH == ARCH_XMEGA) + uint32_t result = 0; + for(uint8_t i = 0; i < 64; i++) + { + while(!(ADCA.CH0.INTFLAGS & AC_AC0IF_bm)) + ; + result += ADCA.CH0.RES; + ADCA.CH0.INTFLAGS = AC_AC0IF_bm; + } + result >>= 6; + V2Params_GetParamFromTable(PARAM_VTARGET)->ParamValue = (((uint16_t)(VTARGET_REF_VOLTS * 10 * VTARGET_SCALE_FACTOR) * result) / 1024); #endif } From 18f9e6730783aea9c46b1c35616eaf0104c0f437 Mon Sep 17 00:00:00 2001 From: MasterQ Date: Thu, 23 Dec 2021 13:52:39 +0100 Subject: [PATCH 24/28] Added hacked, but tested and working ADC init and measure --- Projects/AVRISP-MKII/Lib/V2Protocol.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/Projects/AVRISP-MKII/Lib/V2Protocol.c b/Projects/AVRISP-MKII/Lib/V2Protocol.c index 7a501a160d..320047d812 100644 --- a/Projects/AVRISP-MKII/Lib/V2Protocol.c +++ b/Projects/AVRISP-MKII/Lib/V2Protocol.c @@ -69,6 +69,24 @@ void V2Protocol_Init(void) ADC_Init(ADC_FREE_RUNNING | ADC_PRESCALE_128); ADC_SetupChannel(VTARGET_ADC_CHANNEL); ADC_StartReading(VTARGET_REF_MASK | ADC_RIGHT_ADJUSTED | VTARGET_ADC_CHANNEL_MASK); + #elif !defined(NO_VTARGET_DETECT) && (ARCH == ARCH_XMEGA) + //TODO: Write LUFA XMega ADC Driver + NVM_CMD = NVM_CMD_READ_CALIB_ROW_gc; + uint8_t cal = pgm_read_byte(offsetof(NVM_PROD_SIGNATURES_t, ADCACAL0)); + NVM_CMD = NVM_CMD_NO_OPERATION_gc; + ADCA.CALL = cal; + + NVM_CMD = NVM_CMD_READ_CALIB_ROW_gc; + cal = pgm_read_byte(offsetof(NVM_PROD_SIGNATURES_t, ADCACAL1)); + NVM_CMD = NVM_CMD_NO_OPERATION_gc; + ADCA.CALH = cal; + ADCA.CTRLB = ADC_FREERUN_bm | ADC_IMPMODE_bm; + PORTA.DIRCLR = PIN0_bm; + ADCA.REFCTRL = ADC_REFSEL_INT1V_gc; + ADCA.PRESCALER = ADC_PRESCALER_DIV64_gc; + ADCA.CH0.CTRL = ADC_CH_GAIN_1X_gc; + ADCA.CH0.MUXCTRL = ADC_CH_MUXPOS_PIN0_gc; + ADCA.CTRLA = ADC_ENABLE_bm; #endif /* Timeout timer initialization (~10ms period) */ From dc7bbcf0e859870669db0eb8bb5075fbe6270bf0 Mon Sep 17 00:00:00 2001 From: MasterQ Date: Thu, 23 Dec 2021 13:55:52 +0100 Subject: [PATCH 25/28] Added usart spi master and calculations --- Projects/AVRISP-MKII/Lib/ISP/ISPTarget.h | 32 +++++++++++++++++++----- 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/Projects/AVRISP-MKII/Lib/ISP/ISPTarget.h b/Projects/AVRISP-MKII/Lib/ISP/ISPTarget.h index f056c93c2f..9ab11f36df 100644 --- a/Projects/AVRISP-MKII/Lib/ISP/ISPTarget.h +++ b/Projects/AVRISP-MKII/Lib/ISP/ISPTarget.h @@ -42,11 +42,16 @@ #include #include - #include + #include "../V2Protocol.h" #include "ISPProtocol.h" #include "Config/AppConfig.h" + #if defined(USART_SPI_MASTER) + #include + #else + #include + #endif /* Preprocessor Checks: */ #if ((BOARD == BOARD_XPLAIN) || (BOARD == BOARD_XPLAIN_REV1)) @@ -62,8 +67,11 @@ #define LOAD_EXTENDED_ADDRESS_CMD 0x4D /** Macro to convert an ISP frequency to a number of timer clock cycles for the software SPI driver. */ - #define ISP_TIMER_COMP(freq) (((F_CPU / 8) / 2 / freq) - 1) - + #if (ARCH == ARCH_XMEGA) + #define ISP_TIMER_COMP(prediv, freq) (F_CPU / (prediv * 2ULL * freq)) + #else + #define ISP_TIMER_COMP(freq) (((F_CPU / 8) / 2 / freq) - 1) + #endif /** ISP rescue clock speed in Hz, for clocking targets with incorrectly set fuses. */ #define ISP_RESCUE_CLOCK_SPEED 4000000 @@ -95,7 +103,11 @@ { if (ISPTarget_HardwareSPIMode) #if (ARCH == ARCH_XMEGA) - SPI_SendByte(&SPI_REG, Byte); + #ifdef USART_SPI_MASTER + SerialSPI_SendByte(&USART_SPI_REG, Byte); + #else + SPI_SendByte(&SPI_REG, Byte); + #endif #else SPI_SendByte(Byte); #endif @@ -114,7 +126,11 @@ if (ISPTarget_HardwareSPIMode) #if (ARCH == ARCH_XMEGA) - ReceivedByte = SPI_ReceiveByte(&SPI_REG); + #ifdef USART_SPI_MASTER + ReceivedByte = SerialSPI_ReceiveByte(&USART_SPI_REG); + #else + ReceivedByte = SPI_ReceiveByte(&SPI_REG); + #endif #else ReceivedByte = SPI_ReceiveByte(); #endif @@ -141,7 +157,11 @@ if (ISPTarget_HardwareSPIMode) #if (ARCH == ARCH_XMEGA) - ReceivedByte = SPI_TransferByte(&SPI_REG, Byte); + #ifdef USART_SPI_MASTER + ReceivedByte = SerialSPI_TransferByte(&USART_SPI_REG, Byte); + #else + ReceivedByte = SPI_TransferByte(&SPI_REG, Byte); + #endif #else ReceivedByte = SPI_TransferByte(Byte); #endif From 307845072d5d35547366f4e701a92cb705c8734d Mon Sep 17 00:00:00 2001 From: MasterQ Date: Thu, 23 Dec 2021 13:56:56 +0100 Subject: [PATCH 26/28] Added new univeral precompile defined lookup table for SPI settings for XMega. Can be ported to AVR8 --- Projects/AVRISP-MKII/Lib/ISP/ISPTarget.c | 513 +++++++++++++++++------ 1 file changed, 388 insertions(+), 125 deletions(-) diff --git a/Projects/AVRISP-MKII/Lib/ISP/ISPTarget.c b/Projects/AVRISP-MKII/Lib/ISP/ISPTarget.c index 4e8e782962..19d5b3490d 100644 --- a/Projects/AVRISP-MKII/Lib/ISP/ISPTarget.c +++ b/Projects/AVRISP-MKII/Lib/ISP/ISPTarget.c @@ -41,76 +41,297 @@ * * \hideinitializer */ -static const uint8_t SPIMaskFromSCKDuration[] PROGMEM = -{ -#if (F_CPU == 8000000) - SPI_SPEED_FCPU_DIV_2, // AVRStudio = 8MHz SPI, Actual = 4MHz SPI - SPI_SPEED_FCPU_DIV_2, // AVRStudio = 4MHz SPI, Actual = 4MHz SPI - SPI_SPEED_FCPU_DIV_4, // AVRStudio = 2MHz SPI, Actual = 2MHz SPI - SPI_SPEED_FCPU_DIV_8, // AVRStudio = 1MHz SPI, Actual = 1MHz SPI - SPI_SPEED_FCPU_DIV_16, // AVRStudio = 500KHz SPI, Actual = 500KHz SPI - SPI_SPEED_FCPU_DIV_32, // AVRStudio = 250KHz SPI, Actual = 250KHz SPI - SPI_SPEED_FCPU_DIV_64, // AVRStudio = 125KHz SPI, Actual = 125KHz SPI -#elif (F_CPU == 16000000) - SPI_SPEED_FCPU_DIV_2, // AVRStudio = 8MHz SPI, Actual = 8MHz SPI - SPI_SPEED_FCPU_DIV_4, // AVRStudio = 4MHz SPI, Actual = 4MHz SPI - SPI_SPEED_FCPU_DIV_8, // AVRStudio = 2MHz SPI, Actual = 2MHz SPI - SPI_SPEED_FCPU_DIV_16, // AVRStudio = 1MHz SPI, Actual = 1MHz SPI - SPI_SPEED_FCPU_DIV_32, // AVRStudio = 500KHz SPI, Actual = 500KHz SPI - SPI_SPEED_FCPU_DIV_64, // AVRStudio = 250KHz SPI, Actual = 250KHz SPI - SPI_SPEED_FCPU_DIV_128 // AVRStudio = 125KHz SPI, Actual = 125KHz SPI -#elif (F_CPU == 32000000) - SPI_SPEED_FCPU_DIV_4, // AVRStudio = 8MHz SPI, Actual = 8MHz SPI - SPI_SPEED_FCPU_DIV_8, // AVRStudio = 4MHz SPI, Actual = 4MHz SPI - SPI_SPEED_FCPU_DIV_16, // AVRStudio = 2MHz SPI, Actual = 2MHz SPI - SPI_SPEED_FCPU_DIV_32, // AVRStudio = 1MHz SPI, Actual = 1MHz SPI - SPI_SPEED_FCPU_DIV_64, // AVRStudio = 500KHz SPI, Actual = 500KHz SPI - SPI_SPEED_FCPU_DIV_128, // AVRStudio = 250KHz SPI, Actual = 250KHz SPI - SPI_SPEED_FCPU_DIV_128, //TODO: Incomplete table -#else - #error No SPI prescaler masks for chosen F_CPU speed. +#if (ARCH == ARCH_XMEGA) + +typedef struct SPISetting_t { + uint8_t hardware_spi:1; + uint8_t prediv:7; + uint16_t value; +} SPISetting_t; + + #if defined(USART_SPI_MASTER) + /* Theoritical should we be able to go down until bsel will overflow + * but for some reasons lower frequencies generates random bit rates... + * (< 10000Hz) Maybe this is a problem with the user code, maybe it + * specified somewhere in the datasheet or it may be a hardware bug. + * It was even tested with static bsel that also results in wrong + * bitrates... + * But who cares software SPI works fine with this low rates. + */ + #define SPI_MIN_HW_FREQ() 20000 //(F_CPU/(2*(65535+1))+1) + #define SPI_GEN_HW_VALUE(freq) SERIAL_SPI_UBBRVAL(freq) + #else + /* Max prediv is 128 */ + #define SPI_MIN_HW_FREQ() (F_CPU/128) + #define SPI_GEN_HW_VALUE(freq) (freq >= (F_CPU/2)) ? SPI_SPEED_FCPU_DIV_2 : \ + (freq >= (F_CPU/4)) ? SPI_SPEED_FCPU_DIV_4 : \ + (freq >= (F_CPU/8)) ? SPI_SPEED_FCPU_DIV_8 : \ + (freq >= (F_CPU/16)) ? SPI_SPEED_FCPU_DIV_16 : \ + (freq >= (F_CPU/32)) ? SPI_SPEED_FCPU_DIV_32 : \ + (freq >= (F_CPU/64)) ? SPI_SPEED_FCPU_DIV_64 : \ + SPI_SPEED_FCPU_DIV_128 + #endif + + #define SPI_IS_HW_SPI(freq) (freq >= SPI_MIN_HW_FREQ()) + #define SPI_SW_PREDIV(freq) (ISP_TIMER_COMP(1,freq) >= 32767ULL) ? TC_CLKSEL_DIV64_gc : TC_CLKSEL_DIV1_gc + #define SPI_SW_VALUE(freq) (ISP_TIMER_COMP(1,freq) >= 32767ULL) ? ISP_TIMER_COMP(64, freq) : ISP_TIMER_COMP(1, freq) + #define SPI_GEN_SETTINGS_ROW(freq) { \ + SPI_IS_HW_SPI(freq) ? 1 : 0, \ + SPI_IS_HW_SPI(freq) ? 0 : SPI_SW_PREDIV(freq), \ + SPI_IS_HW_SPI(freq) ? SPI_GEN_HW_VALUE(freq) : SPI_SW_VALUE(freq) \ + } + static const struct SPISetting_t SPISettings[] PROGMEM = + { + SPI_GEN_SETTINGS_ROW(8000000), + SPI_GEN_SETTINGS_ROW(4000000), + SPI_GEN_SETTINGS_ROW(2000000), + SPI_GEN_SETTINGS_ROW(1000000), + SPI_GEN_SETTINGS_ROW(500000), + SPI_GEN_SETTINGS_ROW(250000), + SPI_GEN_SETTINGS_ROW(125000), + SPI_GEN_SETTINGS_ROW(96386), + SPI_GEN_SETTINGS_ROW(89888), + SPI_GEN_SETTINGS_ROW(84211), + SPI_GEN_SETTINGS_ROW(79208), + SPI_GEN_SETTINGS_ROW(74767), + SPI_GEN_SETTINGS_ROW(70797), + SPI_GEN_SETTINGS_ROW(67227), + SPI_GEN_SETTINGS_ROW(64000), + SPI_GEN_SETTINGS_ROW(61069), + SPI_GEN_SETTINGS_ROW(58395), + SPI_GEN_SETTINGS_ROW(55945), + SPI_GEN_SETTINGS_ROW(51613), + SPI_GEN_SETTINGS_ROW(49690), + SPI_GEN_SETTINGS_ROW(47905), + SPI_GEN_SETTINGS_ROW(46243), + SPI_GEN_SETTINGS_ROW(43244), + SPI_GEN_SETTINGS_ROW(41885), + SPI_GEN_SETTINGS_ROW(39409), + SPI_GEN_SETTINGS_ROW(38278), + SPI_GEN_SETTINGS_ROW(36200), + SPI_GEN_SETTINGS_ROW(34335), + SPI_GEN_SETTINGS_ROW(32654), + SPI_GEN_SETTINGS_ROW(31129), + SPI_GEN_SETTINGS_ROW(29740), + SPI_GEN_SETTINGS_ROW(28470), + SPI_GEN_SETTINGS_ROW(27304), + SPI_GEN_SETTINGS_ROW(25724), + SPI_GEN_SETTINGS_ROW(24768), + SPI_GEN_SETTINGS_ROW(23461), + SPI_GEN_SETTINGS_ROW(22285), + SPI_GEN_SETTINGS_ROW(21221), + SPI_GEN_SETTINGS_ROW(20254), + SPI_GEN_SETTINGS_ROW(19371), + SPI_GEN_SETTINGS_ROW(18562), + SPI_GEN_SETTINGS_ROW(17583), + SPI_GEN_SETTINGS_ROW(16914), + SPI_GEN_SETTINGS_ROW(16097), + SPI_GEN_SETTINGS_ROW(15356), + SPI_GEN_SETTINGS_ROW(14520), + SPI_GEN_SETTINGS_ROW(13914), + SPI_GEN_SETTINGS_ROW(13224), + SPI_GEN_SETTINGS_ROW(12599), + SPI_GEN_SETTINGS_ROW(12031), + SPI_GEN_SETTINGS_ROW(11511), + SPI_GEN_SETTINGS_ROW(10944), + SPI_GEN_SETTINGS_ROW(10431), + SPI_GEN_SETTINGS_ROW(9963), + SPI_GEN_SETTINGS_ROW(9468), + SPI_GEN_SETTINGS_ROW(9081), + SPI_GEN_SETTINGS_ROW(8612), + SPI_GEN_SETTINGS_ROW(8239), + SPI_GEN_SETTINGS_ROW(7851), + SPI_GEN_SETTINGS_ROW(7498), + SPI_GEN_SETTINGS_ROW(7137), + SPI_GEN_SETTINGS_ROW(6809), + SPI_GEN_SETTINGS_ROW(6478), + SPI_GEN_SETTINGS_ROW(6178), + SPI_GEN_SETTINGS_ROW(5879), + SPI_GEN_SETTINGS_ROW(5607), + SPI_GEN_SETTINGS_ROW(5359), + SPI_GEN_SETTINGS_ROW(5093), + SPI_GEN_SETTINGS_ROW(4870), + SPI_GEN_SETTINGS_ROW(4633), + SPI_GEN_SETTINGS_ROW(4418), + SPI_GEN_SETTINGS_ROW(4209), + SPI_GEN_SETTINGS_ROW(4019), + SPI_GEN_SETTINGS_ROW(3823), + SPI_GEN_SETTINGS_ROW(3645), + SPI_GEN_SETTINGS_ROW(3474), + SPI_GEN_SETTINGS_ROW(3310), + SPI_GEN_SETTINGS_ROW(3161), + SPI_GEN_SETTINGS_ROW(3011), + SPI_GEN_SETTINGS_ROW(2869), + SPI_GEN_SETTINGS_ROW(2734), + SPI_GEN_SETTINGS_ROW(2611), + SPI_GEN_SETTINGS_ROW(2484), + SPI_GEN_SETTINGS_ROW(2369), + SPI_GEN_SETTINGS_ROW(2257), + SPI_GEN_SETTINGS_ROW(2152), + SPI_GEN_SETTINGS_ROW(2052), + SPI_GEN_SETTINGS_ROW(1956), + SPI_GEN_SETTINGS_ROW(1866), + SPI_GEN_SETTINGS_ROW(1779), + SPI_GEN_SETTINGS_ROW(1695), + SPI_GEN_SETTINGS_ROW(1615), + SPI_GEN_SETTINGS_ROW(1539), + SPI_GEN_SETTINGS_ROW(1468), + SPI_GEN_SETTINGS_ROW(1398), + SPI_GEN_SETTINGS_ROW(1333), + SPI_GEN_SETTINGS_ROW(1271), + SPI_GEN_SETTINGS_ROW(1212), + SPI_GEN_SETTINGS_ROW(1155), + SPI_GEN_SETTINGS_ROW(1101), + SPI_GEN_SETTINGS_ROW(1049), + SPI_GEN_SETTINGS_ROW(1000), + SPI_GEN_SETTINGS_ROW(953), + SPI_GEN_SETTINGS_ROW(909), + SPI_GEN_SETTINGS_ROW(866), + SPI_GEN_SETTINGS_ROW(826), + SPI_GEN_SETTINGS_ROW(787), + SPI_GEN_SETTINGS_ROW(750), + SPI_GEN_SETTINGS_ROW(715), + SPI_GEN_SETTINGS_ROW(682), + SPI_GEN_SETTINGS_ROW(650), + SPI_GEN_SETTINGS_ROW(619), + SPI_GEN_SETTINGS_ROW(590), + SPI_GEN_SETTINGS_ROW(563), + SPI_GEN_SETTINGS_ROW(536), + SPI_GEN_SETTINGS_ROW(511), + SPI_GEN_SETTINGS_ROW(487), + SPI_GEN_SETTINGS_ROW(465), + SPI_GEN_SETTINGS_ROW(443), + SPI_GEN_SETTINGS_ROW(422), + SPI_GEN_SETTINGS_ROW(402), + SPI_GEN_SETTINGS_ROW(384), + SPI_GEN_SETTINGS_ROW(366), + SPI_GEN_SETTINGS_ROW(349), + SPI_GEN_SETTINGS_ROW(332), + SPI_GEN_SETTINGS_ROW(317), + SPI_GEN_SETTINGS_ROW(302), + SPI_GEN_SETTINGS_ROW(288), + SPI_GEN_SETTINGS_ROW(274), + SPI_GEN_SETTINGS_ROW(261), + SPI_GEN_SETTINGS_ROW(249), + SPI_GEN_SETTINGS_ROW(238), + SPI_GEN_SETTINGS_ROW(226), + SPI_GEN_SETTINGS_ROW(216), + SPI_GEN_SETTINGS_ROW(206), + SPI_GEN_SETTINGS_ROW(196), + SPI_GEN_SETTINGS_ROW(187), + SPI_GEN_SETTINGS_ROW(178), + SPI_GEN_SETTINGS_ROW(170), + SPI_GEN_SETTINGS_ROW(162), + SPI_GEN_SETTINGS_ROW(154), + SPI_GEN_SETTINGS_ROW(147), + SPI_GEN_SETTINGS_ROW(140), + SPI_GEN_SETTINGS_ROW(134), + SPI_GEN_SETTINGS_ROW(128), + SPI_GEN_SETTINGS_ROW(122), + SPI_GEN_SETTINGS_ROW(116), + SPI_GEN_SETTINGS_ROW(111), + SPI_GEN_SETTINGS_ROW(105), + SPI_GEN_SETTINGS_ROW(100), + SPI_GEN_SETTINGS_ROW(95.4), + SPI_GEN_SETTINGS_ROW(90.9), + SPI_GEN_SETTINGS_ROW(86.6), + SPI_GEN_SETTINGS_ROW(82.6), + SPI_GEN_SETTINGS_ROW(78.7), + SPI_GEN_SETTINGS_ROW(75.0), + SPI_GEN_SETTINGS_ROW(71.5), + SPI_GEN_SETTINGS_ROW(68.2), + SPI_GEN_SETTINGS_ROW(65.0), + SPI_GEN_SETTINGS_ROW(61.9), + SPI_GEN_SETTINGS_ROW(59.0), + SPI_GEN_SETTINGS_ROW(56.3), + SPI_GEN_SETTINGS_ROW(53.6), + SPI_GEN_SETTINGS_ROW(51.1), + }; + static volatile SPISetting_t SPICurrentSettings; +#endif + +#if (ARCH == ARCH_AVR8) + static const uint8_t SPIMaskFromSCKDuration[] PROGMEM = + { + #if (F_CPU == 8000000) + SPI_SPEED_FCPU_DIV_2, // AVRStudio = 8MHz SPI, Actual = 4MHz SPI + SPI_SPEED_FCPU_DIV_2, // AVRStudio = 4MHz SPI, Actual = 4MHz SPI + SPI_SPEED_FCPU_DIV_4, // AVRStudio = 2MHz SPI, Actual = 2MHz SPI + SPI_SPEED_FCPU_DIV_8, // AVRStudio = 1MHz SPI, Actual = 1MHz SPI + SPI_SPEED_FCPU_DIV_16, // AVRStudio = 500KHz SPI, Actual = 500KHz SPI + SPI_SPEED_FCPU_DIV_32, // AVRStudio = 250KHz SPI, Actual = 250KHz SPI + SPI_SPEED_FCPU_DIV_64, // AVRStudio = 125KHz SPI, Actual = 125KHz SPI + #elif (F_CPU == 16000000) + SPI_SPEED_FCPU_DIV_2, // AVRStudio = 8MHz SPI, Actual = 8MHz SPI + SPI_SPEED_FCPU_DIV_4, // AVRStudio = 4MHz SPI, Actual = 4MHz SPI + SPI_SPEED_FCPU_DIV_8, // AVRStudio = 2MHz SPI, Actual = 2MHz SPI + SPI_SPEED_FCPU_DIV_16, // AVRStudio = 1MHz SPI, Actual = 1MHz SPI + SPI_SPEED_FCPU_DIV_32, // AVRStudio = 500KHz SPI, Actual = 500KHz SPI + SPI_SPEED_FCPU_DIV_64, // AVRStudio = 250KHz SPI, Actual = 250KHz SPI + SPI_SPEED_FCPU_DIV_128 // AVRStudio = 125KHz SPI, Actual = 125KHz SPI + #elif (F_CPU == 32000000) + SPI_SPEED_FCPU_DIV_4, // AVRStudio = 8MHz SPI, Actual = 8MHz SPI + SPI_SPEED_FCPU_DIV_8, // AVRStudio = 4MHz SPI, Actual = 4MHz SPI + SPI_SPEED_FCPU_DIV_16, // AVRStudio = 2MHz SPI, Actual = 2MHz SPI + SPI_SPEED_FCPU_DIV_32, // AVRStudio = 1MHz SPI, Actual = 1MHz SPI + SPI_SPEED_FCPU_DIV_64, // AVRStudio = 500KHz SPI, Actual = 500KHz SPI + SPI_SPEED_FCPU_DIV_128, // AVRStudio = 250KHz SPI, Actual = 250KHz SPI + #elif (F_CPU == 48000000) + SPI_SPEED_FCPU_DIV_4, // AVRStudio = 8MHz SPI, Actual = 12MHz SPI + SPI_SPEED_FCPU_DIV_8, // AVRStudio = 4MHz SPI, Actual = 6MHz SPI + SPI_SPEED_FCPU_DIV_16, // AVRStudio = 2MHz SPI, Actual = 3MHz SPI + SPI_SPEED_FCPU_DIV_32, // AVRStudio = 1MHz SPI, Actual = 1,5MHz SPI + SPI_SPEED_FCPU_DIV_64, // AVRStudio = 500KHz SPI, Actual = 750KHz SPI + SPI_SPEED_FCPU_DIV_128, // AVRStudio = 250KHz SPI, Actual = 375KHz SPI + #else + #error No SPI prescaler masks for chosen F_CPU speed. + #endif + }; + #define SPI_TABLE_SIZE() (sizeof(SPIMaskFromSCKDuration)) + + /** Lookup table to convert the slower ISP speeds into a compare value for the software SPI driver. + * + * \hideinitializer + */ + static const uint16_t TimerCompareFromSCKDuration[] PROGMEM = + { + ISP_TIMER_COMP(96386), ISP_TIMER_COMP(89888), ISP_TIMER_COMP(84211), ISP_TIMER_COMP(79208), ISP_TIMER_COMP(74767), + ISP_TIMER_COMP(70797), ISP_TIMER_COMP(67227), ISP_TIMER_COMP(64000), ISP_TIMER_COMP(61069), ISP_TIMER_COMP(58395), + ISP_TIMER_COMP(55945), ISP_TIMER_COMP(51613), ISP_TIMER_COMP(49690), ISP_TIMER_COMP(47905), ISP_TIMER_COMP(46243), + ISP_TIMER_COMP(43244), ISP_TIMER_COMP(41885), ISP_TIMER_COMP(39409), ISP_TIMER_COMP(38278), ISP_TIMER_COMP(36200), + ISP_TIMER_COMP(34335), ISP_TIMER_COMP(32654), ISP_TIMER_COMP(31129), ISP_TIMER_COMP(29740), ISP_TIMER_COMP(28470), + ISP_TIMER_COMP(27304), ISP_TIMER_COMP(25724), ISP_TIMER_COMP(24768), ISP_TIMER_COMP(23461), ISP_TIMER_COMP(22285), + ISP_TIMER_COMP(21221), ISP_TIMER_COMP(20254), ISP_TIMER_COMP(19371), ISP_TIMER_COMP(18562), ISP_TIMER_COMP(17583), + ISP_TIMER_COMP(16914), ISP_TIMER_COMP(16097), ISP_TIMER_COMP(15356), ISP_TIMER_COMP(14520), ISP_TIMER_COMP(13914), + ISP_TIMER_COMP(13224), ISP_TIMER_COMP(12599), ISP_TIMER_COMP(12031), ISP_TIMER_COMP(11511), ISP_TIMER_COMP(10944), + ISP_TIMER_COMP(10431), ISP_TIMER_COMP(9963), ISP_TIMER_COMP(9468), ISP_TIMER_COMP(9081), ISP_TIMER_COMP(8612), + ISP_TIMER_COMP(8239), ISP_TIMER_COMP(7851), ISP_TIMER_COMP(7498), ISP_TIMER_COMP(7137), ISP_TIMER_COMP(6809), + ISP_TIMER_COMP(6478), ISP_TIMER_COMP(6178), ISP_TIMER_COMP(5879), ISP_TIMER_COMP(5607), ISP_TIMER_COMP(5359), + ISP_TIMER_COMP(5093), ISP_TIMER_COMP(4870), ISP_TIMER_COMP(4633), ISP_TIMER_COMP(4418), ISP_TIMER_COMP(4209), + ISP_TIMER_COMP(4019), ISP_TIMER_COMP(3823), ISP_TIMER_COMP(3645), ISP_TIMER_COMP(3474), ISP_TIMER_COMP(3310), + ISP_TIMER_COMP(3161), ISP_TIMER_COMP(3011), ISP_TIMER_COMP(2869), ISP_TIMER_COMP(2734), ISP_TIMER_COMP(2611), + ISP_TIMER_COMP(2484), ISP_TIMER_COMP(2369), ISP_TIMER_COMP(2257), ISP_TIMER_COMP(2152), ISP_TIMER_COMP(2052), + ISP_TIMER_COMP(1956), ISP_TIMER_COMP(1866), ISP_TIMER_COMP(1779), ISP_TIMER_COMP(1695), ISP_TIMER_COMP(1615), + ISP_TIMER_COMP(1539), ISP_TIMER_COMP(1468), ISP_TIMER_COMP(1398), ISP_TIMER_COMP(1333), ISP_TIMER_COMP(1271), + ISP_TIMER_COMP(1212), ISP_TIMER_COMP(1155), ISP_TIMER_COMP(1101), ISP_TIMER_COMP(1049), ISP_TIMER_COMP(1000), + ISP_TIMER_COMP(953), ISP_TIMER_COMP(909), ISP_TIMER_COMP(866), ISP_TIMER_COMP(826), ISP_TIMER_COMP(787), + ISP_TIMER_COMP(750), ISP_TIMER_COMP(715), ISP_TIMER_COMP(682), ISP_TIMER_COMP(650), ISP_TIMER_COMP(619), + ISP_TIMER_COMP(590), ISP_TIMER_COMP(563), ISP_TIMER_COMP(536), ISP_TIMER_COMP(511), ISP_TIMER_COMP(487), + ISP_TIMER_COMP(465), ISP_TIMER_COMP(443), ISP_TIMER_COMP(422), ISP_TIMER_COMP(402), ISP_TIMER_COMP(384), + ISP_TIMER_COMP(366), ISP_TIMER_COMP(349), ISP_TIMER_COMP(332), ISP_TIMER_COMP(317), ISP_TIMER_COMP(302), + ISP_TIMER_COMP(288), ISP_TIMER_COMP(274), ISP_TIMER_COMP(261), ISP_TIMER_COMP(249), ISP_TIMER_COMP(238), + ISP_TIMER_COMP(226), ISP_TIMER_COMP(216), ISP_TIMER_COMP(206), ISP_TIMER_COMP(196), ISP_TIMER_COMP(187), + ISP_TIMER_COMP(178), ISP_TIMER_COMP(170), ISP_TIMER_COMP(162), ISP_TIMER_COMP(154), ISP_TIMER_COMP(147), + ISP_TIMER_COMP(140), ISP_TIMER_COMP(134), ISP_TIMER_COMP(128), ISP_TIMER_COMP(122), ISP_TIMER_COMP(116), + ISP_TIMER_COMP(111), ISP_TIMER_COMP(105), ISP_TIMER_COMP(100), ISP_TIMER_COMP(95.4), ISP_TIMER_COMP(90.9), + ISP_TIMER_COMP(86.6), ISP_TIMER_COMP(82.6), ISP_TIMER_COMP(78.7), ISP_TIMER_COMP(75.0), ISP_TIMER_COMP(71.5), + ISP_TIMER_COMP(68.2), ISP_TIMER_COMP(65.0), ISP_TIMER_COMP(61.9), ISP_TIMER_COMP(59.0), ISP_TIMER_COMP(56.3), + ISP_TIMER_COMP(53.6), ISP_TIMER_COMP(51.1) + }; + #endif -}; -/** Lookup table to convert the slower ISP speeds into a compare value for the software SPI driver. - * - * \hideinitializer - */ -static const uint16_t TimerCompareFromSCKDuration[] PROGMEM = -{ - ISP_TIMER_COMP(96386), ISP_TIMER_COMP(89888), ISP_TIMER_COMP(84211), ISP_TIMER_COMP(79208), ISP_TIMER_COMP(74767), - ISP_TIMER_COMP(70797), ISP_TIMER_COMP(67227), ISP_TIMER_COMP(64000), ISP_TIMER_COMP(61069), ISP_TIMER_COMP(58395), - ISP_TIMER_COMP(55945), ISP_TIMER_COMP(51613), ISP_TIMER_COMP(49690), ISP_TIMER_COMP(47905), ISP_TIMER_COMP(46243), - ISP_TIMER_COMP(43244), ISP_TIMER_COMP(41885), ISP_TIMER_COMP(39409), ISP_TIMER_COMP(38278), ISP_TIMER_COMP(36200), - ISP_TIMER_COMP(34335), ISP_TIMER_COMP(32654), ISP_TIMER_COMP(31129), ISP_TIMER_COMP(29740), ISP_TIMER_COMP(28470), - ISP_TIMER_COMP(27304), ISP_TIMER_COMP(25724), ISP_TIMER_COMP(24768), ISP_TIMER_COMP(23461), ISP_TIMER_COMP(22285), - ISP_TIMER_COMP(21221), ISP_TIMER_COMP(20254), ISP_TIMER_COMP(19371), ISP_TIMER_COMP(18562), ISP_TIMER_COMP(17583), - ISP_TIMER_COMP(16914), ISP_TIMER_COMP(16097), ISP_TIMER_COMP(15356), ISP_TIMER_COMP(14520), ISP_TIMER_COMP(13914), - ISP_TIMER_COMP(13224), ISP_TIMER_COMP(12599), ISP_TIMER_COMP(12031), ISP_TIMER_COMP(11511), ISP_TIMER_COMP(10944), - ISP_TIMER_COMP(10431), ISP_TIMER_COMP(9963), ISP_TIMER_COMP(9468), ISP_TIMER_COMP(9081), ISP_TIMER_COMP(8612), - ISP_TIMER_COMP(8239), ISP_TIMER_COMP(7851), ISP_TIMER_COMP(7498), ISP_TIMER_COMP(7137), ISP_TIMER_COMP(6809), - ISP_TIMER_COMP(6478), ISP_TIMER_COMP(6178), ISP_TIMER_COMP(5879), ISP_TIMER_COMP(5607), ISP_TIMER_COMP(5359), - ISP_TIMER_COMP(5093), ISP_TIMER_COMP(4870), ISP_TIMER_COMP(4633), ISP_TIMER_COMP(4418), ISP_TIMER_COMP(4209), - ISP_TIMER_COMP(4019), ISP_TIMER_COMP(3823), ISP_TIMER_COMP(3645), ISP_TIMER_COMP(3474), ISP_TIMER_COMP(3310), - ISP_TIMER_COMP(3161), ISP_TIMER_COMP(3011), ISP_TIMER_COMP(2869), ISP_TIMER_COMP(2734), ISP_TIMER_COMP(2611), - ISP_TIMER_COMP(2484), ISP_TIMER_COMP(2369), ISP_TIMER_COMP(2257), ISP_TIMER_COMP(2152), ISP_TIMER_COMP(2052), - ISP_TIMER_COMP(1956), ISP_TIMER_COMP(1866), ISP_TIMER_COMP(1779), ISP_TIMER_COMP(1695), ISP_TIMER_COMP(1615), - ISP_TIMER_COMP(1539), ISP_TIMER_COMP(1468), ISP_TIMER_COMP(1398), ISP_TIMER_COMP(1333), ISP_TIMER_COMP(1271), - ISP_TIMER_COMP(1212), ISP_TIMER_COMP(1155), ISP_TIMER_COMP(1101), ISP_TIMER_COMP(1049), ISP_TIMER_COMP(1000), - ISP_TIMER_COMP(953), ISP_TIMER_COMP(909), ISP_TIMER_COMP(866), ISP_TIMER_COMP(826), ISP_TIMER_COMP(787), - ISP_TIMER_COMP(750), ISP_TIMER_COMP(715), ISP_TIMER_COMP(682), ISP_TIMER_COMP(650), ISP_TIMER_COMP(619), - ISP_TIMER_COMP(590), ISP_TIMER_COMP(563), ISP_TIMER_COMP(536), ISP_TIMER_COMP(511), ISP_TIMER_COMP(487), - ISP_TIMER_COMP(465), ISP_TIMER_COMP(443), ISP_TIMER_COMP(422), ISP_TIMER_COMP(402), ISP_TIMER_COMP(384), - ISP_TIMER_COMP(366), ISP_TIMER_COMP(349), ISP_TIMER_COMP(332), ISP_TIMER_COMP(317), ISP_TIMER_COMP(302), - ISP_TIMER_COMP(288), ISP_TIMER_COMP(274), ISP_TIMER_COMP(261), ISP_TIMER_COMP(249), ISP_TIMER_COMP(238), - ISP_TIMER_COMP(226), ISP_TIMER_COMP(216), ISP_TIMER_COMP(206), ISP_TIMER_COMP(196), ISP_TIMER_COMP(187), - ISP_TIMER_COMP(178), ISP_TIMER_COMP(170), ISP_TIMER_COMP(162), ISP_TIMER_COMP(154), ISP_TIMER_COMP(147), - ISP_TIMER_COMP(140), ISP_TIMER_COMP(134), ISP_TIMER_COMP(128), ISP_TIMER_COMP(122), ISP_TIMER_COMP(116), - ISP_TIMER_COMP(111), ISP_TIMER_COMP(105), ISP_TIMER_COMP(100), ISP_TIMER_COMP(95.4), ISP_TIMER_COMP(90.9), - ISP_TIMER_COMP(86.6), ISP_TIMER_COMP(82.6), ISP_TIMER_COMP(78.7), ISP_TIMER_COMP(75.0), ISP_TIMER_COMP(71.5), - ISP_TIMER_COMP(68.2), ISP_TIMER_COMP(65.0), ISP_TIMER_COMP(61.9), ISP_TIMER_COMP(59.0), ISP_TIMER_COMP(56.3), - ISP_TIMER_COMP(53.6), ISP_TIMER_COMP(51.1) -}; + /** Currently selected SPI driver, either hardware (for fast ISP speeds) or software (for slower ISP speeds). */ bool ISPTarget_HardwareSPIMode = true; @@ -121,7 +342,6 @@ static volatile uint8_t ISPTarget_SoftSPI_Data; /** Number of bits left to transfer in the software SPI driver */ static volatile uint8_t ISPTarget_SoftSPI_BitsRemaining; - /** ISR to handle software SPI transmission and reception */ #if ARCH == ARCH_AVR8 ISR(TIMER1_COMPA_vect, ISR_BLOCK) @@ -152,31 +372,37 @@ ISR(TIMER1_COMPA_vect, ISR_BLOCK) PINB |= (1 << 1); } #elif ARCH == ARCH_XMEGA -ISR(TCC1_CCA_vect, ISR_BLOCK) +ISR(SW_SPI_TIMER_CCB_vect, ISR_BLOCK) { - /* Check if rising edge (output next bit) or falling edge (read in next bit) */ - if (!(SPI_PORT.IN & SPI_SCK_MASK)) + /* Falling edge and setup MOSI data */ + SPI_PORT.OUTCLR = SPI_SCK_MASK; + + if(ISPTarget_SoftSPI_BitsRemaining) { if (ISPTarget_SoftSPI_Data & (1 << 7)) - SPI_PORT.OUTSET = SPI_MOSI_MASK; + SPI_PORT.OUTSET = SPI_MOSI_MASK; else - SPI_PORT.OUTCLR = SPI_MOSI_MASK; + SPI_PORT.OUTCLR = SPI_MOSI_MASK; } else { - ISPTarget_SoftSPI_Data <<= 1; - - if (!(--ISPTarget_SoftSPI_BitsRemaining)) - { - SW_SPI_TIMER.CTRLA = TC_CLKSEL_OFF_gc; - SW_SPI_TIMER.INTCTRLA = TC0_OVFIF_bm; - } - - if (SPI_PORT.IN & SPI_MISO_MASK) - ISPTarget_SoftSPI_Data |= (1 << 0); + //No more bits + SPI_PORT.OUTSET = SPI_MOSI_MASK; + SW_SPI_TIMER.CTRLA = TC_CLKSEL_OFF_gc; } + +} - SPI_PORT.OUTTGL = SPI_SCK_MASK; +ISR(SW_SPI_TIMER_OVF_vect, ISR_BLOCK) +{ + /* Rising edge and read MISO data */ + SPI_PORT.OUTSET = SPI_SCK_MASK; + + ISPTarget_SoftSPI_Data <<= 1; + ISPTarget_SoftSPI_BitsRemaining--; + + if (SPI_PORT.IN & SPI_MISO_MASK) + ISPTarget_SoftSPI_Data |= (1 << 0); } #endif @@ -186,36 +412,66 @@ ISR(TCC1_CCA_vect, ISR_BLOCK) void ISPTarget_EnableTargetISP(void) { uint8_t SCKDuration = V2Params_GetParameterValue(PARAM_SCK_DURATION); + + #if (ARCH == ARCH_AVR8) + if (SCKDuration < SPI_TABLE_SIZE()) + { + ISPTarget_HardwareSPIMode = true; + + SPI_Init(pgm_read_byte(&SPIMaskFromSCKDuration[SCKDuration]) | SPI_ORDER_MSB_FIRST | + SPI_SCK_LEAD_RISING | SPI_SAMPLE_LEADING | SPI_MODE_MASTER); + } + else + { + ISPTarget_HardwareSPIMode = false; + DDRB |= ((1 << 1) | (1 << 2)); //MOSI and SCK High + PORTB |= ((1 << 0) | (1 << 3)); //Pullup on RST and MISO - if (SCKDuration < sizeof(SPIMaskFromSCKDuration)) - { - ISPTarget_HardwareSPIMode = true; -#if (ARCH == ARCH_AVR8) - SPI_Init(pgm_read_byte(&SPIMaskFromSCKDuration[SCKDuration]) | SPI_ORDER_MSB_FIRST | - SPI_SCK_LEAD_RISING | SPI_SAMPLE_LEADING | SPI_MODE_MASTER); -#elif (ARCH == ARCH_XMEGA) - SPI_PORT.DIRSET = SPI_SCK_MASK | SPI_MOSI_MASK | PIN4_bm; - SPI_PORT.DIRCLR = SPI_MISO_MASK; - SPI_PORT.OUTSET = PIN4_bm; - SPI_Init(&SPI_REG, pgm_read_byte(&SPIMaskFromSCKDuration[SCKDuration]) | SPI_ORDER_MSB_FIRST | - SPI_SCK_LEAD_RISING | SPI_SAMPLE_LEADING | SPI_MODE_MASTER); -#endif - } - else - { - ISPTarget_HardwareSPIMode = false; - -#if ARCH == ARCH_AVR8 - DDRB |= ((1 << 1) | (1 << 2)); //MOSI and SCK High - PORTB |= ((1 << 0) | (1 << 3)); //Pullup on RST and MISO -#elif (ARCH == ARCH_XMEGA) - SPI_PORT.DIRSET = SPI_SCK_MASK | SPI_MOSI_MASK; - SPI_PORT.DIRCLR = SPI_MISO_MASK; - SPI_PORT.AUX_LINE_CTRL = PORT_OPC_PULLUP_gc; - SPI_PORT.SPI_MISO_CTRL = PORT_OPC_PULLUP_gc; -#endif - ISPTarget_ConfigureSoftwareSPI(SCKDuration); - } + ISPTarget_ConfigureSoftwareSPI(SCKDuration); + } + #elif (ARCH == ARCH_XMEGA) + //We need to default agains slowest value (AVR096) + if(SCKDuration >= sizeof(SPISettings)/sizeof(SPISettings[0])) + SCKDuration = sizeof(SPISettings)/sizeof(SPISettings[0]) - 1; + //Copy the selected line into RAM. For easy access on Precalculated values + memcpy_P((void *)&SPICurrentSettings, &SPISettings[SCKDuration], sizeof(SPICurrentSettings)); + + + if(!SPICurrentSettings.hardware_spi) + { + /* If the Frequency is too low we need to select software spi */ + ISPTarget_HardwareSPIMode = false; + SPI_PORT.DIRSET = SPI_SCK_MASK | SPI_MOSI_MASK; + SPI_PORT.DIRCLR = SPI_MISO_MASK; + SPI_PORT.AUX_LINE_CTRL = PORT_OPC_PULLUP_gc; + SPI_PORT.SPI_MISO_CTRL = PORT_OPC_PULLUP_gc; + ISPTarget_ConfigureSoftwareSPI(SCKDuration); + } + else + { + /* If we can be slow enough for HW Spi we are going to use it */ + ISPTarget_HardwareSPIMode = true; + //REMAP only available if Standalone SPI module is selected + #if defined(REMAP_SPI) && !defined(USART_SPI_MASTER) + PDI_PORT.REMAP |= PORT_SPI_bm; + #endif + + /* Setup pins */ + SPI_PORT.DIRSET = SPI_SCK_MASK | SPI_MOSI_MASK | PIN4_bm; + SPI_PORT.DIRCLR = SPI_MISO_MASK; + SPI_PORT.OUTSET = PIN4_bm; + #if defined(USART_SPI_MASTER) + //Use Precalculated values for setup SPI + SerialSPI_Init(&USART_SPI_REG, (USART_SPI_SCK_LEAD_RISING | USART_SPI_SAMPLE_LEADING | USART_SPI_ORDER_MSB_FIRST), 200000); + //Sadly hacky but needed, as we have BSEL not the Frequency... + USART_SPI_REG.BAUDCTRLB = (SPICurrentSettings.value >> 8); + USART_SPI_REG.BAUDCTRLA = (SPICurrentSettings.value & 0xFF); + #else + SPI_Init(&SPI_REG, (SPICurrentSettings.value & 0xFF) | SPI_ORDER_MSB_FIRST | + SPI_SCK_LEAD_RISING | SPI_SAMPLE_LEADING | SPI_MODE_MASTER); + #endif + } + #endif } /** Shuts down the current selected SPI driver (hardware or software, depending on the selected ISP speed) so that no @@ -238,9 +494,16 @@ void ISPTarget_DisableTargetISP(void) ISPTarget_ConfigureRescueClock(); } #elif (ARCH == ARCH_XMEGA) - if (ISPTarget_HardwareSPIMode) + if (SPICurrentSettings.hardware_spi) { - SPI_Disable(&SPI_REG); + #if defined(USART_SPI_MASTER) + SerialSPI_Disable(&USART_SPI_REG); + #else + SPI_Disable(&SPI_REG); + #endif + #if defined(REMAP_SPI) + PDI_PORT.REMAP &= ~PORT_SPI_bm; + #endif SPI_PORT.DIRCLR = SPI_SCK_MASK | SPI_MISO_MASK | SPI_MOSI_MASK | PIN4_bm; } else @@ -318,7 +581,8 @@ void ISPTarget_ConfigureSoftwareSPI(const uint8_t SCKDuration) SW_SPI_TIMER.CTRLA = TC_CLKSEL_OFF_gc; SW_SPI_TIMER.INTCTRLA = TC_OVFINTLVL_OFF_gc; SW_SPI_TIMER.CNT = 0; - SW_SPI_TIMER.PER = pgm_read_word(&TimerCompareFromSCKDuration[SCKDuration - sizeof(SPIMaskFromSCKDuration)]); + SW_SPI_TIMER.CCB = SPICurrentSettings.value - 1; + SW_SPI_TIMER.PER = SPICurrentSettings.value * 2 - 1; SW_SPI_TIMER.CTRLB = TC_WGMODE_NORMAL_gc; #endif } @@ -346,16 +610,15 @@ uint8_t ISPTarget_TransferSoftSPIByte(const uint8_t Byte) while (ISPTarget_SoftSPI_BitsRemaining && TimeoutTicksRemaining); TCCR1B = 0; #elif (ARCH == ARCH_XMEGA) - if (ISPTarget_SoftSPI_Data & (1 << 7)) - SPI_PORT.OUTSET = SPI_MOSI_MASK; - else - SPI_PORT.OUTCLR = SPI_MOSI_MASK; - SW_SPI_TIMER.CTRLA = TC_CLKSEL_OFF_gc; SW_SPI_TIMER.CNT = 0; - SW_SPI_TIMER.CTRLA = TC_CLKSEL_DIV64_gc; //TODO: Wrong? - while (ISPTarget_SoftSPI_BitsRemaining && TimeoutTicksRemaining); - SW_SPI_TIMER.CTRLA = TC_CLKSEL_OFF_gc; + SW_SPI_TIMER.INTCTRLA = TC_OVFINTLVL_MED_gc; + SW_SPI_TIMER.INTCTRLB = TC_CCBINTLVL_MED_gc; + SW_SPI_TIMER.CTRLA = SPICurrentSettings.prediv; + while (SW_SPI_TIMER.CTRLA & TC0_CLKSEL_gm) + ; + SW_SPI_TIMER.INTCTRLA = TC_OVFINTLVL_OFF_gc; + SW_SPI_TIMER.INTCTRLB = TC_CCBINTLVL_OFF_gc; #endif return ISPTarget_SoftSPI_Data; } From ed5ba7da538c87ffb386eac0cb7dcb651c514bd3 Mon Sep 17 00:00:00 2001 From: MasterQ Date: Thu, 23 Dec 2021 14:00:02 +0100 Subject: [PATCH 27/28] Updated configuration for to newly implented functionality and updated Values. Added ascii art schematic for default pinout. --- Projects/AVRISP-MKII/Config/AppConfig.h | 79 +++++++++++++++++++++---- 1 file changed, 66 insertions(+), 13 deletions(-) diff --git a/Projects/AVRISP-MKII/Config/AppConfig.h b/Projects/AVRISP-MKII/Config/AppConfig.h index d09b3bb7aa..b8978c2d14 100644 --- a/Projects/AVRISP-MKII/Config/AppConfig.h +++ b/Projects/AVRISP-MKII/Config/AppConfig.h @@ -54,19 +54,71 @@ #define VTARGET_ADC_CHANNEL 2 #define VTARGET_REF_VOLTS 5 #define VTARGET_SCALE_FACTOR 1 -// #define VTARGET_USE_INTERNAL_REF + #define VTARGET_USE_INTERNAL_REF #elif (ARCH == ARCH_XMEGA) - #define SPI_REG SPIC - #define SPI_PORT PORTC +/* Wiring in default config (REMAP SPI Enable or USART SPI Master) + * PORTC + * PIN + * 0 O---120Ohm---| + * O-- RESET (PDI/ISP PIN5) + * 1 O---120Ohm---| + * + * 2 O---180Ohm---O + * | + * 3 O---180Ohm---O + * | + * 4 x O-- MISO/DAT (PDI/ISP PIN1) + * | + * 5 O---120Ohm---|-- SCK (PDI/ISP PIN5) + * | + * 6 O---120Ohm---O + * + * 7 O---120Ohm------ MOSI (PDI/ISP PIN4) + * + * + * GND O---------------O--------- GND (PDI/ISP PIN6) + * | + * PA0 O----O-1.5KOhm--O + * | Scale theoritical 7.66667 with this Resistors, but we needed to adjust to 8.43333. + * O--10KOhm--O You can read voltage from target + * ? Or you can supply the target. We prefer to have addional Power OUT Pins for supply the target. + * VCC O---------???---O---------- VCC (PDI/ISP PIN2) (Dangerous! But can be helpfull, you can also leave it open or use other options) + * + * This allows to program PDI/ISP but only 3.3V!!!!!! + */ + //Remaping spi will swap SCK and MOSI (Same pinout as USART in SPI master mode) + #define REMAP_SPI + + //Use USART interface in SPI master mode instead of the SPI module. + //Recommended it allows higher precision of the SPI CLK. + #define USART_SPI_MASTER + + #ifdef USART_SPI_MASTER + #define USART_SPI_REG USARTC1 + #else + #define SPI_REG SPIC + #endif + + #define SPI_PORT PORTC + + #if defined(REMAP_SPI) || defined(USART_SPI_MASTER) + #define SPI_SCK_MASK (1 << 5) + #define SPI_SCK_CTRL PIN5CTRL + + #define SPI_MOSI_MASK (1 << 7) + #define SPI_MOSI_CTRL PIN7CTRL + #else + #define SPI_SCK_MASK (1 << 7) + #define SPI_SCK_CTRL PIN7CTRL + + #define SPI_MOSI_MASK (1 << 5) + #define SPI_MOSI_CTRL PIN5CTRL + #endif - #define SPI_SCK_MASK (1 << 7) - #define SPI_SCK_CTRL PIN7CTRL + #define SPI_MISO_MASK (1 << 6) + #define SPI_MISO_CTRL PIN6CTRL - #define SPI_MISO_MASK (1 << 6) - #define SPI_MISO_CTRL PIN6CTRL - #define SPI_MOSI_MASK (1 << 5) - #define SPI_MOSI_CTRL PIN5CTRL #define RESCUE_PORT PORTD #define RESCUE_TIMER TCD0 @@ -94,18 +146,19 @@ #define DELAY_TIMER_OVF_vect TCC0_OVF_vect #define SW_SPI_TIMER TCC1 #define SW_SPI_TIMER_CCA_vect TCC1_CCA_vect + #define SW_SPI_TIMER_CCB_vect TCC1_CCB_vect #define SW_SPI_TIMER_OVF_vect TCC1_OVF_vect #define SW_SPI_PIN_IRQ_vect PORTC_INT0_vect - #define VTARGET_ADC_CHANNEL 2 //Unimplemented - #define VTARGET_REF_VOLTS 5 //Unimplemented - #define VTARGET_SCALE_FACTOR 1 //Unimplemented + #define VTARGET_ADC_CHANNEL 1 //Hardcoded allways 1 Connected to PA1 + #define VTARGET_REF_VOLTS 1.00 //Hardcoded allways 1.00 + #define VTARGET_SCALE_FACTOR 8.43333 //GND<->R1<-ADC->R2<->SIGNAL | SCALE = (R1+R2)/R1 #endif #define ENABLE_ISP_PROTOCOL #define ENABLE_XPROG_PROTOCOL - #define NO_VTARGET_DETECT +// #define NO_VTARGET_DETECT // #define XCK_RESCUE_CLOCK_ENABLE // #define INVERTED_ISP_MISO From 0282577f93449dcea00b2338f66ca1dfb6e4a8ed Mon Sep 17 00:00:00 2001 From: MasterQ Date: Sun, 2 Jan 2022 19:59:30 +0100 Subject: [PATCH 28/28] Repaired Vtarget ADC --- Projects/AVRISP-MKII/Config/AppConfig.h | 2 +- Projects/AVRISP-MKII/Lib/V2Protocol.c | 2 +- Projects/AVRISP-MKII/Lib/V2ProtocolParams.c | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Projects/AVRISP-MKII/Config/AppConfig.h b/Projects/AVRISP-MKII/Config/AppConfig.h index b8978c2d14..00c71bf705 100644 --- a/Projects/AVRISP-MKII/Config/AppConfig.h +++ b/Projects/AVRISP-MKII/Config/AppConfig.h @@ -151,7 +151,7 @@ #define SW_SPI_PIN_IRQ_vect PORTC_INT0_vect #define VTARGET_ADC_CHANNEL 1 //Hardcoded allways 1 Connected to PA1 #define VTARGET_REF_VOLTS 1.00 //Hardcoded allways 1.00 - #define VTARGET_SCALE_FACTOR 8.43333 //GND<->R1<-ADC->R2<->SIGNAL | SCALE = (R1+R2)/R1 + #define VTARGET_SCALE_FACTOR 6.8 //GND<->R1<-ADC->R2<->SIGNAL | SCALE = (R1+R2)/R1 #endif #define ENABLE_ISP_PROTOCOL #define ENABLE_XPROG_PROTOCOL diff --git a/Projects/AVRISP-MKII/Lib/V2Protocol.c b/Projects/AVRISP-MKII/Lib/V2Protocol.c index 320047d812..5d7c1f66bd 100644 --- a/Projects/AVRISP-MKII/Lib/V2Protocol.c +++ b/Projects/AVRISP-MKII/Lib/V2Protocol.c @@ -84,7 +84,7 @@ void V2Protocol_Init(void) PORTA.DIRCLR = PIN0_bm; ADCA.REFCTRL = ADC_REFSEL_INT1V_gc; ADCA.PRESCALER = ADC_PRESCALER_DIV64_gc; - ADCA.CH0.CTRL = ADC_CH_GAIN_1X_gc; + ADCA.CH0.CTRL = ADC_CH_GAIN_1X_gc | ADC_CH_INPUTMODE_SINGLEENDED_gc; ADCA.CH0.MUXCTRL = ADC_CH_MUXPOS_PIN0_gc; ADCA.CTRLA = ADC_ENABLE_bm; #endif diff --git a/Projects/AVRISP-MKII/Lib/V2ProtocolParams.c b/Projects/AVRISP-MKII/Lib/V2ProtocolParams.c index 1ba9ff2663..b25ed2dab4 100644 --- a/Projects/AVRISP-MKII/Lib/V2ProtocolParams.c +++ b/Projects/AVRISP-MKII/Lib/V2ProtocolParams.c @@ -143,13 +143,13 @@ void V2Params_UpdateParamValues(void) uint32_t result = 0; for(uint8_t i = 0; i < 64; i++) { - while(!(ADCA.CH0.INTFLAGS & AC_AC0IF_bm)) + while(!(ADCA.CH0.INTFLAGS & ADC_CH0IF_bm)) ; result += ADCA.CH0.RES; - ADCA.CH0.INTFLAGS = AC_AC0IF_bm; + ADCA.CH0.INTFLAGS = ADC_CH0IF_bm; } result >>= 6; - V2Params_GetParamFromTable(PARAM_VTARGET)->ParamValue = (((uint16_t)(VTARGET_REF_VOLTS * 10 * VTARGET_SCALE_FACTOR) * result) / 1024); + V2Params_GetParamFromTable(PARAM_VTARGET)->ParamValue = (((uint16_t)(VTARGET_REF_VOLTS * 10 * VTARGET_SCALE_FACTOR) * result) / 4096); #endif }