• AVR Freaks

Helpful Reply(EEPROM functions PIC18F25K42 are 8-bit but 256 k to address ?) / edit:XC8-free ASM wrong!

Author
j2423
Super Member
  • Total Posts : 279
  • Reward points : 0
  • Joined: 2015/05/15 23:10:36
  • Location: 0
  • Status: offline
2017/06/19 13:21:40 (permalink)
0

(EEPROM functions PIC18F25K42 are 8-bit but 256 k to address ?) / edit:XC8-free ASM wrong!

In memory.h generated by MCC for PIC18F25K42 there are the following functions.
 
void DATAEE_WriteByte(uint8_t bAdd, uint8_t bData)
 
uint8_t DATAEE_ReadByte(uint8_t bAdd)
 
Yet the EEPROM has 256k ??
 
A bug? Just change to uint_16 bAdd ??
post edited by j2423 - 2017/06/20 02:24:43
#1
du00000001
Just Some Member
  • Total Posts : 3237
  • Reward points : 0
  • Joined: 2016/05/03 13:52:42
  • Location: Germany
  • Status: online
Re: MCC EEPROM functions for PIC18F25K42 are 8-bit but 256 k to address ? 2017/06/19 13:35:18 (permalink)
4.67 (3)
DATAEE is 256 Bytes - not kBytes!
#2
j2423
Super Member
  • Total Posts : 279
  • Reward points : 0
  • Joined: 2015/05/15 23:10:36
  • Location: 0
  • Status: offline
Re: MCC EEPROM functions for PIC18F25K42 are 8-bit but 256 k to address ? 2017/06/19 13:36:50 (permalink)
3 (1)
this is not my day ;-)
 
(32 degrees C )
#3
j2423
Super Member
  • Total Posts : 279
  • Reward points : 0
  • Joined: 2015/05/15 23:10:36
  • Location: 0
  • Status: offline
Re: MCC EEPROM functions for PIC18F25K42 are 8-bit but 256 k to address ? 2017/06/19 22:17:38 (permalink)
0
If I'm posting nonsense like this it's not just the heat but also something not working.
 
Using ICD3, in debug mode the EE-Datamemory view remains all FF whatever - and wherever (0-FF) I write. It's not a refresh issue since reading back in code reveals FF too.
 
Nothing is protected in the Config:
 
// CONFIG4H
#pragma config WRTB = OFF // Configuration Register Write Protection bit->Configuration registers (300000-30000Bh) not write-protected
#pragma config WRTC = OFF // Boot Block Write Protection bit->Boot Block (000000-0007FFh) not write-protected
#pragma config WRTD = OFF // Data EEPROM Write Protection bit->Data EEPROM not write-protected
#pragma config WRTSAF = OFF // SAF Write protection bit->SAF not Write Protected
#pragma config LVP = OFF // Low Voltage Programming Enable bit->HV on MCLR/VPP must be used for programming
// CONFIG5L
#pragma config CP = OFF // PFM and Data EEPROM Code Protection bit->PFM and Data EEPROM code protection disabled
 
The function is called: DATAEE_WriteByte( 0x00, 0x12); (for example)
 
The MCC generated function fits the datasheet (selecting EEPROM, enabling write, unlocking, launching write, waiting - and there are no interrupts enabled anyway):
 
void DATAEE_WriteByte(uint8_t bAdd, uint8_t bData)
{
uint8_t GIEBitValue = INTCON0bits.GIE;
NVMADRL = (bAdd & 0xFF);
NVMDAT = bData;
NVMCON1bits.NVMREG = 0;
NVMCON1bits.WREN = 1;
INTCON0bits.GIE = 0; // Disable interrupts
NVMCON2 = 0x55;
NVMCON2 = 0xAA;
NVMCON1bits.WR = 1;
// Wait for write to complete
while (NVMCON1bits.WR)
{
}

NVMCON1bits.WREN = 0;
INTCON0bits.GIE = GIEBitValue; // Restore interrupt enable
}
 
The PIC has plenty of juice (5.0v).
 
Have also tried running in non-debug mode. (Have also activated EEPROM memory preservation in ICD3 prefs, for what it's worth).
 
What am I missing?
 
#4
qhb
Superb Member
  • Total Posts : 9999
  • Reward points : 0
  • Joined: 2016/06/05 14:55:32
  • Location: One step ahead...
  • Status: offline
Re: MCC EEPROM functions for PIC18F25K42 are 8-bit but 256 k to address ? 2017/06/19 22:21:32 (permalink)
4.67 (3)
Is XC8 in free, or pro mode?
Have you checked the assembly code output, to see if the 55/AA write code is exactly as specified in the datasheet?
 
Note, you can NOT single step that code, it MUST run at full speed, or the unlock sequence won't work.
 
#5
j2423
Super Member
  • Total Posts : 279
  • Reward points : 0
  • Joined: 2015/05/15 23:10:36
  • Location: 0
  • Status: offline
Re: MCC EEPROM functions for PIC18F25K42 are 8-bit but 256 k to address ? 2017/06/19 22:49:08 (permalink)
0
Using XC8 free. Assembly looks as follows:
 
void DATAEE_WriteByte(uint8_t bAdd, uint8_t bData)
3E4A 6E02 MOVWF bAdd, ACCESS
165: {
166: uint8_t GIEBitValue = INTCON0bits.GIE;
3E4C 013F MOVLB 0x3F
3E4E 0E00 MOVLW 0x0
3E50 BFD2 BTFSC 0xD2, 7, BANKED
3E52 0E01 MOVLW 0x1
3E54 6E03 MOVWF c, ACCESS
167:
168: NVMADRL = (bAdd & 0xFF);
3E58 F00B NOP
3E5A F9E0 NOP
169: NVMDAT = bData;
3E5E F007 NOP
3E60 F9E3 NOP
170: NVMCON1bits.NVMREG = 0;
3E62 0E3F MOVLW 0x3F
3E64 0139 MOVLB 0x39
3E66 17E5 ANDWF exp, F, BANKED
171: NVMCON1bits.WREN = 1;
3E68 0139 MOVLB 0x39
3E6A 85E5 BSF exp, 2, BANKED
172: INTCON0bits.GIE = 0; // Disable interrupts
3E6C 013F MOVLB 0x3F
3E6E 9FD2 BCF 0xD2, 7, BANKED
173: NVMCON2 = 0x55;
3E70 0E55 MOVLW 0x55
3E72 0139 MOVLB 0x39
3E74 6FE6 MOVWF 0xE6, BANKED
174: NVMCON2 = 0xAA;
3E76 0EAA MOVLW 0xAA
3E78 0139 MOVLB 0x39
3E7A 6FE6 MOVWF 0xE6, BANKED
175: NVMCON1bits.WR = 1;
3E7C 0139 MOVLB 0x39
3E7E 83E5 BSF exp, 1, BANKED
176: // Wait for write to complete
177: while (NVMCON1bits.WR)
178: {
179:
180: }
3E80 0139 MOVLB 0x39
3E82 B3E5 BTFSC exp, 1, BANKED
3E84 D7FD BRA 0x3E80
181:
182: NVMCON1bits.WREN = 0;
3E86 0139 MOVLB 0x39
3E88 95E5 BCF exp, 2, BANKED
183: INTCON0bits.GIE = GIEBitValue; // Restore interrupt enable
3E8A B003 BTFSC c, 0, ACCESS
3E8C D003 BRA 0x3E94
3E8E 013F MOVLB 0x3F
3E90 9FD2 BCF 0xD2, 7, BANKED
3E92 D002 BRA 0x3E98
3E94 013F MOVLB 0x3F
3E96 8FD2 BSF 0xD2, 7, BANKED
184: }
3E98 0012 RETURN 0

Indeed this differs massively from the datasheet (p200) - see below. Nasty trick.
 
Can I place assembly inline in the C-file? 

Attached Image(s)

#6
qhb
Superb Member
  • Total Posts : 9999
  • Reward points : 0
  • Joined: 2016/06/05 14:55:32
  • Location: One step ahead...
  • Status: offline
Re: MCC EEPROM functions for PIC18F25K42 are 8-bit but 256 k to address ? 2017/06/19 23:00:31 (permalink)
4 (2)
j2423
Indeed this differs massively from the datasheet (p200) - see below. Nasty trick.

Pro mode would do it better.
 
 
Can I place assembly inline in the C-file? 

Yes. The XC8 user guide explains how.
#7
j2423
Super Member
  • Total Posts : 279
  • Reward points : 0
  • Joined: 2015/05/15 23:10:36
  • Location: 0
  • Status: offline
Re: MCC EEPROM functions for PIC18F25K42 are 8-bit but 256 k to address ? 2017/06/19 23:57:37 (permalink)
0
Got this far quite quickly:
 
INTCON0bits.GIE = 0; // Disable interrupts
#asm
BANKSEL NVMCON1;
BSF NVMCON1, WREN;
MOVLW 0x55;

MOVWF NVMCON2;
MOVLW 0xAA;
MOVWF NVMCON2;
BSF NVMCON1, WR;
#endasm
// NVMCON2 = 0x55;
// NVMCON2 = 0xAA;
//NVMCON1bits.WR = 1;
// Wait for write to complete
while (NVMCON1bits.WR)
{
 

But stuck with the following output errors:
 
mcc_generated_files/memory.c:175: error: (800) undefined symbol "WREN"
mcc_generated_files/memory.c:181: error: (800) undefined symbol "WR"
mcc_generated_files/memory.c:178: warning: (1352) truncation of operand value (0x39e6) to 8 bits
mcc_generated_files/memory.c:180: warning: (1352) truncation of operand value (0x39e6) to 8 bits
 
Guess that WREN is defined in a C-language union that the assembly can't see? 
 
So WREN in the datasheet NVM example is a placeholder (like "55h") and one has to write it differently? 
 
But how?
 
post edited by j2423 - 2017/06/20 00:31:21
#8
j2423
Super Member
  • Total Posts : 279
  • Reward points : 0
  • Joined: 2015/05/15 23:10:36
  • Location: 0
  • Status: offline
Re: MCC EEPROM functions for PIC18F25K42 are 8-bit but 256 k to address ? 2017/06/20 00:45:10 (permalink)
0
Just to add to my woes - and despite zero knowledge of assembly - I think that the NVM unlock routine on p200 of the PIC18F25K42 datasheet (attached to post #6 of this thread) contains an error?
 
Surely:
 
BSF INTCON1, WR 
 
should be
 
BSF NVMCON1, WR 
 
??!!
#9
qhb
Superb Member
  • Total Posts : 9999
  • Reward points : 0
  • Joined: 2016/06/05 14:55:32
  • Location: One step ahead...
  • Status: offline
Re: MCC EEPROM functions for PIC18F25K42 are 8-bit but 256 k to address ? 2017/06/20 01:25:05 (permalink)
4 (2)
j2423
Surely:
BSF INTCON1, WR 
should be
BSF NVMCON1, WR 

Yup. Congratulations on finding your first datasheet SNAFU. It won't be the last.
(The text descriptions are usually correct. It's the example code they often leave for vacation students to fill in...)
#10
j2423
Super Member
  • Total Posts : 279
  • Reward points : 0
  • Joined: 2015/05/15 23:10:36
  • Location: 0
  • Status: offline
Re: MCC EEPROM functions for PIC18F25K42 are 8-bit but 256 k to address ? 2017/06/20 01:37:25 (permalink)
0
This is what I have (and it's the first time I meddle with assembly).
 
XC8 didn't like "AAh" so I replaced it with "0xAA". However it didn't complain about "55h" so I left that as per datasheet (having tried 0x55 as well!).
 
WREN and WR (not found by XC8) were replaced by 0b100 and 0b10 respectively.
 
Still not writing to EEPROM (and the following output errors):
 
mcc_generated_files/memory.c:174: warning: (1352) truncation of operand value (0x39e5) to 8 bits
mcc_generated_files/memory.c:178: warning: (1352) truncation of operand value (0x39e6) to 8 bits
mcc_generated_files/memory.c:180: warning: (1352) truncation of operand value (0x39e6) to 8 bits
mcc_generated_files/memory.c:182: warning: (1352) truncation of operand value (0x39e5) to 8 bits
 
 
void DATAEE_WriteByte(uint8_t bAdd, uint8_t bData)
{
uint8_t GIEBitValue = INTCON0bits.GIE;
NVMADRL = (bAdd & 0xFF);
NVMDAT = bData;
NVMCON1bits.NVMREG = 0;
// NVMCON1bits.WREN = 1;
INTCON0bits.GIE = 0; // Disable interrupts
#asm
BSF NVMCON1, 0b100; //WREN;

MOVLW 55h;

MOVWF NVMCON2;
MOVLW 0xAA;
MOVWF NVMCON2;

BSF NVMCON1, 0b10; //WR;
#endasm
// NVMCON2 = 0x55;
// NVMCON2 = 0xAA;
// NVMCON1bits.WR = 1;
// Wait for write to complete
while (NVMCON1bits.WR)
{
}

NVMCON1bits.WREN = 0;
INTCON0bits.GIE = GIEBitValue; // Restore interrupt enable
}
 
 
Any suggestions?
 
 
 
 
 
post edited by j2423 - 2017/06/20 01:39:08
#11
qhb
Superb Member
  • Total Posts : 9999
  • Reward points : 0
  • Joined: 2016/06/05 14:55:32
  • Location: One step ahead...
  • Status: offline
Re: MCC EEPROM functions for PIC18F25K42 are 8-bit but 256 k to address ? 2017/06/20 01:44:06 (permalink)
3.67 (3)
Change
BSF NVMCON1, 0b100; //WREN;
to
BSF NVMCON1, 2; //WREN;
 
and
BSF NVMCON1, 0b10; //WR;
to
BSF NVMCON1, 1; //WR;
 
The argument is the bit number, not a bitmask.
 
 
#12
qhb
Superb Member
  • Total Posts : 9999
  • Reward points : 0
  • Joined: 2016/06/05 14:55:32
  • Location: One step ahead...
  • Status: offline
Re: MCC EEPROM functions for PIC18F25K42 are 8-bit but 256 k to address ? 2017/06/20 01:53:57 (permalink)
4 (2)
j2423
XC8 didn't like "AAh" so I replaced it with "0xAA". However it didn't complain about "55h" so I left that as per datasheet (having tried 0x55 as well!).

Numbers must start with a digit, so 55h is ok, but AAh is not. 0AAh would be ok.
 
#13
j2423
Super Member
  • Total Posts : 279
  • Reward points : 0
  • Joined: 2015/05/15 23:10:36
  • Location: 0
  • Status: offline
Re: MCC EEPROM functions for PIC18F25K42 are 8-bit but 256 k to address ? 2017/06/20 02:19:58 (permalink)
3 (1)
Thanks. The code below finally works! 
 
Found another NVM example on page 212 of datasheet and, emboldened by what learnt so far, moved the Interrupt Disable command down into the identical position in the ASM sequence. That finally did it. 
 
(Double confirmed by reversing the code change, changing the values to be saved to EEPROM, verifying not writing, redoing the code change, seeing new values written.)
 
Why? Is another question. Is it acting as a delay? What is really the sequence that must be critically timed? Not just the 55/AA part?
 
1000 thanks.... It feels less hot today!
 
void DATAEE_WriteByte(uint8_t bAdd, uint8_t bData)
{
uint8_t GIEBitValue = INTCON0bits.GIE;
NVMADRL = (bAdd & 0xFF);
NVMDAT = bData;
NVMCON1bits.NVMREG = 0;
// NVMCON1bits.WREN = 1;
// INTCON0bits.GIE = 0; // Disable interrupts
#asm
BSF NVMCON1, 2; //WREN;

BCF INTCON0, 7; // GIE, bit 7

MOVLW 55h;

MOVWF NVMCON2;
MOVLW 0AAh;
MOVWF NVMCON2;

BSF NVMCON1, 1; //WR;
#endasm
// NVMCON2 = 0x55;
// NVMCON2 = 0xAA;
// NVMCON1bits.WR = 1;
// Wait for write to complete
while (NVMCON1bits.WR)
{
}

NVMCON1bits.WREN = 0;
INTCON0bits.GIE = GIEBitValue; // Restore interrupt enable
}
#14
qhb
Superb Member
  • Total Posts : 9999
  • Reward points : 0
  • Joined: 2016/06/05 14:55:32
  • Location: One step ahead...
  • Status: offline
Re: MCC EEPROM functions for PIC18F25K42 are 8-bit but 256 k to address ? 2017/06/20 02:32:10 (permalink)
0
I don't understand why moving it would matter, apart from one version being in C, and the other in assembler.
#15
mprab
New Member
  • Total Posts : 1
  • Reward points : 0
  • Joined: 2017/11/19 06:39:39
  • Location: 0
  • Status: offline
Re: MCC EEPROM functions for PIC18F25K42 are 8-bit but 256 k to address ? 2017/11/22 00:47:15 (permalink)
0
I too faced the exact same issue on exact same part.
The solution as mentioned above, is to ensure that the WREN and GIE flag setting be done using the below instructions in assembly and NOT through C code.
BSF NVMCON1, 2; //WREN;
BCF INTCON0, 7; // GIE, bit 7
 
I also observed that if the line INTCON0bits.GIE = 0; is retained in C code, the code fails to write to EEPROM !
so, it appears that there is more to the unlock sequence than writing 55/AA one after other.
#16
j2423
Super Member
  • Total Posts : 279
  • Reward points : 0
  • Joined: 2015/05/15 23:10:36
  • Location: 0
  • Status: offline
Re: MCC EEPROM functions for PIC18F25K42 are 8-bit but 256 k to address ? 2017/11/23 01:11:06 (permalink)
0
I haven't had the chance to check, but have just learnt that on the MCC page you can download new libraries for MCC. The libraries contain part specific information to generate the code. The thing is that when a new version of MCC comes out it comes with a certain library, but that library is not updated automatically until the next version of MCC plugin comes out. So we don't get the intermediate library updates automatically but must download them manually.

From memory MCC 3.36 came with library 1.45 for pic18 but there's a 1.55 library one can install by download. I suppose there's a tiny chance they might have fixed the above issue? ;-)
#17
1and0
Access is Denied
  • Total Posts : 9994
  • Reward points : 0
  • Joined: 2007/05/06 12:03:20
  • Location: Harry's Gray Matter
  • Status: offline
Re: MCC EEPROM functions for PIC18F25K42 are 8-bit but 256 k to address ? 2017/11/23 03:02:18 (permalink) ☄ Helpfulby mprab 2017/11/28 02:52:57
3 (1)
It looks like XC8 is not so smart and accesses INTCON0 using banked memory instruction instead of access memory.

172: INTCON0bits.GIE = 0; // Disable interrupts
3E6C 013F MOVLB 0x3F
3E6E 9FD2 BCF 0xD2, 7, BANKED

That is,

INTCON0bits.GIE = 0; // this C line selects bank 63
#asm
BSF NVMCON1, 2; // but NVMCON1 is located in bank 57

So, the fix is you must guarantee the assembly sequence access the correct bank for the NVMCONx registers, either by selecting the bank for NVMCON1 with BANKSEL NVMCON1 or by accessing INTCON0 using the access RAM so not to corrupt BSR.
post edited by 1and0 - 2017/11/23 03:19:02
#18
1and0
Access is Denied
  • Total Posts : 9994
  • Reward points : 0
  • Joined: 2007/05/06 12:03:20
  • Location: Harry's Gray Matter
  • Status: offline
Re: MCC EEPROM functions for PIC18F25K42 are 8-bit but 256 k to address ? 2017/11/23 06:01:39 (permalink)
5 (1)
I wanted to post this earlier, but was in a hurry.  Anyway, here's how I would modify that MCC generated function and use symbols for the assembly bits.
void DATAEE_WriteByte(uint8_t bAdd, uint8_t bData)
{
    NVMADRL = bAdd;
    NVMDAT = bData;
    NVMCON1bits.NVMREG = 0;
    NVMCON1bits.WREN = 1;
 
    #asm
    bcf     STATUS,_STATUS_C_POSN // Save interrupt enable
    btfsc   INTCON0,_INTCON0_GIE_POSN
    bsf     STATUS,_STATUS_C_POSN
    movlw   0x55
    bcf     INTCON0,_INTCON0_GIE_POSN // Disable interrupts

    movwf   NVMCON2
    movlw   0xAA
    movwf   NVMCON2
    bsf     NVMCON1,_NVMCON1_WR_POSN
 
    btfsc   STATUS,_STATUS_C_POSN
    bsf     INTCON0,_INTCON0_GIE_POSN // Restore interrupt enable
    #endasm

    // Wait for write to complete
    while (NVMCON1bits.WR) {}
    NVMCON1bits.WREN = 0;
}

#19
Jump to:
© 2019 APG vNext Commercial Version 4.5