void glcd_image(long mempointer /*This is the image location in program memory*/) { int j, i; int page = 0xB8; char chipsel; char buffer[1]; output_low(GLCD_DI); // Set for instruction glcd_writeByte(GLCD_CS1, 0x40); // Set the column address to 0 glcd_writeByte(GLCD_CS2, 0x40); glcd_writeByte(GLCD_CS1, page); // Set the page address to 0 glcd_writeByte(GLCD_CS2, page); for (j = 0; j < 8; j++, page+=1) { output_low(GLCD_DI); glcd_writeByte(GLCD_CS1, page); glcd_writeByte(GLCD_CS2, page); for (i = 0; i < 128; i++) { if ( i < 64) { chipsel = GLCD_CS1; } else { chipsel = GLCD_CS2; } read_program_memory(mempointer, buffer, 1); mempointer++; output_high(GLCD_DI); glcd_writeByte(chipsel, *buffer); } } }
//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; } }
void memcpypgm2ram(unsigned int8 *d, __ADDRESS__ s, unsigned int16 n) { //printf("ROM_0x%LX-to-0x%LX ", d, s); #if (getenv("PROGRAM_MEMORY") > 0x10000) #warning temporary ccs bug fix s |= 0x10000; #endif read_program_memory(s, d, n); }
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); }
void downloadBootloader() { int Buffer[SerBufferSize]; // serial input buffer int1 notDone = 1; unsigned int recLen; // HEX file record length unsigned int16 writeAddr; // HEX file write address unsigned char recType; // HEX file record type unsigned char i=0,j; // general counters /// unsigned int16 UserBootVectorAddr; // holds the address of our new boot vector unsigned int positionInMemoryBlock; unsigned int16 memoryBlockAddress; unsigned int bufferIndex; unsigned int writeLen; int16 BankAddress; int1 skipWriting=0; int relocateCount=0; #define REC_SIZE 0x10 int relocateRecordLen[6]; int relocateOriginalAddress[6]; // int flashReadBuffer[getenv("FLASH_ERASE_SIZE")]; // buffer for the relocated first mem block int flashReadBuffer[REC_SIZE]; // buffer for the relocated first mem block usb_init(); while(!usb_cdc_connected()); while (notDone) { ////////////////////////////////////////// /// Wait for ':' do { while (!usb_cdc_kbhit()); } while (usb_cdc_getc() != ':'); ///////////////////////////////////////// // Record length recLen = read8(); ///////////////////////////////////////// // Write Address writeAddr = ((int16)read8() << 8) + read8(); ///////////////////////////////////////// // Rec Type usb_cdc_getc(); // ignore the first digit, it is always '0' recType = usb_cdc_getc(); if (recType == '1') { // End of file record notDone = 0; } else if (recType == '4') { // bank select record BankAddress = (read8()<<8) + read8(); if (BankAddress != 0) skipWriting = 1; else skipWriting = 0; } else if ((recType == '0') && !(skipWriting)) { // data record /// get the data for (i=0; i < recLen ; i++) { Buffer[i] = read8(); } /* // if data is in the EEPROM area -> do nothing if ((writeAddr >= 0x2100) && (writeAddr <= 0x21FF)) { // we don't support EEPROM records yet } */ // if writing to the first memory block -> we need to temporarily // relocate it elsewhere. Since this area contains the boot and // interrupt vectors -> it should be written as the very last memory // block. if (writeAddr & (0xFFFF ^ (getenv("FLASH_ERASE_SIZE")-1)) == 0) { relocateOriginalAddress[relocateCount] = writeAddr; // remmber the orginal location relocateRecordLen[relocateCount] = recLen; // remember each record's len writeAddr = RESERVED_MEMORY_START + (relocateCount * REC_SIZE); relocateCount++; } positionInMemoryBlock = writeAddr & (getenv("FLASH_ERASE_SIZE")-1); memoryBlockAddress = writeAddr & (0xFFFF ^ (getenv("FLASH_ERASE_SIZE")-1)); writeFlash(memoryBlockAddress, positionInMemoryBlock, recLen, Buffer); } if (notDone) // Tells the PC to send the next line printf(active_comm_putc, "%c",READY_FOR_NEXT); } // Tells the PC that we are finished printf(active_comm_putc,"%c", FINISH_FLAG); delay_ms(100); ///////////////////////////////////////////////////////////////////////// // // Now we move the relocated first block to its original place // // read the entire flash block to memory disable_interrupts(GLOBAL); for (i=0;i<relocateCount;i++) { read_program_memory(RESERVED_MEMORY_START + (i*REC_SIZE), flashReadBuffer, REC_SIZE); writeAddr = relocateOriginalAddress[i]; writeFlash(0x0, writeAddr, relocateRecordLen[i], flashReadBuffer ); } output_low(USER_LED); delay_ms(100); reset_cpu(); }