Jump to content

    

Stubiflex

Новичок
  • Content Count

    1
  • Joined

  • Last visited

Community Reputation

0 Обычный
  1. Сгенерировал с помощью МСС код загрузчика. При попытке залить приложение с помощью Unified Bootloader Host Application, получаю сообщение, которая на скриншоте. PIC6F18456 Как перебороть? //****************************************************************************** // Software License Agreement // // ©2016 Microchip Technology Inc. and its subsidiaries. You may use this // software and any derivatives exclusively with Microchip products. // // THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER // EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED // WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A PARTICULAR // PURPOSE, OR ITS INTERACTION WITH MICROCHIP PRODUCTS, COMBINATION WITH ANY // OTHER PRODUCTS, OR USE IN ANY APPLICATION. // // IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, // INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND // WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS // BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE // FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN // ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, // THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. // // MICROCHIP PROVIDES THIS SOFTWARE CONDITIONALLY UPON YOUR ACCEPTANCE OF THESE TERMS. //****************************************************************************** // // // // Memory Map // ----------------- // | 0x0000 | Reset vector // | | // | 0x0004 | Interrupt vector // | | // | | // | Boot Block | (this program) // | | // | 0x0300 | Re-mapped Reset Vector // | 0x0304 | Re-mapped High Priority Interrupt Vector // | | // | | | // | | // | Code Space | User program space // | | // | | | // | | // | 0x3FFF | // ----------------- // // // // Definitions: // // STX - Start of packet indicator // DATA - General data up to 255 bytes // COMMAND - Base command // DLEN - Length of data associated to the command // ADDR - Address up to 24 bits // DATA - Data (if any) // // // Commands: // // RD_VER 0x00 Read Version Information // RD_MEM 0x01 Read Program Memory // WR_MEM 0x02 Write Program Memory // ER_MEM 0x03 Erase Program Memory (NOT supported by PIC16) // RD_EE 0x04 Read EEDATA Memory // WR_EE 0x05 Write EEDATA Memory // RD_CONFIG 0x06 Read Config Memory (NOT supported by PIC16) // WT_CONFIG 0x07 Write Config Memory (NOT supported by PIC16) // CHECKSUM 0x08 Calculate 16 bit checksum of specified region of memory // RESET 0x09 Reset Device and run application // // ***************************************************************************** #define READ_VERSION 0 #define READ_FLASH 1 #define WRITE_FLASH 2 #define ERASE_FLASH 3 #define READ_EE_DATA 4 #define WRITE_EE_DATA 5 #define READ_CONFIG 6 #define WRITE_CONFIG 7 #define CALC_CHECKSUM 8 #define RESET_DEVICE 9 #define CALC_CRC 10 // ***************************************************************************** #include "xc.h" // Standard include #include <stdint.h> #include <stdbool.h> #include "bootload.h" #include "mcc.h" // ***************************************************************************** void Get_Buffer (void); // generic comms layer uint8_t Get_Version_Data(void); uint8_t Read_Flash(void); uint8_t Write_Flash(void); uint8_t Erase_Flash(void); uint8_t Read_EE_Data(void); uint8_t Write_EE_Data(void); uint8_t Read_Config(void); uint8_t Write_Config(void); uint8_t Calc_Checksum(void); void StartWrite(void); void BOOTLOADER_Initialize(void); void Run_Bootloader(void); bool Bootload_Required (void); // ***************************************************************************** #define MINOR_VERSION 0x07 // Version #define MAJOR_VERSION 0x00 //#define STX 0x55 // Actually code 0x55 is 'U' But this is what the autobaud feature of the PIC16F1 EUSART is looking for #define ERROR_ADDRESS_OUT_OF_RANGE 0xFE #define ERROR_INVALID_COMMAND 0xFF #define COMMAND_SUCCESS 0x01 // To be device independent, these are set by mcc in memory.h #define LAST_WORD_MASK (WRITE_FLASH_BLOCKSIZE - 1) #define NEW_RESET_VECTOR 0x500 #define NEW_INTERRUPT_VECTOR 0x504 #define _str(x) #x #define str(x) _str(x) // ***************************************************************************** // ***************************************************************************** uint16_t check_sum; // Checksum accumulator uint16_t counter; // General counter uint8_t data_length; uint8_t rx_data; uint8_t tx_data; bool reset_pending = false; // Force variables into Unbanked for 1-cycle accessibility uint8_t EE_Key_1 __at(0x70); uint8_t EE_Key_2 __at(0x71); frame_t frame; // ***************************************************************************** // The bootloader code does not use any interrupts. // However, the application code may use interrupts. // The interrupt vector on a PIC16F is located at // address 0x0004. // The following function will be located // at the interrupt vector and will contain a jump to // the new application interrupt vector asm ("psect intentry,global,class=CODE,delta=2"); asm ("pagesel " str(NEW_INTERRUPT_VECTOR)); asm ("GOTO " str(NEW_INTERRUPT_VECTOR)); void BOOTLOADER_Initialize () { EE_Key_1 = 0; EE_Key_2 = 0; if (Bootload_Required () == true) { Run_Bootloader (); // generic comms layer } STKPTR = 0x1F; asm ("pagesel " str(NEW_RESET_VECTOR)); asm ("goto " str(NEW_RESET_VECTOR)); } // ***************************************************************************** bool Bootload_Required () { // ****************************************************************** // Check the reset vector for code to initiate bootloader // ****************************************************************** // This section reads the application start vector to see if the location is blank NVMADRL = NEW_RESET_VECTOR & 0xFF; // (0x3FFF) or not. If blank, it runs the bootloader. NVMADRH = (NEW_RESET_VECTOR & 0xFF00UL)>> 8; // Otherwise, it assumes the application is loaded and instead runs the application. NVMCON1 = 0x80; NVMCON1bits.RD = 1; NOP(); NOP(); if ((NVMDATH == 0x3F) && (NVMDATL == 0xFF)) { return (true); } return (false); } // ***************************************************************************** uint8_t ProcessBootBuffer() { uint8_t len; EE_Key_1 = frame.EE_key_1; EE_Key_2 = frame.EE_key_2; // *********************************************** // Test the command field and sub-command. switch (frame.command) { case READ_VERSION: len = Get_Version_Data(); break; case READ_FLASH: len = Read_Flash(); break; case WRITE_FLASH: len = Write_Flash(); break; case ERASE_FLASH: len = Erase_Flash(); break; case READ_CONFIG: len = Read_Config(); break; case WRITE_CONFIG: len = Write_Config(); break; case CALC_CHECKSUM: len = Calc_Checksum(); break; case RESET_DEVICE: reset_pending = true; len = 9; break; default: frame.data[0] = ERROR_INVALID_COMMAND; len = 10; } return (len); } // ************************************************************************************** // Commands // // Cmd Length---------------- Address--------------- // In: [<0x00> <0x00><0x00><0x00><0x00> <0x00><0x00><0x00><0x00>] // OUT: [<0x00> <0x00><0x00><0x00><0x00> <0x00><0x00><0x00><0x00> <VERL><VERH>] uint8_t Get_Version_Data() { frame.data[0] = MINOR_VERSION; frame.data[1] = MAJOR_VERSION; frame.data[2] = 0; // Max packet size (256) frame.data[3] = 1; frame.data[4] = 0; frame.data[5] = 0; NVMADRL = 0x06; // Get device ID NVMADRH = 0x00; NVMCON1bits.NVMREGS = 1; NVMCON1bits.RD = 1; NOP(); NOP(); frame.data[6] = NVMDATL; frame.data[7] = NVMDATH; frame.data[8] = 0; frame.data[9] = 0; frame.data[10] = ERASE_FLASH_BLOCKSIZE; frame.data[11] = WRITE_FLASH_BLOCKSIZE; NVMADRL = 0x00; NVMADRH = 0x00; NVMCON1bits.NVMREGS = 1; for (uint8_t i= 12; i < 16; i++) { NVMCON1bits.RD = 1; NOP(); NOP(); frame.data[i] = NVMDATL; if ((++ NVMADRL) == 0x00) { ++ NVMADRH; } } return 25; // total length to send back 9 byte header + 16 byte payload } // ************************************************************************************** // Read Flash // In: [<0x01><DLEN><ADDRL><ADDRH><ADDRU>] // OUT: [<0x01><DLEN><ADDRL><ADDRH><ADDRU><DATA>...] uint8_t Read_Flash() { NVMADRL = frame.address_L; NVMADRH = frame.address_H; NVMCON1 = 0x80; for (uint16_t i = 0; i < frame.data_length; i += 2) { NVMCON1bits.RD = 1; NOP(); NOP(); frame.data[i] = NVMDATL; frame.data[i+1] = NVMDATH; if ((++ NVMADRL) == 0x00) { ++ NVMADRH; } } return (frame.data_length + 9); } // ************************************************************************************** // Write Flash // In: [<0x02><DLENBLOCK><0x55><0xAA><ADDRL><ADDRH><ADDRU><DATA>...] // OUT: [<0x02>] uint8_t Write_Flash() { NVMADRL = frame.address_L; NVMADRH = frame.address_H; NVMCON1 = 0xA4; // Setup writes for (uint16_t i= 0; i < frame.data_length; i += 2) { if (((NVMADRL & LAST_WORD_MASK) == LAST_WORD_MASK)|| (i == frame.data_length - 2)) NVMCON1bits.LWLO = 0; NVMDATL = frame.data[i]; NVMDATH = frame.data[i+1]; StartWrite(); if ((++ NVMADRL) == 0x00) { ++ NVMADRH; } } frame.data[0] = COMMAND_SUCCESS; EE_Key_1 = 0x00; // erase EE Keys EE_Key_2 = 0x00; return (10); } // ************************************************************************************** // Erase Program Memory // Erases data_length rows from program memory uint8_t Erase_Flash () { NVMADRL = frame.address_L; NVMADRH = frame.address_H; for (uint16_t i=0; i < frame.data_length; i++) { if ((NVMADRH & 0x7F) >= ((END_FLASH & 0xFF00) >> 8)) { frame.data[0] = ERROR_ADDRESS_OUT_OF_RANGE; return (10); } NVMCON1 = 0x94; // Setup writes StartWrite(); if ((NVMADRL += ERASE_FLASH_BLOCKSIZE) == 0x00) { ++ NVMADRH; } } frame.data[0] = COMMAND_SUCCESS; frame.EE_key_1 = 0x00; // erase EE Keys frame.EE_key_2 = 0x00; return (10); } // ************************************************************************************** // Read Config Words // In: [<0x06><DataLengthL><unused> <unused><unused> <ADDRL><ADDRH><ADDRU><unused>...] // OUT: [9 byte header + 4 bytes config1 + config 2] uint8_t Read_Config () { NVMADRL = frame.address_L; NVMADRH = frame.address_H; NVMCON1 = 0x40; // can these be combined? for (uint8_t i= 0; i < frame.data_length; i += 2) { NVMCON1bits.RD = 1; NOP(); NOP(); frame.data[i] = NVMDATL; frame.data[i+1] = NVMDATH; ++ NVMADRL; } return (13); // 9 byte header + 4 bytes config words } // ************************************************************************************** // Write Config Words uint8_t Write_Config () { NVMADRL = frame.address_L; NVMADRH = frame.address_H; NVMCON1 = 0xC4; // Setup writes for (uint8_t i = 0; i < frame.data_length; i += 2) { NVMDATL = frame.data[i]; NVMDATH = frame.data[i+1]; StartWrite(); if ((++ NVMADRL) == 0x00) { ++ NVMADRH; } } frame.data[0] = COMMAND_SUCCESS; EE_Key_1 = 0x00; // erase EE Keys EE_Key_2 = 0x00; return (10); } // ************************************************************************************** // Calculate Checksum // In: [<0x08><DataLengthL><DataLengthH> <unused><unused> <ADDRL><ADDRH><ADDRU><unused>...] // OUT: [9 byte header + ChecksumL + ChecksumH] uint8_t Calc_Checksum() { NVMADRL = frame.address_L; NVMADRH = frame.address_H; NVMCON1 = 0x80; check_sum = 0; for (uint16_t i = 0;i < frame.data_length; i += 2) { NVMCON1bits.RD = 1; NOP(); NOP(); check_sum += (uint16_t)NVMDATL; check_sum += ((uint16_t)NVMDATH) << 8; if ((++ NVMADRL) == 0x00) { ++ NVMADRH; } } frame.data[0] = (uint8_t) (check_sum & 0x00FF); frame.data[1] = (uint8_t)((check_sum & 0xFF00) >> 8); return (11); } // In: [<0x08><DataLengthL><DataLengthH> <unused><unused> <ADDRL><ADDRH><ADDRU><unused>...] // OUT: [9 byte header + ChecksumL + ChecksumH] /*uint8_t Calc_Checksum() { uint16_t addr = (frame.address_H << 8) | frame.address_L; check_sum = 0; for (uint16_t i = 0;i < frame.data_length; i += 2) { check_sum += FLASH_ReadWord(addr); ++ addr; } frame.data[0] = (uint8_t) (check_sum & 0x00FF); frame.data[1] = (uint8_t)((check_sum & 0xFF00) >> 8); return (11); }*/ // ***************************************************************************** // Unlock and start the write or erase sequence. void StartWrite() { CLRWDT(); // NVMCON2 = EE_Key_1; // NVMCON2 = EE_Key_2; // NVMCON1bits.WR = 1; // Start the write // had to switch to assembly - compiler doesn't comprehend no need for bank switch asm ("movf " str(_EE_Key_1) ",w"); asm ("movwf " str(BANKMASK(NVMCON2))); asm ("movf " str(_EE_Key_2) ",w"); asm ("movwf " str(BANKMASK(NVMCON2))); asm ("bsf " str(BANKMASK(NVMCON1)) ",1"); // Start the write NOP(); NOP(); return; } // ***************************************************************************** // Check to see if a device reset had been requested. We can't just reset when // the reset command is issued. Instead we have to wait until the acknowledgement // is finished sending back to the host. Then we reset the device. void Check_Device_Reset () { if (reset_pending == true) { RESET(); } } // ***************************************************************************** // ***************************************************************************** А вот код, сгенерированный с помощью МСС.