From f69f03cb0d02937dee018264f0ac4e9be76fc1f4 Mon Sep 17 00:00:00 2001 From: Dean Camera Date: Thu, 3 Dec 2009 00:53:45 +0000 Subject: [PATCH] Started implementing the low level PDI protocol in the AVRISP project, for XMEGA device programming. --- LUFA.pnproj | 2 +- Projects/AVRISP/AVRISP.c | 1 - Projects/AVRISP/AVRISP.h | 1 - Projects/AVRISP/Lib/ISPProtocol.c | 2 +- Projects/AVRISP/Lib/PDIProtocol.c | 83 +++++++++++++-------- Projects/AVRISP/Lib/PDIProtocol.h | 3 +- Projects/AVRISP/Lib/PDITarget.c | 105 +++++++++++++++++++++++++++ Projects/AVRISP/Lib/PDITarget.h | 74 +++++++++++++++++++ Projects/AVRISP/makefile | 2 +- Projects/XPLAINBridge/Lib/SoftUART.c | 4 +- 10 files changed, 240 insertions(+), 37 deletions(-) create mode 100644 Projects/AVRISP/Lib/PDITarget.c create mode 100644 Projects/AVRISP/Lib/PDITarget.h diff --git a/LUFA.pnproj b/LUFA.pnproj index de32cdbd3f..fb1dc1a78b 100644 --- a/LUFA.pnproj +++ b/LUFA.pnproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/Projects/AVRISP/AVRISP.c b/Projects/AVRISP/AVRISP.c index 02292aa46f..c0572fca2f 100644 --- a/Projects/AVRISP/AVRISP.c +++ b/Projects/AVRISP/AVRISP.c @@ -70,7 +70,6 @@ void SetupHardware(void) /* Hardware Initialization */ LEDs_Init(); USB_Init(); - SerialStream_Init(9600, true); #if defined(ADC) /* Initialize the ADC converter for VTARGET level detection on supported AVR models */ diff --git a/Projects/AVRISP/AVRISP.h b/Projects/AVRISP/AVRISP.h index bf9763afb4..a0f4d5e792 100644 --- a/Projects/AVRISP/AVRISP.h +++ b/Projects/AVRISP/AVRISP.h @@ -47,7 +47,6 @@ #include #include #include - #include #if defined(ADC) #include diff --git a/Projects/AVRISP/Lib/ISPProtocol.c b/Projects/AVRISP/Lib/ISPProtocol.c index 8bfa4d4d7e..c023234c3a 100644 --- a/Projects/AVRISP/Lib/ISPProtocol.c +++ b/Projects/AVRISP/Lib/ISPProtocol.c @@ -61,7 +61,7 @@ void ISPProtocol_EnterISPMode(void) CurrentAddress = 0; - V2Protocol_DelayMS(Enter_ISP_Params.ExecutionDelayMS); + V2Protocol_DelayMS(Enter_ISP_Params.ExecutionDelayMS); SPI_Init(ISPTarget_GetSPIPrescalerMask() | SPI_SCK_LEAD_RISING | SPI_SAMPLE_LEADING | SPI_MODE_MASTER); while (Enter_ISP_Params.SynchLoops-- && (ResponseStatus == STATUS_CMD_FAILED)) diff --git a/Projects/AVRISP/Lib/PDIProtocol.c b/Projects/AVRISP/Lib/PDIProtocol.c index b095a49c5e..c919561435 100644 --- a/Projects/AVRISP/Lib/PDIProtocol.c +++ b/Projects/AVRISP/Lib/PDIProtocol.c @@ -35,7 +35,7 @@ * PDI Protocol handler, to process V2 Protocol wrapped PDI commands used in Atmel programmer devices. */ -#define INCLUDE_FROM_XPROG_C +#define INCLUDE_FROM_PDIPROTOCOL_C #include "PDIProtocol.h" uint32_t XPROG_Param_NVMBase; @@ -91,6 +91,59 @@ void PDIProtocol_XPROG_Command(void) } } +static void PDIProtocol_EnterXPROGMode(void) +{ + uint8_t ReturnStatus = XPRG_ERR_OK; + + Endpoint_ClearOUT(); + Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN); + + PDIDATA_LINE_DDR |= PDIDATA_LINE_MASK; + PDICLOCK_LINE_DDR |= PDICLOCK_LINE_MASK; + + PDIDATA_LINE_PORT |= PDIDATA_LINE_MASK; + + _delay_us(1); + + for (uint8_t i = 0; i < 16; i++) + { + PDICLOCK_LINE_PORT ^= PDICLOCK_LINE_MASK; + PDICLOCK_LINE_PORT ^= PDICLOCK_LINE_MASK; + } + + static const uint8_t NVMKey[8] = {0x12, 0x89, 0xAB, 0x45, 0xCD, 0xD8, 0x88, 0xFF}; + + PDITarget_SendByte(PDI_CMD_KEY); + for (uint8_t i = 0; i < 8; i++) + PDITarget_SendByte(NVMKey[i]); + + PDITarget_SendByte(PDI_CMD_LDCS | PD_STATUS_REG); + if (!(PDITarget_ReceiveByte() & PDI_STATUS_NVM)) + ReturnStatus = XPRG_ERR_FAILED; + + Endpoint_Write_Byte(CMD_XPROG); + Endpoint_Write_Byte(XPRG_CMD_ENTER_PROGMODE); + Endpoint_Write_Byte(ReturnStatus); + Endpoint_ClearIN(); +} + +static void PDIProtocol_LeaveXPROGMode(void) +{ + Endpoint_ClearOUT(); + Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN); + + PDIDATA_LINE_DDR &= ~PDIDATA_LINE_MASK; + PDICLOCK_LINE_DDR &= ~PDICLOCK_LINE_MASK; + + PDIDATA_LINE_PORT &= ~PDIDATA_LINE_MASK; + PDICLOCK_LINE_PORT &= ~PDICLOCK_LINE_MASK; + + Endpoint_Write_Byte(CMD_XPROG); + Endpoint_Write_Byte(XPRG_CMD_LEAVE_PROGMODE); + Endpoint_Write_Byte(XPRG_ERR_OK); + Endpoint_ClearIN(); +} + static void PDIProtocol_EraseChip(void) { uint8_t ReturnStatus = XPRG_ERR_OK; @@ -209,34 +262,6 @@ static void PDIProtocol_ReadCRC(void) Endpoint_ClearIN(); } -static void PDIProtocol_EnterXPROGMode(void) -{ - uint8_t ReturnStatus = XPRG_ERR_OK; - - Endpoint_ClearOUT(); - Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN); - - // TODO: Enter device programming mode here via PDI protocol - - Endpoint_Write_Byte(CMD_XPROG); - Endpoint_Write_Byte(XPRG_CMD_ENTER_PROGMODE); - Endpoint_Write_Byte(ReturnStatus); - Endpoint_ClearIN(); -} - -static void PDIProtocol_LeaveXPROGMode(void) -{ - Endpoint_ClearOUT(); - Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN); - - // TODO: Exit device programming mode here via PDI protocol - - Endpoint_Write_Byte(CMD_XPROG); - Endpoint_Write_Byte(XPRG_CMD_LEAVE_PROGMODE); - Endpoint_Write_Byte(XPRG_ERR_OK); - Endpoint_ClearIN(); -} - static void PDIProtocol_SetParam(void) { uint8_t ReturnStatus = XPRG_ERR_OK; diff --git a/Projects/AVRISP/Lib/PDIProtocol.h b/Projects/AVRISP/Lib/PDIProtocol.h index 2710b2ff51..53388d0609 100644 --- a/Projects/AVRISP/Lib/PDIProtocol.h +++ b/Projects/AVRISP/Lib/PDIProtocol.h @@ -41,6 +41,7 @@ #include #include "V2Protocol.h" + #include "PDITarget.h" /* Macros: */ #define XPRG_CMD_ENTER_PROGMODE 0x01 @@ -87,7 +88,7 @@ void PDIProtocol_XPROG_SetMode(void); void PDIProtocol_XPROG_Command(void); - #if defined(INCLUDE_FROM_XPROG_C) + #if defined(INCLUDE_FROM_PDIPROTOCOL_C) static void PDIProtocol_EnterXPROGMode(void); static void PDIProtocol_LeaveXPROGMode(void); static void PDIProtocol_SetParam(void); diff --git a/Projects/AVRISP/Lib/PDITarget.c b/Projects/AVRISP/Lib/PDITarget.c new file mode 100644 index 0000000000..57a1a29eeb --- /dev/null +++ b/Projects/AVRISP/Lib/PDITarget.c @@ -0,0 +1,105 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2009. + + dean [at] fourwalledcubicle [dot] com + www.fourwalledcubicle.com +*/ + +/* + Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, and distribute this software + and its documentation for any purpose and without fee is hereby + granted, provided that the above copyright notice appear in all + copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +#if defined(ENABLE_XPROG_PROTOCOL) + +/** \file + * + * Target-related functions for the PDI Protocol decoder. + */ + +#define INCLUDE_FROM_PDITARGET_C +#include "PDITarget.h" + +void PDITarget_SendByte(uint8_t Byte) +{ + PDIDATA_LINE_PORT &= ~PDIDATA_LINE_MASK; + + PDICLOCK_LINE_PORT ^= PDICLOCK_LINE_MASK; + PDICLOCK_LINE_PORT ^= PDICLOCK_LINE_MASK; + + for (uint8_t i = 0; i < 8; i++) + { + if (Byte & 0x01) + PDIDATA_LINE_PORT |= PDIDATA_LINE_MASK; + else + PDIDATA_LINE_PORT &= ~PDIDATA_LINE_MASK; + + Byte >>= 1; + + PDICLOCK_LINE_PORT ^= PDICLOCK_LINE_MASK; + PDICLOCK_LINE_PORT ^= PDICLOCK_LINE_MASK; + } + + PDIDATA_LINE_PORT |= PDIDATA_LINE_MASK; + + PDICLOCK_LINE_PORT ^= PDICLOCK_LINE_MASK; + PDICLOCK_LINE_PORT ^= PDICLOCK_LINE_MASK; + PDICLOCK_LINE_PORT ^= PDICLOCK_LINE_MASK; + PDICLOCK_LINE_PORT ^= PDICLOCK_LINE_MASK; +} + +uint8_t PDITarget_ReceiveByte(void) +{ + uint8_t ReceivedByte = 0; + + PDIDATA_LINE_DDR &= ~PDIDATA_LINE_MASK; + + bool FoundStartBit; + + do + { + PDICLOCK_LINE_PORT ^= PDICLOCK_LINE_MASK; + PDICLOCK_LINE_PORT ^= PDICLOCK_LINE_MASK; + FoundStartBit = !(PDIDATA_LINE_PIN & PDIDATA_LINE_MASK); + } while (!FoundStartBit); + + for (uint8_t i = 0; i < 8; i++) + { + if (PDIDATA_LINE_PIN & PDIDATA_LINE_MASK) + ReceivedByte |= 0x01; + + ReceivedByte <<= 1; + + PDICLOCK_LINE_PORT ^= PDICLOCK_LINE_MASK; + PDICLOCK_LINE_PORT ^= PDICLOCK_LINE_MASK; + } + + PDICLOCK_LINE_PORT ^= PDICLOCK_LINE_MASK; + PDICLOCK_LINE_PORT ^= PDICLOCK_LINE_MASK; + PDICLOCK_LINE_PORT ^= PDICLOCK_LINE_MASK; + PDICLOCK_LINE_PORT ^= PDICLOCK_LINE_MASK; + + PDIDATA_LINE_DDR |= PDIDATA_LINE_MASK; + + return ReceivedByte; +} + +#endif diff --git a/Projects/AVRISP/Lib/PDITarget.h b/Projects/AVRISP/Lib/PDITarget.h new file mode 100644 index 0000000000..cc8c7dbc5c --- /dev/null +++ b/Projects/AVRISP/Lib/PDITarget.h @@ -0,0 +1,74 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2009. + + dean [at] fourwalledcubicle [dot] com + www.fourwalledcubicle.com +*/ + +/* + Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, and distribute this software + and its documentation for any purpose and without fee is hereby + granted, provided that the above copyright notice appear in all + copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * + * Header file for PDITarget.c. + */ + +#ifndef _PDI_TARGET_ +#define _PDI_TARGET_ + + /* Includes: */ + #include + #include + + /* Defines: */ + #define PDIDATA_LINE_PORT PORTB + #define PDIDATA_LINE_DDR DDRB + #define PDIDATA_LINE_PIN PINB + #define PDIDATA_LINE_MASK (1 << 2) + + #define PDICLOCK_LINE_PORT RESET_LINE_PORT + #define PDICLOCK_LINE_DDR RESET_LINE_DDR + #define PDICLOCK_LINE_MASK RESET_LINE_MASK + + #define PDI_CMD_LDS 0x00 + #define PDI_CMD_LD 0x20 + #define PDI_CMD_STS 0x40 + #define PDI_CMD_ST 0x60 + #define PDI_CMD_LDCS 0x80 + #define PDI_CMD_REPEAT 0xA0 + #define PDI_CMD_STCS 0xC0 + #define PDI_CMD_KEY 0xE0 + + #define PD_STATUS_REG 0 + #define PD_RESET_REG 1 + #define PD_CTRL_REG 2 + + #define PDI_STATUS_NVM (1 << 1) + #define PDI_RESET_KEY 0x59 + + + /* Function Prototypes: */ + void PDITarget_SendByte(uint8_t Byte); + uint8_t PDITarget_ReceiveByte(void); + +#endif diff --git a/Projects/AVRISP/makefile b/Projects/AVRISP/makefile index 91e6b08991..cf4fa00783 100644 --- a/Projects/AVRISP/makefile +++ b/Projects/AVRISP/makefile @@ -132,7 +132,7 @@ SRC = $(TARGET).c \ Lib/ISPProtocol.c \ Lib/ISPTarget.c \ Lib/PDIProtocol.c \ - $(LUFA_PATH)/LUFA/Drivers/Peripheral/SerialStream.c \ + Lib/PDITarget.c \ $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/DevChapter9.c \ $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Endpoint.c \ $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Host.c \ diff --git a/Projects/XPLAINBridge/Lib/SoftUART.c b/Projects/XPLAINBridge/Lib/SoftUART.c index 390e6d59b5..ca3eaf7ab9 100644 --- a/Projects/XPLAINBridge/Lib/SoftUART.c +++ b/Projects/XPLAINBridge/Lib/SoftUART.c @@ -68,7 +68,7 @@ void SoftUART_Init(void) { OCR2B = TCNT2 + 1; // force first compare TCCR2A = (1 << COM2B1) | (1 << COM2B0); // T1 mode 0 - TCCR2B = (1 << FOC2B) | (1 << CS21); // CLK/8, T1 mode 0 + TCCR2B = (1 << FOC2B) | (1 << CS21); // CLK/8, T1 mode 0 TIMSK2 = (1 << OCIE2B); // enable tx and wait for start EICRA = (1 << ISC01); // -ve edge EIMSK = (1 << INT0); // enable INT0 interrupt @@ -76,7 +76,7 @@ void SoftUART_Init(void) stx_count = 0; // nothing to send srx_done = 0; // nothing received STXPORT |= 1 << STX; // TX output - STXDDR |= 1 << STX; // TX output + STXDDR |= 1 << STX; // TX output SRXPORT |= (1 << SRX); // pullup on INT0 }