void PageErase(uint16_t PageAdr) { DF_reset(); // reset dataflash command decoder DF_SPI_RW(PageEraseCmd); // Page erase op-code DF_SPI_RW((uint8_t)(PageAdr >> 7)); // upper part of page address DF_SPI_RW((uint8_t)(PageAdr << 1)); // lower part of page address and MSB of int.page adr. DF_SPI_RW(0x00); // dont cares DF_reset(); // initiate flash page erase while (!(ReadDFStatus() & 0x80)); // monitor the status register, wait until busy-flag is high }
static void BufferReadStr(uint8_t BufferNo, uint16_t IntPageAdr, uint16_t No_of_bytes, uint8_t *BufferPtr) { uint16_t i; // printf("BufferReadStr(BufferNo %u, IntPageAdr %u)\r\n", BufferNo, IntPageAdr); DF_reset(); // reset dataflash command decoder // Note that this test selects either Buffer 1 or the other buffer, whatever you call it. // You can call it Buffer 0 or Buffer 2 and it will work as long as you are consistant. // No matter what, a buffer will be selected. if (1 == BufferNo) // read uint8_t from buffer 1 DF_SPI_RW(Buf1Read); // buffer 1 read op-code else DF_SPI_RW(Buf2Read); // buffer 2 read op-code DF_SPI_RW(0x00); // don't cares DF_SPI_RW((uint8_t)(IntPageAdr>>8));// upper part of internal buffer address DF_SPI_RW((uint8_t)(IntPageAdr)); // lower part of internal buffer address DF_SPI_RW(0x00); // don't cares to initialize the read operation for (i = 0; i < No_of_bytes; i++) { *(BufferPtr) = DF_SPI_RW(0x00); // read byte and put it in buffer pointed to by *BufferPtr // printf("%02x ", *(BufferPtr)); BufferPtr++; // point to next element in buffer } // printf("\r\n"); }
static void PageToBuffer(uint16_t PageAdr, uint8_t BufferNo) { // printf("PageToBuffer(PageAdr %u, BufferNo %u)\r\n", PageAdr, BufferNo); DF_reset(); // reset dataflash command decoder // Note that this test selects either Buffer 1 or the other buffer, whatever you call it. // You can call it Buffer 0 or Buffer 2 and it will work as long as you are consistant. // No matter what, a buffer will be selected. if (BufferNo == 1) // transfer flash page to buffer 1 DF_SPI_RW(FlashToBuf1Transfer); // transfer to buffer 1 op-code else DF_SPI_RW(FlashToBuf2Transfer); // transfer to buffer 2 op-code DF_SPI_RW((uint8_t)(PageAdr >> (16 - PAGE_BITS))); // upper part of page address DF_SPI_RW((uint8_t)(PageAdr << (PAGE_BITS - 8))); // lower part of page address DF_SPI_RW(0x00); // don't cares DF_reset(); // init transfer while(!(ReadDFStatus() & 0x80)); // monitor the status register, wait until busy-flag is high }
static void BufferToPage(uint8_t BufferNo, uint16_t PageAdr) { // printf("BufferToPage(BufferNo %u, PageAdr %u)\r\n", BufferNo, PageAdr); DF_reset(); // reset dataflash command decoder // Note that this test selects either Buffer 1 or the other buffer, whatever you call it. // You can call it Buffer 0 or Buffer 2 and it will work as long as you are consistant. // No matter what, a buffer will be selected. if (1 == BufferNo) // program flash page from buffer 1 DF_SPI_RW(Buf1ToFlashWE); // buffer 1 to flash with erase op-code else DF_SPI_RW(Buf2ToFlashWE); // buffer 2 to flash with erase op-code DF_SPI_RW((uint8_t)(PageAdr >> (16 - PAGE_BITS))); //upper part of page address DF_SPI_RW((uint8_t)(PageAdr << (PAGE_BITS - 8))); //lower part of page address DF_SPI_RW(0x00); // don't cares DF_reset(); // initiate flash page programming while (!(ReadDFStatus() & 0x80)); // monitor the status register, wait until busy-flag is high }
uint8_t ReadDFStatus(void) { uint8_t result; DF_reset(); result = DF_SPI_RW(StatusReg); result = DF_SPI_RW(0x00); // device_id = ((result & 0x3C) >> 2); return result; }
static int AT45D_ReadSector(uint16_t sector) { // printf("AT45D_ReadSector(%u)\r\n", sector); #ifdef SPI_VERBOSE while (IsBusy) { printf("."); } printf("\r\n"); while (SPI2STATbits.SPIRBF) { int result = SPI2BUF; // dummy read of the SPIBUF register to clear the SPIRBF flag printf("AT45D_ReadSector discarding %x\r\n", result); } if (SPI2STATbits.SPIROV) { printf("AT45D_ReadSector SPI2STAT = %x\r\n", SPI2STAT); SPI2STATbits.SPIROV = 0; } while (!(ReadDFStatus() & 0x80)) { printf("#"); } #else while (IsBusy); while (!(ReadDFStatus() & 0x80)); // monitor the status register, wait until busy-flag is high #endif IsBusy = 1; DF_reset(); // reset dataflash command decoder DF_SPI_RW(FlashPageRead); // transfer to buffer 1 op-code DF_SPI_RW((uint8_t)(sector >> (16 - PAGE_BITS))); // upper part of page address DF_SPI_RW((uint8_t)(sector << (PAGE_BITS - 8))); // lower part of page address DF_SPI_RW(0x00); // page starting address (lower 8 bits) DF_SPI_RW(0x00); // don't cares DF_SPI_RW(0x00); // don't cares DF_SPI_RW(0x00); // don't cares DF_SPI_RW(0x00); // don't cares // DF_SPI_RW(0x00); // why is this required - odd... DMA1CONbits.NULLW = 1; DMA1CONbits.CHEN = 1; // enable DMA Channel SPI2BUF = 0; // start the DMA transaction // DMA1REQbits.FORCE = 1; return 1; }
static void BufferWriteStr(uint8_t BufferNo, uint16_t IntPageAdr, uint16_t No_of_bytes, uint8_t *BufferPtr) { uint16_t i; // printf("BufferWriteStr(BufferNo %u, IntPageAdr %u)\r\n", BufferNo, IntPageAdr); DF_reset(); // reset dataflash command decoder // Note that this test selects either Buffer 1 or the other buffer, whatever you call it. // You can call it Buffer 0 or Buffer 2 and it will work as long as you are consistant. // No matter what, a buffer will be selected. if (1 == BufferNo) // write enable to buffer 1 DF_SPI_RW(Buf1Write); // buffer 1 write op-code else DF_SPI_RW(Buf2Write); // buffer 2 write op-code DF_SPI_RW(0x00); // Don't care DF_SPI_RW((uint8_t)(IntPageAdr>>8));// Upper part of internal buffer address DF_SPI_RW((uint8_t)(IntPageAdr)); // Lower part of internal buffer address for (i = 0; i < No_of_bytes; i++) { // printf("%02x ", (uint8_t)*BufferPtr); DF_SPI_RW(*BufferPtr); // write byte pointed at by *BufferPtr to dataflash buffer location BufferPtr++; // point to next element in buffer } // printf("\r\n"); }