isp2.c

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

© 2000-2010 by contributors - visit http://www.ethernut.de/