123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266 |
- /*
- Test program for SPI flash memory
- */
- #define word char
- #include "LIB/MATH.C"
- #include "LIB/STDLIB.C"
- #include "LIB/SYS.C"
- // Sets SPI0_CS low
- void SpiBeginTransfer()
- {
- asm(
- "; Backup regs\n"
- "push r1\n"
- "push r2\n"
- "load32 0xC02729 r2 ; r2 = 0xC02729\n"
- "load 0 r1 ; r1 = 0 (enable)\n"
- "write 0 r2 r1 ; write to SPI0_CS\n"
- "; Restore regs\n"
- "pop r2\n"
- "pop r1\n"
- );
- }
- // Sets SPI0_CS high
- void SpiEndTransfer()
- {
- asm(
- "; Backup regs\n"
- "push r1\n"
- "push r2\n"
- "load32 0xC02729 r2 ; r2 = 0xC02729\n"
- "load 1 r1 ; r1 = 1 (disable)\n"
- "write 0 r2 r1 ; write to SPI0_CS\n"
- "; Restore regs\n"
- "pop r2\n"
- "pop r1\n"
- );
- }
- // Write dataByte and return read value
- // Write 0x00 for a read
- // Writes byte over SPI0
- word SpiTransfer(word dataByte)
- {
- word retval = 0;
- asm(
- "load32 0xC02728 r2 ; r2 = 0xC02728\n"
- "write 0 r2 r4 ; write r4 over SPI0\n"
- "read 0 r2 r2 ; read return value\n"
- "write -4 r14 r2 ; write to stack to return\n"
- );
- return retval;
- }
- // Inits SPI by enabling SPI0 and resetting the chip
- void initSPI()
- {
- // Already set CS high before enabling SPI0
- SpiEndTransfer();
- // Enable SPI0
- word *p = (word *) 0xC0272A; // Set address (SPI0 enable)
- *p = 1; // Write value
- delay(10);
- // Reset to get out of continuous read mode
- SpiBeginTransfer();
- SpiTransfer(0x66);
- SpiEndTransfer();
- delay(1);
- SpiBeginTransfer();
- SpiTransfer(0x99);
- SpiEndTransfer();
- delay(1);
- SpiBeginTransfer();
- SpiTransfer(0x66);
- SpiEndTransfer();
- delay(1);
- SpiBeginTransfer();
- SpiTransfer(0x99);
- SpiEndTransfer();
- delay(1);
- }
- // Should print 239 as Winbond manufacturer, and 23 for W25Q128 device ID
- void readDeviceID()
- {
- SpiBeginTransfer();
- SpiTransfer(0x90);
- SpiTransfer(0);
- SpiTransfer(0);
- SpiTransfer(0);
- word manufacturer = SpiTransfer(0);
- word deviceID = SpiTransfer(0);
- SpiEndTransfer();
- BDOS_PrintConsole("Manufacturer ID: ");
- BDOS_PrintDecConsole(manufacturer);
- BDOS_PrintConsole("\n");
- BDOS_PrintConsole("Device ID: ");
- BDOS_PrintDecConsole(deviceID);
- BDOS_PrintConsole("\n");
- }
- void enableWrite()
- {
- SpiBeginTransfer();
- SpiTransfer(0x06);
- SpiEndTransfer();
- }
- void read_from_address(word addr, word len)
- {
- SpiBeginTransfer();
- SpiTransfer(0x03);
- SpiTransfer(addr >> 16);
- SpiTransfer(addr >> 8);
- SpiTransfer(addr);
- word i;
- for (i = 0; i < len; i++)
- {
- word x = SpiTransfer(0x00);
- // delay a bit here
- uprintDec(x);
- uprint(" ");
- }
- uprint("\n");
- SpiEndTransfer();
- }
- word readStatusRegister(word reg)
- {
- SpiBeginTransfer();
- if (reg == 2)
- SpiTransfer(0x35);
- else if (reg == 3)
- SpiTransfer(0x15);
- else
- SpiTransfer(0x05);
- word status = SpiTransfer(0);
- SpiEndTransfer();
- return status;
- }
- // Executes chip erase operation
- // TAKES AT LEAST 20 SECONDS!
- // Returns 1 on success
- word chipErase()
- {
- enableWrite();
- word status = readStatusRegister(1);
- // Check if write is enabled
- if ((status & 0x2) == 0)
- {
- BDOS_PrintlnConsole("WE disabled!");
- return 0;
- }
- // Send command
- SpiBeginTransfer();
- SpiTransfer(0xC7);
- SpiEndTransfer();
- // Wait for busy bit to be 0
- status = 1;
- while((status & 0x1) == 1)
- {
- delay(100);
- status = readStatusRegister(1);
- }
- BDOS_PrintlnConsole("Chip erase complete!");
- return 1;
- }
- void dump_memory()
- {
- word page_max = 9000;//65536;
- word page;
- for (page = 0; page < page_max; page++)
- {
- uprintDec(page);
- uprint(": ");
- word addr = page * 256;
- SpiBeginTransfer();
- SpiTransfer(0x03);
- SpiTransfer(addr >> 16);
- SpiTransfer(addr >> 8);
- SpiTransfer(addr);
- word i;
- for (i = 0; i < 16; i++)
- {
- word x = SpiTransfer(0x00);
-
- uprintDec(x);
- uprint(" ");
- }
- uprint("\n");
- SpiEndTransfer();
- }
- }
- int main()
- {
- // Clear UART screen:
- uprintc(0x1B);
- uprintc(0x5B);
- uprintc(0x32);
- uprintc(0x4A);
- BDOS_PrintConsole("SPI Flash test\n");
- initSPI();
- readDeviceID();
- //chipErase();
- word addr = 2000000;
- read_from_address(addr, 512);
- //dump_memory();
- return 'q';
- }
- void interrupt()
- {
- // Handle all interrupts
- word i = getIntID();
- switch(i)
- {
- case INTID_TIMER1:
- timer1Value = 1; // Notify ending of timer1
- break;
- default:
- break;
- }
- }
|