Moved all source to the trunk directory.
[pub/lufa.git] / Projects / AVRISP_Programmer / AVRISP_Firmware_Design.txt
diff --git a/Projects/AVRISP_Programmer/AVRISP_Firmware_Design.txt b/Projects/AVRISP_Programmer/AVRISP_Firmware_Design.txt
new file mode 100644 (file)
index 0000000..643454d
--- /dev/null
@@ -0,0 +1,176 @@
+Instructions for converting the LUFA USBtoSerial Demo to an AVR ISP Programmer.\r
+By Opendous Inc., Copyright under the Creative Commons Attribution License:\r
+http://creativecommons.org/licenses/by/3.0/\r
+\r
+1) Start with the LUFA/Demos/USBtoSerial firmware.\r
+    - rename USBtoSerial.c, USBtoSerial.h, and USBtoSerial.aps to\r
+      AVRISP_Programmer.*\r
+    - edit AVRISP_Programmer.aps and rename all instances of "USBtoSerial" to\r
+      "AVRISP_Programmer"\r
+    - copy AVRISP_Programmer.txt from an older version of AVRISP_Programmer\r
+\r
+2) Edit makefile by changing TARGET from "USBtoSerial" to "AVRISP_Programmer"\r
+\r
+3) Edit AVRISP_Programmer.h:\r
+    - change ifdef _USB_TO_SERIAL_H to _AVRISP_PROGRAMMER_H_\r
+    - rename ReconfigureUSART(void) to ReconfigureSPI(void)\r
+    - add  void processHostSPIRequest(void);  &  void delay_ms(uint8_t dly);\r
+    - replace the define for Serial.h with one for SPI.h:\r
+      #include <libs/LUFA/Drivers/AT90USBXXX/SPI.h>\r
+\r
+4) Make alterations to Descriptors.c\r
+    - change manufacturer string to "www.AVRopendous.org", length=19\r
+    - change product string to "LUFA-Based AVR ISP Programmer", length=29\r
+\r
+5) Edit Ringbuff.h to enable the Peek Command:  #define BUFF_USEPEEK\r
+\r
+6) Edit AVRISP_Programmer.c:\r
+    - change #include "USBtoSerial.h"  to  #include "AVRISP_Programmer.h"\r
+    - change BUTTLOADTAG(ProjName to "LUFA AVR910 ISP Programmer"\r
+    - in main(), rename ReconfigureUSART() to Reconfigure();\r
+    - in EVENT_HANDLER(USB_UnhandledControlPacket), rename ReconfigureUSART\r
+    - delete the ISRs: ISR(USART1_RX_vect)  &  ISR(USART1_TX_vect)\r
+    - delete ReconfigureUSART(void)\r
+    - add  void ReconfigureSPI(void),  void processHostSPIRequest(void),\r
+      and  void delay_ms(uint8_t dly)  from a previous version\r
+    - add Timer1 and SPI initialization code to main():\r
+           /* Hardware Initialization */\r
+           //LEDs_Init();\r
+           DDRB = 0;\r
+           PORTB = 0;\r
+           DDRC |= ((1 << PC2) | (1 << PC4) | (1 << PC5) | (1 << PC6) | (1 << PC7)); //AT90USBxx2\r
+           // PC2 is also used for RESET, so set it HIGH initially - note 'P' command sets it to LOW (Active)\r
+           PORTC |= ((1 << PC2) | (1 << PC4) | (1 << PC5) | (1 << PC6) | (1 << PC7)); //AT90USBxx2\r
+           DDRD = 0;\r
+           PORTD = (1 << PB7); // only PB7(HWB) should be High as this is the bootloader pin\r
+           // Prepare PortB for SPI - set PB0(^SS), PB1(SCK), PB2(MOSI) as output as well as all other pins except PB3(MISO)\r
+           DDRB = (1 << PB0) | (1 << PB1) | (1 << PB2) | (0 << PB3) | (1 << PB4) | (1 << PB5) | (1 << PB6) | (1 << PB7);\r
+           PORTB |= (1 << PB0);\r
+\r
+           // initialize Timer1 for use in delay function\r
+           TCCR1A = 0;\r
+           //TCCR1B = (1 << CS10); // no prescaling, use CLK\r
+           TCCR1B = ((1 << CS12) | (1 << CS10)); // prescale by CLK/1024\r
+           // 8MHz/1024 = 7813 ticks per second --> ~8 ticks per millisecond (ms)\r
+           timerval = TCNT1; // start timer1\r
+\r
+    - In TASK(CDC_Task) in the\r
+        if (USB_IsConnected) {\r
+            if (Endpoint_ReadWriteAllowed()) {\r
+                while (Endpoint_BytesInEndpoint()) {\r
+                    ...\r
+      structure, after  Buffer_StoreElement(&Rx_Buffer, Endpoint_Read_Byte()):\r
+\r
+        /* Each time there is an element, check which comand should be\r
+               run and if enough data is available to run that command.\r
+               There are 1-byte, 2-byte, 3-byte, 4-byte commands, and 5-byte commands\r
+               Remember that the "which command" byte counts as 1 */\r
+        if (Rx_Buffer.Elements == 0) {\r
+               // do nothing, wait for data\r
+        } else {\r
+               tempByte = Buffer_PeekElement(&Rx_Buffer); // peek at first element\r
+\r
+                       /* make sure the issued command and associated data are all ready */\r
+               if (Rx_Buffer.Elements == 1) { // zero data byte command\r
+                       if ((tempByte == 'P') | (tempByte == 'a') | (tempByte == 'm') |\r
+                       (tempByte == 'R') | (tempByte == 'd') | (tempByte == 'e') |\r
+                       (tempByte == 'L') | (tempByte == 's') | (tempByte == 't') | \r
+                       (tempByte == 'S') | (tempByte == 'V') | (tempByte == 'v') |\r
+                       (tempByte == 'p') | (tempByte == 'F')) {\r
+               processHostSPIRequest(); // command has enough data, process it\r
+                       }\r
+               } else if (Rx_Buffer.Elements == 2) { // one data byte command\r
+                       if ((tempByte == 'T') | (tempByte == 'c') | (tempByte == 'C') |\r
+                               (tempByte == 'D') | (tempByte == 'l') | (tempByte == 'f') |\r
+                               (tempByte == 'x') | (tempByte == 'y')) {\r
+                               processHostSPIRequest(); // command has enough data, process it\r
+                       }\r
+               } else if (Rx_Buffer.Elements == 3) { // two data byte command\r
+                       if ((tempByte == 'A') | (tempByte == 'Z')) {\r
+                               processHostSPIRequest(); // command has enough data, process it\r
+                       }\r
+               } else if (Rx_Buffer.Elements == 4) { // three data byte command\r
+                       if ((tempByte == ':')) {\r
+               processHostSPIRequest(); // command has enough data, process it\r
+                       }\r
+               } else if (Rx_Buffer.Elements == 5) { // four data byte command\r
+                       if ((tempByte == '.')) {\r
+                               processHostSPIRequest(); // command has enough data, process it\r
+                       }\r
+               } else {\r
+                       // do nothing\r
+               }\r
+        }\r
+\r
+    - need to add code to flush the buffer.  Change:\r
+        /* Check if Rx buffer contains data */\r
+               if (Rx_Buffer.Elements)\r
+               {\r
+                       /* Initiate the transmission of the buffer contents if USART idle*/\r
+                       if (!(Transmitting))\r
+                       {\r
+                               Transmitting = true;\r
+                               Serial_TxByte(Buffer_GetElement(&Rx_Buffer));\r
+                       }\r
+               }\r
+      To:\r
+        /* Check if Rx buffer contains data */\r
+               if (Rx_Buffer.Elements)\r
+               {\r
+                       /* Initiate the transmission of the buffer contents if USART idle*/\r
+                       if (!(Transmitting))\r
+                       {\r
+                               Transmitting = true;\r
+                               /* The following flushes the receive buffer to prepare for new\r
+                   data and commands. Need to flush the buffer as the command\r
+                   byte which is peeked above needs to be dealt with, otherwise\r
+                   the command bytes will overflow the buffer eventually */\r
+                               //Buffer_GetElement(&Rx_Buffer); // also works\r
+                               Buffer_Initialize(&Rx_Buffer);\r
+                       }\r
+               }\r
+\r
+    - need to add the following defines and globals:\r
+        #define RESETPORT       PORTB\r
+        #define RESETPIN        PB0\r
+        #define RESETPORT2      PORTC\r
+        #define RESETPIN2       PC2\r
+        #define CR_HEX          '\r'\r
+\r
+        #define DELAY_VERYSHORT    0x01\r
+        #define DELAY_SHORT        0x02\r
+        #define DELAY_MEDIUM       0x03\r
+        #define DELAY_LONG         0x05\r
+        #define DELAY_MULTIPLE     0x04\r
+\r
+        /*  AVR Device Codes - Can have a maximum of 14 but can be any you want.\r
+            Note that these are completely irrelevent.  If AVRdude supports a\r
+            device, then that device is programmable.  Use -F switch to ignore\r
+            device codes. */\r
+        #define AVRDEVCODE01   0x55 /* ATtiny12 */\r
+        #define AVRDEVCODE02   0x56 /* ATtiny15 */\r
+        #define AVRDEVCODE03   0x5E /* ATtiny261 */\r
+        #define AVRDEVCODE04   0x76 /* ATmega8 */\r
+        #define AVRDEVCODE05   0x74 /* ATmega16 */\r
+        #define AVRDEVCODE06   0x72 /* ATmega32 */\r
+        #define AVRDEVCODE07   0x45 /* ATmega64 */\r
+        #define AVRDEVCODE08   0x74 /* ATmega644 */\r
+        #define AVRDEVCODE09   0x43 /* ATmega128 */\r
+        #define AVRDEVCODE10   0x63 /* ATmega162 */\r
+        #define AVRDEVCODE11   0x78 /* ATmega169 */\r
+        #define AVRDEVCODE12   0x6C /* AT90S4434 */\r
+        #define AVRDEVCODE13   0x38 /* AT90S8515A */\r
+        #define AVRDEVCODE14   0x65 /* AT90S8555 */\r
+\r
+        /* some global variables used throughout */\r
+        uint8_t tempIOreg = 0;\r
+        uint8_t tempIOreg2 = 0;\r
+        uint8_t tempIOreg3 = 0;\r
+        uint8_t tempIOreg4 = 0;\r
+        uint8_t dataWidth = 0;\r
+        uint8_t firstRun = 1;\r
+        uint8_t deviceCode = 0;\r
+        uint8_t tempByte = 0;\r
+        uint16_t currAddress = 0;\r
+        uint16_t timerval = 0;\r
+\r