Programming PIC18F2550 with Bootloader firmware (using PICkit2)
test bootloader by checking the LED (button at, LED at)
Programming PIC18F2550 with PICkit2 firmware
check PICkit2App
[Bluetooth module: AT COMMAND (NO \n\r)
1.AT
2.AT+NAME
3.AT+PIN (xxx8)
4.AT+BAUD5 (for 19200)]
Write a simple UART program to echo the data sent from the host.
Setup Vdd, Vpp circuit
Vpp_Feedback
Vdd_Target_FB
Vpp_ON
Vpp_PUMP
Vdd_TARGET_N
Vdd_TARGET_P
Vdd_TARGET_adj
Update firmware with serial port support
programming the new firmware to PIC18F2550
XC8
section // linker class // memory
text; CODE, Flash
bss0; BANK0; RAM
data0; BANK0; RAM
idata; CODE; Flash
PSECT bss0, class=BANK0
PSECT text, class=CODE
Tuesday, December 15, 2015
Using Executive Code Memory as the Bootloader
---- Diagnosis Phase ----
Open RIPE_XX_XX.hex in MPLAB X.
Change Base Address of Code
:020000040100f9
Export the Assembly Code
--> Interrupt Vector
Open RIPE_XX_XX.hex in MPLAB X.
Change Base Address of Code
:020000040100f9
Export the Assembly Code
--> Interrupt Vector
PICKIT DIY
Originally working on dsPIC30F2011 with bluetooth module.
Work on PIC18LF2455, first using PICkit 2 to flash bootloader to PIC18LF2455.
RB5 - Push Button (Enter Bootloader Mode)
RC0 - Busy LED
//PICkit User Guide
PK2Error0018: Unable to enter bootloader
Description: PICkit 2 Debug Express was unable to access the PICkit 2 unit bootloader
while updating the PICkit 2 Operating System.
Suggested Actions: Disconnect the PICkit 2 unit from USB and the target board. While
holding the PICkit 2 unit push button down, plug the PICkit 2 unit back into the USB
port. The BUSY LED should flash slowly. If it does not, the bootloader may be
corrupted. Contact Microchip about the problem.
//******************
see boot.h for memory maps for remapped vectors
#define RM_RESET_VECTOR 0x002000
#define RM_HIGH_INTERRUPT_VECTOR 0x002008
#define RM_LOW_INTERRUPT_VECTOR 0x002018
-------------------------------
// Write key 0x5555 at last memory location to tell bootloader FW loaded.
if (!Pk2.BL_WriteFWLoadedKey())
{
displayStatusWindow.Text = "Error loading Operating System.";
displayStatusWindow.BackColor = Color.Salmon;
return;
}
---------------------------------
public static bool BL_WriteFWLoadedKey()
{
byte[] flashWriteData = new byte[3 + 32]; // 3 address bytes plus 32 data bytes.
flashWriteData[0] = 0xE0;
flashWriteData[1] = 0x7F;
flashWriteData[2] = 0x00; // Address = 0x007FE0
for (int i = 3; i < flashWriteData.Length; i++)
{
flashWriteData[i] = 0xFF;
}
flashWriteData[flashWriteData.Length - 2] = 0x55;
flashWriteData[flashWriteData.Length - 1] = 0x55;
return BL_WriteFlash(flashWriteData);
}
----------------------------------------
// boot_main.c
if (PROG_SWITCH) { // is the push button pressed?
// if no, does program memory location 0x7FFE contain 0x55?
Temp = * ((rom far char *) 0x7FFE);
if(Temp == 0x55) {
_asm goto RM_RESET_VECTOR _endasm
}
} // end if (PROG_SWITCH)
1845 0E68 AA81 BTFSS PORTB, 5, ACCESS
1846 0E6A D00D BRA 0xE86
1847 0E6C 0EFE MOVLW 0xFE
1848 0E6E 6EF6 MOVWF TBLPTRL, ACCESS
1849 0E70 0E7F MOVLW 0x7F
1850 0E72 6EF7 MOVWF TBLPTRH, ACCESS
1851 0E74 6AF8 CLRF TBLPTRU, ACCESS
1852 0E76 0008 TBLRD*
1853 0E78 50F5 MOVF TABLAT, W, ACCESS
1854 0E7A 6EDF MOVWF INDF2, ACCESS
1855 0E7C 0E55 MOVLW 0x55
1856 0E7E 5CDF SUBWF INDF2, W, ACCESS
1857 0E80 E102 BNZ 0xE86
1858 0E82 EF00 GOTO 0x2000
1859 0E84 F010 NOP
Work on PIC18LF2455, first using PICkit 2 to flash bootloader to PIC18LF2455.
RB5 - Push Button (Enter Bootloader Mode)
RC0 - Busy LED
//PICkit User Guide
PK2Error0018: Unable to enter bootloader
Description: PICkit 2 Debug Express was unable to access the PICkit 2 unit bootloader
while updating the PICkit 2 Operating System.
Suggested Actions: Disconnect the PICkit 2 unit from USB and the target board. While
holding the PICkit 2 unit push button down, plug the PICkit 2 unit back into the USB
port. The BUSY LED should flash slowly. If it does not, the bootloader may be
corrupted. Contact Microchip about the problem.
//******************
see boot.h for memory maps for remapped vectors
#define RM_RESET_VECTOR 0x002000
#define RM_HIGH_INTERRUPT_VECTOR 0x002008
#define RM_LOW_INTERRUPT_VECTOR 0x002018
-------------------------------
// Write key 0x5555 at last memory location to tell bootloader FW loaded.
if (!Pk2.BL_WriteFWLoadedKey())
{
displayStatusWindow.Text = "Error loading Operating System.";
displayStatusWindow.BackColor = Color.Salmon;
return;
}
---------------------------------
public static bool BL_WriteFWLoadedKey()
{
byte[] flashWriteData = new byte[3 + 32]; // 3 address bytes plus 32 data bytes.
flashWriteData[0] = 0xE0;
flashWriteData[1] = 0x7F;
flashWriteData[2] = 0x00; // Address = 0x007FE0
for (int i = 3; i < flashWriteData.Length; i++)
{
flashWriteData[i] = 0xFF;
}
flashWriteData[flashWriteData.Length - 2] = 0x55;
flashWriteData[flashWriteData.Length - 1] = 0x55;
return BL_WriteFlash(flashWriteData);
}
----------------------------------------
// boot_main.c
if (PROG_SWITCH) { // is the push button pressed?
// if no, does program memory location 0x7FFE contain 0x55?
Temp = * ((rom far char *) 0x7FFE);
if(Temp == 0x55) {
_asm goto RM_RESET_VECTOR _endasm
}
} // end if (PROG_SWITCH)
// disassembly
Line Address Opcode Label DisAssy 1845 0E68 AA81 BTFSS PORTB, 5, ACCESS
1846 0E6A D00D BRA 0xE86
1847 0E6C 0EFE MOVLW 0xFE
1848 0E6E 6EF6 MOVWF TBLPTRL, ACCESS
1849 0E70 0E7F MOVLW 0x7F
1850 0E72 6EF7 MOVWF TBLPTRH, ACCESS
1851 0E74 6AF8 CLRF TBLPTRU, ACCESS
1852 0E76 0008 TBLRD*
1853 0E78 50F5 MOVF TABLAT, W, ACCESS
1854 0E7A 6EDF MOVWF INDF2, ACCESS
1855 0E7C 0E55 MOVLW 0x55
1856 0E7E 5CDF SUBWF INDF2, W, ACCESS
1857 0E80 E102 BNZ 0xE86
1858 0E82 EF00 GOTO 0x2000
1859 0E84 F010 NOP
// HEX file
:100E70007F0EF76EF86A0800F550DF6E550EDF5CE6
change 7F to 5F for 24Kbyte device, 5FFF(24K device), 7FFF(32K device) end of on-chip program memory. E6 is the checksum
to
:100E70005F0EF76EF86A0800F550DF6E550EDF5C06
>PIC18F2550
:100D400000430031003800460032003500350030E5
>PIC18F2455
:100D400000430031003800460032003400350035E1
// user program can start from address 1000
--------------------
Program Linker Options
Memory Model:: ROM Ranges: default,-5FF0-5FFF
Additional Options:: Codeoffset: 0x2000
--------------------
PIC18LF25k50 Vusb3v3 tied to Vdd (no internal 3.3V LDO regulator)
PIC18F25k50 Vusb3v3 tied to capacitor (using internal 3.3V LDO regulator)
--------------------
VDD ranges are different for PIC18LF25K50 and PIC18LF2550
notes: PIC18LF25K50 is like PIC18F2550, PIC18F25K50 is like PIC18LF2550.
-------------------
PICkit 2 firmware porting to XC8
--------- Bootloader ---------
1. Create MPLAB X project.
2. Update Compiler Include Path
3. Generate Configuration File
4. Compile each c file
a. Change typedefs.h
b. Comment out "pragma udata", "pragma code"
c. Change _asm to asm()
#pragma psect usbram XX -> using @0x400...
if (U1IEbits.UERRIE && U1IRbits.UERRIF)
{
#if defined (DEBUG_ENABLE)
DEBUG_PutChar('#');
DEBUG_PutHexUINT8( U1EIR );
#endif
* * * *
porting to XC8 on halt due to unknow USB issues ... try another approach using MLA usb bootloader...
1. Copy Project
2. Change Descriptor Data
3. Change Enter Bootloader Button to RB5 as in PICkit 2
4. Change Command
5. Check BootPICxxx.h and VectorRemap.asm for Vector setup
4. Change Command
5. Check BootPICxxx.h and VectorRemap.asm for Vector setup
#define REMAPPED_APPLICATION_RESET_VECTOR 0x2000
#define APP_SIGNATURE_ADDRESS 0x7FFE
#define APP_SIGNATURE_VALUE 0x5555
======== PICkit Bootloader / Find PICkit Device==========
1. Send Command 'v', if the return data[1]=0x76, it's the bootloader
data[6]='B',data[7]=Major_Version,data[8]=Minor_Version
2. Configuration Bits, WRTB, WRT0 is clear for Write Protection from 0x0000~0x1FFF
data[6]='B',data[7]=Major_Version,data[8]=Minor_Version
2. Configuration Bits, WRTB, WRT0 is clear for Write Protection from 0x0000~0x1FFF
3.
void ReadVersion(void); //test OK void ReadProgMem(void); //test OK void WriteProgMem(void); //test OK void EraseProgMem(void); //test OK void ReadEE(void); //? void WriteEE(void); //?
4. PICkit2 Firmware (Reserve the last 32 bytes block for signature 0x5555@0x7FFE
5. Download the firmware to PIC18F2550, OK.
5. Download the firmware to PIC18F2550, OK.
dsPIC33EP256MC202 - PICkit2
family ID: 5
search Priority: 2
using example from dsPIC33FJ256MC510, dsPIC33FJ256MC710, dsPIC33FJ128MC202
family ID: 1
search Priority: 0
using example from PIC24FJ64GB002
test get DeviceID
delay long: 5.46ms
delay short: 21.3us
dsPIC33EP256MC202
TBLPAG: 0x54
VISI: 0x0F88, VISI>>1:0x07C4
MOV W0, TBLPAG, 8802A0
MOV W0, VISI 887C40
MOV #VISI, W7 20F887
double word write cycle time: 346 FRC cycles, 54.4us ~ 60us
dsPIC33F
TBLPAG: 0x32
VISI: 0x0784, VISI>>1:0x03C2
MOV W0, TBLPAG, 880190
MOV W0, VISI, 883C20
MOV #VISI, W7 207847
row(64 instructions) programming time: 1.28 ms
<ICSP>
enter ICSP (OK)
get DeviceID (OK)
disable PE33 in PICkit2.ini
adjust DialogConfigEdit.cs (OK)
create simple LED blinking app running with internal oscillator. (OK)
update Script
ScriptLength cannot be greater than 61
[#ChipEraseScript]
[#ConfigRdScript] <--- need to change to byte
[#UserIDRdScript] <--- need to change byte to word
[#ProgMemAddrSetScript]
MOV ADDR_L, W6
MOV.B ADDR_H, W0
MOV W0, TBLPAG
MOV #VISI,W7
[#ProgMemRdScript]
TBLRDL [W6],[W7]
TBLRDH [W6++],[W7]
===========
[#ProgMemWrPrepScript]
MOV #0x4001, W10 //word write
MOV W10, NVMCON
MOV ADDR_L, W7
MOV.B ADDR_H, W0
MOV W0, TBLPAG
[#ProgMemWrScript]
[#ConfigWrScript]
[#UserIDWrScript]
test erase script(should be OK)
test programming script(OK)
add script buffer location (number): PROGMEM_WR2 = 30; // not required
test configure write script (OK)
test userid write script(Pending)
add device family dsPIC33EP FamilyID:18, FamilyType:18, SearchPriority:3 (OK)
enable PE33 in PICkit2.ini (as default)
---
load PE executive (OK)
<Enhanced ICSP>
PE: A delay of 25 ms is required between commands.
PE_DownloadAndConnect(OK)
PE_Connect (OK)
PE_Read(OK)
add a dealy_short(1) between read_byte and read_byte_buffer
PE_BlankCheck(OK)
PE bug: Expected Reponse[0] should be 0x1E, but returned 0x1A
PE_Write(OK) might have problem with the last block(32 instructions) with the Configuration Bits
PE_Verify(OK)
Export the script(OK)
Add CRC check (WIP)
Apply Object Oriented Design...
[get device ID script]
$COREINST24 00 02 04 //goto 0x200
$COREINST24 00 02 04
$NOP24
$NOP24
$NOP24
$COREINST24 00 02 04
$NOP24
$COREINST24 F0 0F 20 //mov 0xff, w0
$COREINST24 90 01 88 //mov w0, tblpag
$COREINST24 06 00 20 //mov 0x0000, w6
$NOP24
$NOP24
$COREINST24 07 00 20 //mov 0x0000, w7
$COREINST24 B6 0B BA //mov [w6++], [w7] == mov [w6++],w0
$NOP24
$NOP24
$COREINST24 20 3C 88 //mov w0, visi
$NOP24
$VISI24
$NOP24
$LOOP 0D 01
search Priority: 2
using example from dsPIC33FJ256MC510, dsPIC33FJ256MC710, dsPIC33FJ128MC202
family ID: 1
search Priority: 0
using example from PIC24FJ64GB002
test get DeviceID
delay long: 5.46ms
delay short: 21.3us
dsPIC33EP256MC202
TBLPAG: 0x54
VISI: 0x0F88, VISI>>1:0x07C4
MOV W0, TBLPAG, 8802A0
MOV W0, VISI 887C40
MOV #VISI, W7 20F887
double word write cycle time: 346 FRC cycles, 54.4us ~ 60us
dsPIC33F
TBLPAG: 0x32
VISI: 0x0784, VISI>>1:0x03C2
MOV W0, TBLPAG, 880190
MOV W0, VISI, 883C20
MOV #VISI, W7 207847
row(64 instructions) programming time: 1.28 ms
<ICSP>
enter ICSP (OK)
get DeviceID (OK)
disable PE33 in PICkit2.ini
adjust DialogConfigEdit.cs (OK)
create simple LED blinking app running with internal oscillator. (OK)
ScriptLength cannot be greater than 61
[#ChipEraseScript]
[#ConfigRdScript] <--- need to change to byte
[#UserIDRdScript] <--- need to change byte to word
[#ProgMemAddrSetScript]
MOV ADDR_L, W6
MOV.B ADDR_H, W0
MOV W0, TBLPAG
MOV #VISI,W7
[#ProgMemRdScript]
TBLRDL [W6],[W7]
TBLRDH [W6++],[W7]
[#ProgMemWrPrepScript]
MOV #0x4001, W10 //word write
MOV W10, NVMCON
MOV ADDR_L, W7
MOV.B ADDR_H, W0
MOV W0, TBLPAG
[#ProgMemWrScript]
[#ConfigWrScript]
[#UserIDWrScript]
test erase script(should be OK)
test programming script(OK)
add script buffer location (number): PROGMEM_WR2 = 30; // not required
test configure write script (OK)
test userid write script(Pending)
add device family dsPIC33EP FamilyID:18, FamilyType:18, SearchPriority:3 (OK)
enable PE33 in PICkit2.ini (as default)
---
load PE executive (OK)
<Enhanced ICSP>
PE: A delay of 25 ms is required between commands.
PE_DownloadAndConnect(OK)
PE_Connect (OK)
PE_Read(OK)
add a dealy_short(1) between read_byte and read_byte_buffer
PE_BlankCheck(OK)
PE bug: Expected Reponse[0] should be 0x1E, but returned 0x1A
PE_Write(OK) might have problem with the last block(32 instructions) with the Configuration Bits
PE_Verify(OK)
Export the script(OK)
Add CRC check (WIP)
Apply Object Oriented Design...
[get device ID script]
$COREINST24 00 02 04 //goto 0x200
$COREINST24 00 02 04
$NOP24
$NOP24
$NOP24
$COREINST24 00 02 04
$NOP24
$COREINST24 F0 0F 20 //mov 0xff, w0
$COREINST24 90 01 88 //mov w0, tblpag
$COREINST24 06 00 20 //mov 0x0000, w6
$NOP24
$NOP24
$COREINST24 07 00 20 //mov 0x0000, w7
$COREINST24 B6 0B BA //mov [w6++], [w7] == mov [w6++],w0
$NOP24
$NOP24
$COREINST24 20 3C 88 //mov w0, visi
$NOP24
$VISI24
$NOP24
$LOOP 0D 01
HID Bootloader - PIC18F2550 XC8
Duplicate configuration
Follow comments in main.c to
change PIC to PIC18F2550
setup board parameters in main.c, HardwareProfile.h, usb_config.h
in usb_config.h
#define ENABLE_USB_LED_BLINK_STATUS
Follow comments in main.c to
change PIC to PIC18F2550
setup board parameters in main.c, HardwareProfile.h, usb_config.h
in usb_config.h
#define ENABLE_USB_LED_BLINK_STATUS
dsPIC33E/PIC24E Flash Programming Notes
For some devices without volatile configuration bits have special programming requirements.
Devices such as dsPIC33EP256MU806, MU810, MU814, dsPIC33EP512GP806, MC806, MU810, MU814...
See the Flash Programming Spec 70619B, Table 6-5, Table 7-1, for clock frequency > 2MHz
There is no such requirement for dsPIC33EP256MC20X
Devices such as dsPIC33EP256MU806, MU810, MU814, dsPIC33EP512GP806, MC806, MU810, MU814...
See the Flash Programming Spec 70619B, Table 6-5, Table 7-1, for clock frequency > 2MHz
There is no such requirement for dsPIC33EP256MC20X
Subscribe to:
Comments (Atom)