PIC18F4682: 80 KB Starts Where 16-Bit Addresses Run Out

Up to 64 KB, a PIC18 program address fits in sixteen bits and every reader ever written for the family handles it. The PIC18F4682 has 80 KB, and the last sixteen of them need an address that does not fit.

The PIC18F4682 is a 40-pin member of the PIC18F2682/2685/4682/4685 family, DS39761. It has 80 KB of program memory as 40,960 words, 3,328 bytes of RAM, 1,024 bytes of data EEPROM, an ECAN module, eleven 10-bit ADC channels, two comparators, one CCP and one ECCP, and a parallel slave port. The extra 16 KB is what makes it interesting, and what makes it the part most often delivered incomplete.

Where the Extra Sixteen Kilobyte Lives

Range Size Notes
0x000000–0x00FFFF 64 KB the whole 16-bit address space
0x010000–0x013FFF 16 KB needs the seventeenth program bit

Nothing else on the device moved. The configuration block is still at 0x300000, the device ID at 0x3FFFFE, and the EEPROM is still reached through its own registers. Only the array grew, and it grew past a boundary a lot of software treats as the end of the world.

Boot Block, Then Five

Block Byte range Size Bit
Boot 0x0000–0x07FF 2 KB CPB
0 0x0800–0x3FFF 14 KB CP0
1 0x4000–0x7FFF 16 KB CP1
2 0x8000–0xBFFF 16 KB CP2
3 0xC000–0xFFFF 16 KB CP3
4 0x10000–0x13FFF 16 KB CP4

The protect bits are in CONFIG5L at 0x300008, with CPB and CPD in CONFIG5H at 0x300009 for the boot block and the 1 KB EEPROM. BBSIZ in CONFIG4L can enlarge the boot block to 4 or 8 KB, which moves Block 0’s start with it. The shape is boot-plus-binary, not four equal quarters, so a completeness check built on the smaller CAN parts’ 4 KB boundaries will misreport protected regions.

Reading Above the Line

An Intel HEX file expresses addresses as 16-bit offsets plus a segment, and for anything above 0xFFFF it emits a type-04 extended linear address record with the upper sixteen bits. For this part, program data above 0x10000 requires records reading :020000040001F9.

A reader that ignores type-04 does not fail. It reads 0x0000–0xFFFF, reaches the end of the low bank, and stops; the file it produces is exactly 64 KB, carries a valid checksum, and validates in every tool written for a 64 KB device. What it does not contain is the upper sixteen kilobytes — and the configuration block, which also lives above the 16-bit line and is dropped by the same omission.

This is the single most common defect in 4682 images that arrive for comparison. The array looks whole because it is whole by the standards of the previous generation.

The Block Above the Line

Nothing straddles 0xFFFF. Block 3 ends exactly at the boundary and Block 4 begins at 0x10000, so a locked Block 4 has a precise signature: the low 64 KB reads normally and the top 16 KB reads as zeros. Since 0x0000 is a legal instruction on this core, that zero run disassembles into plausible padding rather than announcing itself. Block 4’s state is set by CP4, one bit in the same register as the rest, readable no matter how the array is locked.

The 96 KB Twin

The PIC18F2685 and the PIC18F4685 share DS39761 and reach 96 KB, ending at 0x017FFF. The PIC18F2685 is the 28-pin version of that larger array, and both are confused with the 4682 because they share its datasheet and peripherals.

The file tells you which is which. A 4682 image never addresses program memory above 0x013FFF, and its highest type-04 record for code is 0x0001. A 4685 image runs to 0x017FFF in the same bank, so the two differ only in how far the data goes. Burning a 4685 image into a 4682 programs the first 80 KB and then has nowhere to put the rest; the application runs until the first call above 0x013FFF, which fails in a way that looks like a stack problem.

What a Complete 4682 File Contains

The array to 0x013FFF, the configuration block 0x300000–0x30000D, the device ID at 0x3FFFFE, and the 1,024 bytes of EEPROM, which is where the CAN node identity and the calibration table usually sit. Then the checks described elsewhere still apply, with the boundaries adjusted: uniform zero runs aligned to the block table above — ending at 0x3FFF, 0x7FFF, 0xBFFF, 0xFFFF, or filling all of 0x10000–0x13FFF — mean a protected block, and a branch landing mid-instruction at a seam means a word was lost.

If the file stops at 0xFFFF, chip extraction analysis is how to establish whether the upper bank is protected or was never read. The reading the program memory page covers how the two banks and the configuration region are captured together, and the services page lists what a delivered image contains.