📄 asmi_spi.c
字号:
//TODO: Increase address from 2 bytes to 3#include "excalibur.h"#include "asmi_spi.h"void nr_spi_init(){ //Set slave select register na_spi->np_spislaveselect = 1;}//wait until all the data is shifted outvoid nr_spi_wait_tx_complete (){ while (!(na_spi->np_spistatus & np_spistatus_tmt_mask));}//set the chip-selectvoid nr_spi_set_cs (){ na_spi->np_spicontrol |= np_spicontrol_sso_mask;}//clear the chip-selectvoid nr_spi_clear_cs (){ int value; nr_spi_wait_tx_complete (na_asmi); //clear only the sso bit value = na_spi->np_spicontrol; value = value & (~np_spicontrol_sso_mask); na_spi->np_spicontrol = value;}//send 8 bits to the memoryvoid spi_txchar (unsigned char data){ while (!(na_spi->np_spistatus & np_spistatus_trdy_mask)); na_spi->np_spitxdata = data;}//receive 8 bits from the memoryunsigned char spi_rxchar (){ while (!(na_spi->np_spistatus & np_spistatus_rrdy_mask)); return (na_spi->np_spirxdata);}//read the memories status registerunsigned char nr_spi_read_status (){ unsigned char value; // set chip select nr_spi_set_cs (); // send READ command spi_txchar (na_asmi_rdsr); spi_rxchar (); // throw out the garbage // read the byte spi_txchar (0); // send out some garbage while were reading value = spi_rxchar (); // clear chip select nr_spi_clear_cs (); //printf("Read status reported: %X\n",value); return (value);}//wait until the write operation is finishedint nr_spi_wait_write_complete (){ volatile unsigned long int i=0; // Compute a maximum timeout value for all callers of this function. // This value is computed for a maximum timeout of 10s (EPCS4 bulk // erase). The calculation goes as follows: // // maximum spi clock rate: 20MHz // read status time: 16 clocks + 1/2 clock period on either side = // 17/20M = 850ns // 10s / 850ns = 11,764,706 read status commands. const unsigned long i_timeout=11770000; while ((nr_spi_read_status() & na_asmi_wip) && (i<i_timeout)) { i++; } if (i >= i_timeout) { printf("Timed out in nr_spi_wait_write_complete()\n"); return (na_asmi_err_timedout); } else return (na_asmi_success);}//returns true if the chip is present else falseint nr_spi_is_device_present (){ volatile int i; // 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 (); // some delay between chip select change for (i=0;i<20;i++); //not check the value i = nr_spi_read_status (); if (i & na_asmi_wel) { //printf("First device present check worked\n"); // previous write worked, // but if the pins are floating, // we don't know what the value might be, // so lets switch values and check again // set chip select nr_spi_set_cs (); // send WRITE DISABLE command spi_txchar (na_asmi_wrdi); spi_rxchar (); // throw out the garbage //clear chip select to set write enable latch nr_spi_clear_cs (); // some delay between chip select change for (i=0;i<200;i++); //now check the value again i = nr_spi_read_status (); if ((i & na_asmi_wel) == 0) { //printf("Second check passed\n"); return (1); } } //if we made it this far then the device is not present return (0);}//returns the lowest protected addressunsigned long nr_spi_lowest_protected_address(){ int bp; //verify device presence if (!nr_spi_is_device_present()) return (na_asmi_err_device_not_present); bp = nr_spi_read_status () & na_asmi_bp; //switch (bp) //{ return na_spi_bulk_size; //} //this should never happen, but to make the compiler happy... return (0);}int nr_spi_write_status (unsigned char value){ volatile int i; //verify device presence if (!nr_spi_is_device_present()) 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 (); // some dealy between chip select change for (i=0; i<20; i++); // set chip select nr_spi_set_cs (); // send WRSR command spi_txchar (na_asmi_wrsr); spi_rxchar (); // throw out the garbage // write the byte spi_txchar (value); spi_rxchar (); // clear chip select nr_spi_clear_cs (); //now wait until the write operation is finished if (i=nr_spi_wait_write_complete ()) return (i); //now verify that the write was successful i = nr_spi_read_status (); if (i != (int)value) return (na_asmi_err_write_failed); return (na_asmi_success);}//set the status register to protect the selected regionint nr_spi_protect_region (int bpcode){ unsigned char value; //verify device presence if (!nr_spi_is_device_present()) return (na_asmi_err_device_not_present); value = nr_spi_read_status (); value = value & (!na_asmi_bp); value |= bpcode; return (nr_spi_write_status (value));}//read 1 byte from the memoryint nr_spi_read_byte (unsigned long address, unsigned char *data){ //verify device presence /*if (!nr_spi_is_device_present()) return (na_asmi_err_device_not_present); */ // set chip select 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 (); // read the byte spi_txchar (0); // send out some garbage while were reading *data = (unsigned char) spi_rxchar (); // clear chip select nr_spi_clear_cs (); return (na_asmi_success);}//write 1 byte to the memroyint nr_spi_write_byte (unsigned long address, unsigned char data){ volatile int i; unsigned char verify; //verify device presence 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 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 spi_txchar (data); spi_rxchar (); // throw out the garbage // clear chip select to set 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); //now verify that the write was successful nr_spi_read_byte (address, &verify); if (verify != data) return (na_asmi_err_write_failed); return (na_asmi_success);}//erase sector which contains addressint nr_spi_erase_sector (unsigned long address){ volatile int i; //verify device presence
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -