isp2.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2003 by egnite Software GmbH. All rights reserved.
00003  *
00004  * Redistribution and use in source and binary forms, with or without
00005  * modification, are permitted provided that the following conditions
00006  * are met:
00007  *
00008  * 1. Redistributions of source code must retain the above copyright
00009  *    notice, this list of conditions and the following disclaimer.
00010  * 2. Redistributions in binary form must reproduce the above copyright
00011  *    notice, this list of conditions and the following disclaimer in the
00012  *    documentation and/or other materials provided with the distribution.
00013  * 3. Neither the name of the copyright holders nor the names of
00014  *    contributors may be used to endorse or promote products derived
00015  *    from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH AND CONTRIBUTORS
00018  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00019  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00020  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL EGNITE
00021  * SOFTWARE GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00022  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00023  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
00024  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
00025  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00026  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
00027  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00028  * SUCH DAMAGE.
00029  *
00030  * For additional information see http://www.ethernut.de/
00031  *
00032  */
00033 
00041 /*
00042  * This application will update the ISP Adapter software.
00043  */
00044 
00045 #include <stdio.h>
00046 #include <io.h>
00047 #include <sys/timer.h>
00048 #include <dev/debug.h>
00049 #include <dev/urom.h>
00050 
00051 /*
00052  * Port Layout
00053  *
00054  * Coconut
00055  * -------
00056  * PB0(O): SS
00057  * PB1(O): SCK
00058  * PB2(O): MOSI
00059  * PB3(I): MISO
00060  *
00061  * PB4(O): Reset target
00062  * PB5(-): Unused
00063  * PB6(-): Unused
00064  * PB7(-): Unused
00065  *
00066  * ISP at Ethernut 2
00067  * -----------------
00068  * PE0(O): ISP-MOSI
00069  * PE1(I): ISP-MISO
00070  * PB1(O): ISP-SCK
00071  */
00072 
00073 #define ISPMOSI_PORT    PORTE
00074 #define ISPMOSI_DDR     DDRE
00075 #define ISPMOSI_BIT     0
00076 
00077 #define ISPMISO_PORT    PORTE
00078 #define ISPMISO_DDR     DDRE
00079 #define ISPMISO_PIN     PINE
00080 #define ISPMISO_BIT     1
00081 
00082 #define ISPSCK_PORT     PORTB
00083 #define ISPSCK_DDR      DDRB
00084 #define ISPSCK_BIT      1
00085 
00089 static u_char SpiByte(u_char c)
00090 {
00091     u_char i;
00092 
00093     for(i = 0; i < 8; i++) {
00094         if(c & 0x80)
00095             sbi(ISPMOSI_PORT, ISPMOSI_BIT);
00096         else
00097             cbi(ISPMOSI_PORT, ISPMOSI_BIT);
00098         sbi(ISPSCK_PORT, ISPSCK_BIT);
00099         c <<= 1;
00100         if(bit_is_set(ISPMISO_PIN, ISPMISO_BIT))
00101             c++;
00102         cbi(ISPSCK_PORT, ISPSCK_BIT);
00103     }
00104     cbi(ISPMOSI_PORT, ISPMOSI_BIT);
00105 
00106     return c;
00107 }
00108 
00114 int SpiFlashEnable(void)
00115 {
00116     u_char i;
00117     u_char rc;
00118 
00119     cbi(ISPMOSI_PORT, ISPMOSI_BIT);
00120     sbi(ISPMOSI_DDR, ISPMOSI_BIT);
00121 
00122     cbi(ISPMISO_PORT, ISPMISO_BIT);
00123     cbi(ISPMISO_DDR, ISPMISO_BIT);
00124 
00125     cbi(ISPSCK_PORT, ISPSCK_BIT);
00126     sbi(ISPSCK_DDR, ISPSCK_BIT);
00127 
00128     for (i = 0; i < 32; i++) {
00129 
00130         /*
00131          * Try to enable programming.
00132          */
00133         SpiByte(0xAC);
00134         SpiByte(0x53);
00135         rc = SpiByte(0xFF);
00136         SpiByte(0xff);
00137 
00138         if (rc == 0x53)
00139             return 0;
00140 
00141         /*
00142          * Programming enable failed. This may be because the
00143          * target is not synchronized. A positive pulse on the
00144          * clock line should help.
00145          */
00146         sbi(ISPSCK_PORT, ISPSCK_BIT);
00147         cbi(ISPSCK_PORT, ISPSCK_BIT);
00148     }
00149     return -1;
00150 }
00151 
00158 void SpiFlashId(u_char * id)
00159 {
00160     u_char i;
00161 
00162     for (i = 0; i < 3; i++) {
00163         SpiByte(0x30);
00164         SpiByte(0x00);
00165         SpiByte(i);
00166         id[i] = SpiByte(0x00);
00167     }
00168 }
00169 
00183 int SpiFlashWriteByte(u_char high, u_short addr, u_char data)
00184 {
00185     u_char d;
00186 
00187     if (data != 0xff) {
00188         SpiByte(0x40 | high);
00189         SpiByte(addr >> 8);
00190         SpiByte(addr & 0xFF);
00191         SpiByte(data);
00192 
00193         /*
00194          * During programming a value of 0x7F appears at the memory location. 
00195          * If we are programming this value, we delay execution by 10 ms.
00196          * Otherwise we poll the memory location until we read back the 
00197          * programmed value.
00198          */
00199         if (data == 0x7f)
00200             NutDelay(10);
00201         else {
00202             for (d = 0; d < 255; d++) {
00203                 /*
00204                  * Read program flash byte.
00205                  */
00206                 SpiByte(0x20 | high);
00207                 SpiByte(addr >> 8);
00208                 SpiByte(addr & 0xFF);
00209                 if (SpiByte(0xFF) == data)
00210                     break;
00211             }
00212             if (d == 255) {
00213                 return -1;
00214             }
00215         }
00216     }
00217     return 0;
00218 }
00219 
00228 int SpiFlashWriteWord(u_short addr, u_short data)
00229 {
00230     if (SpiFlashWriteByte(0, addr, data & 0xFF))
00231         return -1;
00232     if (SpiFlashWriteByte(8, addr, data >> 8))
00233         return -1;
00234 
00235     return 0;
00236 }
00237 
00244 void SpiFlashErase(void)
00245 {
00246     /*
00247      * Send chip erase command.
00248      */
00249     SpiByte(0xAC);
00250     SpiByte(0x80);
00251     SpiByte(0x00);
00252     SpiByte(0x00);
00253     NutDelay(50);
00254 }
00255 
00256 
00257 int main(void)
00258 {
00259     u_char id[3];
00260     u_long baud = 115200;
00261     char *filename = "UROM:sisp.bin";
00262     int val;
00263     u_short word;
00264     u_short addr;
00265     FILE *fp;
00266 
00267     /*
00268      * Register Nut/OS devices. We can't use UART0, because
00269      * it uses the same pins as the ISP port.
00270      */
00271     NutRegisterDevice(&devDebug1, 0, 0);
00272     NutRegisterDevice(&devUrom, 0, 0);
00273 
00274     /*
00275      * Open stdout for displaying our progress.
00276      */
00277     freopen("uart1", "w", stdout);
00278     _ioctl(_fileno(stdout), UART_SETSPEED, &baud);
00279     puts("\nISP2 1.0.1");
00280 
00281     /*
00282      * Open the file to burn into the adapter's flash memory.
00283      */
00284     fp = fopen(filename, "rb");
00285     if (fp == 0) {
00286         printf("ERROR: Failed to open %s\n", filename);
00287         for(;;);
00288     } 
00289 
00290     /*
00291      * Try to enter programming mode.
00292      */
00293     printf("Enable programming...");
00294     if(SpiFlashEnable()) {
00295         puts("failed\n" 
00296              "Make sure that the ISP adapter is connected to the\n"
00297              "Ethernut ISP port and that the MCU on the adapter\n"
00298              "is held in reset state.");
00299         for(;;);
00300     }
00301     puts("OK");
00302 
00303     /*
00304      * Read the target device's signature.
00305      */
00306     printf("Reading signature... ");
00307     SpiFlashId(id);
00308     if(id[0] != 0x1E || id[1] != 0x91 || id[2] != 0x01) {
00309         printf("unexpected %02X%02X%02X\n", id[0], id[1], id[2]);
00310     }
00311     else {
00312         puts("OK");
00313     }
00314 
00315     /*
00316      * Erase the target device.
00317      */
00318     printf("Erasing device...    ");
00319     SpiFlashErase();
00320     puts("OK");
00321 
00322     printf("Programming device");
00323     addr = 0;
00324     for (;;) {
00325         if((addr & 0xFF) == 0)
00326             putchar('.');
00327         if((val = fgetc(fp)) == EOF) {
00328             puts("OK");
00329             break;
00330         }
00331         word = ((u_char)fgetc(fp) << 8) + (u_char)val;
00332         if (SpiFlashWriteWord(addr, word)) {
00333             printf("failed at %04X\n", addr);
00334             break;
00335         }
00336         addr++;
00337     }
00338     for(;;);
00339 }

© 2000-2007 by egnite Software GmbH - visit http://www.ethernut.de/