int cmd_write(unsigned long cmd, unsigned long lba) { int ctr; int result=0xff; DBG("In cmd_write\n"); SPI(cmd & 255); DBG("Command sent\n"); if(!SDHCtype) // If normal SD then we have to use byte offset rather than LBA offset. lba<<=9; DBG("Sending LBA!\n"); SPI((lba>>24)&255); DBG("Sent 1st byte\n"); SPI((lba>>16)&255); DBG("Sent 2nd byte\n"); SPI((lba>>8)&255); DBG("Sent 3rd byte\n"); SPI(lba&255); DBG("Sent 4th byte\n"); DBG("Sending CRC - if any\n"); SPI((cmd>>16)&255); // CRC, if any ctr=40000; result=SPI_READ(); while(--ctr && (result==0xff)) { SPI(0xff); result=SPI_READ(); } #ifdef SPI_DEBUG putchar('0'+(result>>4)); putchar('0'+(result&15)); #endif // printf("Got result %d \n",result); return(result); }
int is_sdhc() { int i,r; spi_spin(); r=cmd_CMD8(); // test for SDHC capability // printf("cmd_CMD8 response: %d\n",r); if(r!=1) { wait_init(); return(0); } r=SPI_PUMP(); if((r&0xffff)!=0x01aa) { // printf("CMD8_4 response: %d\n",r); wait_init(); return(0); } SPI(0xff); // If we get this far we have a V2 card, which may or may not be SDHC... i=50; while(--i) { if(wait_initV2()) { if((r=cmd_CMD58())==0) { // printf("CMD58 %d\n ",r); SPI(0xff); r=SPI_READ(); // printf("CMD58_2 %d\n ",r); SPI(0xff); SPI(0xff); SPI(0xff); SPI(0xff); if(r&0x40) return(1); else return(0); } // else // printf("CMD58 %d\n ",r); } if(i==2) { puts("SDHC error!\n"); return(0); } } return(0); }
void nrf51822_interrupt(uint8_t port, uint8_t pin) { uint16_t b; uint8_t buf[256]; int i; leds_toggle(LEDS_RED); spi_set_mode(SSI_CR0_FRF_MOTOROLA, 0, 0, 8); SPI_CS_CLR(NRF51822_CS_N_PORT_NUM, NRF51822_CS_N_PIN); clock_delay_usec(8); // READ_IRQ SPI_WRITE(0x01); SPI_FLUSH(); SPI_CS_SET(NRF51822_CS_N_PORT_NUM, NRF51822_CS_N_PIN); clock_delay_usec(75); SPI_CS_CLR(NRF51822_CS_N_PORT_NUM, NRF51822_CS_N_PIN); clock_delay_usec(8); SPI_READ(b); if (b == 0xFF) { // ERROR on the nrf51822 side. Skip this. } else { for (i=0; i<b; i++) { SPI_READ(buf[i]); } } SPI_CS_SET(NRF51822_CS_N_PORT_NUM, NRF51822_CS_N_PIN); }
uint8_t fm25v02_readStatus(){ uint8_t statusReg; spi_set_mode(SSI_CR0_FRF_MOTOROLA, 0, 0, 8); SPI_CS_CLR(FM25V02_CS_N_PORT_NUM, FM25V02_CS_N_PIN); SPI_WRITE(FM25V02_READ_STATUS_COMMAND); SPI_FLUSH(); SPI_READ(statusReg); SPI_CS_SET(FM25V02_CS_N_PORT_NUM, FM25V02_CS_N_PIN); return statusReg; }
size_t AB08XX_SPI::_read(uint8_t offset, uint8_t* buf, uint16_t size) { digitalWrite(this->cs_pin, LOW); SPI.transfer(SPI_READ(offset)); for(uint16_t i = 0; i < size; i++) { buf[i] = SPI.transfer(0); } digitalWrite(this->cs_pin, HIGH); return size; }
int mmc_response(unsigned char response){ //reads the MMC until we get the response we want or timeout int16 count; // 16bit repeat, it may be possible to shrink this to 8 bit but there is not much point char temp; for(count=520;count>0;count--){ temp = SPI_READ(0xFF); if(temp == response){ return (0); } } return 1; }
int mmc_response(unsigned char response) { unsigned long count = 0xFFFF; // 16bit repeat, it may be possible to shrink this to 8 bit but there is not much point while(SPI_READ(0xFF) != response && --count > 0); if(count==0) return 1; // loop was exited due to timeout else return 0; // loop was exited before timeout }
void fm25v02_dummyWakeup(){ uint8_t dummyReg; //uint16_t dummyCnt; spi_set_mode(SSI_CR0_FRF_MOTOROLA, 0, 0, 8); SPI_CS_CLR(FM25V02_CS_N_PORT_NUM, FM25V02_CS_N_PIN); // Delay for 400-ish us clock_delay_usec(400); //for (dummyCnt=0; dummyCnt<800; dummyCnt++) // asm("nop"); SPI_FLUSH(); SPI_READ(dummyReg); SPI_CS_SET(FM25V02_CS_N_PORT_NUM, FM25V02_CS_N_PIN); }
int sd_read_sector(unsigned long lba,unsigned char *buf) { int result=0; int i; int r; // printf("sd_read_sector %d, %d\n",lba,buf); SPI(0xff); SPI_CS(1|(1<<HW_SPI_FAST)); SPI(0xff); r=cmd_read(lba); if(r!=0) { puts("Read failed\n"); // printf("Read command failed at %d (%d)\n",lba,r); return(result); } i=1500000; while(--i) { int v; SPI(0xff); // SPI_WAIT(); v=SPI_READ(); if(v==0xfe) { // puts("Reading sector data\n"); // spi_readsector((long *)buf); int j; // SPI(0xff); for(j=0;j<128;++j) { int t,v; t=SPI_PUMP(); *(int *)buf=t; // printf("%d: %d\n",buf,t); buf+=4; } i=1; // break out of the loop result=1; } } SPI(0xff); SPI(0xff); // Discard Two CRC bytes SPI_CS(0); return(result); }
int cmd_write(unsigned long cmd, unsigned long lba) { int ctr; int result=0xff; // puts("In cmd_write\n"); SPI(cmd & 255); // puts("Command sent\n"); if(!SDHCtype) // If normal SD then we have to use byte offset rather than LBA offset. lba<<=9; // puts("Sending LBA\n"); SPI((lba>>24)&255); SPI((lba>>16)&255); SPI((lba>>8)&255); SPI(lba&255); // puts("Sending CRC - if any\n"); SPI((cmd>>16)&255); // CRC, if any ctr=40000; result=SPI_READ(); while(--ctr && (result==0xff)) { SPI(0xff); result=SPI_READ(); } // printf("Got result %d \n",result); return(result); }
int init_MMC(int max_tries) { int i,tries,c; tries=0; output_low(ChipSel); /// reset chip hardware !!! required delay_ms(100); for(tries=0; tries < max_tries; tries++) { output_high(ChipSel); /// reset chip hardware !!! required delay_ms(20); for(i=0;i<20;i++) SPI_READ(0xFF); // min 80 clocks to get MMC ready output_low(ChipSel); /// !!! required delay_ms(20); c=mmc_cmd(0x40,0x00000000,128,0x01,0x99); if (c==0x01) break; } if(tries >= max_tries) { output_high(ChipSel); return MMC_INIT_RESET_ERR; } /// now try to switch to idle mode /// Note: cmd1(idle) is the only command allowed after a cmd0(reset) for(tries=0; tries < max_tries; tries++) { c=mmc_cmd(0x41,0x00000000,128,0x00,0x99); if (c==0x00) break; } output_high(ChipSel); if(tries >= max_tries) return MMC_INIT_IDLE_ERR; return MMC_NO_ERR; }
int rv3049_read_time(rv3049_time_t* time) { uint8_t buf[8]; int i; spix_set_mode(SPI_CONF_DEFAULT_INSTANCE, SSI_CR0_FRF_MOTOROLA, 0, SSI_CR0_SPH, 8); SPI_CS_SET(RV3049_CS_PORT_NUM, RV3049_CS_PIN); // Tell the RTC we want to read the clock SPI_WRITE(RV3049_SET_READ_BIT(RV3049_PAGE_ADDR_CLOCK)); SPI_FLUSH(); // Read a null byte here. Not exactly sure why. SPI_READ(buf[0]); // Then actually read the clock for (i=0; i<RV3049_READ_LEN_TIME; i++) { SPI_READ(buf[i]); } SPI_CS_CLR(RV3049_CS_PORT_NUM, RV3049_CS_PIN); // Convert the values time->seconds = BCD_TO_BINARY(buf[0]); time->minutes = BCD_TO_BINARY(buf[1]); time->hours = BCD_TO_BINARY((buf[2])&0x3F); time->days = BCD_TO_BINARY(buf[3]); time->weekday = buf[4]; time->month = buf[5]; time->year = BCD_TO_BINARY(buf[6])+2000; return 0; }
/* ---------------------------------------------------------------------------- * Function : uint8_t EEPROM_Read_Byte(uint32_t spi_interface) * ---------------------------------------------------------------------------- * Description : Read a byte from the EEPROM * Inputs : spi_interface - Index of SPI interface; use 0, 1 * Outputs : data - Byte read (return 0xFF if the specified * SPI interface is invalid) * Assumptions : - EEPROM is initialized to an address * - EEPROM is selected by chip select * ------------------------------------------------------------------------- */ uint8_t EEPROM_Read_Byte(uint32_t spi_interface) { /* Check if SPI interface exists. If interface is invalid, return 0xFF. */ if(spi_interface > (EEPROM_SPI_NUM_INTERFACE - 1)) { return 0xFF; } SPI_TRANSFERCONFIG(spi_interface, EEPROM_SPI_READ_BYTE); while(SPI_IS_BUSY(spi_interface)); return (uint8_t)SPI_READ(spi_interface); /* NOTE: Chip select is left low. */ }
static int rt305x_spi_wait(struct rt305x_spi_softc *sc) { int i = 1000; while (i--) { if (!SPI_READ(sc, RT305X_SPIBUSY)) break; } if (i == 0) { printf("busy\n"); return (1); } return (0); }
int sd_write_sector(unsigned long lba,unsigned char *buf) // FIXME - Stub { int i,t,timeout; SPI(0xff); SPI_CS(1|(1<<HW_SPI_FAST)); SPI(0xff); t=cmd_writesector(lba); if(t!=0) { puts("Write failed\n"); // printf("Read command failed at %d (%d)\n",lba,r); return(1); } SPI(0xFF); // one byte gap SPI(0xFE); // send Data Token // send sector bytes for (i = 0; i < 128; i++) { int t=*(int *)buf; SPI((t>>24)&255); SPI((t>>16)&255); SPI((t>>8)&255); SPI(t&255); buf+=4; } SPI(0xFF); // send CRC lo byte SPI(0xFF); // send CRC hi byte SPI(0xFF); // Pump the response byte timeout = 100000; do { SPI(0xFF); i=SPI_READ(); } while((i==0) && --timeout); SPI(0xff); SPI_CS(0); return(0); }
static int ar71xx_spi_attach(device_t dev) { struct ar71xx_spi_softc *sc = device_get_softc(dev); int rid; sc->sc_dev = dev; rid = 0; sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); if (!sc->sc_mem_res) { device_printf(dev, "Could not map memory\n"); return (ENXIO); } SPI_WRITE(sc, AR71XX_SPI_FS, 1); /* Flush out read before reading the control register */ SPI_BARRIER_WRITE(sc); sc->sc_reg_ctrl = SPI_READ(sc, AR71XX_SPI_CTRL); /* * XXX TODO: document what the SPI control register does. */ SPI_WRITE(sc, AR71XX_SPI_CTRL, 0x43); /* * Ensure the config register write has gone out before configuring * the chip select mask. */ SPI_BARRIER_WRITE(sc); SPI_WRITE(sc, AR71XX_SPI_IO_CTRL, SPI_IO_CTRL_CSMASK); /* * .. and ensure the write has gone out before continuing. */ SPI_BARRIER_WRITE(sc); device_add_child(dev, "spibus", -1); return (bus_generic_attach(dev)); }
/*---------------------------------------------------------------------------*/ static unsigned read_status_register(void) { unsigned char u; int s; s = splhigh(); SPI_FLASH_ENABLE(); SPI_WRITE(SPI_FLASH_INS_RDSR); SPI_FLUSH(); SPI_READ(u); SPI_FLASH_DISABLE(); splx(s); return u; }
static uint8_t rt305x_spi_txrx(struct rt305x_spi_softc *sc, uint8_t *data, int write) { if (rt305x_spi_wait(sc)) return (EBUSY); if (write == RT305X_SPI_WRITE) { SPI_WRITE(sc, RT305X_SPIDATA, *data); SPI_SET_BITS(sc, RT305X_SPICTL, START_WRITE); //printf("%s(W:%d)\n", __func__, *data); } else {/* RT305X_SPI_READ */ SPI_SET_BITS(sc, RT305X_SPICTL, START_READ); if (rt305x_spi_wait(sc)) return (EBUSY); *data = SPI_READ(sc, RT305X_SPIDATA) & 0xff; //printf("%s(R:%d)\n", __func__, *data); } return (0); }
static int ar71xx_spi_attach(device_t dev) { struct ar71xx_spi_softc *sc = device_get_softc(dev); int rid; sc->sc_dev = dev; rid = 0; sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); if (!sc->sc_mem_res) { device_printf(dev, "Could not map memory\n"); return (ENXIO); } SPI_WRITE(sc, AR71XX_SPI_FS, 1); sc->sc_reg_ctrl = SPI_READ(sc, AR71XX_SPI_CTRL); SPI_WRITE(sc, AR71XX_SPI_CTRL, 0x43); SPI_WRITE(sc, AR71XX_SPI_IO_CTRL, SPI_IO_CTRL_CSMASK); device_add_child(dev, "spibus", 0); return (bus_generic_attach(dev)); }
int is_sdhc() { int i,r; spi_spin(); r=cmd_CMD8(); // test for SDHC capability // printf("cmd_CMD8 response: %d\n",r); if(r!=1) { wait_init(); return(0); } #if 0 SPI(0xff); // SPI_WAIT(); r=SPI_READ(); // printf("CMD8_1 response: %d\n",r); SPI(0xff); // SPI_WAIT(); r=SPI_READ(); // printf("CMD8_2 response: %d\n",r); SPI(0xff); // SPI_WAIT(); r=SPI_READ(); if(r!=1) { wait_init(); return(0); } // printf("CMD8_3 response: %d\n",r); SPI(0xff); // SPI_WAIT(); r=SPI_READ(); if(r!=0xaa) { wait_init(); return(0); } #endif r=SPI_PUMP(); if((r&0xffff)!=0x01aa) { wait_init(); return(0); } // printf("CMD8_4 response: %d\n",r); SPI(0xff); // If we get this far we have a V2 card, which may or may not be SDHC... i=50; while(--i) { if(wait_initV2()) { if((r=cmd_CMD58())==0) { printf("CMD58 %d\n ",r); SPI(0xff); // SPI_WAIT(); r=SPI_READ(); printf("CMD58_2 %d\n ",r); SPI_PUMP(); // SPI(0xff); // SPI(0xff); // SPI(0xff); // SPI(0xff); if(r&0x40) return(1); else return(0); } else printf("CMD58 %d\n ",r); } if(i==2) { printf("SDHC Initialization error!\n"); return(0); } } puts("Determined SDHC status\n"); return(0); }
void mmc_read(void){ data_lo=SPI_READ(0xFF); data_hi=SPI_READ(0xFF); }
int ReadSector( int32 sector, char *buff) { int r1; long i,iw; /// allows large gt 255 buff size addressing output_low(ChipSel); delay_ms(1); TRACE1("\r\nRead sector# %lu.", sector); r1=mmc_cmd(0x51,sector<<9,16,0x00,0x40); if(r1 == 0x40) { output_high(ChipSel); return MMC_READ_INVALID_ERR; } else if(r1 != 0x00) { output_high(ChipSel); return MMC_READ_GEN_ERR; } //Get token for(iw=0;iw<1024;iw++) { r1=SPI_READ(0xFF); if (r1==0xFE) break; } //Get token error. It may be caused by improper MMC reset if(r1 != 0xFE) { output_high(ChipSel); return MMC_READ_TOKEN_ERR; } #ifdef SPEED_BOOST FSR0 = buff; // Set start address in index register for (i=0;i<512;i++) { // POSTINC0 = SPI_READ(0xFF); // Write data to Buffer and increase address WRITE_SSP(0xFF); WAIT_FOR_SSP(); POSTINC0 = READ_SSP(); } #else //Read the whole sector (512 bytes) for (i=0;i<512;i++) buff[i]=SPI_READ(0xFF); #endif SPI_READ(0xFF); // read crc SPI_READ(0xFF); #ifdef TRACE_READ_SECTOR fprintf(debug, "\r\nRead sector #%lu:", sector); for(i = 0; i<512; i++) { if(i%16 == 0) fprintf(debug, "\r\n%04LX - ", i); r1 = *buff; if(r1 < ' ' || r1 > 'z') r1 = '.'; fprintf(debug, "%02X%c ", *buff++, r1); } #endif output_high(ChipSel); return MMC_NO_ERR; }
int sd_read_sector(unsigned long lba,unsigned char *buf) { int result=0; int i; int r; // printf("sd_read_sector %d, %d\n",lba,buf); SPI_CS(1|(1<<VAMPIRE_SPI_FAST)); SPI(0xff); r=cmd_read(lba); if(r!=0) { printf("Read command failed at %d (%d)\n",lba,r); return(result); } i=1500000; while(--i) { int v; SPI(0xff); // SPI_WAIT(); v=SPI_READ(); if(v==0xfe) { // puts("Reading sector data\n"); // spi_readsector((long *)buf); int j; // SPI(0xff); short *out=(short *)buf; for(j=0;j<256;++j) { unsigned int t=0; SPI(0xff); t=SPI_READ()<<8; SPI(0xff); t|=SPI_READ(); *out++=t; } #if 0 for(j=0;j<256;++j) { int t,v; t=SPI_PUMP(); *(short *)buf=t; // printf("%d: %d\n",buf,t); buf+=2; } #endif i=1; // break out of the loop result=1; } } SPI(0xff); // SPI_WAIT(); SPI_CS(0); // puts("Sector read\n"); return(result); }
rtk_int32 smi_read(rtk_uint32 mAddrs, rtk_uint32 *rData) { #if defined(MDC_MDIO_OPERATION) /* Write Start command to register 29 */ MDC_MDIO_WRITE(MDC_MDIO_PREAMBLE_LEN, MDC_MDIO_DUMMY_ID, MDC_MDIO_START_REG, MDC_MDIO_START_OP); /* Write address control code to register 31 */ MDC_MDIO_WRITE(MDC_MDIO_PREAMBLE_LEN, MDC_MDIO_DUMMY_ID, MDC_MDIO_CTRL0_REG, MDC_MDIO_ADDR_OP); /* Write Start command to register 29 */ MDC_MDIO_WRITE(MDC_MDIO_PREAMBLE_LEN, MDC_MDIO_DUMMY_ID, MDC_MDIO_START_REG, MDC_MDIO_START_OP); /* Write address to register 23 */ MDC_MDIO_WRITE(MDC_MDIO_PREAMBLE_LEN, MDC_MDIO_DUMMY_ID, MDC_MDIO_ADDRESS_REG, mAddrs); /* Write Start command to register 29 */ MDC_MDIO_WRITE(MDC_MDIO_PREAMBLE_LEN, MDC_MDIO_DUMMY_ID, MDC_MDIO_START_REG, MDC_MDIO_START_OP); /* Write read control code to register 21 */ MDC_MDIO_WRITE(MDC_MDIO_PREAMBLE_LEN, MDC_MDIO_DUMMY_ID, MDC_MDIO_CTRL1_REG, MDC_MDIO_READ_OP); /* Write Start command to register 29 */ MDC_MDIO_WRITE(MDC_MDIO_PREAMBLE_LEN, MDC_MDIO_DUMMY_ID, MDC_MDIO_START_REG, MDC_MDIO_START_OP); /* Read data from register 25 */ MDC_MDIO_READ(MDC_MDIO_PREAMBLE_LEN, MDC_MDIO_DUMMY_ID, MDC_MDIO_DATA_READ_REG, rData); return RT_ERR_OK; #elif defined(SPI_OPERATION) /* Write 8 bits READ OP_CODE */ SPI_WRITE(SPI_READ_OP, SPI_READ_OP_LEN); /* Write 16 bits register address */ SPI_WRITE(mAddrs, SPI_REG_LEN); /* Read 16 bits data */ SPI_READ(rData, SPI_DATA_LEN); #else rtk_uint32 rawData=0, ACK; rtk_uint8 con; rtk_uint32 ret = RT_ERR_OK; /*Disable CPU interrupt to ensure that the SMI operation is atomic. The API is based on RTL865X, rewrite the API if porting to other platform.*/ rtlglue_drvMutexLock(); _smi_start(); /* Start SMI */ _smi_writeBit(0x0b, 4); /* CTRL code: 4'b1011 for RTL8370 */ _smi_writeBit(0x4, 3); /* CTRL code: 3'b100 */ _smi_writeBit(0x1, 1); /* 1: issue READ command */ con = 0; do { con++; _smi_readBit(1, &ACK); /* ACK for issuing READ command*/ } while ((ACK != 0) && (con < ack_timer)); if (ACK != 0) ret = RT_ERR_FAILED; _smi_writeBit((mAddrs&0xff), 8); /* Set reg_addr[7:0] */ con = 0; do { con++; _smi_readBit(1, &ACK); /* ACK for setting reg_addr[7:0] */ } while ((ACK != 0) && (con < ack_timer)); if (ACK != 0) ret = RT_ERR_FAILED; _smi_writeBit((mAddrs>>8), 8); /* Set reg_addr[15:8] */ con = 0; do { con++; _smi_readBit(1, &ACK); /* ACK by RTL8369 */ } while ((ACK != 0) && (con < ack_timer)); if (ACK != 0) ret = RT_ERR_FAILED; _smi_readBit(8, &rawData); /* Read DATA [7:0] */ *rData = rawData&0xff; _smi_writeBit(0x00, 1); /* ACK by CPU */ _smi_readBit(8, &rawData); /* Read DATA [15: 8] */ _smi_writeBit(0x01, 1); /* ACK by CPU */ *rData |= (rawData<<8); _smi_stop(); rtlglue_drvMutexUnlock();/*enable CPU interrupt*/ return ret; #endif /* end of #if defined(MDC_MDIO_OPERATION) */ }
int WriteSector(int32 sector, char *buff) { int r1; int16 i; TRACE1("\r\nWriteSector(%lu).", sector); if(sector == 0) //never write sector 0 return MMC_WRITE_SEC0_ERR; output_low(ChipSel); delay_ms(1); r1=mmc_cmd(0x58,sector<<9,16,0x00,0x40); if(r1 == 0x40) { output_high(ChipSel); return MMC_WRITE_INVALID_ERR; } else if(r1 != 0x00) { output_high(ChipSel); return MMC_WRITE_GEN_ERR; } SPI_READ(0xFE); #ifdef SPEED_BOOST FSR0 = buff; // Set start address in index register for (i=0;i<512;i++) { // SPI_READ(POSTINC0); /// send payload WRITE_SSP(POSTINC0); WAIT_FOR_SSP(); } #else for (i=0;i < 512;i++) { SPI_READ(buff[i]); /// send payload } #endif SPI_READ(0xFF); // send dummy chcksum SPI_READ(0xFF); r1=SPI_READ(0xFF); for( i=0;i<0x0fff;i++) { r1=SPI_READ(0xFF);// digest prior operation if (r1!=0x00) break; } #ifdef TRACE_WRITE_SECTOR fprintf(debug, "\r\nWrite sector #%lu:", sector); for(i = 0; i<512; i++) { if(i%16 == 0) fprintf(debug, "\r\n%04LX - ", i); r1 = *buff; if(r1 < ' ' || r1 > 'z') r1 = '.'; fprintf(debug, "%02X%c ", *buff++, r1); } #endif output_high(ChipSel); return MMC_NO_ERR; }
/** * @brief Reads data from SRAM of the transceiver * * This function reads from the SRAM of the transceiver * * @param[in] addr Start address in SRAM for read operation * @param[out] data Pointer to the location where data stored * @param[in] length Number of bytes to be read from SRAM */ void pal_trx_sram_read(uint8_t addr, uint8_t *data, uint8_t length) { uint8_t dummy_rx_data; PAL_WAIT_500_NS(); ENTER_CRITICAL_REGION(); /* Start SPI transaction by pulling SEL low */ SS_LOW(); /* Send the command byte */ SPI_WRITE(TRX_CMD_SR); /* * Done to clear the RDRF bit in the SPI status register, which will be set * as a result of reception of some data from the transceiver as a result * of SPI write operation done above. */ SPI_READ(dummy_rx_data); /* Send the address from which the read operation should start */ SPI_WRITE(addr); /* * Done to clear the RDRF bit in the SPI status register, which will be set * as a result of reception of some data from the transceiver as a result * of SPI write operation done above. */ SPI_READ(dummy_rx_data); /* * Done to avoid compiler warning about variable being not used after * setting. */ dummy_rx_data = dummy_rx_data; #ifdef NODMA_SPI do { /* Do dummy write for initiating SPI read */ SPI_WRITE(SPI_DUMMY_VALUE); /* Upload the received byte in the user provided location */ SPI_READ(*data); data++; } while (--length > 0); #else /* Disable both read and write. */ SPI_USED->SPI_PTCR = SPI_PTCR_RXTDIS | SPI_PTCR_TXTDIS; memset(data, 0xFF, length); SPI_USED->SPI_RPR = SPI_USED->SPI_TPR = (uint32_t)data; SPI_USED->SPI_RCR = SPI_USED->SPI_TCR = length; /* Enable read and write. */ SPI_USED->SPI_PTCR = SPI_PTCR_RXTEN | SPI_PTCR_TXTEN; /* Wait for end of read */ while (SPI_USED->SPI_RCR); #endif SS_HIGH(); LEAVE_CRITICAL_REGION(); }