/** @brief Enable SPI hardware and reset the connected device. This function leaves the target in reset mode. Use SET_RST() to un-reset the target device. @param clockOption Clock option for spi clock speed @param maintainReset True to maintain target reset state @return actual set clock option: this may differ from the option passed in if the passed in value is invalid or if the slow clock jumper is connected */ uchar SPI_Connect(uchar clockOption, uchar maintainReset) { clockOption = SPI_SetSCKOption(clockOption); /** Turn on the SPI pins */ EnableSPI(); /** Reset the device, and maintain reset */ SET_RST(); CLR_RST(); clockWait(1); SET_RST(); /** Put the device back into reset mode if required */ if (maintainReset) { clockWait(1); CLR_RST(); } /** Enable the SPI Hardware (if needed) */ if (sw_delay_time == 0) spiHWenable(); return clockOption; }
uchar SPI_EnterProgrammingMode() { uchar check; uchar count = 3; // Try to connect 3 times for (; count > 0; count--) { SPI_Transmit(0xAC); SPI_Transmit(0x53); check = SPI_Transmit(0); SPI_Transmit(0); if (check == 0x53) { return 0; // Success! We're connected an in programming mode! } // If the connect command failed, // the communication may be out of sync. // Pulse reset (as per the datasheet) and // try again. SET_RST(); // Device into normal operation clockWait(1); CLR_RST(); // Device back into reset mode clockWait(63); // Wait 20 ms before sending another program enable command } return 1; /* error: device dosn't answer */ }
void ispProgramPage(unsigned int address) { ispTransmit(0x4C); ispTransmit(address >> 9); ispTransmit(address >> 1); ispTransmit(0); clockWait(15); // if (pollvalue == 0xFF) // { // return 0; // } // else // { // /* polling flash */ // uchar retries = 30; // uint16_t startTime = hwTimerValue() ; // while (retries != 0) // { // if (ispReadFlash(address) != 0xFF) // { // return 0; // } // if ( (uint16_t)( hwTimerValue() - startTime ) > 3200 ) // { // startTime = hwTimerValue() ; // retries --; // } // } // return 1; /* error */ // } }
uchar SPI_FlushPage(unsigned long address, uchar pollvalue) { SPI_Transmit(0x4C); SPI_Transmit(address >> 9); SPI_Transmit(address >> 1); SPI_Transmit(0); if (pollvalue == 0xFF) { clockWait(15); return 0; } else { /* polling flash */ uchar counter = 30; TIMER1 = 0; while (counter != 0) { if (SPI_ReadFlash(address) != 0xFF) { return 0; } if (TIMER1 > CLOCK_T_320us) { TIMER1 = 0; counter--; } } return 1; /* error */ } }
void ispChipErase() { ispTransmit(0xAC) ; ispTransmit(0x80) ; ispTransmit(0) ; ispTransmit(0) ; clockWait(50) ; }
uchar SPI_WriteEEPROM(unsigned int address, uchar data) { SPI_Transmit(0xC0); SPI_Transmit(address >> 8); SPI_Transmit(address); SPI_Transmit(data); clockWait(30); // Wait 9.6ms for write to complete return 0; }
uchar SPI_WriteFlash(unsigned long address, uchar data, uchar pollmode) { // We're not guarenteed that there was a chip erase, so we can't // skip programming of 0xFF... /* 0xFF is value after chip erase, so skip programming if (data == 0xFF) { return 0; } */ SPI_Transmit(0x40 | ((address & 1) << 3)); SPI_Transmit(address >> 9); SPI_Transmit(address >> 1); SPI_Transmit(data); if (pollmode == 0) return 0; if (data == 0x7F) { clockWait(15); // wait 4,8 ms return 0; } else { // Poll flash for (30 * 320 uS) uchar counter = 30; TIMER1 = 0; while (counter != 0) { if (SPI_ReadFlash(address) != 0x7F) { return 0; }; if (TIMER1 > CLOCK_T_320us) { TIMER1 = 0; counter--; } } return 1; /* error */ } }
void ispConnect() { init_hw_timer() ; /* all ISP pins are inputs before */ /* now set output pins */ RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN ; // Enable portA clock RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN ; // Enable portB clock RCC->AHB1ENR |= RCC_AHB1ENR_GPIOCEN ; // Enable portC clock configure_pins( GPIO_Pin_M64_RST, PIN_OUTPUT | PIN_PUSHPULL | PIN_OS25 | PIN_PORTC ) ; configure_pins( GPIO_Pin_M64_SCK, PIN_OUTPUT | PIN_PUSHPULL | PIN_OS25 | PIN_PORTA ) ; configure_pins( GPIO_Pin_M64_MOSI, PIN_OUTPUT | PIN_PUSHPULL | PIN_OS25 | PIN_PORTB ) ; /* reset device */ RST_LOW() ; /* RST low */ SCK_LOW() ; /* SCK low */ /* positive reset pulse > 2 SCK (target) */ ispDelay(); RST_HIGH() ; /* RST high */ clockWait(64) ; RST_LOW() ; /* RST low */ }
uchar usbFunctionSetup(uchar data[8]) { uchar len = 0; if (data[1] == USBASP_FUNC_CONNECT) { /* set SCK speed */ if ((PINC & (1 << PC2)) == 0) { ispSetSCKOption(USBASP_ISP_SCK_8); } else { ispSetSCKOption(prog_sck); } /* set compatibility mode of address delivering */ prog_address_newmode = 0; ledRedOn(); ispConnect(); } else if (data[1] == USBASP_FUNC_DISCONNECT) { ispDisconnect(); ledRedOff(); } else if (data[1] == USBASP_FUNC_TRANSMIT) { if(chip==ATM){ replyBuffer[0] = ispTransmit(data[2]); replyBuffer[1] = ispTransmit(data[3]); replyBuffer[2] = ispTransmit(data[4]); replyBuffer[3] = ispTransmit(data[5]); } else { if(data[2]==0x24) { // read lock bits replyBuffer[0] = ispTransmit(data[2]); replyBuffer[1] = ispTransmit(data[3]); replyBuffer[2] = ispTransmit(data[4]); switch(ispTransmit(data[5])&0x1C) { case(0x00):replyBuffer[3]=0xE0;break; case(0x04):replyBuffer[3]=0xE5;break; case(0x0C):replyBuffer[3]=0xEE;break; case(0x1C):replyBuffer[3]=0xFF;break; } } else if(data[2]==0x30) { // read signature replyBuffer[0] = ispTransmit(0x28); replyBuffer[1] = ispTransmit(data[3]); replyBuffer[2] = ispTransmit(data[4]); replyBuffer[3] = ispTransmit(data[5]); } else { replyBuffer[0] = ispTransmit(data[2]); replyBuffer[1] = ispTransmit(data[3]); replyBuffer[2] = ispTransmit(data[4]); replyBuffer[3] = ispTransmit(data[5]); } } len = 4; } else if (data[1] == USBASP_FUNC_READFLASH) { if (!prog_address_newmode) prog_address = (data[3] << 8) | data[2]; prog_nbytes = (data[7] << 8) | data[6]; prog_state = PROG_STATE_READFLASH; len = 0xff; /* multiple in */ } else if (data[1] == USBASP_FUNC_READEEPROM) { if (!prog_address_newmode) prog_address = (data[3] << 8) | data[2]; prog_nbytes = (data[7] << 8) | data[6]; prog_state = PROG_STATE_READEEPROM; len = 0xff; /* multiple in */ } else if (data[1] == USBASP_FUNC_ENABLEPROG) { // replyBuffer[0] = ispEnterProgrammingMode(); replyBuffer[0] = ispEnterProgrammingMode_jarodlau();//代码修改成自动降速,jarodlau len = 1; } else if (data[1] == USBASP_FUNC_WRITEFLASH) { if (!prog_address_newmode) prog_address = (data[3] << 8) | data[2]; prog_pagesize = data[4]; prog_blockflags = data[5] & 0x0F; prog_pagesize += (((unsigned int) data[5] & 0xF0) << 4); if (prog_blockflags & PROG_BLOCKFLAG_FIRST) { prog_pagecounter = prog_pagesize; } prog_nbytes = (data[7] << 8) | data[6]; prog_state = PROG_STATE_WRITEFLASH; len = 0xff; /* multiple out */ } else if (data[1] == USBASP_FUNC_WRITEEEPROM) { if (!prog_address_newmode) prog_address = (data[3] << 8) | data[2]; prog_pagesize = 0; prog_blockflags = 0; prog_nbytes = (data[7] << 8) | data[6]; prog_state = PROG_STATE_WRITEEEPROM; len = 0xff; /* multiple out */ } else if (data[1] == USBASP_FUNC_SETLONGADDRESS) { /* set new mode of address delivering (ignore address delivered in commands) */ prog_address_newmode = 1; /* set new address */ prog_address = *((unsigned long*) &data[2]); } else if (data[1] == USBASP_FUNC_SETISPSCK) { /* set sck option */ prog_sck = data[2]; replyBuffer[0] = 0; len = 1; } else if (data[1] == USBASP_FUNC_TPI_CONNECT) { tpi_dly_cnt = data[2] | (data[3] << 8); /* RST high */ ISP_OUT |= (1 << ISP_RST); ISP_DDR |= (1 << ISP_RST); clockWait(3); /* RST low */ ISP_OUT &= ~(1 << ISP_RST); ledRedOn(); clockWait(16); tpi_init(); } else if (data[1] == USBASP_FUNC_TPI_DISCONNECT) { tpi_send_byte(TPI_OP_SSTCS(TPISR)); tpi_send_byte(0); clockWait(10); /* pulse RST */ ISP_OUT |= (1 << ISP_RST); clockWait(5); ISP_OUT &= ~(1 << ISP_RST); clockWait(5); /* set all ISP pins inputs */ ISP_DDR &= ~((1 << ISP_RST) | (1 << ISP_SCK) | (1 << ISP_MOSI)); /* switch pullups off */ ISP_OUT &= ~((1 << ISP_RST) | (1 << ISP_SCK) | (1 << ISP_MOSI)); ledRedOff(); } else if (data[1] == USBASP_FUNC_TPI_RAWREAD) { replyBuffer[0] = tpi_recv_byte(); len = 1; } else if (data[1] == USBASP_FUNC_TPI_RAWWRITE) { tpi_send_byte(data[2]); } else if (data[1] == USBASP_FUNC_TPI_READBLOCK) { prog_address = (data[3] << 8) | data[2]; prog_nbytes = (data[7] << 8) | data[6]; prog_state = PROG_STATE_TPI_READ; len = 0xff; /* multiple in */ } else if (data[1] == USBASP_FUNC_TPI_WRITEBLOCK) { prog_address = (data[3] << 8) | data[2]; prog_nbytes = (data[7] << 8) | data[6]; prog_state = PROG_STATE_TPI_WRITE; len = 0xff; /* multiple out */ } else if (data[1] == USBASP_FUNC_GETCAPABILITIES) { replyBuffer[0] = USBASP_CAP_0_TPI; replyBuffer[1] = 0; replyBuffer[2] = 0; replyBuffer[3] = 0; len = 4; } usbMsgPtr = replyBuffer; return len; }
uchar usbFunctionSetup(uchar data[8]) { uchar len = 0; #ifdef UART_DEBUG TransmitHex(data[1]); #endif if (data[1] == USBASP_FUNC_CONNECT) { #if 0 /* set SCK speed */ if ((PINC & (1 << PC2)) == 0) { ispSetSCKOption(USBASP_ISP_SCK_8); } else { ispSetSCKOption(prog_sck); } #endif /* set compatibility mode of address delivering */ prog_address_newmode = 0; ledRedOn(); ispConnect(); } else if (data[1] == USBASP_FUNC_DISCONNECT) { ispDisconnect(); ledRedOff(); } else if (data[1] == USBASP_FUNC_TRANSMIT) { // debug - print out contents of message #ifdef UART_DEBUG TransmitHex(data[2]); TransmitHex(data[3]); TransmitHex(data[4]); TransmitHex(data[5]); #endif replyBuffer[0] = 0; replyBuffer[1] = 0; replyBuffer[2] = 0; replyBuffer[3] = interpretSPICommand(&data[2]); len = 4; } else if (data[1] == USBASP_FUNC_READFLASH) { if (!prog_address_newmode) prog_address = (data[3] << 8) | data[2]; prog_nbytes = (data[7] << 8) | data[6]; prog_state = PROG_STATE_READFLASH; len = 0xff; /* multiple in */ } else if (data[1] == USBASP_FUNC_READEEPROM) { if (!prog_address_newmode) prog_address = (data[3] << 8) | data[2]; prog_nbytes = (data[7] << 8) | data[6]; prog_state = PROG_STATE_READEEPROM; len = 0xff; /* multiple in */ } else if (data[1] == USBASP_FUNC_ENABLEPROG) { replyBuffer[0] = ispEnterProgrammingMode(); len = 1; } else if (data[1] == USBASP_FUNC_WRITEFLASH) { if (!prog_address_newmode) prog_address = (data[3] << 8) | data[2]; prog_pagesize = data[4]; prog_blockflags = data[5] & 0x0F; prog_pagesize += (((unsigned int) data[5] & 0xF0) << 4); if (prog_blockflags & PROG_BLOCKFLAG_FIRST) { prog_pagecounter = prog_pagesize; } prog_nbytes = (data[7] << 8) | data[6]; prog_state = PROG_STATE_WRITEFLASH; len = 0xff; /* multiple out */ } else if (data[1] == USBASP_FUNC_WRITEEEPROM) { if (!prog_address_newmode) prog_address = (data[3] << 8) | data[2]; prog_pagesize = 0; prog_blockflags = 0; prog_nbytes = (data[7] << 8) | data[6]; prog_state = PROG_STATE_WRITEEEPROM; len = 0xff; /* multiple out */ } else if (data[1] == USBASP_FUNC_SETLONGADDRESS) { /* set new mode of address delivering (ignore address delivered in commands) */ prog_address_newmode = 1; /* set new address */ prog_address = *((unsigned long*) &data[2]); } else if (data[1] == USBASP_FUNC_SETISPSCK) { /* set sck option */ prog_sck = data[2]; replyBuffer[0] = 0; len = 1; #if 0 } else if (data[1] == USBASP_FUNC_TPI_CONNECT) { tpi_dly_cnt = data[2] | (data[3] << 8); /* RST high */ ISP_OUT |= (1 << ISP_RST); ISP_DDR |= (1 << ISP_RST); clockWait(3); /* RST low */ ISP_OUT &= ~(1 << ISP_RST); ledRedOn(); clockWait(16); tpi_init(); } else if (data[1] == USBASP_FUNC_TPI_DISCONNECT) { tpi_send_byte(TPI_OP_SSTCS(TPISR)); tpi_send_byte(0); clockWait(10); /* pulse RST */ ISP_OUT |= (1 << ISP_RST); clockWait(5); ISP_OUT &= ~(1 << ISP_RST); clockWait(5); /* set all ISP pins inputs */ ISP_DDR &= ~((1 << ISP_RST) | (1 << ISP_SCK) | (1 << ISP_MOSI)); /* switch pullups off */ ISP_OUT &= ~((1 << ISP_RST) | (1 << ISP_SCK) | (1 << ISP_MOSI)); ledRedOff(); } else if (data[1] == USBASP_FUNC_TPI_RAWREAD) { replyBuffer[0] = tpi_recv_byte(); len = 1; } else if (data[1] == USBASP_FUNC_TPI_RAWWRITE) { tpi_send_byte(data[2]); } else if (data[1] == USBASP_FUNC_TPI_READBLOCK) { prog_address = (data[3] << 8) | data[2]; prog_nbytes = (data[7] << 8) | data[6]; prog_state = PROG_STATE_TPI_READ; len = 0xff; /* multiple in */ } else if (data[1] == USBASP_FUNC_TPI_WRITEBLOCK) { prog_address = (data[3] << 8) | data[2]; prog_nbytes = (data[7] << 8) | data[6]; prog_state = PROG_STATE_TPI_WRITE; len = 0xff; /* multiple out */ #endif } else if (data[1] == USBASP_FUNC_GETCAPABILITIES) { replyBuffer[0] = USBASP_CAP_0_TPI; replyBuffer[1] = 0; replyBuffer[2] = 0; replyBuffer[3] = 0; len = 4; } usbMsgPtr = replyBuffer; #ifdef UART_DEBUG TransmitString("\r\n"); #endif return len; }
uint32_t flashAvr( uint8_t *data64, uint8_t *data2561, uint16_t size64, uint16_t size2561 ) { uint32_t i ; uint8_t *data ; uint16_t address ; uint16_t size ; uint8_t *verifyData ; ispConnect() ; clockWait( 64 ) ; // 20mS wdt_reset() ; if ( ( IspStatus = ispEnterProgrammingMode() ) == 0 ) { Signature[0] = ispReadSignature(0) ; Signature[1] = ispReadSignature(1) ; Signature[2] = ispReadSignature(2) ; } // choose file here data = data64 ; size = size64 ; if ( Signature[1] == 0x98 ) { data = data2561 ; size = size2561 ; } verifyData = data ; ispChipErase() ; if ( Signature[1] == 0x98 ) { ispTransmit(0x4D) ; ispTransmit(0) ; ispTransmit(0) ; ispTransmit(0) ; } for ( address = 0 ; address < size ; address += 256 ) { i = 256 ; if ( address + 256 > size ) { i = size - address ; } flashPage( data, address, i ) ; data += 256 ; wdt_reset() ; } for ( i = 0 ; i < 64 ; i += 1 ) { M64Program[i] = ispReadFlash( i ) ; } ispDisconnect() ; clockWait(64) ; wdt_reset() ; for ( i = 0 ; i < 64 ; i += 1 ) { if ( *verifyData++ != M64Program[i] ) { return 1 ; } } return 0 ; }