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

📄 stk500protocol.c

📁 ATmega8实现USB接口(采用USB的CDC类
💻 C
字号:
#include "hardware.h"#include <avr/pgmspace.h>#include <string.h>#include "oddebug.h"#include "stk500protocol.h"#include "utils.h"#include "isp.h"#include "hvprog.h"#include "timer.h"#include "vreg.h"#define BUFFER_SIZE     281 /* results in 275 bytes max body size */#define RX_TIMEOUT      200 /* timeout in milliseconds */#define STK_TXMSG_START 5static uchar        rxBuffer[BUFFER_SIZE];static uint         rxPos;static utilWord_t   rxLen;static uchar        txBuffer[BUFFER_SIZE];static uint         txPos, txLen;stkParam_t      stkParam = {{                    0, 0, 0, 0, 0, 0, 0, 0,                    0, 0, 0, 0, 0, 0, 0, 0,                    1, 2, 4, 0, 50, 0, 1, 0x80,                    0, 0, 0xaa, 0, 0, 0, 0, 0,                }};utilDword_t     stkAddress;/* ------------------------------------------------------------------------- */void    stkIncrementAddress(void){    stkAddress.dword++;}/* ------------------------------------------------------------------------- */static void stkSetTxMessage(uint len){uchar   *p = txBuffer, sum = 0;    *p++ = STK_STX;    *p++ = rxBuffer[1];  /* sequence number */    *p++ = utilHi8(len);    *p++ = len;    *p++ = STK_TOKEN;    txPos = 0;    len += 6;    txLen = len--;    p = txBuffer;    while(len--){        sum ^= *p++;    }    *p = sum;    DBG1(0xe0, txBuffer, txLen);}/* ------------------------------------------------------------------------- */static void setParameter(uchar index, uchar value){    if(index == STK_PARAM_OSC_PSCALE){        TCCR2 = (TCCR2 & ~7) | (value & 7);    }else if(index == STK_PARAM_OSC_CMATCH){        OCR2 = value;    }    index &= 0x1f;    stkParam.bytes[index] = value;}static uchar getParameter(uchar index){    if(index == STK_PARAM_OSC_PSCALE)        return TCCR2 & 7;    if(index == STK_PARAM_OSC_CMATCH)        return OCR2;    index &= 0x1f;    return stkParam.bytes[index];}/* ------------------------------------------------------------------------- *//* Use defines for the switch statement so that we can choose between an * if()else if() and a switch/case based implementation. switch() is more * efficient for a LARGE set of sequential choices, if() is better in all other * cases. */#if 0#define SWITCH_START        if(0){#define SWITCH_CASE(value)  }else if(cmd == (value)){#define SWITCH_CASE2(v1,v2) }else if(cmd == (v1) || cmd == (v2)){#define SWITCH_CASE3(v1,v2,v3) }else if(cmd == (v1) || cmd == (v2) || (cmd == v3)){#define SWITCH_CASE4(v1,v2,v3,v4) }else if(cmd == (v1) || cmd == (v2) || cmd == (v3) || cmd == (v4)){#define SWITCH_DEFAULT      }else{#define SWITCH_END          }#else#define SWITCH_START        switch(cmd){{#define SWITCH_CASE(value)  }break; case (value):{#define SWITCH_CASE2(v1,v2) }break; case (v1): case(v2):{#define SWITCH_CASE3(v1,v2,v3) }break; case (v1): case(v2): case(v3):{#define SWITCH_CASE4(v1,v2,v3,v4) }break; case (v1): case(v2): case(v3): case(v4):{#define SWITCH_DEFAULT      }break; default:{#define SWITCH_END          }}#endifvoid stkEvaluateRxMessage(void) /* not static to prevent inlining */{uchar       i, cmd;utilWord_t  len = {2};  /* defaults to cmd + error code */void        *param;    DBG1(0xf1, rxBuffer, rxLen.bytes[0]);    cmd = rxBuffer[STK_TXMSG_START];    txBuffer[STK_TXMSG_START] = cmd;    txBuffer[STK_TXMSG_START + 1] = STK_STATUS_CMD_OK;    param = &rxBuffer[STK_TXMSG_START + 1];    SWITCH_START    SWITCH_CASE(STK_CMD_SIGN_ON)        static PROGMEM uchar string[] = {8, 'S', 'T', 'K', '5', '0', '0', '_', '2', 0};        uchar *p = &txBuffer[STK_TXMSG_START + 2];        strcpy_P(p, string);        len.bytes[0] = 11;    SWITCH_CASE(STK_CMD_SET_PARAMETER)        setParameter(rxBuffer[STK_TXMSG_START + 1], rxBuffer[STK_TXMSG_START + 2]);    SWITCH_CASE(STK_CMD_GET_PARAMETER)        txBuffer[STK_TXMSG_START + 2] = getParameter(rxBuffer[STK_TXMSG_START + 1]);        len.bytes[0] = 3;    SWITCH_CASE(STK_CMD_OSCCAL)        txBuffer[STK_TXMSG_START + 1] = STK_STATUS_CMD_FAILED;        /* not yet implemented */    SWITCH_CASE(STK_CMD_LOAD_ADDRESS)        for(i=0;i<4;i++){            stkAddress.bytes[3-i] = rxBuffer[STK_TXMSG_START + 1 + i];        }    SWITCH_CASE(STK_CMD_SET_CONTROL_STACK)        /* AVR Studio sends:        1b 08 00 21 0e 2d         4c 0c 1c 2c 3c 64 74 66        68 78 68 68 7a 6a 68 78        78 7d 6d 0c 80 40 20 10        11 08 04 02 03 08 04 00        bf        */        /* dummy: ignore */    SWITCH_CASE(STK_CMD_ENTER_PROGMODE_HVSP)        hvspEnterProgmode(param);    SWITCH_CASE(STK_CMD_LEAVE_PROGMODE_HVSP)        hvspLeaveProgmode(param);    SWITCH_CASE(STK_CMD_CHIP_ERASE_HVSP)        txBuffer[STK_TXMSG_START + 1] = hvspChipErase(param);    SWITCH_CASE(STK_CMD_PROGRAM_FLASH_HVSP)        txBuffer[STK_TXMSG_START + 1] = hvspProgramMemory(param, 0);    SWITCH_CASE(STK_CMD_READ_FLASH_HVSP)        len.word = 1 + hvspReadMemory(param, (void *)&txBuffer[STK_TXMSG_START + 1], 0);    SWITCH_CASE(STK_CMD_PROGRAM_EEPROM_HVSP)        txBuffer[STK_TXMSG_START + 1] = hvspProgramMemory(param, 1);    SWITCH_CASE(STK_CMD_READ_EEPROM_HVSP)        len.word = 1 + hvspReadMemory(param, (void *)&txBuffer[STK_TXMSG_START + 1], 1);    SWITCH_CASE(STK_CMD_PROGRAM_FUSE_HVSP)        txBuffer[STK_TXMSG_START + 1] = hvspProgramFuse(param);    SWITCH_CASE(STK_CMD_READ_FUSE_HVSP)        txBuffer[STK_TXMSG_START + 2] = hvspReadFuse(param);        len.bytes[0] = 3;    SWITCH_CASE(STK_CMD_PROGRAM_LOCK_HVSP)        txBuffer[STK_TXMSG_START + 1] = hvspProgramLock(param);    SWITCH_CASE(STK_CMD_READ_LOCK_HVSP)        txBuffer[STK_TXMSG_START + 2] = hvspReadLock();        len.bytes[0] = 3;    SWITCH_CASE(STK_CMD_READ_SIGNATURE_HVSP)        txBuffer[STK_TXMSG_START + 2] = hvspReadSignature(param);        len.bytes[0] = 3;    SWITCH_CASE(STK_CMD_READ_OSCCAL_HVSP)        txBuffer[STK_TXMSG_START + 2] = hvspReadOsccal();        len.bytes[0] = 3;    SWITCH_CASE(STK_CMD_ENTER_PROGMODE_PP)        ppEnterProgmode(param);    SWITCH_CASE(STK_CMD_LEAVE_PROGMODE_PP)        ppLeaveProgmode(param);    SWITCH_CASE(STK_CMD_CHIP_ERASE_PP)        txBuffer[STK_TXMSG_START + 1] = ppChipErase(param);    SWITCH_CASE(STK_CMD_PROGRAM_FLASH_PP)        txBuffer[STK_TXMSG_START + 1] = ppProgramMemory(param, 0);    SWITCH_CASE(STK_CMD_READ_FLASH_PP)        len.word = 1 + ppReadMemory(param, (void *)&txBuffer[STK_TXMSG_START + 1], 0);    SWITCH_CASE(STK_CMD_PROGRAM_EEPROM_PP)        txBuffer[STK_TXMSG_START + 1] = ppProgramMemory(param, 1);    SWITCH_CASE(STK_CMD_READ_EEPROM_PP)        len.word = 1 + ppReadMemory(param, (void *)&txBuffer[STK_TXMSG_START + 1], 1);    SWITCH_CASE(STK_CMD_PROGRAM_FUSE_PP)        txBuffer[STK_TXMSG_START + 1] = ppProgramFuse(param);    SWITCH_CASE(STK_CMD_READ_FUSE_PP)        txBuffer[STK_TXMSG_START + 2] = ppReadFuse(param);        len.bytes[0] = 3;    SWITCH_CASE(STK_CMD_PROGRAM_LOCK_PP)        txBuffer[STK_TXMSG_START + 1] = ppProgramLock(param);    SWITCH_CASE(STK_CMD_READ_LOCK_PP)        txBuffer[STK_TXMSG_START + 2] = ppReadLock();        len.bytes[0] = 3;    SWITCH_CASE(STK_CMD_READ_SIGNATURE_PP)        txBuffer[STK_TXMSG_START + 2] = ppReadSignature(param);        len.bytes[0] = 3;    SWITCH_CASE(STK_CMD_READ_OSCCAL_PP)        txBuffer[STK_TXMSG_START + 2] = ppReadOsccal();        len.bytes[0] = 3;    SWITCH_CASE(STK_CMD_ENTER_PROGMODE_ISP)        txBuffer[STK_TXMSG_START + 1] = ispEnterProgmode(param);    SWITCH_CASE(STK_CMD_LEAVE_PROGMODE_ISP)        ispLeaveProgmode(param);    SWITCH_CASE(STK_CMD_CHIP_ERASE_ISP)        txBuffer[STK_TXMSG_START + 1] = ispChipErase(param);    SWITCH_CASE(STK_CMD_PROGRAM_FLASH_ISP)        txBuffer[STK_TXMSG_START + 1] = ispProgramMemory(param, 0);    SWITCH_CASE(STK_CMD_READ_FLASH_ISP)        len.word = 1 + ispReadMemory(param, (void *)&txBuffer[STK_TXMSG_START + 1], 0);    SWITCH_CASE(STK_CMD_PROGRAM_EEPROM_ISP)        txBuffer[STK_TXMSG_START + 1] = ispProgramMemory(param, 1);    SWITCH_CASE(STK_CMD_READ_EEPROM_ISP)        len.word = 1 + ispReadMemory(param, (void *)&txBuffer[STK_TXMSG_START + 1], 1);    SWITCH_CASE(STK_CMD_PROGRAM_FUSE_ISP)        txBuffer[STK_TXMSG_START + 1] = ispProgramFuse(param);    SWITCH_CASE4(STK_CMD_READ_FUSE_ISP, STK_CMD_READ_LOCK_ISP, STK_CMD_READ_SIGNATURE_ISP, STK_CMD_READ_OSCCAL_ISP)        txBuffer[STK_TXMSG_START + 2] = ispReadFuse(param);        txBuffer[STK_TXMSG_START + 3] = STK_STATUS_CMD_OK;        len.bytes[0] = 4;    SWITCH_CASE(STK_CMD_PROGRAM_LOCK_ISP)        txBuffer[STK_TXMSG_START + 1] = ispProgramFuse(param);    SWITCH_CASE(STK_CMD_SPI_MULTI)        len.word = 1 + ispMulti(param, (void *)&txBuffer[STK_TXMSG_START + 1]);    SWITCH_DEFAULT  /* unknown command */        DBG1(0xf8, 0, 0);        txBuffer[STK_TXMSG_START + 1] = STK_STATUS_CMD_FAILED;    SWITCH_END    stkSetTxMessage(len.word);}/* ------------------------------------------------------------------------- */void    stkSetRxChar(uchar c){    if(timerLongTimeoutOccurred()){        rxPos = 0;    }    if(rxPos == 0){     /* only accept STX as the first character */        if(c == STK_STX)            rxBuffer[rxPos++] = c;    }else{        if(rxPos < BUFFER_SIZE){            rxBuffer[rxPos++] = c;            if(rxPos == 4){     /* do we have length byte? */                rxLen.bytes[0] = rxBuffer[3];                rxLen.bytes[1] = rxBuffer[2];                rxLen.word += 6;                if(rxLen.word > BUFFER_SIZE){    /* illegal length */                    rxPos = 0;      /* reset state */                }            }else if(rxPos == 5){   /* check whether this is the token byte */                if(c != STK_TOKEN){                    rxPos = 0;  /* reset state */                }            }else if(rxPos > 4 && rxPos == rxLen.word){ /* message is complete */                uchar sum = 0;                uchar *p = rxBuffer;                while(rxPos){ /* decrement rxPos down to 0 -> reset state */                    sum ^= *p++;                    rxPos--;                }                if(sum == 0){   /* check sum is correct, evaluate rx message */                    stkEvaluateRxMessage();                }else{          /* checksum error */                    DBG2(0xf2, rxBuffer, rxLen.word);                    txBuffer[STK_TXMSG_START] = STK_ANSWER_CKSUM_ERROR;                    txBuffer[STK_TXMSG_START + 1] = STK_ANSWER_CKSUM_ERROR;                    stkSetTxMessage(2);                }            }        }else{  /* overflow */            rxPos = 0;  /* reset state */        }    }    timerSetupLongTimeout(RX_TIMEOUT);}int stkGetTxCount(void){    return txLen - txPos;}int stkGetTxByte(void){uchar   c;    if(txLen == 0){        return -1;    }    c = txBuffer[txPos++];    if(txPos >= txLen){         /* transmit ready */        txPos = txLen = 0;    }    return c;}/* ------------------------------------------------------------------------- */

⌨️ 快捷键说明

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