Application - MX35LFxGE4AB, SPI NAND Flash
於 2018年8月23日 (四) 10:20 由 Tommy (對話 | 貢獻) 所做的修訂 (已建立頁面,內容為 "thumb|200px|RPi2 with SPI NAND Flash(MX35LFxGE4AB) == HW connection == <pre> PRi2 -- MX35LFxGE4AB VCC -- VC…")
HW connection
PRi2 -- MX35LFxGE4AB VCC -- VCC(3.3V) VCC -- HOLD(3.3V) GPIO19(MOSI) -- SI GPIO21(MISO) -- SO GPIO23(CLK) -- SCLK GPIO24(CS0) -- CS Gnd -- Gnd Gnd -- WP
Timing
Hack libbcm2835
- Add bcm2835_spi_transfernb_adv() in bcm2835.c
/* Writes an number of bytes to SPI and read an number of bytes from SPI*/ void bcm2835_spi_transfernb_adv(char* tbuf, char* rbuf, uint32_t tx_len, uint32_t rx_len) { volatile uint32_t* paddr = bcm2835_spi0 + BCM2835_SPI0_CS/4; volatile uint32_t* fifo = bcm2835_spi0 + BCM2835_SPI0_FIFO/4; uint32_t TXCnt=0; uint32_t RXCnt=0; /* This is Polled transfer as per section 10.6.1 // BUG ALERT: what happens if we get interupted in this section, and someone else // accesses a different peripheral? */ /* Clear TX and RX fifos */ bcm2835_peri_set_bits(paddr, BCM2835_SPI0_CS_CLEAR, BCM2835_SPI0_CS_CLEAR); /* Set TA = 1 */ bcm2835_peri_set_bits(paddr, BCM2835_SPI0_CS_TA, BCM2835_SPI0_CS_TA); /* Use the FIFO's to reduce the interbyte times */ /* TX fifo not full, so add some more bytes */ while(TXCnt < len) while((BCM2835_SPI0_CS_TXD & bcm2835_peri_read(paddr))) { bcm2835_peri_write_nb(fifo, tbuf[TXCnt]); TXCnt++; } /* read dummy */ while(RXCnt < tx_len) while((BCM2835_SPI0_CS_RXD & bcm2835_peri_read(paddr))) { rbuf[RXCnt] = bcm2835_peri_read_nb(fifo); RXCnt++; } RXCnt = 0; /* Rx fifo not empty, so get the next received bytes */ while((BCM2835_SPI0_CS_RXD & bcm2835_peri_read(paddr))) { rbuf[RXCnt] = bcm2835_peri_read_nb(fifo); RXCnt++; } /* Wait for DONE to be set */ while (!(bcm2835_peri_read_nb(paddr) & BCM2835_SPI0_CS_DONE)) ; /* Set TA = 0, and also set the barrier */ bcm2835_peri_set_bits(paddr, 0, BCM2835_SPI0_CS_TA); }
Example code
#include <bcm2835.h> #include <stdio.h> int main(int argc, char **argv) { int i, tx_len=2, rx_len=2; if (!bcm2835_init()) return 1; bcm2835_spi_begin(); bcm2835_spi_setBitOrder(BCM2835_SPI_BIT_ORDER_MSBFIRST); // The default bcm2835_spi_setDataMode(BCM2835_SPI_MODE0); // The default bcm2835_spi_setClockDivider(BCM2835_SPI_CLOCK_DIVIDER_512); // The default bcm2835_spi_chipSelect(BCM2835_SPI_CS0); // The default bcm2835_spi_setChipSelectPolarity(BCM2835_SPI_CS0, LOW); // the default // Send a byte to the slave and simultaneously read a byte back from the slave // If you tie MISO to MOSI, you should read back what was sent usleep(500); uint8_t tx_data[]={0x9f, 0x44}; static uint8_t rx_data[10]={0}; bcm2835_spi_transfernb_adv(tx_data,rx_data, tx_len, rx_len); for(i=0;i<rx_len;i++) printf("Read from SPI: 0x%.2X \n", rx_data[i]); bcm2835_spi_end(); bcm2835_close(); return 0; }