Пример #1
0
WORD read_freq(void)
{
  WORD offset;

  TBLPAG = __builtin_tblpage(&dat);
  offset = __builtin_tbloffset(&dat);
  return(__builtin_tblrdl(offset));
}
Пример #2
0
DWORD FlashReadDWORD(DWORD address) {
  DWORD_VAL a = { address };
  DWORD_VAL res;
  TBLPAG = a.word.HW;
  res.word.HW = __builtin_tblrdh(a.word.LW);
  res.word.LW = __builtin_tblrdl(a.word.LW);
  return res.Val;
}
Пример #3
0
/*********************************************************************
 * Function:        static DWORD ReadProgramMemory(DWORD address)
 *
 * PreCondition:    None
 *
 * Input:           Program memory address to read from.  Should be 
 *					an even number.
 *
 * Output:          Program word at the specified address.  For the 
 *					PIC24, dsPIC, etc. which have a 24 bit program 
 *					word size, the upper byte is 0x00.
 *
 * Side Effects:    None
 *
 * Overview:        Modifies and restores TBLPAG.  Make sure that if 
 *					using interrupts and the PSV feature of the CPU 
 *					in an ISR that the TBLPAG register is preloaded 
 *					with the correct value (rather than assuming 
 *					TBLPAG is always pointing to the .const section.
 *
 * Note:            None
 ********************************************************************/
static DWORD ReadProgramMemory(DWORD address) 
{  
	DWORD dwResult;
	WORD wTBLPAGSave;

	wTBLPAGSave = TBLPAG;
	TBLPAG = ((WORD*)&address)[1];
	((WORD*)&dwResult)[1] = __builtin_tblrdh((WORD)address);
	((WORD*)&dwResult)[0] = __builtin_tblrdl((WORD)address);
	TBLPAG = wTBLPAGSave;

	return dwResult;
}
Пример #4
0
/********************************************************************
* Function: 	ValidAppPresent()
********************************************************************/
BOOL ValidAppPresent(void)
{
   volatile DWORD AppPtr;

   TBLPAG = 0x00;

   AppPtr = ((DWORD)__builtin_tblrdh(0) << 16);
   AppPtr = AppPtr | ((DWORD)__builtin_tblrdl(0));

   if(AppPtr == 0xFFFFFF)
      return FALSE;
   else
      return TRUE;
}
Пример #5
0
DWORD ReadProgramMemory(DWORD address) 
{  
      DWORD_VAL dwvResult;
    WORD wTBLPAGSave;
 
      wTBLPAGSave = TBLPAG;
    TBLPAG = ((DWORD_VAL*)&address)->w[1];

    dwvResult.w[1] = __builtin_tblrdh((WORD)address);
    dwvResult.w[0] = __builtin_tblrdl((WORD)address);
    TBLPAG = wTBLPAGSave;
 
      return dwvResult.Val;
}
Пример #6
0
u32 flashRead1Instruction ( u32 * wordAddress )
{
    DWORD_VAL value;
    u32 temp = *wordAddress;
    u32 offset = temp & FLASH_TABLE_PAGE_SIZE_MASK; /* offset into table page */
    TBLPAG = temp >> FLASH_TABLE_PAGE_SIZE_SHIFT; /* select table page */

    /* a pic 24 word is 16-bits, we write 3-Bytes + phantom = 2 16-bit words */
    *wordAddress += 2;

    value.word.LW = __builtin_tblrdl( offset );
    value.word.HW = __builtin_tblrdh( offset );

    return value.Val;
}
Пример #7
0
BYTE MDD_IntFlash_SectorRead(DWORD sector_addr, BYTE* buffer)
{
    WORD i;
    DWORD flashAddress;
    BYTE TBLPAGSave;
    WORD_VAL temp;
    
    //Error check.  Make sure the host is trying to read from a legitimate
    //address, which corresponds to the MSD volume (and not some other program
    //memory region beyond the end of the MSD volume).
    if(sector_addr >= MDD_INTERNAL_FLASH_TOTAL_DISK_SIZE)
    {
        return FALSE;
    }    
    
    //Save TBLPAG register
    TBLPAGSave = TBLPAG;
   
    //Compute the 24 bit starting address.  Note: this is a word address, but we
    //only store data in and read from the lower word (even LSB).
    //Starting address will always be even, since MasterBootRecord[] uses aligned attribute in declaration.
    flashAddress = (DWORD)FILES_ADDRESS + (DWORD)(sector_addr*(WORD)MEDIA_SECTOR_SIZE);  
    
    //Read a sector worth of data from the flash, and copy to the user specified "buffer".
    for(i = 0; i < (MEDIA_SECTOR_SIZE / 2u); i++)
    {
        TBLPAG = (BYTE)(flashAddress >> 16);   //Load TBLPAG pointer (upper 8 bits of total address.  A sector could get split at 
                                        //a 16-bit address boundary, and therefore could exist on two TBLPAG pages.
                                        //Therefore, need to reload TBLPAG every iteration of the for() loop
        temp.Val = __builtin_tblrdl((WORD)flashAddress);
        *buffer++ = temp.v[0];
        *buffer++ = temp.v[1];
        flashAddress += 2u;             //Increment address by 2.  No MSD data stored in the upper WORD (which only has one implemented byte anyway).
        
    }   
    
    //Restore TBLPAG register to original value
    TBLPAG = TBLPAGSave;
    
    return TRUE;
}    
Пример #8
0
BYTE MDD_IntFlash_SectorWrite(DWORD sector_addr, BYTE* buffer, BYTE allowWriteToZero)
{
#if !defined(INTERNAL_FLASH_WRITE_PROTECT)
    WORD i;
    BYTE j;
    WORD offset;
    DWORD flashAddress;
    WORD TBLPAGSave;


    //First, error check the resulting address, to make sure the MSD host isn't trying 
    //to erase/program illegal LBAs that are not part of the designated MSD volume space.
    if(sector_addr >= MDD_INTERNAL_FLASH_TOTAL_DISK_SIZE)
    {
        return FALSE;
    }  

    TBLPAGSave = TBLPAG;
    
#if defined (__dsPIC33E__) || defined (__PIC24E__)
    

    // First, save the contents of the entire erase page.  
    // To do this, we need to get a pointer to the start of the erase page.
    // AND mask 0xFFFFF800 is to clear the lower bits, 
    // so we go back to the start of the erase page.
    
    flashAddress = ((DWORD)FILES_ADDRESS + (DWORD)(sector_addr*MEDIA_SECTOR_SIZE)) 
                & (DWORD)0xFFFFF800;  
    
    //Now save all of the contents of the erase page.
    TBLPAG = (BYTE)(flashAddress >> 16);
    for(i = 0; i < ERASE_BLOCK_SIZE;i++)
    {
        file_buffer[i] = __builtin_tblrdl((WORD)flashAddress + (2 * i));
    }    

    // Now we want to overwrite the file_buffer[] contents 
    // for the sector that we are trying to write to.
    // The lower 2 bits of the helps to determine this.
   
    offset = 0x200 * (BYTE)(sector_addr & 0x3);   

    //Overwrite the file_buffer[] RAM contents for the sector that we are trying to write to.
    for(i = 0; i < MEDIA_SECTOR_SIZE; i++)
    {
        *((unsigned char *)file_buffer + offset + i) = *buffer++;
    }
#else

     //First, save the contents of the entire erase page.  To do this, we need to get a pointer to the start of the erase page.
    flashAddress = ((DWORD)FILES_ADDRESS + (DWORD)(sector_addr*MEDIA_SECTOR_SIZE)) & (DWORD)0xFFFFFC00;  //AND mask 0xFFFFFC00 is to clear the lower bits, so we go back to the start of the erase page.
    //Now save all of the contents of the erase page.
    for(i = 0; i < ERASE_BLOCK_SIZE;)
    {
        TBLPAG = (BYTE)(flashAddress >> 16);
        *(WORD*)&file_buffer[i] = __builtin_tblrdl((WORD)flashAddress);
        flashAddress += 2u;    //Skipping upper word.  Don't care about the implemented byte/don't use it when programming or reading from the sector.
        i += 2u;
    }    

    //Now we want to overwrite the file_buffer[] contents for the sector that we are trying to write to.
    //Need to figure out if the buffer[] data goes in the upper sector or the lower sector of the file_buffer[]
    if(sector_addr & 0x00000001)
    {
        //Odd sector address, must be the high file_buffer[] sector
        offset = MEDIA_SECTOR_SIZE;
    }
    else
    {
        offset = 0;
    }        

    //Overwrite the file_buffer[] RAM contents for the sector that we are trying to write to.
    for(i = 0; i < MEDIA_SECTOR_SIZE; i++)
    {
        file_buffer[offset + i] = *buffer++;
    }
    #endif
    

#if defined(__dsPIC33E__) || defined (__PIC24E__)

    INT gieBkUp;

    //Now erase the entire erase page of flash memory.  
    //First we need to calculate the actual flash memory 
    //address of the erase page. 
    
    gieBkUp = INTCON2bits.GIE;
    INTCON2bits.GIE = 0; // Disable interrupts
    NVMADRU = (WORD)(flashAddress >> 16);
    NVMADR = (WORD)(flashAddress & 0xFFFF);
    NVMCON = 0x4003;    // This value will erase a page.
    __builtin_write_NVM();
    INTCON2bits.GIE = gieBkUp; // Enable interrupts

    //Now reprogram the erase page with previously obtained contents of the file_buffer[]
    //We only write to the even flash word addresses, the odd word addresses are left blank.  
    //Therefore, we only store 2 bytes of application data for every 2 flash memory word addresses.
    //This "wastes" 1/3 of the flash memory, but it provides extra protection from accidentally executing
    //the data.  It also allows quick/convenient PSV access when reading back the flash contents.

    TBLPAG = 0xFA;
    j = 0;
    for(i = 0; i < ERASE_BLOCK_SIZE;i++)
    {

       //
        __builtin_tblwtl((j * 2), file_buffer[i]);
        __builtin_tblwth((j * 2), 0);
           
        j ++;

        //Check if we have reached a program block size boundary.  If so, program the last 128 
        //useful bytes (192 bytes total, but 64 of those are filled with '0' filler bytes).
        if(j >= 128u)
        {
            j = j - 128u;
            NVMADRU = (WORD)(flashAddress >> 16);
            NVMADR = (WORD)(flashAddress & 0xFFFF);
            NVMCON = 0x4002;
            gieBkUp = INTCON2bits.GIE;
            INTCON2bits.GIE = 0; // Disable interrupts
            __builtin_write_NVM();
            INTCON2bits.GIE = gieBkUp; // Enable interrupts
            flashAddress += 256;
        }    
    } 
Пример #9
0
	}

	asm("DISI #5");
	__builtin_write_NVM();

	while (NVMCONbits.WR == 1)
		;
}

/* Read an instruction from flash. word_addr is the word address, not
 * the byte address. */
static void read_flash(uint32_t word_addr, uint16_t *low, uint16_t *high)
{
	TBLPAG = word_addr >> 16 & 0xff;
	*high = __builtin_tblrdh(word_addr & 0xffff);
	*low  = __builtin_tblrdl(word_addr & 0xffff);
}

/* Read data starting at prog_addr into the global prog_buf. prog_addr
 * and len are in words, not bytes. */
static void read_prog_data(uint32_t prog_addr, uint32_t len/*words*/)
{
	int i;
	for (i = 0; i < len; i += 2) {
		read_flash(prog_addr + i,
		           &prog_buf[i]   /*low*/,
		           &prog_buf[i+1] /*high*/);
	}
}

int main(void)