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; }
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 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 }