📄 atmel.c
字号:
/* ---------------------------------------------------------------------------- * atmel.c * this module contains all functions regarding ATMEL programming protocol * * Copyright 2003/2004 * * 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 of the License, or (at your option) any later version. * ----------------------------------------------------------------------------*/#ifdef HAVE_CONFIG_H# include <config.h>#endif#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sys/ioctl.h>#include <linux/ppdev.h>#include "isp-at89.h"#include "atmel.h"static unsigned char parport = 0;/* sets the atmel processro in reset mode * regarding ATMEL Errata sheet 1486A-10/99 * on=1 = reset, on=0 = processor is running * Delay 1 second after setting reset high * for slow boards */voidatmel_setReset (int fd, int on){#ifndef __powerpc__ if (on == 1) { parport |= RESET; ioctl (fd, PPWDATA, &parport); usleep(1000000);#ifdef DEBUG printf(" DBG: Reset active.\n");#endif } else { parport &= ~RESET; ioctl (fd, PPWDATA, &parport);#ifdef DEBUG printf(" DBG: Reset released.\n");#endif }#endif}/* This functions tries to detect a attached device. * It tries to write to a random address of the EEPROM. * A random address is used not to stress a single EEPROM * cell more than neseccary because of limited write cycles. * If it was possible, a device would be present and * OK is returned. Otherwise this function returns * ERROR */intatmel_checkDevice (int fd){ unsigned char org, notorg, rc; int addr; srand(getpid()); addr = (int) (2048.0*rand()/(RAND_MAX+1.0));#ifdef DEBUG printf(" DBG: Testing ATMEL at EEPROM address %04xh\n", addr);#endif#ifndef __powerpc__ atmel_setReset(fd, 1); atmel_initProgMode(fd); org = atmel_readDataMemory(fd, addr); notorg = (org == 0 || org == 255) ? 0x55 : ~org; atmel_writeDataMemory(fd, addr, notorg); rc = atmel_readDataMemory(fd, addr); atmel_writeDataMemory(fd, addr, org); return (notorg == rc) ? OK : ERROR;#else return OK;#endif}/* This functions sends a command to the Atmel that sets * it into programming mode. */voidatmel_initProgMode(int fd){ atmel_sendCommand (fd, PROGENABLE);#ifdef DEBUG printf(" DBG: Programming enabled.\n");#endif}/* This functions sends a command to the Atmel that erases * its internal flash memory. */voidatmel_eraseChip(int fd){ atmel_sendCommand (fd, CHIPERASE); usleep(20000);#ifdef DEBUG printf(" DBG: Chip Erased.\n");#endif}/* This functions writes a byte to the internal program/data * memory of the microprocessor. The Atmel has 8192 Bytes of * internal program/data memory. */voidatmel_writeCodeMemory(int fd, int addr, unsigned char data){ unsigned char val; unsigned char laddr = addr & 0xFF; unsigned char haddr = (addr >> 8) & 0x1F; atmel_sendCommand(fd, WRITECODEMEM | (haddr<<19) | (laddr<<8) | data); data ^= 0x80; /* xor bit #7 */ do { val = atmel_sendCommand(fd, READCODEMEM | (haddr<<19) | (laddr<<8)); } while (val == data);}/* This functions reads a byte from the internal program/data * memory of the microprocessor. The Atmel has 8192 Bytes of * internal program/data memory. */unsigned charatmel_readCodeMemory(int fd, int addr){ unsigned long laddr = addr & 0xFF; unsigned long haddr = (addr >> 8) & 0x1F; return (atmel_sendCommand(fd, READCODEMEM | (haddr<<19) | (laddr<<8)) & 0xff);}/* This functions writes a byte to the internal EEPROM of the * microprocessor. The Atmel has 2048 Bytes of internal EEPROM. */voidatmel_writeDataMemory(int fd, int addr, unsigned char data){ unsigned char val; unsigned long laddr = addr & 0xFF; unsigned long haddr = (addr >> 8) & 0x7; atmel_sendCommand(fd, WRITEDATAMEM | (haddr<<19) | (laddr<<8) | data); data ^= 0x80; /* xor bit #7 */ do { val = atmel_sendCommand(fd, READDATAMEM | (haddr<<19) | (laddr<<8)); } while (val == data);}/* This functions reads a byte from the internal EEPROM of the * microprocessor. The Atmel has 2048 Bytes of internal EEPROM. */unsigned charatmel_readDataMemory(int fd, int addr){ unsigned long laddr = addr & 0xFF; unsigned long haddr = (addr >> 8) & 0x7; return (atmel_sendCommand(fd, READDATAMEM | (haddr<<19) | (laddr<<8)) & 0xFF);}/* sends an command via SPI to the processor. each * command consists out of three bytes so the only * the lower three bytes from the long arg would be * used. The return value of this function is whatever * the processor clocked out through MISO during the * command is sent. */longatmel_sendCommand (int fd, long cmd){ int i; long mmask = 0x00800000, result = 0;#ifdef DEBUG// debug_resetbuffer();#endif#ifndef __powerpc__ for (i=0; i<24; i++) { parport &= ~SCK; parport &= ~MOSI; parport |= (cmd & mmask) ? MOSI : 0; parport_wdata (fd, parport); parport |= SCK; result = result << 1; result |= parport_wdata (fd, parport); mmask = mmask >> 1; }#endif#ifdef DEBUG// debug_printbuffer(result);#endif return result;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -