📄 asmi_spi.c
字号:
if (!nr_spi_is_device_present()) return (na_asmi_err_device_not_present); // make sure the address is writable if (address >= nr_spi_lowest_protected_address()) return (na_asmi_err_write_failed); // set chip select nr_spi_set_cs (); // send WRITE ENABLE command spi_txchar (na_asmi_wren); spi_rxchar (); // throw out the garbage // clear chip select to set write enable latch nr_spi_clear_cs (); //maybe we need some delay here? for (i=0; i<20; i++); //set chip select nr_spi_set_cs (); // send SE command spi_txchar (na_asmi_se); spi_rxchar (); // throw out the garbage // send high byte of address spi_txchar ((address >> 16)&0x000000ff); spi_rxchar (); // throw out the garbage // send middle byte of address spi_txchar ((address >> 8)&0x000000ff); spi_rxchar (); // throw out the garbage // send low byte of address spi_txchar (address&0x000000ff); spi_rxchar (); // throw out the garbage // clear chip select to complete the write cycle nr_spi_clear_cs (); //now wait until the write operation is finished if (i=nr_spi_wait_write_complete ()) return (i); return (na_asmi_success);}//erase entire chipint nr_spi_erase_bulk (){ volatile int i; //verify device presence if (!nr_spi_is_device_present()) return (na_asmi_err_device_not_present); // make sure the address is writable if (nr_spi_lowest_protected_address() != na_spi_bulk_size) return (na_asmi_err_write_failed); // set chip select nr_spi_set_cs (); // send WRITE ENABLE command spi_txchar (na_asmi_wren); spi_rxchar (); // throw out the garbage // clear chip select to set write enable latch nr_spi_clear_cs (); //maybe we need some delay here? for (i=0; i<20; i++); //set chip select nr_spi_set_cs (); // send BE command spi_txchar (na_asmi_be); spi_rxchar (); // throw out the garbage // clear chip select to complete the write cycle nr_spi_clear_cs (); //now wait until the write operation is finished if (i=nr_spi_wait_write_complete ()) return (i); return (na_asmi_success);}//read buffer from memoryint nr_spi_read_buffer (unsigned long address, int length, unsigned char *data){ volatile int i; //verify device presence /* if (!nr_spi_is_device_present()) return (na_asmi_err_device_not_present); */ // set chip select //printf("Attempting read of %X bytes from %X into %X\n",length,address,data); nr_spi_set_cs (); // send READ command spi_txchar (na_asmi_read); spi_rxchar (); // send high byte of address spi_txchar ((address >> 16)&0x000000ff); spi_rxchar (); // send middle byte of address spi_txchar ((address >> 8)&0x000000ff); spi_rxchar (); // send low byte of address spi_txchar (address&0x000000ff); spi_rxchar (); while (length-- > 0) { // read the byte spi_txchar (0); // send out some garbage while were reading *data++ = spi_rxchar (); } // clear chip select nr_spi_clear_cs (); return (na_asmi_success);}//write page to memoryint nr_spi_write_page (unsigned long address, int length, unsigned char *data){ volatile int i; unsigned char verify[na_spi_page_size]; int my_length = length; unsigned char *my_data = data; //verify device presence if (!nr_spi_is_device_present()) { printf("Device not found in nr_spi_page_write()\n"); return (na_asmi_err_device_not_present); } // set chip select nr_spi_set_cs (); // send WRITE ENABLE command spi_txchar (na_asmi_wren); spi_rxchar (); // throw out the garbage // clear chip select to set write enable latch nr_spi_clear_cs (); //maybe we need some delay here? for (i=0; i<20; i++); //set chip select nr_spi_set_cs (); // send WRITE command spi_txchar (na_asmi_write); spi_rxchar (); // throw out the garbage // send high byte of address spi_txchar ((address >> 16)&0x000000ff); spi_rxchar (); // throw out the garbage // send middle byte of address spi_txchar ((address >> 8)&0x000000ff); spi_rxchar (); // throw out the garbage // send low byte of address spi_txchar (address&0x000000ff); spi_rxchar (); // throw out the garbage // send the data while (my_length-- > 0) { // write the byte spi_txchar (*my_data++); spi_rxchar (); // throw out the garbage } // clear chip select to complete the write cycle nr_spi_clear_cs (); //now wait until the write operation is finished if (i=nr_spi_wait_write_complete ()) { printf("Terminated while waiting for write in nr_spi_page_write()\n"); return (i); } //verify that the data was correctly written nr_spi_read_buffer (address, length, verify); for (i=0; i<length; i++) { if (verify[i] != data[i]) { printf("Failed to verify data in nr_spi_page_write(): Read %X v. %X, index %X\n",verify[i],data[i],i); return (na_asmi_err_write_failed); } } return (na_asmi_success);}//write buffer to memroyint nr_spi_write_buffer (unsigned long address, int length, unsigned char *data){ volatile int i; int status; //printf("Attempting to write %X bytes to %X from %X\n",length,address,data); //verify device presence if (!nr_spi_is_device_present()) { printf("Device not found in function nr_spi_write_buffer()\n"); return (na_asmi_err_device_not_present); } // make sure the full address range is writable if ((address >= nr_spi_lowest_protected_address()) || ((address+length-1) >= nr_spi_lowest_protected_address())) { printf("Full address range not writable in flash, function nr_spi_write_buffer()\n"); return (na_asmi_err_write_failed); } //send partial first page (if there is one) i = address % na_spi_page_size; if ((i != 0) && (i+length > na_spi_page_size)) { i = na_spi_page_size-i; if (status = nr_spi_write_page (address, i, data)) { printf("Partial first page write failed in nr_spi_write_buffer()\n"); return (status); //write failed } address += i; data += i; length -= i; } //send all full pages while (length/na_spi_page_size > 0) { if (status = nr_spi_write_page (address, na_spi_page_size, data)) { printf("Full page write failed in nr_spi_write_buffer(), address: %X, bytes left: %X, data buffer: %X\n",address,length,data); return (status); //write failed } address += na_spi_page_size; data += na_spi_page_size; length -= na_spi_page_size; } //send partial last page (if there is one) if (length > 0) { if (status = nr_spi_write_page (address, length, data)) { printf("Partial last page write failed nr_spi_write_buffer()\n"); return (status); //write failed } } return (na_asmi_success);}#define NR_spi_BITREVERSE(x) \ ((((x) & 0x80) ? 0x01 : 0) | \ (((x) & 0x40) ? 0x02 : 0) | \ (((x) & 0x20) ? 0x04 : 0) | \ (((x) & 0x10) ? 0x08 : 0) | \ (((x) & 0x08) ? 0x10 : 0) | \ (((x) & 0x04) ? 0x20 : 0) | \ (((x) & 0x02) ? 0x40 : 0) | \ (((x) & 0x01) ? 0x80 : 0))int nr_spi_address_past_config (unsigned long *addr){ unsigned long i; int j; unsigned char value; unsigned char buf[4]; int err; if (err=nr_spi_read_buffer(0, sizeof(buf) / sizeof(*buf), buf)) return (err); for (i=0; i<na_spi_bulk_size - 8; i++) { if (err=nr_spi_read_byte (i, &value)) return (err); if (value == NR_spi_BITREVERSE(0x6A)) break; if (value != 0xFF) return (na_asmi_invalid_config); } //if we haven't seen any data by the 64th byte, //then it doesn't look like there's any configuration data if (i >= na_spi_bulk_size - 8) return (na_asmi_invalid_config); // If we made it this far, we found the 0x6A byte at address i. Beyond that, // we expect an 8-byte "option register", of which the last 4 bytes are the // length, LS-byte first. i += 5; // Jump ahead to the length. // Read the 4 bytes of the length. if (err=nr_spi_read_buffer(i,4,buf)) return (err); // Compute the length. *addr = 0; for (j = 3; j != ~0; --j) { *addr <<= 8; *addr |= NR_spi_BITREVERSE(buf[j]); } // The last address, oddly enough, is in bits. // Convert to bytes, rounding up. *addr += 7; *addr /= 8; return (na_asmi_success);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -