/* vim: set sw=8 ts=8 si et: */ /********************************************* * An implemenation of the STK500 specification (appl. note AVR068) for atmega8 * * Author: Guido Socher, Copyright: GPL * * Ported to PIC24/Bus Pirate by Ian Lesnet, http://dangerousprototypes.com, 2009 * Copyright: GPL **********************************************/ #include "base.h" #include "UART.h" #include "SPI.h" #include "command.h" #include "redefines.h" /* Definitions to get the existing code working with the Bus Pirate */ /* Orig. source defines */ #define CONFIG_PARAM_BUILD_NUMBER_LOW 0 #define CONFIG_PARAM_BUILD_NUMBER_HIGH 1 // be careful with changing HW versions. avrstudio does not like all numbers: #define CONFIG_PARAM_HW_VER 2 //was 2 // update here our own default sw version: #define D_CONFIG_PARAM_SW_MAJOR 0x02 //was 2 #define D_CONFIG_PARAM_SW_MINOR 0x0a //was 4 #define CONFIG_PARAM_VTARGET 50 #define CONFIG_PARAM_VADJUST 25 #define CONFIG_PARAM_OSC_PSCALE 2 #define CONFIG_PARAM_OSC_CMATCH 1 uint8_t CONFIG_PARAM_SW_MAJOR; uint8_t CONFIG_PARAM_SW_MINOR; #define MSG_IDLE 0 #define MSG_WAIT_SEQNUM 1 #define MSG_WAIT_SIZE1 2 #define MSG_WAIT_SIZE2 3 #define MSG_WAIT_TOKEN 4 #define MSG_WAIT_MSG 5 #define MSG_WAIT_CKSUM 6 //set custom configuration for PIC 24F _CONFIG2(FNOSC_FRCPLL & OSCIOFNC_ON &POSCMOD_NONE & I2C1SEL_PRI) // Internal FRC OSC = 8MHz _CONFIG1(JTAGEN_OFF & GCP_OFF & GWRP_OFF & COE_OFF & FWDTEN_OFF & ICS_PGx1) //turn off junk we don't need static unsigned char msg_buf[295]; static unsigned char param_reset_polarity=1; // 1=avr (reset active=low), 0=at89 (not supported by this avrusb500) static unsigned char param_controller_init=0; // handling off addressed larger than 64k words static unsigned char larger_than_64k=0; static unsigned char new_address=0; static unsigned char extended_address=0; static unsigned long address=0; static uint16_t saddress=0; /* transmit an answer back to the programmer software, message is * in msg_buf, seqnum is the seqnum of the last message from the programmer software, * len=1..275 according to avr068 */ void transmit_answer(unsigned char seqnum,unsigned int len) { unsigned char cksum; unsigned char ch; int i; if (len>285 || len <1){ // software error len = 2; // msg_buf[0]: not changed msg_buf[1] = STATUS_CMD_FAILED; } uart_sendchar(MESSAGE_START); // 0x1B cksum = MESSAGE_START^0; uart_sendchar(seqnum); cksum^=seqnum; ch=(len>>8)&0xFF; uart_sendchar(ch); cksum^=ch; ch=len&0xFF; uart_sendchar(ch); cksum^=ch; uart_sendchar(TOKEN); // 0x0E cksum^=TOKEN; wd_kick(); for(i=0;i= 0x80) { larger_than_64k = 1; }else{ larger_than_64k = 0; } extended_address = msg_buf[2]; new_address = 1; answerlen = 2; //msg_buf[0] = CMD_LOAD_ADDRESS; msg_buf[1] = STATUS_CMD_OK; break; case CMD_FIRMWARE_UPGRADE: // firmare upgrade is not supported this way answerlen = 2; //msg_buf[0] = CMD_FIRMWARE_UPGRADE; msg_buf[1] = STATUS_CMD_FAILED; break; case CMD_ENTER_PROGMODE_ISP: // 0x10 // The syntax of this command is as follows: // 0: Command ID 1 byte, CMD_ENTER_ PROGMODE_ISP // 1: timeout 1 byte, Command time-out (in ms) // 2: stabDelay 1 byte, Delay (in ms) used for pin stabilization // 3: cmdexeDelay 1 byte, Delay (in ms) in connection with the EnterProgMode command execution // 4: synchLoops 1 byte, Number of synchronization loops // 5: byteDelay 1 byte, Delay (in ms) between each byte in the EnterProgMode command. // 6: pollValue 1 byte, Poll value: 0x53 for AVR, 0x69 for AT89xx // 7: pollIndex 1 byte, Start address, received byte: 0 = no polling, 3 = AVR, 4 = AT89xx // cmd1 1 byte // cmd2 1 byte // cmd3 1 byte // cmd4 1 byte LED_ON; spi_init(); delay_ms(msg_buf[2]); // stabDelay answerlen=2; //msg_buf[0] = CMD_ENTER_PROGMODE_ISP; // set default to failed: msg_buf[1] = STATUS_CMD_FAILED; //connect to the target i=0; // limit the loops: if (msg_buf[4]> 48){ msg_buf[4]=48; } if (msg_buf[5] < 1){ // minimum byteDelay msg_buf[5]=1; } while(i 32){ msg_buf[4]=32; } saddress=address&0xFFFF; // previous address, start address nbytes = ((unsigned int)msg_buf[1])<<8; nbytes |= msg_buf[2]; if (nbytes> 280){ // corrupted message answerlen = 2; msg_buf[1] = STATUS_CMD_FAILED; break; } wd_kick(); // store the original mode: tmp2=msg_buf[3]; // result code cstatus=STATUS_CMD_OK; // msg_buf[3] test Word/Page Mode bit: if ((msg_buf[3]&1)==0){ // word mode for(i=0;i 280){ nbytes=280; } // for(i=0;i= tmp2 && ci 0){ // message correct, process it wdt_reset(); //wd_kick(); programcmd(seqnum); }else{ msg_buf[0] = ANSWER_CKSUM_ERROR; msg_buf[1] = STATUS_CKSUM_ERROR; transmit_answer(seqnum,2); } // no continue here, set state=MSG_IDLE } msgparsestate=MSG_IDLE; msglen=0; seqnum=0; prev_ch=0; i=0; } return(0); }