/******************************************************************************* * It returns 8 bits vendor ID *******************************************************************************/ uint8_t EEPROM_readVendorId(){ unsigned short r_data = 0; unsigned char r_pcs; spi_write(SPI, RDID, spi_get_pcs(3), 0); while((spi_read_status(SPI) & SPI_SR_RDRF) == 0); spi_read(SPI, (uint16_t*) &r_data, (uint8_t*) &r_pcs); /**************** SENDING DUMMY ADDRESS ************************/ spi_write(SPI, 0x00, spi_get_pcs(3), 0); while((spi_read_status(SPI) & SPI_SR_RDRF) == 0); spi_read(SPI, (uint16_t*) &r_data, (uint8_t*) &r_pcs); spi_write(SPI, 0x00, spi_get_pcs(3), 0); while((spi_read_status(SPI) & SPI_SR_RDRF) == 0); spi_read(SPI, (uint16_t*) &r_data, (uint8_t*) &r_pcs); spi_write(SPI, 0x00, spi_get_pcs(3), 0); while((spi_read_status(SPI) & SPI_SR_RDRF) == 0); spi_read(SPI, (uint16_t*) &r_data, (uint8_t*) &r_pcs); /**************** RECEIVING DATA ************************/ spi_write(SPI, 0x05, spi_get_pcs(3), 1); while((spi_read_status(SPI) & SPI_SR_RDRF) == 0); spi_read(SPI, (uint16_t*) &r_data, (uint8_t*) &r_pcs); return r_data; }
static int sf_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf) { struct wmt_sf_info_t *info = (struct wmt_sf_info_t *)mtd->priv; unsigned char *sf_base_addr = info->io_base; int rc; REG32_VAL(PMCEU_ADDR) |= SF_CLOCK_EN; //printk("re sf check"); if ((from + MTDSF_PHY_ADDR) >= g_sf_info[0].phy) { rc = spi_read_status(0); if (rc) printk("sfread: sf0 is busy"); } else { rc = spi_read_status(1); if (rc) printk("sfread: sf1 is busy"); } //printk("end\n"); /*printk("sf_read(pos:%x, len:%x)\n", (long)from, (long)len);*/ if (from + len > mtd->size) { printk(KERN_ERR "sf_read() out of bounds (%lx > %lx)\n", (long)(from + len), (long)mtd->size); return -EINVAL; } memcpy_fromio(buf, (sf_base_addr+from), len); *retlen = len; REG32_VAL(PMCEU_ADDR) &= ~(SF_CLOCK_EN); return 0; }
/******************************************************************************* * WRITE EEPROM STATUS BYTE * | W/R|| _ | _ | _ | W/R | W/R | R | R | * | WPEN| X | X | X | BP1 | BP0 | WEL | WIP | *******************************************************************************/ void _EEPROM_writeStatusReg(uint8_t w_status){ unsigned char r_pcs; uint8_t r_data = 0; spi_write(SPI, WRSR, spi_get_pcs(3), 0); while((spi_read_status(SPI) & SPI_SR_RDRF) == 0); spi_read(SPI, (uint16_t*) &r_data, (uint8_t*) &r_pcs); spi_write(SPI, w_status, spi_get_pcs(3), 1); while((spi_read_status(SPI) & SPI_SR_RDRF) == 0); spi_read(SPI, (uint16_t*) &r_data, (uint8_t*) &r_pcs); }
/* * poll the "Status Register" waiting till it is not busy. * * input: none * returns: none */ static void spi_wait_till_ready( spi_chipsel_type const chipsel) { #if defined(CONFIG_SPI_FLASH_ATMEL) while (!(spi_read_status(chipsel) & SR_READY)) ; /* do nothing */ #elif defined(CONFIG_SPI_FLASH_ST) || defined(CONFIG_SPI_FLASH_MXIC) while (spi_read_status(chipsel) & SR_WIP) ; /* do nothing */ #else #error Please specify which SPI Serial Flash is being used #endif /* defined(CONFIG_STM_SPI_xxxxxx) */ }
/******************************************************************************* * READ EEPROM STATUS BYTE * | W/R|| _ | _ | _ | W/R | W/R | R | R | * | WPEN| X | X | X | BP1 | BP0 | WEL | WIP | *******************************************************************************/ uint8_t _EEPROM_readStatusReg(){ unsigned char r_pcs; uint8_t r_data = 0; spi_write(SPI, RDSR, spi_get_pcs(3), 0); while((spi_read_status(SPI) & SPI_SR_RDRF) == 0); spi_read(SPI, (uint16_t*) &r_data, (uint8_t*) &r_pcs); spi_write(SPI, 0x00, spi_get_pcs(3), 1); while((spi_read_status(SPI) & SPI_SR_RDRF) == 0); spi_read(SPI, (uint16_t*) &r_data, (uint8_t*) &r_pcs); return r_data; }
void platform_wifi_spi_rx_dma_irq(void) { uint8_t junk1; uint16_t junk2; pdc_packet_t pdc_spi_packet = { 0, 1 }; Pdc* spi_pdc = spi_get_pdc_base( wifi_spi.port ); uint32_t status = spi_read_status( wifi_spi.port ); uint32_t mask = spi_read_interrupt_mask( wifi_spi.port ); if ( ( mask & SPI_IMR_RXBUFF ) && ( status & SPI_SR_RXBUFF ) ) { pdc_disable_transfer( spi_pdc, PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS ); pdc_rx_init( spi_pdc, &pdc_spi_packet, NULL ); pdc_tx_init( spi_pdc, &pdc_spi_packet, NULL ); spi_disable_interrupt( wifi_spi.port, SPI_IER_RXBUFF ); } if ( ( mask & SPI_IMR_ENDTX ) && ( status & SPI_SR_ENDTX ) ) { pdc_disable_transfer( spi_pdc, PERIPH_PTCR_TXTDIS ); pdc_tx_init( spi_pdc, &pdc_spi_packet, NULL ); spi_disable_interrupt( wifi_spi.port, SPI_IER_ENDTX ); /* Clear SPI RX data in a SPI send sequence */ spi_read( wifi_spi.port, &junk2, &junk1); } mico_rtos_set_semaphore( &spi_transfer_finished_semaphore ); }
int get_sw_write_protect_state(void) { uint8_t status; /* Return unprotected status if status read fails. */ return spi_read_status(&status) ? 0 : !!(status & 0x80); }
void setup_rf_attenuator(uint16_t atten) { volatile uint32_t data; __attribute__((unused)) uint16_t dummy; __attribute__((unused)) uint8_t dummy2; current_attenution = atten; // Clear receive buffer //while((spi_read_status(SPI0) & SPI_SR_RDRF) == 0); spi_read(SPI0, &dummy, &dummy2); data = (uint32_t)atten & 0x007F; data = __RBIT(data); data >>= 16; spi_write(SPI0, data, SPI_ALT_CHIP_SEL, 0); /* Wait transfer done. */ while((spi_read_status(SPI0) & SPI_SR_RDRF) == 0); spi_read(SPI0, &dummy, &dummy2); ioport_set_pin_level(RF_ATTEN_SLOAD_GPIO, IOPORT_PIN_LEVEL_HIGH); for(int i=0;i<30;i++); ioport_set_pin_level(RF_ATTEN_SLOAD_GPIO, IOPORT_PIN_LEVEL_LOW); }
void SPI0_Handler(void) { uint16_t us_data; uint32_t us_tx_data; uint8_t p_pcs; uint32_t status = spi_read_status(_spi_base); if (status & SPI_SR_RDRF) { if ( spi_read( _spi_base, &us_data, &p_pcs ) == SPI_OK ) { // store received byte fifo_push_uint8(_this->_spi_rx_fifo_desc, us_data); // If handler defined - call it with instance and received byte. if (_this->_call_back) { _this->_call_back(_this, (uint8_t)us_data); } } } if (status & SPI_SR_TDRE) { // more bytes to send? if ( fifo_pull_uint32(_this->_spi_tx_fifo_desc, &us_tx_data) == FIFO_OK ) { _spi_base->SPI_TDR = us_tx_data; } else { // No // Disable SPI TX interrupt spi_disable_interrupt(_spi_base, SPI_IDR_TDRE); _spi_active = 0; } } }
/******************************************************************************* * DISABLE WRITE EEPROM LATCH *******************************************************************************/ void _EEPROM_wrdi(){ unsigned short r_data = 0; unsigned char r_pcs; spi_write(SPI, WRDI, spi_get_pcs(3), 1); while((spi_read_status(SPI) & SPI_SR_RDRF) == 0); spi_read(SPI, (uint16_t*) &r_data, (uint8_t*) &r_pcs); }
/** * \brief Interrupt handler for the SPI slave. */ void SPI_Handler(void) { uint32_t new_cmd = 0; static uint16_t data; uint8_t uc_pcs; if (spi_read_status(SPI_SLAVE_BASE) & SPI_SR_RDRF) { spi_read(SPI_SLAVE_BASE, &data, &uc_pcs); gs_puc_transfer_buffer[gs_ul_transfer_index] = data; gs_ul_transfer_index++; gs_ul_transfer_length--; if (gs_ul_transfer_length) { spi_write(SPI_SLAVE_BASE, gs_puc_transfer_buffer[gs_ul_transfer_index], 0, 0); } if (!gs_ul_transfer_length) { spi_slave_command_process(); new_cmd = 1; } if (new_cmd) { if (gs_ul_spi_cmd != CMD_END) { gs_spi_status.ul_cmd_list[gs_spi_status.ul_total_command_number] = gs_ul_spi_cmd; gs_spi_status.ul_total_command_number++; } spi_slave_new_command(); } } }
/******************************************************************************* * DEEP POWER DOWN MODE *******************************************************************************/ void EEPROM_powerDownMode(){ unsigned short r_data = 0; unsigned char r_pcs; spi_write(SPI, DPD, spi_get_pcs(3), 1); while((spi_read_status(SPI) & SPI_SR_RDRF) == 0); spi_read(SPI, (uint16_t*) &r_data, (uint8_t*) &r_pcs); }
static void spi_clear_ovres( void ) { volatile uint32_t rc; rc = KSZ8851SNL_SPI->SPI_RDR; spi_read_status( KSZ8851SNL_SPI ); }
platform_result_t sam4s_spi_transfer_internal( const platform_spi_t* spi, const uint8_t* data_out, uint8_t* data_in, uint32_t data_length ) { Pdc* spi_pdc = spi_get_pdc_base( spi->peripheral ); pdc_packet_t pdc_spi_packet; pdc_spi_packet.ul_addr = (uint32_t)data_in; pdc_spi_packet.ul_size = (uint32_t)data_length; pdc_rx_init( spi_pdc, &pdc_spi_packet, NULL ); pdc_spi_packet.ul_addr = (uint32_t)data_out; pdc_spi_packet.ul_size = (uint32_t)data_length; pdc_tx_init( spi_pdc, &pdc_spi_packet, NULL ); /* Enable the RX and TX PDC transfer requests */ pdc_enable_transfer( spi_pdc, PERIPH_PTCR_RXTEN | PERIPH_PTCR_TXTEN ); /* Waiting transfer done*/ while ( ( spi_read_status( spi->peripheral ) & SPI_SR_RXBUFF ) == 0 ) { } /* Disable the RX and TX PDC transfer requests */ pdc_disable_transfer(spi_pdc, PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS); return PLATFORM_SUCCESS; }
/******************************************************************************* * The Chip Erase function will erase all bits (0xFF) in the array. * * While the device is executing the chipErase() function, the WriteInProcess() * macro can be read to determine when the Chip Erase function is complete. * *******************************************************************************/ void EEPROM_chipErase(){ unsigned short r_data = 0; unsigned char r_pcs; _EEPROM_wren(); spi_write(SPI, CE, spi_get_pcs(3), 1); while((spi_read_status(SPI) & SPI_SR_RDRF) == 0); spi_read(SPI, (uint16_t*) &r_data, (uint8_t*) &r_pcs); }
/** * \brief Perform SPI master transfer. * * \param pbuf Pointer to buffer to transfer. * \param size Size of the buffer. */ void spi_master_transfer(void *p_buf, uint32_t size, uint8_t chip_sel) { uint32_t i = 0; uint8_t pcs; pcs = spi_get_pcs(chip_sel); uint16_t data; uint8_t timeout = 84; // ~1us timeout for getting the read status back. uint16_t *p_buffer; p_buffer = p_buf; if(size == 1) // Only transfer a single message. { spi_write(SPI_MASTER_BASE, p_buffer[i], pcs, 1); // The last parameter above tells SPI whether this is the last byte to be transferred. /* Wait transfer done. */ while ((spi_read_status(SPI_MASTER_BASE) & SPI_SR_RDRF) == 0); spi_read(SPI_MASTER_BASE, &data, &pcs); p_buffer[i] = data; return; } // Keep CS low for the duration of the transfer, set high @ end. for (i = 0; i < (size - 1); i++) { spi_write(SPI_MASTER_BASE, p_buffer[i], pcs, 0); /* Wait transfer done. */ while ((spi_read_status(SPI_MASTER_BASE) & SPI_SR_RDRF) == 0); spi_read(SPI_MASTER_BASE, &data, &pcs); p_buffer[i] = data; delay_us(100); } delay_us(100); spi_write(SPI_MASTER_BASE, p_buffer[(size - 1)], pcs, 1); /* Wait transfer done. */ while ((spi_read_status(SPI_MASTER_BASE) & SPI_SR_RDRF) == 0); spi_read(SPI_MASTER_BASE, &data, &pcs); p_buffer[(size - 1)] = data; return; }
/******************************************************************************* * READ DATA FROM EEPROM * ***** ARGUMENTS ***** * /param reasAdd: EEEPROM address from where it is wanted to start reading * /param data: Pointer of a byte vector variable in which data read is going to be stored * /param dataSize: Size of the vector variable pointed by "data" pointer * * ***** FUNCTIONALITY ***** * readData() reads a frame of 0-137071 data, the start address is specified in "readAdd" argument, * then the function will query as many data as specified by sizeData from EEPROM and will store it * in variable pointed by "data" pointer argument. * * IMPORTANT: there's not knowledge about the limit of data it's allowed to be read in a frame *******************************************************************************/ void EEPROM_readData(uint8_t *readAdd, uint8_t *data, uint32_t dataSize){ unsigned short r_data = 0; unsigned char r_pcs; spi_write(SPI, READ, spi_get_pcs(3), 0); while((spi_read_status(SPI) & SPI_SR_RDRF) == 0); spi_read(SPI, (uint16_t*) &r_data, (uint8_t*) &r_pcs); /**************** SENDING ADDRESS ************************/ spi_write(SPI, readAdd[2], spi_get_pcs(3), 0); // Address MSB while((spi_read_status(SPI) & SPI_SR_RDRF) == 0); spi_read(SPI, (uint16_t*) &r_data, (uint8_t*) &r_pcs); spi_write(SPI, readAdd[1], spi_get_pcs(3), 0); while((spi_read_status(SPI) & SPI_SR_RDRF) == 0); spi_read(SPI, (uint16_t*) &r_data, (uint8_t*) &r_pcs); spi_write(SPI, readAdd[0], spi_get_pcs(3), 0); while((spi_read_status(SPI) & SPI_SR_RDRF) == 0); spi_read(SPI, (uint16_t*) &r_data, (uint8_t*) &r_pcs); /**************** RECEIVING DATA ************************/ for(int i = 0; i<dataSize-1; i++){ spi_write(SPI, 0xAA, spi_get_pcs(3), 0); while((spi_read_status(SPI) & SPI_SR_RDRF) == 0); spi_read(SPI, (uint16_t*) data, (uint8_t*) &r_pcs); // It receive data in "data" and it's a pointer data++; } spi_write(SPI, 0x55, spi_get_pcs(3), 1); // The las byte must toggle CS while((spi_read_status(SPI) & SPI_SR_RDRF) == 0); spi_read(SPI, (uint16_t*) data, (uint8_t*) &r_pcs); }
/** * \brief Interrupt handler for the SPI slave. */ void SPI_Handler(void) { uint32_t status; status = spi_read_status(SPI_SLAVE_BASE) ; if(status & SPI_SR_NSSR) { if ( status & SPI_SR_RXBUFF ) { spi_slave_transfer(gs_uc_spi_s_tbuffer, COMM_BUFFER_SIZE, gs_uc_spi_s_rbuffer, COMM_BUFFER_SIZE); } } }
/******************************************************************************* * ERRASE A WHOLE SECTOR OF DATA FROM EPPROM * \param pageAdd: you can write any of the 65535 address into this function and it will erase the whole sector *******************************************************************************/ void EEPROM_sectorErase(uint8_t *sectorAdd){ unsigned short r_data = 0; unsigned char r_pcs; //Command spi_write(SPI, SE, spi_get_pcs(3), 0); while((spi_read_status(SPI) & SPI_SR_RDRF) == 0); spi_read(SPI, (uint16_t*) &r_data, (uint8_t*) &r_pcs); //address spi_write(SPI, sectorAdd[2], spi_get_pcs(3), 0); while((spi_read_status(SPI) & SPI_SR_RDRF) == 0); spi_read(SPI, (uint16_t*) &r_data, (uint8_t*) &r_pcs); spi_write(SPI, sectorAdd[1], spi_get_pcs(3), 0); while((spi_read_status(SPI) & SPI_SR_RDRF) == 0); spi_read(SPI, (uint16_t*) &r_data, (uint8_t*) &r_pcs); spi_write(SPI, sectorAdd[0], spi_get_pcs(3), 1); while((spi_read_status(SPI) & SPI_SR_RDRF) == 0); spi_read(SPI, (uint16_t*) &r_data, (uint8_t*) &r_pcs); }
/** * \brief Test SPI interrupt handler. */ void CONF_TEST_SPI_HANDLER(void) { uint32_t status = spi_read_status(CONF_TEST_SPI); if (status & SPI_SR_TDRE) { g_b_spi_interrupt_tx_ready = true; spi_disable_interrupt(CONF_TEST_SPI, SPI_IDR_TDRE); } if (status & SPI_SR_RDRF) { g_b_spi_interrupt_rx_ready = true; spi_disable_interrupt(CONF_TEST_SPI, SPI_IDR_RDRF); } }
/** * SPI interrupt service routine */ void AJ_WSL_SPI_ISR(void) { uint32_t status = spi_read_status(AJ_WSL_SPI_DEVICE); if (status & SPI_SR_TDRE) { //g_b_spi_interrupt_tx_ready = true; spi_disable_interrupt(AJ_WSL_SPI_DEVICE, SPI_IDR_TDRE); } if (status & SPI_SR_RDRF) { //g_b_spi_interrupt_rx_ready = true; spi_disable_interrupt(AJ_WSL_SPI_DEVICE, SPI_IDR_RDRF); } }
/* * Write to the SPI stacking interface * */ void stack_write(uint8_t value) { uint8_t uc_pcs; static uint16_t data; for (int i = 0; i < 16; i++) { spi_write(SPI_MASTER_BASE, value + i, 0, 0); /* Wait transfer done. */ while ((spi_read_status(SPI_MASTER_BASE) & SPI_SR_RDRF) == 0); spi_read(SPI_MASTER_BASE, &data, &uc_pcs); printf("%d , %d\r", data, ioport_get_pin_level(SPI_IRQ1)); } return; }
void setup_delay(uint16_t channel, uint16_t PD1, uint16_t PD0) { volatile uint32_t data; __attribute__((unused)) uint16_t dummy; __attribute__((unused)) uint8_t dummy2; // Clear receive buffer //while((spi_read_status(SPI0) & SPI_SR_RDRF) == 0); spi_read(SPI0, &dummy, &dummy2); data = PD1 << 2; data |= 0x03; data = __RBIT(data); data >>= (32-11); spi_write(SPI0, data, SPI_CHIP_SEL, 0); /* Wait transfer done. */ while((spi_read_status(SPI0) & SPI_SR_RDRF) == 0); spi_read(SPI0, &dummy, &dummy2); ioport_set_pin_level(channel, IOPORT_PIN_LEVEL_HIGH); for(int i=0;i<30;i++); ioport_set_pin_level(channel, IOPORT_PIN_LEVEL_LOW); data = PD0 << 2; data |= 0x02; data = __RBIT(data); data >>= (32-11); spi_write(SPI0, data, SPI_CHIP_SEL, 0); /* Wait transfer done. */ while((spi_read_status(SPI0) & SPI_SR_RDRF) == 0); spi_read(SPI0, &dummy, &dummy2); ioport_set_pin_level(channel, IOPORT_PIN_LEVEL_HIGH); for(int i=0;i<30;i++); ioport_set_pin_level(channel, IOPORT_PIN_LEVEL_LOW); }
/******************************************************************************* * WRITE DATA FROM EEPROM * ***** ARGUMENTS ***** * /param reasAdd: EEEPROM address where it is wanted to start writing * /param data: Pointer of a byte vector variable in where data to be sent is * /param dataSize: Size of the vector variable pointed by "data" pointer * * ***** FUNCTIONALITY ***** * writeData() writes a frame of 0-137071 data, the start address is specified in "readAdd" argument, * then the function will store as many data as specified by sizeData in EEPROM and will store it * in the variable pointed by "data" pointer argument. * * IMPORTANT: there's not knowledge about the limit of data it's allowed to be read in a frame *******************************************************************************/ void EEPROM_writeData(uint8_t *writeAdd, uint8_t *data, uint8_t dataSize){ unsigned short r_data = 0; unsigned char r_pcs; _EEPROM_wren(); spi_write(SPI, WRITE, spi_get_pcs(3), 0); while((spi_read_status(SPI) & SPI_SR_RDRF) == 0); spi_read(SPI, (uint16_t*) &r_data, (uint8_t*) &r_pcs); /**************** SENDING ADDRESS ************************/ spi_write(SPI, writeAdd[2], spi_get_pcs(3), 0); while((spi_read_status(SPI) & SPI_SR_RDRF) == 0); spi_read(SPI, (uint16_t*) &r_data, (uint8_t*) &r_pcs); spi_write(SPI, writeAdd[1], spi_get_pcs(3), 0); while((spi_read_status(SPI) & SPI_SR_RDRF) == 0); spi_read(SPI, (uint16_t*) &r_data, (uint8_t*) &r_pcs); spi_write(SPI, writeAdd[0], spi_get_pcs(3), 0); while((spi_read_status(SPI) & SPI_SR_RDRF) == 0); spi_read(SPI, (uint16_t*) &r_data, (uint8_t*) &r_pcs); /**************** SENDING DATA ************************/ for(int i = 0; i<dataSize-1; i++){ spi_write(SPI, *data, spi_get_pcs(3), 0); // It receive data in "data" and it's a pointer while((spi_read_status(SPI) & SPI_SR_RDRF) == 0); spi_read(SPI, (uint16_t*) r_data, (uint8_t*) &r_pcs); data++; } spi_write(SPI, *data, spi_get_pcs(3), 1); // The las byte must toggle CS spi_read(SPI, (uint16_t*) r_data, (uint8_t*) &r_pcs); while( EEPROM_getWriteInProcess() ); // Deberíamos hacer esto aquí pa evitarle el complique al usuario }
/** * \brief Interrupt handler for the SPI slave. */ void SPI_Handler(void) { static uint16_t data; uint8_t uc_pcs; uint32_t* reg_ptr = 0x4000800C; // SPI_TDR (SPI0) if (spi_read_status(SPI_SLAVE_BASE) & SPI_SR_RDRF) { spi_read(SPI_SLAVE_BASE, &data, &uc_pcs); // SPI message is put into the 16-bit data variable. //gs_ul_transfer_index++; //gs_ul_transfer_length--; *reg_ptr |= 0x00BB; // transfer 0xFF back to the SSM. } }
/*int wmt_sf_suspend(struct device *dev, pm_message_t state)*/ int wmt_sf_suspend(struct platform_device *pdev, pm_message_t state) { unsigned int boot_value = GPIO_STRAP_STATUS_VAL; int rc = 0; /*Judge whether boot from SF in order to implement power self management*/ if ((boot_value & 0x6) == SPI_FLASH_TYPE) { REG32_VAL(PMCEU_ADDR) |= SF_CLOCK_EN; rc = spi_read_status(0); if (rc) printk("sfread: sf0 is busy"); } printk(KERN_INFO "wmt_sf_suspend\n"); return 0; }
/** * \brief Read a register value. * * \param reg the register address to modify. * * \return the register value. */ uint16_t ksz8851_reg_read(uint16_t reg) { pdc_packet_t g_pdc_spi_tx_packet; pdc_packet_t g_pdc_spi_rx_packet; uint16_t cmd = 0; uint16_t res = 0; gpio_set_pin_low(KSZ8851SNL_CSN_GPIO); /* Move register address to cmd bits 9-2, make 32-bit address. */ cmd = (reg << 2) & REG_ADDR_MASK; /* Last 2 bits still under "don't care bits" handled with byte enable. */ /* Select byte enable for command. */ if (reg & 2) { /* Odd word address writes bytes 2 and 3 */ cmd |= (0xc << 10); } else { /* Even word address write bytes 0 and 1 */ cmd |= (0x3 << 10); } /* Add command read code. */ cmd |= CMD_READ; tmpbuf[0] = cmd >> 8; tmpbuf[1] = cmd & 0xff; tmpbuf[2] = CONFIG_SPI_MASTER_DUMMY; tmpbuf[3] = CONFIG_SPI_MASTER_DUMMY; /* Prepare PDC transfer. */ g_pdc_spi_tx_packet.ul_addr = (uint32_t) tmpbuf; g_pdc_spi_tx_packet.ul_size = 4; g_pdc_spi_rx_packet.ul_addr = (uint32_t) tmpbuf; g_pdc_spi_rx_packet.ul_size = 4; pdc_disable_transfer(g_p_spi_pdc, PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS); pdc_tx_init(g_p_spi_pdc, &g_pdc_spi_tx_packet, 0); pdc_rx_init(g_p_spi_pdc, &g_pdc_spi_rx_packet, 0); pdc_enable_transfer(g_p_spi_pdc, PERIPH_PTCR_RXTEN | PERIPH_PTCR_TXTEN); while (!(spi_read_status(KSZ8851SNL_SPI) & SPI_SR_ENDRX)) ; gpio_set_pin_high(KSZ8851SNL_CSN_GPIO); res = (tmpbuf[3] << 8) | tmpbuf[2]; return res; }
/** * \brief Write dummy data to the internal fifo buffer. * * \param len the amount of dummy data to write. */ void ksz8851_fifo_dummy(uint32_t len) { pdc_packet_t g_pdc_spi_tx_packet; pdc_packet_t g_pdc_spi_rx_packet; /* Prepare PDC transfer. */ g_pdc_spi_tx_packet.ul_addr = (uint32_t) tmpbuf; g_pdc_spi_tx_packet.ul_size = len; g_pdc_spi_rx_packet.ul_addr = (uint32_t) tmpbuf; g_pdc_spi_rx_packet.ul_size = len; pdc_disable_transfer(g_p_spi_pdc, PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS); pdc_tx_init(g_p_spi_pdc, &g_pdc_spi_tx_packet, 0); pdc_rx_init(g_p_spi_pdc, &g_pdc_spi_rx_packet, 0); pdc_enable_transfer(g_p_spi_pdc, PERIPH_PTCR_RXTEN | PERIPH_PTCR_TXTEN); while (!(spi_read_status(KSZ8851SNL_SPI) & SPI_SR_ENDRX)) ; }
/** * \brief Perform SPI master transfer. * * \param pbuf Pointer to buffer to transfer. * \param size Size of the buffer. */ static void spi_master_transfer(void *p_buf, uint32_t size) { uint32_t i; uint8_t uc_pcs; static uint16_t data; uint8_t *p_buffer; p_buffer = p_buf; for (i = 0; i < size; i++) { spi_write(SPI_MASTER_BASE, p_buffer[i], 0, 0); /* Wait transfer done. */ while ((spi_read_status(SPI_MASTER_BASE) & SPI_SR_RDRF) == 0); spi_read(SPI_MASTER_BASE, &data, &uc_pcs); p_buffer[i] = data; } }
void spi_master_read(void *p_buf, uint32_t size, uint32_t chip_sel) { uint32_t i; uint8_t pcs; pcs = spi_get_pcs(chip_sel); uint16_t data; uint16_t *p_buffer; p_buffer = p_buf; for (i = 0; i < size; i++) { spi_write(SPI_MASTER_BASE, 0, pcs, 0); /* Wait transfer done. */ while ((spi_read_status(SPI_MASTER_BASE) & SPI_SR_RDRF) == 0); spi_read(SPI_MASTER_BASE, &data, &pcs); p_buffer[i] = (uint8_t)data; } }