/* * Turbo Programmer Utilities, turbo-prog-utils, www.bladox.com * * Copyright (C) 2004 BLADOX, s.r.o. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2, or (at your option) any * later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. */ /* * This file is based on uisp by Uros Platise * (c) 1997-1999 Uros Platise, 2000-2003 Marek Michalkiewicz * http://savannah.nongnu.org/download/uisp/ */ #include <config.h> #include <tprog/tprog.h> #include "../../usbprog/pins.h" #include "isp.h" #include <avr/io.h> void ispSckDelay () { // delayUs(3); delayUs (10); } void ispOutReset (u8 resetValue) { u8 tmpResetValue; tmpResetValue = inb (PROG_RESETn_PORT); if (resetValue == 0) tmpResetValue = tmpResetValue & ~(1 << PROG_RESETn_PORT_PIN); else tmpResetValue = tmpResetValue | (1 << PROG_RESETn_PORT_PIN); outb (PROG_RESETn_PORT, tmpResetValue); } void ispOutSck (u8 sckValue) { u8 tmpSckValue; tmpSckValue = inb (PROG_SCK_PORT); if (sckValue == 0) tmpSckValue = tmpSckValue & ~(1 << PROG_SCK_PORT_PIN); else tmpSckValue = tmpSckValue | (1 << PROG_SCK_PORT_PIN); outb (PROG_SCK_PORT, tmpSckValue); } u8 ispSendRecv (u8 b) { // clear flag inb (SPSR); inb (SPDR); // send char to SPI outb (SPDR, b); // wait until char was transmitted loop_until_bit_is_set (SPSR, SPIF); // return received value return inb (SPDR); } u16 ispSend (u8 * queue, int queueSize) { u8 *p = queue, ch; int i = queueSize; while (i--) { ch = ispSendRecv (*p); *p++ = ch; } return queueSize; } void ispPulseSck (void) { ispSckDelay (); // __asm__ __volatile__ ("nop"); // __asm__ __volatile__ ("nop"); ispOutSck (1); ispSckDelay (); // __asm__ __volatile__ ("nop"); // __asm__ __volatile__ ("nop"); ispOutSck (0); } void ispPulseReset (void) { ispOutReset (1); ispOutReset (0); } u8 ispEnableAvr (void) { u8 prg[4] = { 0xAC, 0x53, 0, 0 }; int try_number = 32; do { prg[0] = 0xAC; prg[1] = 0x53; prg[2] = prg[3] = 0; ispSend (prg, 4); if (prg[2] == 0x53) break; ispPulseSck (); // __asm__ __volatile__ ("nop"); // __asm__ __volatile__ ("nop"); // __asm__ __volatile__ ("nop"); } while (try_number--); if (try_number >= 0) //OK return 1; else //ERROR return 0; } u8 ispGetPartInfo (u8 addr) { u8 info[4] = { 0x30, 0, addr, 0 }; ispSend (info, 4); return info[3]; } u8 ispReadByteFlash (unsigned long addr) { u8 readback = 0xFF; u8 hl = (addr & 1) ? 0x28 : 0x20; u8 flash[4] = { hl, (u8) ((addr >> 9) & 0xFF), (u8) ((addr >> 1) & 0xFF), 0 }; ispSend (flash, 4); readback = flash[3]; return readback; } u8 ispReadChunkFlash (unsigned long addr, u8 * chunk, u8 chunkSize) { u8 readback = 0xFF; u8 i; unsigned long tmpAddr; tmpAddr = addr; for (i = 0; i < chunkSize; i++) { readback = ispReadByteFlash (tmpAddr); chunk[i] = readback; tmpAddr++; } // return readback; return 1; } u8 ispReadByteEeprom (unsigned long addr) { u8 readback = 0xFF; u8 eeprom[4] = { 0xA0, (u8) ((addr >> 8) & 0xFF), (u8) (addr & 0xFF), 0 }; ispSend (eeprom, 4); readback = eeprom[3]; return readback; } u8 ispReadChunkEeprom (unsigned long addr, u8 * chunk, u8 chunkSize) { u8 readback = 0xFF; u8 i; unsigned long tmpAddr; tmpAddr = addr; for (i = 0; i < chunkSize; i++) { readback = ispReadByteEeprom (tmpAddr); chunk[i] = readback; tmpAddr++; } return 1; } u8 ispReadLockBits () { u8 lockfuse[4] = { 0x58, 0, 0, 0 }; ispSend (lockfuse, 4); return lockfuse[3]; } u8 ispReadFuseLowBits () { u8 fuselow[4] = { 0x50, 0, 0, 0 }; ispSend (fuselow, 4); return fuselow[3]; } u8 ispReadFuseHighBits () { u8 fusehigh[4] = { 0x58, 0x08, 0, 0 }; ispSend (fusehigh, 4); return fusehigh[3]; } u8 ispReadFuseExtBits () { u8 fuseext[4] = { 0x50, 0x08, 0, 0 }; ispSend (fuseext, 4); return fuseext[3]; } u8 ispReadCalByte (u8 addr) { u8 cal[4] = { 0x38, 0, addr, 0 }; ispSend (cal, 4); return cal[3]; } void ispWriteOldFuseBits (u8 val) { u8 oldfuse[4] = { 0xAC, (val & 0x1F) | 0xA0, 0, 0xD2 }; ispSend (oldfuse, 4); } void ispWriteFuseLowBits (u8 val) { u8 fuselow[4] = { 0xAC, 0xA0, 0, val }; ispSend (fuselow, 4); } void ispWriteFuseHighBits (u8 val) { u8 fusehigh[4] = { 0xAC, 0xA8, 0, val }; ispSend (fusehigh, 4); } void ispWriteFuseExtBits (u8 val) { u8 fuseext[4] = { 0xAC, 0xA4, 0, val }; ispSend (fuseext, 4); } void ispChipErase () { u8 chip_erase[4] = { 0xAC, 0x80, 0x00, 0x00 }; ispSend (chip_erase, 4); delayUs (9000); delayUs (9000); ispPulseReset (); ispEnableAvr (); } void ispWriteLockBits (u8 bits) { u8 lock[4] = { 0xAC, 0xF9 | ((bits << 1) & 0x06), 0xFF, bits }; u8 rbits; ispSend (lock, 4); delayUs (9000); ispPulseReset (); ispEnableAvr (); } void ispWriteByteFlash (unsigned long addr, u8 val) { u8 flash[4] = { 0x40 | ((addr & 0x01) << 3), 0, ((addr >> 1) & 0xFF), val }; ispSend (flash, 4); } u8 ispWriteChunkFlash (unsigned long addr, u8 * chunk, u8 chunkSize) { u8 readback; u8 i; unsigned long tmpAddr; u16 j; tmpAddr = addr; for (i = 0; i < chunkSize; i++) { ispWriteByteFlash (tmpAddr, chunk[i]); tmpAddr++; } return 1; } u8 ispWriteByteEeprom (unsigned long addr, u8 val) { u8 readback; u8 eeprom[4] = { 0xC0, (addr >> 8), (addr & 0xFF), val }; u16 j; readback = ispReadByteEeprom (addr); if (readback == val) return 0; ispSend (eeprom, 4); for (j = 0; j < 100; j++) { delayUs (1000); readback = ispReadByteEeprom (addr); if (readback == val) j = 100; } if (readback != val) return 1; return 0; } // 1 OK // 0 ERROR u8 ispWriteChunkEeprom (unsigned long addr, u8 * chunk, u8 chunkSize) { u8 readback; u8 i; unsigned long tmpAddr; u16 j; u8 err; tmpAddr = addr; for (i = 0; i < chunkSize; i++) { err = ispWriteByteEeprom (tmpAddr, chunk[i]); if (err == 1) return 0; tmpAddr++; } return 1; } void ispWriteProgramMemoryPage (unsigned long pageAddr) { u8 prg_page[4] = { 0x4C, (u8) ((pageAddr >> 9) & 0xFF), (u8) ((pageAddr >> 1) & 0xFF), 0 }; ispSend (prg_page, 4); delayUs (5000); }
Copyright © 2004 BLADOX | Turbo Programmer version 2.0
|