News:

PROTON pic BASIC Compilers for PIC, PIC24, dsPIC33

Main Menu

DsPic33CK256MP508 Flash Erase/Write/Read

Started by Wimax, Oct 26, 2025, 10:20 PM

Previous topic - Next topic

Wimax

Hello Everybody  ;)

I know this is a "strange" post, but I'm trying to understand what I'm doing wrong in the assembly routine on dspic33ck256mp508 (which I would then like to integrate with Basic) where I delete a page of flash memory, write 4 bytes to flash and then read them.

'****************************************************************
'*  Name    : Test_DSPIC33CK256MP508_FLASH.BAS                  *
'*  Author  : [Max]                                             *
'*  Notice  : Copyright (c) 2025                                *
'*          : All Rights Reserved                               *
'*  Date    : 26/10/2025                                        *
'*  Version : 1.0                                               *
'*  Notes   :                                                   *
'*          : Microchip curiosity board                         *
'****************************************************************

Device = 33CK256MP508
Declare Xtal = 200
Declare Hserial_Baud = 9600 ' USART1 Baud rate @ 9.6 Kbps

PPS_Output(cOut_Pin_RP68, cOut_Fn_U1TX) ' Map UART1 TX pin to RD4
PPS_Input(cIn_Pin_RP67, cIn_Fn_U1RX)    ' Map UART1 RX pin to RD3

Dim i As Word
Dim dax [4] As Word
Dim appoggio As Dword
Dim FlashStart As Dword

IntOsc_200MHz()

FlashStart=0x2000

'-----------------------------
' ERASE PAGE 0 _______________
'-----------------------------

Asm
 ' Set up the NVMADR registers To the starting address of the page
 
 Mov #0x2000,W1
 Mov #0x00,W0
 Mov W1,NVMADR       
 Mov W0,NVMADRU
 
  ' Set up NVMCON to erase one page of Program Memory
 Mov #0x4003,W0
 Mov  W0,NVMCON
 
   ' Disable interrupts < priority 7 for next 5 instructions
 Disi #06
 ' Write the KEY Sequence
 Mov   #0x55,W0
 Mov   W0,NVMKEY
 Mov   #0xAA,W0
 Mov   W0,NVMKEY
 
 ' Start the erase operation
 Bset  NVMCON,#15

 ' Insert two NOPs after the erase cycle (required)
 Nop
 Nop
 
 ; Wait erasing process
 WaitErase:
 Btsc    NVMCON, #15        ; If WR than wait
 Bra     WaitErase

 ; Check for error
 Btss    NVMCON, #13        ; If WRERR = 0 ? OK
 Bra     NoErr

 ; Error, so turn on LED on RE5
 Bclr.b  TRISEH, #5         ; RE5 output
 Bset.b  LATEH,  #5         ; Turn on LED

 NoErr:
 
 
 
'-----------------------------
' WRITE 2 WORDS IN PAGE 0 @ 0x2000
'-----------------------------

 
 ' Load the destination address to be written
 Mov #0x2000,W1
 Mov #0x00,W0
 Mov W1,NVMADR       
 Mov W0,NVMADRU
 
' Set up a pointer to the first latch location to be written
 Mov #0xFA,W0
 Mov W0,TBLPAG
 Mov #0,W1
 
 ' Load the two words into the latches

 Mov #0x2233, W2         ' LSW Word 0
 Mov #0x0011, W3         ' MSB Word 0
 Mov #0x0000, W4         ' LSW Word 1
 Mov #0x0044, W5         ' MSB Word 1
 
 'Performs the TBLWT instructions to write the latches
 
 TblwtL    W2, [W1]      ' Write LSW Word 0
 TblwtH.B  W3, [W1++]    ' Write MSB Word 0
 TblwtL    W4, [W1]      ' Write LSW Word 1
 TblwtH.B  W5, [W1++]    ' Write MSB Word 1
 
 ' Setup NVMCON for word programming
 Mov #0x4001,W0
 Mov W0,NVMCON
 ' Disable interrupts < priority 7 for next 5 instructions
 Disi #06
 ' Write the key sequence
 Mov #0x55,W0
 Mov W0,NVMKEY
 Mov #0xAA,W0
 Mov W0,NVMKEY
 ' Start the write cycle
 Bset NVMCON, #15     ' Start Flash Write
 Nop
 Nop
 WaitWR:
 Btsc NVMCON, #15     ' If WR than wait
 Bra  WaitWR
 Nop
 Nop

 Btss    NVMCON, #13  'If WRERR than error
 Bra     NoError      'if not than...no error
 
 Bclr.b  TRISEH, #5   ' Turn on LED
 Bset.b  LATEH,  #5

 NoError:


'-----------------------------
' READ 2 WORDS IN PAGE 0 @ 0x2000
'-----------------------------

Mov     #0x00, W0           ' Load 0x00 in W0
Mov     W0, TBLPAG          ' Select page 0x00
Mov     #0x2000, W6         ' W6 points to first word

' Read  Word 0 (addresses 0x2000 and 0x2001)
' =========================================================================
TblrdL  [W6++], W1          ' Reads 16 LSbits in W1.
                            ' W6 is increased to 0x2001.

TblrdH.B [W6++], W2         ' Reads  8 MSbits in W2.
                            ' W6 is increased To 0x2002.

' Read  Word 1 (addresses 0x2002 and 0x2003)
' =========================================================================
TblrdL  [W6++], W4          ' Reads 16 LSbits in W4.
                            ' W6 is increased To 0x2003.

TblrdH.B [W6], W3           ' Reads  8 MSbits in W3.
                            ' (W6 remains unchanged)

' Copy to dax array (WORD)
Mov     #dax, W10            ' W10 = array pointer
Mov     W1, [W10++]          ' dax[0] = LSW Word 0
Mov     W2, [W10++]          ' dax[1] = MSB Word 0
Mov     W3, [W10++]          ' dax[2] = MSB Word 1
Mov     W4, [W10++]          ' dax[3] = LSW Word 1


EndAsm

For i=0 To 3
HRSOut Dec i," ",
HRSOutLn Hex dax[i]
Next


 
Proc IntOsc_200MHz()


CLKDIV = $3001          ' FRCDIV FRC/1, PLLPRE 1, DOZE 1:8
PLLFBD = 100
OSCTUN = $00
PLLDIV = $21            ' POST1DIV 1:2, VCODIV FVCO/4, POST2DIV 1:1
ACLKCON1 = $0101        ' FRCSEL FRC, APLLPRE 1:1
APLLFBD1 = $C8
APLLDIV1 = $42          ' APOST1DIV 1:4, APOST2DIV 1:2, AVCODIV FVCO/4*)

Write_OSCCON($0301)
While OSCCONbits_OSWEN <> 0 : Wend      ' Wait for the clock switch to occur
While OSCCONbits_LOCK <> 1 : Wend       ' Wait for the oscillator to lock

EndProc
 


' ===== Config  =====
Config FSEC        = BWRP_OFF, BSS_DISABLED, BSEN_OFF, GWRP_OFF, GSS_DISABLED, CWRP_OFF, CSS_DISABLED, AIVTDIS_OFF
Config FOSCSEL     = FNOSC_FRC, IESO_OFF
Config FOSC        = POSCMD_EC, OSCIOFNC_ON, FCKSM_CSECMD, PLLKEN_OFF, XTCFG_G0, XTBST_ENABLE
Config FWDT        = SWDTPS_PS2147483648, RCLKSEL_LPRC
Config FPOR        = BISTDIS_DISABLED
Config FICD        = ICS_PGD3, JTAGEN_OFF, NOBTSWP_DISABLED
Config FDMT        = DMTDIS_OFF
Config FDEVOPT     = ALTI2C1_OFF,ALTI2C2_OFF,ALTI2C3_ON, SMBEN_SMBUS, SPI2PIN_PPS
Config FALTREG     = CTXT1_OFF, CTXT2_OFF, CTXT3_OFF, CTXT4_OFF
Config FBOOT       = BTMODE_SINGLE
I should see:

dax[0]= 0x2233    LSW Word 0
dax[1]= 0x0011    MSB Word 0
dax[2]= 0x0044    MSB Word 1
dax[3]= 0x0000    LSW Word 1

Instead, I get 0x00, 0x2200, 0x00, 0x00.





Pepe

#1
Corrected by AI, I don't know if it works
'****************************************************************
'*  Name    : Test_DSPIC33CK256MP508_FLASH.BAS                  *
'*  Author  : [Max]                                            *
'*  Notice  : Copyright (c) 2025                                *
'*          : All Rights Reserved                              *
'*  Date    : 26/10/2025                                        *
'*  Version : 1.0                                              *
'*  Notes  : Microchip Curiosity board                        *
'****************************************************************

Device = 33CK256MP508
Declare Xtal = 200
Declare Hserial_Baud = 9600    ' USART1 Baud rate @ 9.6 Kbps

PPS_Output(cOut_Pin_RP68, cOut_Fn_U1TX) ' TX1 → RD4
PPS_Input(cIn_Pin_RP67, cIn_Fn_U1RX)    ' RX1 → RD3

Dim i As Word
Dim dax[4] As Word
Dim appoggio As Dword
Dim FlashStart As Dword

IntOsc_200MHz()

FlashStart = 0x2000

'-----------------------------
' ERASE PAGE 0 @ 0x2000
'-----------------------------
Asm
 Mov #0x2000, W1
 Mov #0x00,  W0
 Mov W1, NVMADR
 Mov W0, NVMADRU

 Mov #0x4003, W0
 Mov W0, NVMCON

 Disi #06
 Mov #0x55, W0
 Mov W0, NVMKEY
 Mov #0xAA, W0
 Mov W0, NVMKEY
 Bset NVMCON, #15
 Nop
 Nop

WaitErase:
 Btsc NVMCON, #15
 Bra  WaitErase

 Btss NVMCON, #13
 Bra  NoErr
 Bclr.b TRISEH, #5
 Bset.b LATEH,  #5
NoErr:


'-----------------------------
' WRITE 2 WORDS IN PAGE 0 @ 0x2000
'-----------------------------

 Mov #0x2000, W1
 Mov #0x00,  W0
 Mov W1, NVMADR
 Mov W0, NVMADRU

 Mov #0x00, W0
 Mov W0, TBLPAG

 Mov #0x2000, W1

 Mov #0x2233, W2    ' LSW Word 0
 Mov #0x0011, W3    ' MSB Word 0
 Mov #0x0000, W4    ' LSW Word 1
 Mov #0x0044, W5    ' MSB Word 1

 TblwtL  W2, [W1]
 TblwtH.B W3, [W1++]
 TblwtL  W4, [W1]
 TblwtH.B W5, [W1++]

 Mov #0x4001, W0
 Mov W0, NVMCON

 Disi #06
 Mov #0x55, W0
 Mov W0, NVMKEY
 Mov #0xAA, W0
 Mov W0, NVMKEY
 Bset NVMCON, #15
 Nop
 Nop

WaitWR:
 Btsc NVMCON, #15
 Bra  WaitWR
 Nop
 Nop

 Btss NVMCON, #13
 Bra  NoError
 Bclr.b TRISEH, #5
 Bset.b LATEH,  #5
NoError:


'-----------------------------
' READ 2 WORDS IN PAGE 0 @ 0x2000
'-----------------------------

 Mov #0x00, W0
 Mov W0, TBLPAG
 Mov #0x2000, W6

 TblrdL  [W6++], W1
 TblrdH.B [W6++], W2
 TblrdL  [W6++], W4
 TblrdH.B [W6],  W3

 Mov #dax, W10
 Mov W1, [W10++]
 Mov W2, [W10++]
 Mov W3, [W10++]
 Mov W4, [W10++]
EndAsm


' Mostrar resultados por UART
For i = 0 To 3
    HRSOut Dec i, " ", Hex dax[i], 13, 10
Next


'-----------------------------
' Configuración de oscilador 200 MHz
'-----------------------------
Proc IntOsc_200MHz()

    CLKDIV = $3001
    PLLFBD = 100
    OSCTUN = $00
    PLLDIV = $21
    ACLKCON1 = $0101
    APLLFBD1 = $C8
    APLLDIV1 = $42

    Write_OSCCON($0301)
    While OSCCONbits_OSWEN <> 0 : Wend
    While OSCCONbits_LOCK <> 1 : Wend

EndProc


' ===== Config =====
Config FSEC        = BWRP_OFF, BSS_DISABLED, BSEN_OFF, GWRP_OFF, GSS_DISABLED, CWRP_OFF, CSS_DISABLED, AIVTDIS_OFF
Config FOSCSEL    = FNOSC_FRC, IESO_OFF
Config FOSC        = POSCMD_EC, OSCIOFNC_ON, FCKSM_CSECMD, PLLKEN_OFF, XTCFG_G0, XTBST_ENABLE
Config FWDT        = SWDTPS_PS2147483648, RCLKSEL_LPRC
Config FPOR        = BISTDIS_DISABLED
Config FICD        = ICS_PGD3, JTAGEN_OFF, NOBTSWP_DISABLED
Config FDMT        = DMTDIS_OFF
Config FDEVOPT    = ALTI2C1_OFF, ALTI2C2_OFF, ALTI2C3_ON, SMBEN_SMBUS, SPI2PIN_PPS
Config FALTREG    = CTXT1_OFF, CTXT2_OFF, CTXT3_OFF, CTXT4_OFF
Config FBOOT      = BTMODE_SINGLE
[right][/right]

Wimax

#2
I compared the two and it seems that AI forces the write operation in flash, but it is necessary to use the write latches setting up the pointer to the first location:
Mov #0xFA,W12
Mov W12,TBLPAG

and then use the TblwtL/TblwtH using a Wn register as index to the write latches.
I reviewed the code correcting the final part where I retrieve the data, in this case removing an extra pointer advance.
Now it seems to work, let's proceed one step at a time, next time...row writing.
Asm
 ' Set up the NVMADR registers To the starting address of the page
 
 Mov #0x2000,W3
 Mov #0x00,W4
 Mov W3,NVMADR       
 Mov W4,NVMADRU
 Nop
 Nop
 
  ' Set up NVMCON to erase one page of Program Memory
 Mov #0x4003,W10
 Mov  W10,NVMCON
 Nop
 Nop
 
   ' Disable interrupts < priority 7 for next 5 instructions
 Disi #06
 ' Write the KEY Sequence
 Mov   #0x55,W1
 Mov   W1,NVMKEY
 Mov   #0xAA,W1
 Mov   W1,NVMKEY
 
 ' Start the erase operation
 Bset  NVMCON,#15

 ' Insert two NOPs after the erase cycle (required)
 Nop
 Nop
 
 ; Wait erasing process
 WaitErase:
 Btsc    NVMCON, #15        ; If WR than wait
 Bra     WaitErase

 ; Check for error
 Btss    NVMCON, #13        ; If WRERR = 0 ? OK
 Bra     NoErr

 ; Error, so turn on LED on RE5
 Bclr.b  TRISEH, #5         ; RE5 output
 Bset.b  LATEH,  #5         ; Turn on LED

 NoErr:
 
 '---------------------------
 ' WRITE DATA '
 '---------------------------
 

 
 ' Set up a pointer to the first latch location to be written
 Mov #0xFA,W12
 Mov W12,TBLPAG
 'Mov #0,W1
 
 
  ; Loads 6 byte in Wn registers as 2 program words
  ; Program Word 1 (Byte 0, 1, 2)
  ; Hyp: byte 0x66, 0x55, 0x44
  ; Low Word  (Byte 0 e 1): 0x5566
  ; High Word (Byte 2): 0x0044
  ; Program Word 2 (Byte 3, 4, 5)
  ; Hyp: byte 0x99, 0x88, 0x77
  ; Low Word  (Byte 3 e 4): 0x8899
  ; High Word (Byte 5): 0x0077

    Mov     #0x5566, W0        ; Low word of first program word (Byte 0 e 1)
    Nop
    Mov     #0x0044, W1        ; High word of first program Word (Byte 2)
    Nop
    Mov     #0x8899, W2        ; Low Word of second program word (Byte 3 e 4)
    Nop
    Mov     #0x0077, W3        ; High word of second program word (Byte 5)
 
 'Performs the TBLWT instructions to write the latches
 Clr W6
 Nop
 TblwtL W0, [W6]
 Nop
 Nop
 TblwtH W1, [W6++]
 Nop
 Nop
 TblwtL W2, [W6]
 Nop
 Nop
 TblwtH W3, [W6++]
 Nop
 Nop

 ' Load the destination address to be written
 Mov #0x2000,W4
 Mov #0x00,W5
 Mov W4,NVMADR       
 Mov W5,NVMADRU
 
 
 ' Setup NVMCON for word programming
 Mov #0x4001,W10
 Nop
 Mov W10,NVMCON
 Nop
 Nop
 ' Disable interrupts < priority 7 for next 5 instructions
 Disi #06
 ' Write the key sequence
 Mov #0x55,W1
 Mov W1,NVMKEY
 Mov #0xAA,W1
 Mov W1,NVMKEY
 ' Start the write cycle
 Bset NVMCON, #15     ' Start Flash Write
 Nop
 Nop
 Nop
 Nop
 Nop
 Nop
 WaitWR:
 Btsc NVMCON, #15     ' If WR than wait
 Bra  WaitWR
 Nop
 Nop

 Btss    NVMCON, #13  'If WRERR than error
 Bra     NoError      'if not than...no error
 Bclr.b  TRISEH, #5   ' Turn on LED
 Bset.b  LATEH,  #5

 NoError:


'-----------------------------
' READ 2 WORDS IN PAGE 0 @ 0x2000
'-----------------------------

Mov     #0x00, W0           ' Load 0x00 in W0
Mov     W0, TBLPAG          ' Select page 0x00
Mov     #0x2000, W6         ' W6 points to first word

' Read  Word 0 (addresses 0x2000 and 0x2001)
' =========================================================================

TblrdL  [W6], W1   ' 0x2000-0x2001
Nop
Nop
TblrdH  [W6++], W2 ' 0x2000-0x2001
Nop
Nop                ' 0x2002       
TblrdL  [W6], W4   ' 0x2002-0x2003
Nop
Nop
TblrdH  [W6], W3           
Nop
Nop       
                     
' Copy to dax array (WORD)
 Mov     #dax, W10            ' W10 = array pointer
 Mov     W1, [W10++]          ' dax[0] = LSW Word 0
 Mov     W2, [W10++]          ' dax[1] = MSB Word 0
 Mov     W4, [W10++]          ' dax[2] = MSB Word 1
 Mov     W3, [W10++]          ' dax[3] = LSW Word 1


EndAsm

For i=0 To 3
HRSOut Dec i," ",
HRSOutLn Hex dax[i]
Next