mem.c - Read/write the PIC’s program memory.

 
#include <xc.h>

typedef short          Word16;
typedef unsigned short UWord16;
typedef long           Word32;
typedef unsigned long  UWord32;

//write these in C so that can use the
//__PIC24H__, __PIC24F__ defines.
 

This macro suppressed the “unused parameter” warnings.

#define UNUSED(x) (void)(x)

void WriteMem(UWord16 val) {
  UNUSED(val);

  asm("mov     W0,NVMCON");
  __builtin_write_NVM();

  asm("1:      btsc NVMCON,#15");    //  ;Wait for write end
  asm("        bra 1b");

}

#if (defined(__PIC24E__) || defined(__dsPIC33E__))
void WriteMem2(UWord16 addrhi, UWord16 addrlo, UWord16 val) {
  UNUSED(addrhi);
  UNUSED(addrlo);
  UNUSED(val);

  asm("mov     w0,NVMADRU");           //; Init Pointer to page to be erased
  asm("mov     w1,NVMADR");           //; Init Pointer to offset to be erased
  asm("mov     W2,NVMCON");
  //__builtin_write_NVM();
  asm("disi #06");
  asm("mov #0x55,W0");
  asm("mov W0, NVMKEY");
  asm("mov #0xAA,W0");
  asm("mov W0,NVMKEY");
  asm("bset NVMCON,#15");
  asm("nop");
  asm("nop");

  asm("1:      btsc NVMCON,#15");    //  ;Wait for write end
  asm("        bra 1b");

}
#endif


//_LoadAddr:  ;W0=NVMADRU,W1=NVMADR - no return values
void LoadAddr(UWord16 nvmadru, UWord16 nvmadr) {
  UNUSED(nvmadru);
  UNUSED(nvmadr);

  asm("mov     W0,TBLPAG");
  asm("mov     W1,W1");
}

//_WriteLatch: ;W0=TBLPAG,W1=Wn,W2=WordHi,W3=WordLo - no return values
void WriteLatch(UWord16 addrhi,UWord16 addrlo, UWord16 wordhi, UWord16 wordlo) {
  UNUSED(addrhi);
  UNUSED(addrlo);
  UNUSED(wordhi);
  UNUSED(wordlo);

  asm("        mov     W0,TBLPAG");
  asm("        tblwtl W3,[W1]");
  asm("        tblwth W2,[W1]");
}

#if (defined(__PIC24E__) || defined(__dsPIC33E__))
//_LoadTwoWords: ;W0=TBLPAG,W1=Wn,W2=WordHi,W3=WordLo W4=Word2Hi,W5=Word2Lo
//W0,W1 not really used
void LoadTwoWords(UWord16 addrhi, UWord16 addrlo, UWord16 wordhi, UWord16 wordlo, UWord16 word2hi, UWord16 word2lo) {
  UNUSED(addrhi);
  UNUSED(addrlo);
  UNUSED(wordhi);
  UNUSED(wordlo);
  UNUSED(word2hi);
  UNUSED(word2lo);

  asm("        mov     #0xFA,W0");
  asm(" mov W0, TBLPAG");
  asm("        mov     #0,W1");
  asm("        tblwtl W3,[W1]");
  asm("        tblwth W2,[W1++]");
  asm("        tblwtl W5,[W1]");
  asm("        tblwth W4,[W1++]");
}
#endif

//_ReadLatch: ;W0=TBLPAG,W1=Wn - data in W1:W0
UWord32 ReadLatch(UWord16 addrhi, UWord16 addrlo) {
  UNUSED(addrhi);
  UNUSED(addrlo);

  asm("        mov     W0,TBLPAG");
  asm("        tblrdl [W1],W0");
  asm("        tblrdh [W1],W1");
  //this gives a compiler warning because not explicitly returning
  //a value from the function, but since this is assembly, do not
  //know how to prevent warning.  The function is correct, since
  //W1:W0 being used to return the tblrdl,tblrdh. Could write
  //less efficient code and use a temporary UWord32.
}

#if (defined(__PIC24E__) || defined(__dsPIC33E__))
void ResetDevice(void) {
 
asm(” goto 0xc02”);
  asm(" goto 0x1300");
}

void ResetDeviceasPOR(void) {
  _POR = 1;
asm(” goto 0xc02”);
  asm(" goto 0x1300");
}

#else
void ResetDevice(void) {
 
asm(” goto 0xc02”);
  asm(" goto 0xe00");
}

void ResetDeviceasPOR(void) {
  _POR = 1;
asm(” goto 0xc02”);
  asm(" goto 0xe00");
}
#endif


#if (defined(__PIC24E__) || defined(__dsPIC33E__))
void Erase(UWord16 addrhi, UWord16 addrlo, UWord16 val) {
  UNUSED(addrhi);
  UNUSED(addrlo);
  UNUSED(val);

  asm("mov     W2,NVMCON");

  asm("mov     w0,NVMADRU");           //; Init Pointer to page to be erased
  asm("mov     w1,NVMADR");           //; Init Pointer to offset to be erased

  //__builtin_write_NVM();

  asm("disi #06");
  asm("mov #0x55,W0");
  asm("mov W0, NVMKEY");
  asm("mov #0xAA,W0");
  asm("mov W0,NVMKEY");
  asm("bset NVMCON,#15");
  asm("nop");
  asm("nop");

  asm("1:      btsc NVMCON,#15");    //  ;Wait for write end
  asm("        bra 1b");


}
#else
//_Erase:
void Erase(UWord16 addrhi, UWord16 addrlo, UWord16 val) {
  UNUSED(addrhi);
  UNUSED(addrlo);
  UNUSED(val);

  asm("push    TBLPAG");
  asm("mov     W2,NVMCON");

  asm("mov     w0,TBLPAG");           //; Init Pointer to page to be erased
  asm("tblwtl  w1,[w1]");           //; Dummy write to select the row

  __builtin_write_NVM();


  asm("1:      btsc NVMCON,#15");    //  ;Wait for write end
  asm("        bra 1b");

  asm("pop     TBLPAG");
}
#endif