⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hvprog.c

📁 老外做的 AVR-Doper 很强大
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Name: hvprog.c * Project: AVR-Doper * Author: Christian Starkjohann <cs@obdev.at> * Creation Date: 2006-07-07 * Tabsize: 4 * Copyright: (c) 2006 by Christian Starkjohann, all rights reserved. * License: GNU GPL v2 (see License.txt) or proprietary (CommercialLicense.txt) * Revision: $Id: hvprog.c 566 2008-04-26 14:21:47Z cs $ */#include "hardware.h"#if ENABLE_HVPROG#include <avr/io.h>#include <avr/wdt.h>#include "timer.h"#include "utils.h"#include "hvprog.h"/* This module can handle high voltage serial and parallel programming. Serial * programming can be understood as a serial interface to parallel programming: * SDI represents programming data and SII a serial input for the control * input lines /OE, /WR, BS1, XA0, XA1, PAGEL, and BS2. * In order to handle both with similar code, we define the function * hvSetControlAndData() which takes care of the underlying mechanism. *//* control lines for high voltage serial (and parallel) programming *//*    7       6       5       4    |  3       2       1       0    n/a     XA1     XA0     BS1  |  /WR     /OE     BS2     PAGEL*/#define HVCTL_PAGEL (1 << 0)#define HVCTL_BS2   (1 << 1)#define HVCTL_nOE   (1 << 2)#define HVCTL_nWR   (1 << 3)#define HVCTL_BS1   (1 << 4)#define HVCTL_XA0   (1 << 5)#define HVCTL_XA1   (1 << 6)/* actions: */#define HV_ADDR     0#define HV_DATA     HVCTL_XA0#define HV_CMD      HVCTL_XA1#define HV_NONE     (HVCTL_XA1 | HVCTL_XA0)#define HV_PAGEL    (HVCTL_XA1 | HVCTL_XA0 | HVCTL_PAGEL)/* bytes: */#define HV_LOW      0#define HV_HIGH     HVCTL_BS1#define HV_EXT      HVCTL_BS2#define HV_EXT2     (HVCTL_BS1 | HVCTL_BS2)/* modes: */#define HV_READ     HVCTL_nWR#define HV_WRITE    HVCTL_nOE#define HV_NORW     (HVCTL_nWR | HVCTL_nOE)#define HVCTL(action, byte, mode)   ((action) | (byte) | (mode))/* high voltage parallel and serial programming commands */#define HVCMD_CHIP_ERASE    0x80#define HVCMD_WRITE_FUSE    0x40#define HVCMD_WRITE_LOCK    0x20#define HVCMD_WRITE_FLASH   0x10#define HVCMD_WRITE_EEPROM  0x11#define HVCMD_READ_SIGCAL   0x08#define HVCMD_READ_FUSELCK  0x04#define HVCMD_READ_FLASH    0x02#define HVCMD_READ_EEPROM   0x03#define HVCMD_NOP           0x00/* ------------------------------------------------------------------------- */static uchar    progModeIsPp;   /* use parallel programming primitives */static uchar    hvPollTimeout;/*Implementing High Voltage Parallel Programming:4 functions have to be implemented for HVPP:ppEnterProgmode()    This function brings the port lines into the state required for programming.ppLeaveProgmode()    This function turns off all signals to the target device.ppExecute()    This function reads data, sets data and sets control lines according to    the parameters passed to the function.ppPoll()    This function polls for "programming ready".You may have to add global variables to communicate additional parameterssuch as e.g. write pulse width. See the hvsp* function implementation formore information.*//* ------------------------------------------------------------------------- */static uchar hvspExecute(uchar ctlLines, uchar data){uchar   cnt, r = 0, port;    port = PORT_OUT(HWPIN_HVSP_SII) & ~((1<<PORT_BIT(HWPIN_HVSP_SII)) | (1<<PORT_BIT(HWPIN_HVSP_SDI)));    PORT_OUT(HWPIN_HVSP_SII) = port;    PORT_PIN_SET(HWPIN_HVSP_SCI);    cnt = 8;    PORT_PIN_CLR(HWPIN_HVSP_SCI);    do{        r <<= 1;        if(PORT_PIN_VALUE(HWPIN_HVSP_SDO))            r |= 1;        if(data & 0x80)            port |= 1 << PORT_BIT(HWPIN_HVSP_SDI);        if(ctlLines & 0x80)            port |= 1 << PORT_BIT(HWPIN_HVSP_SII);        PORT_OUT(HWPIN_HVSP_SII) = port;        PORT_PIN_SET(HWPIN_HVSP_SCI);        port &= ~((1<<PORT_BIT(HWPIN_HVSP_SII)) | (1<<PORT_BIT(HWPIN_HVSP_SDI)));        ctlLines <<= 1;        data <<= 1;        PORT_PIN_CLR(HWPIN_HVSP_SCI);    }while(--cnt);    PORT_OUT(HWPIN_HVSP_SII) = port;    /* clock out two zeros */    PORT_PIN_SET(HWPIN_HVSP_SCI);    PORT_PIN_CLR(HWPIN_HVSP_SCI);    PORT_PIN_SET(HWPIN_HVSP_SCI);    PORT_PIN_CLR(HWPIN_HVSP_SCI);    return r;}/* This function applies 'data' to the data lines, 'ctlLines' to the control * lines and returns the status of the data lines BEFORE any control lines * were changed. These somewhat strange semantics are required for * compatibility with HV serial programming. */static uchar hvSetControlAndData(uchar ctlLines, uchar data){    /* ### insert if(progModeIsPp){}else{} here */    return hvspExecute(ctlLines, data);}/* ------------------------------------------------------------------------- */#if 1void    hvspEnterProgmode(stkEnterProgHvsp_t *param){    progModeIsPp = 0;    PORT_PIN_SET(HWPIN_LED);    TCCR2 &= ~(1 << COM20);             /* clear toggle on compare match mode */    PORT_PIN_SET(HWPIN_HVSP_RESET);    PORT_PIN_CLR(HWPIN_HVSP_SUPPLY);    PORT_DDR(HWPIN_HVSP_SDO) |= (1 << PORT_BIT(HWPIN_HVSP_SDO));    TIMER_US_DELAY(40);    PORT_PIN_CLR(HWPIN_HVSP_RESET);    PORT_DDR_CLR(HWPIN_HVSP_HVRESET);   /* use internal pull-up to source current */    PORT_PIN_SET(HWPIN_HVSP_HVRESET);    TIMER_US_DELAY(15);    PORT_DDR(HWPIN_HVSP_SDO) &= ~(1 << PORT_BIT(HWPIN_HVSP_SDO));   /* prevent contention */    TIMER_US_DELAY(300);}#else/* This is the new mechanism to enter prog mode which is closer to the method * described in the ATTiny45 data sheet, but it seems to fail on some of the * ATTiny45. We therefore stick with the old method, but leave this code * for reference. */void    hvspEnterProgmode(stkEnterProgHvsp_t *param){uchar i;    progModeIsPp = 0;    PORT_PIN_SET(HWPIN_LED);    TCCR2 &= ~(1 << COM20);             /* clear toggle on compare match mode */    PORT_PIN_SET(HWPIN_HVSP_RESET);    PORT_PIN_CLR(HWPIN_HVSP_SUPPLY);    for(i = 0; i < 16; i++){    /* ATTiny[248]4 data sheet says: toggle SCI at least 6 times */        TIMER_US_DELAY(20);        PORT_OUT(HWPIN_HVSP_SCI) ^= 1 << PORT_BIT(HWPIN_HVSP_SCI);    }    PORT_DDR_SET(HWPIN_HVSP_SDO);    TIMER_US_DELAY(45);    PORT_PIN_CLR(HWPIN_HVSP_RESET);    PORT_DDR_CLR(HWPIN_HVSP_HVRESET);   /* use internal pull-up to source current */    PORT_PIN_SET(HWPIN_HVSP_HVRESET);    TIMER_US_DELAY(20);    PORT_DDR_CLR(HWPIN_HVSP_SDO);       /* prevent contention */    TIMER_US_DELAY(300);}#endifvoid    hvspLeaveProgmode(stkLeaveProgHvsp_t *param){    PORT_PIN_CLR(HWPIN_HVSP_HVRESET);    PORT_DDR_SET(HWPIN_HVSP_HVRESET);   /* output low level */    PORT_PIN_SET(HWPIN_HVSP_RESET);    PORT_OUT(HWPIN_HVSP_SII) &= ~((1<<PORT_BIT(HWPIN_HVSP_SII)) | (1<<PORT_BIT(HWPIN_HVSP_SDI)));    PORT_PIN_SET(HWPIN_HVSP_SUPPLY);    PORT_PIN_CLR(HWPIN_HVSP_RESET);    PORT_PIN_CLR(HWPIN_LED);}/* ------------------------------------------------------------------------- */void    ppEnterProgmode(stkEnterProgPp_t *param){    progModeIsPp = 1;    /* ### not implemented yet */}void    ppLeaveProgmode(stkLeaveProgPp_t *param){    /* ### not implemented yet */}/* ------------------------------------------------------------------------- */static uchar    hvspPoll(void){uchar   rval = STK_STATUS_CMD_OK;    timerSetupTimeout(hvPollTimeout);    while(!PORT_PIN_VALUE(HWPIN_HVSP_SDO)){        if(timerTimeoutOccurred()){            rval = STK_STATUS_CMD_TOUT;            break;        }    }    return rval;}static uchar    hvPoll(void){    /* ### insert if(progModeIsPp){}else{} here */    return hvspPoll();}/* ------------------------------------------------------------------------- */static uchar   hvChipErase(uchar eraseTime){uchar rval = STK_STATUS_CMD_OK;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -