From 018b18995155eb99f442181d1120fe8d1c9415eb Mon Sep 17 00:00:00 2001 From: sorgelig Date: Sun, 17 May 2020 19:51:49 +0800 Subject: [PATCH] Optimization and cleanup in HPS-FPGA communication. --- fpga_io.cpp | 88 ++++++++++++--- fpga_io.h | 10 +- main.cpp | 1 - spi.cpp | 168 +++++++++-------------------- spi.h | 38 ++++--- support/minimig/minimig_boot.cpp | 2 +- support/minimig/minimig_config.cpp | 8 +- support/st/st_tos.cpp | 2 +- support/x86/x86.cpp | 16 +-- user_io.cpp | 69 +++++------- 10 files changed, 184 insertions(+), 218 deletions(-) diff --git a/fpga_io.cpp b/fpga_io.cpp index 8e56282..d74a7f2 100644 --- a/fpga_io.cpp +++ b/fpga_io.cpp @@ -533,33 +533,19 @@ int fpga_load_rbf(const char *name, const char *cfg, const char *xml) return ret; } -int fpga_io_init() -{ - if ((fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1) return -1; - - map_base = (uint32_t*)mmap(0, FPGA_REG_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, FPGA_REG_BASE); - if (map_base == (void *)-1) - { - printf("Unable to mmap(/dev/mem)\n"); - close(fd); - return -1; - } - return 0; -} - static uint32_t gpo_copy = 0; -void fpga_gpo_write(uint32_t value) +void inline fpga_gpo_write(uint32_t value) { gpo_copy = value; writel(value, (void*)(SOCFPGA_MGR_ADDRESS + 0x10)); } -uint32_t fpga_gpo_read() +uint32_t inline fpga_gpo_read() { return gpo_copy; //readl((void*)(SOCFPGA_MGR_ADDRESS + 0x10)); } -int fpga_gpi_read() +int inline fpga_gpi_read() { return readl((void*)(SOCFPGA_MGR_ADDRESS + 0x14)); } @@ -575,6 +561,22 @@ uint32_t fpga_core_read(uint32_t offset) return 0; } +int fpga_io_init() +{ + if ((fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1) return -1; + + map_base = (uint32_t*)mmap(0, FPGA_REG_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, FPGA_REG_BASE); + if (map_base == (void *)-1) + { + printf("Unable to mmap(/dev/mem)\n"); + close(fd); + return -1; + } + + fpga_gpo_write(0); + return 0; +} + int fpga_core_id() { uint32_t gpo = (fpga_gpo_read() & 0x7FFFFFFF); @@ -672,3 +674,55 @@ int is_fpga_ready(int quick) return fpgamgr_test_fpga_ready(); } + +#define SSPI_STROBE (1<<17) +#define SSPI_ACK SSPI_STROBE + +void fpga_spi_en(uint32_t mask, uint32_t en) +{ + uint32_t gpo = fpga_gpo_read() | 0x80000000; + fpga_gpo_write(en ? gpo | mask : gpo & ~mask); +} + +uint16_t fpga_spi(uint16_t word) +{ + uint32_t gpo = (fpga_gpo_read() & ~(0xFFFF | SSPI_STROBE)) | word; + + fpga_gpo_write(gpo); + fpga_gpo_write(gpo | SSPI_STROBE); + + int gpi; + do + { + gpi = fpga_gpi_read(); + if (gpi < 0) + { + printf("GPI[31]==1. FPGA is uninitialized?\n"); + return 0; + } + } while (!(gpi & SSPI_ACK)); + + fpga_gpo_write(gpo); + + do + { + gpi = fpga_gpi_read(); + if (gpi < 0) + { + printf("GPI[31]==1. FPGA is uninitialized?\n"); + return 0; + } + } while (gpi & SSPI_ACK); + + return (uint16_t)gpi; +} + +uint16_t fpga_spi_fast(uint16_t word) +{ + uint32_t gpo = (fpga_gpo_read() & ~(0xFFFF | SSPI_STROBE)) | word; + + fpga_gpo_write(gpo); + fpga_gpo_write(gpo | SSPI_STROBE); + fpga_gpo_write(gpo); + return (uint16_t)fpga_gpi_read(); +} diff --git a/fpga_io.h b/fpga_io.h index 17861df..dbd1b30 100644 --- a/fpga_io.h +++ b/fpga_io.h @@ -9,9 +9,9 @@ int fpga_io_init(); -void fpga_gpo_write(uint32_t value); -uint32_t fpga_gpo_read(); -int fpga_gpi_read(); +void fpga_spi_en(uint32_t mask, uint32_t en); +uint16_t fpga_spi(uint16_t word); +uint16_t fpga_spi_fast(uint16_t word); void fpga_set_led(uint32_t on); int fpga_get_buttons(); @@ -26,10 +26,10 @@ int is_fpga_ready(int quick); int fpga_get_fio_size(); int fpga_get_io_version(); -int fpga_load_rbf(const char *name, const char *cfg = NULL, const char *xml=NULL); +int fpga_load_rbf(const char *name, const char *cfg = 0, const char *xml = 0); void reboot(int cold); -void app_restart(const char *path, const char *xml=NULL); +void app_restart(const char *path, const char *xml = 0); char *getappname(); #endif diff --git a/main.cpp b/main.cpp index 0927b4a..68cc7fb 100644 --- a/main.cpp +++ b/main.cpp @@ -46,7 +46,6 @@ int main(int argc, char *argv[]) sched_setaffinity(0, sizeof(set), &set); fpga_io_init(); - fpga_gpo_write(0); DISKLED_OFF; diff --git a/spi.cpp b/spi.cpp index 59b1bfa..d859146 100644 --- a/spi.cpp +++ b/spi.cpp @@ -2,73 +2,20 @@ #include "hardware.h" #include "fpga_io.h" -#define SSPI_STROBE (1<<17) -#define SSPI_ACK SSPI_STROBE - #define SSPI_FPGA_EN (1<<18) #define SSPI_OSD_EN (1<<19) #define SSPI_IO_EN (1<<20) #define SWAPW(a) ((((a)<<8)&0xff00)|(((a)>>8)&0x00ff)) -static void spi_en(uint32_t mask, uint32_t en) -{ - uint32_t gpo = fpga_gpo_read() | 0x80000000; - fpga_gpo_write(en ? gpo | mask : gpo & ~mask); -} - -uint16_t spi_w(uint16_t word) -{ - uint32_t gpo = (fpga_gpo_read() & ~(0xFFFF | SSPI_STROBE)) | word; - - fpga_gpo_write(gpo); - fpga_gpo_write(gpo | SSPI_STROBE); - - int gpi; - do - { - gpi = fpga_gpi_read(); - if (gpi < 0) - { - printf("GPI[31]==1. FPGA is uninitialized?\n"); - return 0; - } - } while (!(gpi & SSPI_ACK)); - - fpga_gpo_write(gpo); - - do - { - gpi = fpga_gpi_read(); - if (gpi < 0) - { - printf("GPI[31]==1. FPGA is uninitialized?\n"); - return 0; - } - } while (gpi & SSPI_ACK); - - return (uint16_t)gpi; -} - -void spi_init(int enable) -{ - (void)enable; - printf("Init SPI.\n"); -} - -uint8_t spi_b(uint8_t parm) -{ - return (uint8_t)spi_w(parm); -} - void EnableFpga() { - spi_en(SSPI_FPGA_EN, 1); + fpga_spi_en(SSPI_FPGA_EN, 1); } void DisableFpga() { - spi_en(SSPI_FPGA_EN, 0); + fpga_spi_en(SSPI_FPGA_EN, 0); } static int osd_target = OSD_ALL; @@ -87,56 +34,25 @@ void EnableOsd() if (osd_target & OSD_HDMI) mask &= ~SSPI_FPGA_EN; if (osd_target & OSD_VGA) mask &= ~SSPI_IO_EN; - spi_en(mask, 1); + fpga_spi_en(mask, 1); } void DisableOsd() { - spi_en(SSPI_OSD_EN | SSPI_IO_EN | SSPI_FPGA_EN, 0); + fpga_spi_en(SSPI_OSD_EN | SSPI_IO_EN | SSPI_FPGA_EN, 0); } void EnableIO() { - spi_en(SSPI_IO_EN, 1); + fpga_spi_en(SSPI_IO_EN, 1); } void DisableIO() { - spi_en(SSPI_IO_EN, 0); + fpga_spi_en(SSPI_IO_EN, 0); } -uint8_t spi_in() -{ - return spi_b(0); -} - -void spi8(uint8_t parm) -{ - spi_b(parm); -} - -void spi16(uint16_t parm) -{ - spi8(parm >> 8); - spi8(parm >> 0); -} - -void spi24(uint32_t parm) -{ - spi8(parm >> 16); - spi8(parm >> 8); - spi8(parm >> 0); -} - -void spi32(uint32_t parm) -{ - spi8(parm >> 24); - spi8(parm >> 16); - spi8(parm >> 8); - spi8(parm >> 0); -} - -uint32_t spi32w(uint32_t parm) +uint32_t spi32_w(uint32_t parm) { uint32_t res; res = spi_w(parm); @@ -145,19 +61,19 @@ uint32_t spi32w(uint32_t parm) } // little endian: lsb first -void spi32le(uint32_t parm) +void spi32_b(uint32_t parm) { - spi8(parm >> 0); - spi8(parm >> 8); - spi8(parm >> 16); - spi8(parm >> 24); + spi_b(parm >> 0); + spi_b(parm >> 8); + spi_b(parm >> 16); + spi_b(parm >> 24); } /* OSD related SPI functions */ void spi_osd_cmd_cont(uint8_t cmd) { EnableOsd(); - spi8(cmd); + spi_b(cmd); } void spi_osd_cmd(uint8_t cmd) @@ -169,8 +85,8 @@ void spi_osd_cmd(uint8_t cmd) void spi_osd_cmd8_cont(uint8_t cmd, uint8_t parm) { EnableOsd(); - spi8(cmd); - spi8(parm); + spi_b(cmd); + spi_b(parm); } void spi_osd_cmd8(uint8_t cmd, uint8_t parm) @@ -179,17 +95,11 @@ void spi_osd_cmd8(uint8_t cmd, uint8_t parm) DisableOsd(); } -void spi_uio_cmd32le_cont(uint8_t cmd, uint32_t parm) +void spi_uio_cmd32_cont(uint8_t cmd, uint32_t parm) { EnableIO(); - spi8(cmd); - spi32le(parm); -} - -void spi_uio_cmd32le(uint8_t cmd, uint32_t parm) -{ - spi_uio_cmd32le_cont(cmd, parm); - DisableIO(); + spi_b(cmd); + spi32_b(parm); } /* User_io related SPI functions */ @@ -209,8 +119,8 @@ uint8_t spi_uio_cmd(uint8_t cmd) void spi_uio_cmd8_cont(uint8_t cmd, uint8_t parm) { EnableIO(); - spi8(cmd); - spi8(parm); + spi_b(cmd); + spi_b(parm); } void spi_uio_cmd8(uint8_t cmd, uint8_t parm) @@ -229,7 +139,7 @@ void spi_uio_cmd16(uint8_t cmd, uint16_t parm) void spi_uio_cmd32(uint8_t cmd, uint32_t parm, int wide) { EnableIO(); - spi8(cmd); + spi_b(cmd); if (wide) { spi_w((uint16_t)parm); @@ -237,17 +147,17 @@ void spi_uio_cmd32(uint8_t cmd, uint32_t parm, int wide) } else { - spi8(parm); - spi8(parm >> 8); - spi8(parm >> 16); - spi8(parm >> 24); + spi_b(parm); + spi_b(parm >> 8); + spi_b(parm >> 16); + spi_b(parm >> 24); } DisableIO(); } void spi_n(uint8_t value, uint16_t cnt) { - while (cnt--) spi8(value); + while (cnt--) spi_b(value); } void spi_read(uint8_t *addr, uint16_t len, int wide) @@ -276,18 +186,38 @@ void spi_write(const uint8_t *addr, uint16_t len, int wide) } else { - while (len--) spi8(*addr++); + while (len--) spi_b(*addr++); } } void spi_block_read(uint8_t *addr, int wide) { - spi_read(addr, 512, wide); + if (wide) + { + uint16_t len16 = 256; + uint16_t *a16 = (uint16_t*)addr; + while (len16--) *a16++ = fpga_spi_fast(0); + } + else + { + uint16_t len = 512; + while (len--) *addr++ = fpga_spi_fast(0); + } } void spi_block_write(const uint8_t *addr, int wide) { - spi_write(addr, 512, wide); + if (wide) + { + uint16_t len16 = 256; + uint16_t *a16 = (uint16_t*)addr; + while (len16--) fpga_spi_fast(*a16++); + } + else + { + uint16_t len = 512; + while (len--) fpga_spi_fast(*addr++); + } } void spi_block_write_16be(const uint16_t *addr) diff --git a/spi.h b/spi.h index 7a1e5ad..a12265a 100644 --- a/spi.h +++ b/spi.h @@ -2,14 +2,12 @@ #define SPI_H #include +#include "fpga_io.h" #define OSD_HDMI 1 #define OSD_VGA 2 #define OSD_ALL (OSD_VGA|OSD_HDMI) -/* main init functions */ -void spi_init(int enable); - /* chip select functions */ void EnableFpga(); void DisableFpga(); @@ -19,25 +17,32 @@ void EnableIO(); void DisableIO(); // base functions -uint8_t spi_b(uint8_t parm); -uint16_t spi_w(uint16_t word); +uint8_t inline spi_b(uint8_t parm) +{ + return (uint8_t)fpga_spi(parm); +} + +uint16_t inline spi_w(uint16_t word) +{ + return fpga_spi(word); +} // input only helper -uint8_t spi_in(); +uint8_t inline spi_in() +{ + return (uint8_t)fpga_spi(0); +} -void spi8(uint8_t parm); -void spi16(uint16_t parm); -void spi24(uint32_t parm); -void spi32(uint32_t parm); -void spi32le(uint32_t parm); -void spi_n(uint8_t value, uint16_t cnt); -uint32_t spi32w(uint32_t parm); +#define spi8(x) spi_b(x) + +void spi32_b(uint32_t parm); +uint32_t spi32_w(uint32_t parm); /* block transfer functions */ -void spi_block_read(uint8_t *addr, int wide); void spi_read(uint8_t *addr, uint16_t len, int wide); -void spi_block_write(const uint8_t *addr, int wide); void spi_write(const uint8_t *addr, uint16_t len, int wide); +void spi_block_read(uint8_t *addr, int wide); +void spi_block_write(const uint8_t *addr, int wide); void spi_block_write_16be(const uint16_t *addr); void spi_block_read_16be(uint16_t *addr); @@ -55,7 +60,6 @@ void spi_uio_cmd8(uint8_t cmd, uint8_t parm); void spi_uio_cmd8_cont(uint8_t cmd, uint8_t parm); void spi_uio_cmd16(uint8_t cmd, uint16_t parm); void spi_uio_cmd32(uint8_t cmd, uint32_t parm, int wide); -void spi_uio_cmd32le_cont(uint8_t cmd, uint32_t parm); -void spi_uio_cmd32le(uint8_t cmd, uint32_t parm); +void spi_uio_cmd32_cont(uint8_t cmd, uint32_t parm); #endif // SPI_H diff --git a/support/minimig/minimig_boot.cpp b/support/minimig/minimig_boot.cpp index 9b2254f..2c17d60 100644 --- a/support/minimig/minimig_boot.cpp +++ b/support/minimig/minimig_boot.cpp @@ -18,7 +18,7 @@ static uint8_t buffer[1024]; static void mem_upload_init(unsigned long addr) { - spi_uio_cmd32le_cont(UIO_MM2_WR, addr); + spi_uio_cmd32_cont(UIO_MM2_WR, addr); } static void mem_upload_fini() diff --git a/support/minimig/minimig_config.cpp b/support/minimig/minimig_config.cpp index c11e32d..37176ea 100644 --- a/support/minimig/minimig_config.cpp +++ b/support/minimig/minimig_config.cpp @@ -129,7 +129,7 @@ static char UploadKickstart(char *name) FileClose(&file); //clear tag (write 0 to $fc0000) to force bootrom to load Kickstart from disk //and not use one which was already there. - spi_uio_cmd32le_cont(UIO_MM2_WR, 0xfc0000); + spi_uio_cmd32_cont(UIO_MM2_WR, 0xfc0000); spi8(0x00);spi8(0x00); DisableIO(); return(1); @@ -139,7 +139,7 @@ static char UploadKickstart(char *name) BootPrint("Uploading A1000 boot ROM"); SendFileV2(&file, NULL, 0, 0xf80000, file.size >> 9); FileClose(&file); - spi_uio_cmd32le_cont(UIO_MM2_WR, 0xfc0000); + spi_uio_cmd32_cont(UIO_MM2_WR, 0xfc0000); spi8(0x00);spi8(0x00); DisableIO(); return(1); @@ -205,7 +205,7 @@ static char UploadActionReplay() SendFileV2(&file, NULL, 0, 0xa10000, (file.size + 511) >> 9); // HRTmon config adr = 0xa10000 + 20; - spi_uio_cmd32le_cont(UIO_MM2_WR, adr); + spi_uio_cmd32_cont(UIO_MM2_WR, adr); data = 0x00800000; // mon_size, 4 bytes spi8((data >> 24) & 0xff); spi8((data >> 16) & 0xff); spi8((data >> 8) & 0xff); spi8((data >> 0) & 0xff); @@ -247,7 +247,7 @@ static char UploadActionReplay() spi8((data >> 0) & 0xff); DisableIO(); adr = 0xa10000 + 68; - spi_uio_cmd32le_cont(UIO_MM2_WR, adr); + spi_uio_cmd32_cont(UIO_MM2_WR, adr); data = ((minimig_config.memory & 0x3) + 1) * 512 * 1024; // maxchip, 4 bytes TODO is this correct? spi8((data >> 24) & 0xff); spi8((data >> 16) & 0xff); spi8((data >> 8) & 0xff); spi8((data >> 0) & 0xff); diff --git a/support/st/st_tos.cpp b/support/st/st_tos.cpp index 0bdab7f..64b133e 100644 --- a/support/st/st_tos.cpp +++ b/support/st/st_tos.cpp @@ -61,7 +61,7 @@ static void set_control(uint32_t ctrl) ctrl = uart_mode ? (ctrl | TOS_CONTROL_REDIR0) : (ctrl & ~TOS_CONTROL_REDIR0); spi_uio_cmd_cont(UIO_SET_STATUS2); - spi32w(ctrl); + spi32_w(ctrl); DisableIO(); } diff --git a/support/x86/x86.cpp b/support/x86/x86.cpp index 4bc2649..9d89889 100644 --- a/support/x86/x86.cpp +++ b/support/x86/x86.cpp @@ -88,8 +88,8 @@ static void dma_set(uint32_t address, uint32_t data) { EnableIO(); spi8(UIO_DMA_WRITE); - spi32w(address); - spi32w(data); + spi32_w(address); + spi32_w(data); DisableIO(); } @@ -97,8 +97,8 @@ static void dma_sendbuf(uint32_t address, uint32_t length, uint32_t *data) { EnableIO(); spi8(UIO_DMA_WRITE); - spi32w(address); - while (length--) spi32w(*data++); + spi32_w(address); + while (length--) spi32_w(*data++); DisableIO(); } @@ -106,8 +106,8 @@ static void dma_rcvbuf(uint32_t address, uint32_t length, uint32_t *data) { EnableIO(); spi8(UIO_DMA_READ); - spi32w(address); - while (length--) *data++ = spi32w(0); + spi32_w(address); + while (length--) *data++ = spi32_w(0); DisableIO(); } @@ -123,7 +123,7 @@ static int load_bios(const char* name, uint8_t index) EnableIO(); spi8(UIO_DMA_WRITE); - spi32w( index ? 0x80C0000 : 0x80F0000 ); + spi32_w( index ? 0x80C0000 : 0x80F0000 ); while (bytes2send) { @@ -136,7 +136,7 @@ static int load_bios(const char* name, uint8_t index) chunk = (chunk + 3) >> 2; uint32_t* p = buf; - while(chunk--) spi32w(*p++); + while(chunk--) spi32_w(*p++); } DisableIO(); FileClose(&f); diff --git a/user_io.cpp b/user_io.cpp index f96da08..7d704e5 100644 --- a/user_io.cpp +++ b/user_io.cpp @@ -742,7 +742,6 @@ void user_io_init(const char *path, const char *xml) io_ver = 0; } - spi_init(core_type != CORE_TYPE_UNKNOWN); OsdSetSize(8); user_io_read_confstr(); @@ -1199,7 +1198,7 @@ int user_io_file_mount(const char *name, unsigned char index, char pre) FileClose(&sd_image[index]); } - buffer_lba[index] = ULLONG_MAX; + buffer_lba[index] = -1; if (!ret) { @@ -1235,15 +1234,13 @@ int user_io_file_mount(const char *name, unsigned char index, char pre) if (io_ver) { - spi_w((uint16_t)(size)); - spi_w((uint16_t)(size>>16)); - spi_w((uint16_t)(size>>32)); - spi_w((uint16_t)(size>>48)); + spi32_w(size); + spi32_w(size >> 32); } else { - spi32le(size); - spi32le(size>>32); + spi32_b(size); + spi32_b(size>>32); } DisableIO(); @@ -1544,8 +1541,8 @@ static void check_status_change() if ((stchg & 0xF0) == 0xA0 && last_status_change != (stchg & 0xF)) { last_status_change = (stchg & 0xF); - uint32_t st0 = spi32w(0); - uint32_t st1 = spi32w(0); + uint32_t st0 = spi32_w(0); + uint32_t st1 = spi32_w(0); DisableIO(); user_io_8bit_set_status(st0, ~UIO_STATUS_RESET, 0); user_io_8bit_set_status(st1, 0xFFFFFFFF, 1); @@ -1943,8 +1940,8 @@ uint32_t user_io_8bit_set_status(uint32_t new_status, uint32_t mask, int ex) else { spi_uio_cmd_cont(UIO_SET_STATUS2); - spi32w(status[0]); - spi32w(status[1]); + spi32_w(status[0]); + spi32_w(status[1]); DisableIO(); } } @@ -2192,7 +2189,7 @@ void user_io_poll() { if (is_st()) tos_poll(); - static uint8_t buffer[4][512]; + static uint8_t buffer[4][8192]; uint32_t lba; uint16_t req_type = 0; uint16_t c = user_io_sd_get_status(&lba, &req_type); @@ -2222,15 +2219,13 @@ void user_io_poll() { //printf("SD WR %d on %d\n", lba, disk); - int done = 0; - buffer_lba[disk] = lba; + buffer_lba[disk] = -1; // Fetch sector data from FPGA ... spi_uio_cmd_cont(UIO_SECTOR_WR); spi_block_read(buffer[disk], fio_size); DisableIO(); - if (sd_image[disk].type == 2 && !lba) { //Create the file @@ -2240,7 +2235,6 @@ void user_io_poll() if (FileWriteSec(&sd_image[disk], buffer[disk])) { sd_image[disk].size = 512; - done = 1; } } else @@ -2259,7 +2253,6 @@ void user_io_poll() { if (FileWriteSec(&sd_image[disk], buffer[disk])) { - done = 1; if (size == lba) { size++; @@ -2269,8 +2262,6 @@ void user_io_poll() } } } - - if (!done) buffer_lba[disk] = -1; } } else if (c & 0x0701) @@ -2283,15 +2274,16 @@ void user_io_poll() //printf("SD RD %d on %d, WIDE=%d\n", lba, disk, fio_size); int done = 0; + uint32_t offset; - if (buffer_lba[disk] != lba) + if ((buffer_lba[disk] == (uint64_t)-1) || lba < buffer_lba[disk] || lba >(buffer_lba[disk] + 15)) { if (sd_image[disk].size) { diskled_on(); if (FileSeekLBA(&sd_image[disk], lba)) { - if (FileReadSec(&sd_image[disk], buffer[disk])) + if (FileReadAdv(&sd_image[disk], buffer[disk], sizeof(buffer[disk]))) { done = 1; } @@ -2326,34 +2318,21 @@ void user_io_poll() memset(buffer[disk], 0, sizeof(buffer[disk])); } } + buffer_lba[disk] = lba; + offset = 0; } - - if (buffer_lba[disk] == lba) + else { - //hexdump(buffer, 32, 0); - - // data is now stored in buffer. send it to fpga - spi_uio_cmd_cont(UIO_SECTOR_RD); - spi_block_write(buffer[disk], fio_size); - DisableIO(); + offset = (lba - buffer_lba[disk])*512; } - // just load the next sector now, so it may be prefetched - // for the next request already - done = 0; - if (sd_image[disk].size) - { - diskled_on(); - if (FileSeekLBA(&sd_image[disk], lba + 1)) - { - if (FileReadSec(&sd_image[disk], buffer[disk])) - { - done = 1; - } - } - } - if (done) buffer_lba[disk] = lba + 1; + //hexdump(buffer, 32, 0); + + // data is now stored in buffer. send it to fpga + spi_uio_cmd_cont(UIO_SECTOR_RD); + spi_block_write(buffer[disk] + offset, fio_size); + DisableIO(); if (sd_image[disk].type == 2) {