#include #if USE_SPI static struct sdcard_dev _sdcard_device; static struct spi_dev *const _spi_device = (struct spi_dev*) IOC_PADDR_BASE; #endif #define SDCARD_RESET_ITER_MAX 4 /////////////////////////////////// inline void reset_sleep(int cycles) { int i; for (i = 0; i < cycles; i++); } #if USE_SPI /////////////////////////////////////////////////////////////////////////////// // reset_ioc_init // This function initializes the SDCARD / required for FPGA. /////////////////////////////////////////////////////////////////////////////// int reset_ioc_init() { unsigned char sdcard_rsp; reset_puts("Initializing block device\n\r"); /** * Initializing the SPI controller */ spi_dev_config ( _spi_device , 200000 , /**< SPI_clk: 200 Khz */ SYSCLK_FREQ , /**< Sys_clk */ 8 , /**< Charlen: 8 */ SPI_TX_NEGEDGE, SPI_RX_POSEDGE ); /** * Initializing the SD Card */ unsigned int iter = 0; while(1) { reset_puts("Trying to initialize SD card... "); sdcard_rsp = sdcard_dev_open(&_sdcard_device, _spi_device, 0); if (sdcard_rsp == 0) { reset_puts("OK\n"); break; } reset_puts("KO\n"); reset_sleep(1000); if (++iter >= SDCARD_RESET_ITER_MAX) { reset_puts("\nERROR: During SD card reset to IDLE state\n" "/ card response = "); reset_putx(sdcard_rsp); reset_puts("\n"); reset_exit(); } } /** * Set the block length of the SD Card */ sdcard_rsp = sdcard_dev_set_blocklen(&_sdcard_device, 512); if (sdcard_rsp) { reset_puts("ERROR: During SD card blocklen initialization\n"); reset_exit(); } /** * Incrementing SDCARD clock frequency for normal function */ spi_dev_config ( _spi_device , 10000000 , /**< SPI_clk 10 Mhz */ SYSCLK_FREQ , /**< Sys_clk */ -1 , /**< Charlen: 8 */ -1 , -1 ); reset_puts("Finish block device initialization\n\r"); return 0; } // end reset_ioc_init() #endif ////////////////////////////////////////////////////////////////////////////// // reset_bdv_read() ///////////////////////////////////////////////////////////////////////////// #if USE_BDV int reset_bdv_read( unsigned int lba, void* buffer, unsigned int count ) { unsigned int * ioc_address = (unsigned int*)IOC_PADDR_BASE; // block_device configuration iowrite32( &ioc_address[BLOCK_DEVICE_BUFFER], (unsigned int) buffer ); iowrite32( &ioc_address[BLOCK_DEVICE_COUNT], count ); iowrite32( &ioc_address[BLOCK_DEVICE_LBA], lba ); iowrite32( &ioc_address[BLOCK_DEVICE_IRQ_ENABLE], 0 ); // block_device trigger transfer iowrite32( &ioc_address[BLOCK_DEVICE_OP], ( unsigned int ) BLOCK_DEVICE_READ ); unsigned int status = 0; while ( 1 ) { status = ioread32(&ioc_address[BLOCK_DEVICE_STATUS]); if ( status == BLOCK_DEVICE_READ_SUCCESS ) { break; } if ( status == BLOCK_DEVICE_READ_ERROR ) { reset_puts("ERROR during read on the BLK device\n"); return 1; } } #if (CACHE_COHERENCE == 0) || USE_IOB reset_buf_invalidate(buffer, CACHE_LINE_SIZE, count * 512); #endif return 0; } #endif ////////////////////////////////////////////////////////////////////////////// // reset_spi_read() ///////////////////////////////////////////////////////////////////////////// #if USE_SPI static int reset_spi_read( unsigned int lba, void* buffer, unsigned int count ) { unsigned int sdcard_rsp; unsigned int i; sdcard_dev_lseek(&_sdcard_device, lba); for(i = 0; i < count; i++) { unsigned char* buf = (unsigned char *) buffer + (512 * i); if (( sdcard_rsp = sdcard_dev_read ( &_sdcard_device, buf, 512 ) )) { reset_puts("ERROR during read on the SDCARD device. Code: "); reset_putx(sdcard_rsp); reset_puts("\n"); return 1; } } return 0; } #endif ////////////////////////////////////////////////////////////////////////////// // reset_rdk_read() ///////////////////////////////////////////////////////////////////////////// #if USE_RDK static int reset_rdk_read( unsigned int lba, void* buffer, unsigned int count ) { unsigned int* rdk_address = (unsigned int*) RDK_PADDR_BASE; char* src = (char*) rdk_address + (lba * 512); memcpy(buffer, (void*) src, count * 512); return 0; } #endif /////////////////////////////////////////////////////////////////////////////// // reset_ioc_read() // Transfer data from disk to a memory buffer // - param lba : first block index on the disk // - param buffer : base address of the memory buffer // - param count : number of blocks to be transfered // This is a blocking function. The function returns once the transfer is // completed. // // The USE_BDV, USE_SPI and USE_RDK variables signal if the disk is accessed // through a BLOCK DEVICE, SPI or RAMDISK respectively /////////////////////////////////////////////////////////////////////////////// int reset_ioc_read( unsigned int lba, void* buffer, unsigned int count ) { int status; #if USE_BDV status = reset_bdv_read(lba, buffer, count); #endif #if USE_SPI status = reset_spi_read(lba, buffer, count); #endif #if USE_RDK status = reset_rdk_read(lba, buffer, count); #endif return status; } /* * vim: tabstop=4 : shiftwidth=4 : expandtab */