Пример #1
0
//Write to Flash ROM.
//
// location - flash program memory address
// src - pointer to data to write
// size - number of bytes to write to flash
//
// Here is the sequence of events:
//   1.) Goes to the beginning of the first erase block for this address
//   2.) Reads n records to ram, where n is the PIC's flash erase size
//   3.) Erases block in flash
//   4.) Modifies block in RAM
//   5.) Writes changed block back to FLASH.  Writes in chunks defined by PIC's flash write size
//   6.) Goes back to step1 if there is still more data to be written
void rom_w(int32 location, char *src, int16 size)
{
   #define EEPROM_ERASE_SIZE  getenv("FLASH_ERASE_SIZE")
   #define EEPROM_WRITE_SIZE  getenv("FLASH_WRITE_SIZE")
   int8 block[EEPROM_ERASE_SIZE];
   int32 block_start;
   int8 i;
   int8 num;

   block_start = location & (~((int32)EEPROM_ERASE_SIZE-1));
   i=location-block_start;

   while (size) 
   {
      read_program_memory(block_start, block, sizeof(block));  //read entire block to ram buffer

      if (size>(EEPROM_ERASE_SIZE-i)) {num=EEPROM_ERASE_SIZE-i;} else {num=size;}

      memcpy(&block[i],src,num);    //modify ram buffer

      erase_program_eeprom(block_start);     //erase entire block

      write_program_memory(block_start, block, sizeof(block));    //write modified block

      src+=num;
      block_start+=EEPROM_ERASE_SIZE;
      i=0;
      size-=num;
   }
}
Пример #2
0
void writeFlash(int16 memoryBlockAddress, int16 positionInMemoryBlock, int16 len, int *Buffer) {

   int writeBuffer[getenv("FLASH_ERASE_SIZE")];
   int16 i, counter;
   int16 writeLenInThisBlock;
   int1 notDone = 1;
   
   
   
  
   
   do {
   
      // read the entire erase block to memory
      read_program_memory(memoryBlockAddress, writeBuffer, getenv("FLASH_ERASE_SIZE"));
      
      // if write len is longer than the current memory block -> trim it
      if ( len > (getenv("FLASH_ERASE_SIZE") - positionInMemoryBlock)) {
         writeLenInThisBlock = getenv("FLASH_ERASE_SIZE") - positionInMemoryBlock;
      } else {
         writeLenInThisBlock = len;
      }
      
      // modify parts of the block with the new data
      for (i=positionInMemoryBlock, counter=0; counter<writeLenInThisBlock; i++, counter++) {
         writeBuffer[i] = *(Buffer+counter);
      }

      // write the block back to the flash memory. 
      for (i=0 ; i< (getenv("FLASH_ERASE_SIZE") / getenv("FLASH_WRITE_SIZE")); i++) {
         disable_interrupts(GLOBAL);
         write_program_memory( memoryBlockAddress + (i * getenv("FLASH_WRITE_SIZE")) ,
                               writeBuffer + (i * getenv("FLASH_WRITE_SIZE")), 
                               getenv("FLASH_WRITE_SIZE"));
         enable_interrupts(GLOBAL);
      }
      
      // if write-data overlaps between memory blocks -> update variables and
      // loop to write the next block
      if ((positionInMemoryBlock + len) > getenv("FLASH_ERASE_SIZE")) {
         memoryBlockAddress += getenv("FLASH_ERASE_SIZE");
         len -= getenv("FLASH_ERASE_SIZE") - positionInMemoryBlock;
         Buffer += getenv("FLASH_ERASE_SIZE") - positionInMemoryBlock;
         positionInMemoryBlock = 0;

      } else {
         notDone = 0;
      }
   } while (notDone);


}
Пример #3
0
/* ========================================================================= */
void bootloader(void)
{
    uint32 addr;
    uint16 addr_low;
    uint8 addr_high = 0;
    uint8 reclen;
    uint8 rectype;
    uint8 idx;
    uint8 buffer[HEX_LINE_LEN_MAX];
    uint8 ch;
    bool hexend = 0;
    
    #if getenv("FLASH_ERASE_SIZE")>2
    uint16 next_addr = 0;
    #endif

    
    /* until end of HEX file */
    while(hexend == 0)
    {
        /* get one line of the HEX file via RS232 until we receive CR or */
        /* we reached the end of the buffer */
        idx = 0;
        do
        {
             /* get one byte */
             ch = getch();
             /* save to buffer */
             buffer[idx] = ch;
             /* increment buffer index */
             idx++;
        }
        while(ch != 0x0A);


        /* get record length */
        reclen = get_hexbyte(&buffer[HEX_LEN_START]);

        /* check for proper checksum */
        if (check_checksum(&buffer[HEX_LEN_START], reclen) != 0)
        {
            /* checkum error - send negative acknowledge */
            putc(NAK);
        }
        else
        {
            /* checkum ok */

            /* get address */
            addr_low = make16(get_hexbyte(&buffer[HEX_ADDR_START]),
                              get_hexbyte(&buffer[HEX_ADDR_START+2]));

            /* make 32 bit address */
            addr = make32(addr_high, addr_low);

            /* get record type */
            rectype = get_hexbyte(&buffer[HEX_TYPE_START]);
            
            if (rectype == HEX_DATA_REC)
            {
                /* only program code memory */
                if ((addr_high < 0x30) && (addr >= RESET_VECTOR))
                {
                    for (idx=0; idx < reclen; idx++)
                    {
                        buffer[idx] = get_hexbyte(&buffer[HEX_DATA_START+(idx*2)]);
                    }

                    #if getenv("FLASH_ERASE_SIZE") > getenv("FLASH_WRITE_SIZE")
                    #if defined(__PCM__)
                    if ((addr_low!=next_addr)&&(addr_low&(getenv("FLASH_ERASE_SIZE")-1)!=0))
                    #else
                    if ((addr_low!=next_addr)&&(addr_low&(getenv("FLASH_ERASE_SIZE")/2-1)!=0))
                    #endif
                        erase_program_eeprom(addr);
                    next_addr = addr_low + 1;
                    #endif
                    write_program_memory(addr, buffer, reclen);
                }
            }
            else if (rectype == HEX_EOF_REC)
            {
                hexend = 1;
            }
            else if (rectype == HEX_EXTADDR_REC)
            {
                /* to save resources, only take lower byte - this */
                /* allows 24 bit addresses => enough for PIC18F */
                //addr_high = make16(get_hexbyte(&buffer[HEX_DATA_START]),
                //                   get_hexbyte(&buffer[HEX_DATA_START+2]));
                addr_high = get_hexbyte(&buffer[HEX_DATA_START+2]);
            }
            
            /* send positive acknowledge */
            putc(ACK);
        }
    }
}