+ for (i = 0; i < config->cmd_num; i++) {
+
+ while (METAL_SPI_REGW(METAL_SIFIVE_SPI0_TXDATA) & METAL_SPI_TXDATA_FULL)
+ ;
+
+ if (tx_buf) {
+ METAL_SPI_REGB(METAL_SIFIVE_SPI0_TXDATA) = tx_buf[i];
+ } else {
+ METAL_SPI_REGB(METAL_SIFIVE_SPI0_TXDATA) = 0;
+ }
+
+ endwait = metal_time() + METAL_SPI_RXDATA_TIMEOUT;
+
+ while ((rxdata = METAL_SPI_REGW(METAL_SIFIVE_SPI0_RXDATA)) &
+ METAL_SPI_RXDATA_EMPTY) {
+ if (metal_time() > endwait) {
+ METAL_SPI_REGW(METAL_SIFIVE_SPI0_CSMODE) &=
+ ~(METAL_SPI_CSMODE_MASK);
+
+ return 1;
+ }
+ }
+
+ if (rx_buf) {
+ rx_buf[i] = (char)(rxdata & METAL_SPI_TXRXDATA_MASK);
+ }
+ }
+
+ /* switch to Dual/Quad mode */
+ spi_mode_switch(spi, config, MULTI_WIRE_ADDR_DATA);
+
+ /* Send Addr data */
+ for (; i < (config->cmd_num + config->addr_num); i++) {
+
+ while (METAL_SPI_REGW(METAL_SIFIVE_SPI0_TXDATA) & METAL_SPI_TXDATA_FULL)
+ ;
+
+ if (tx_buf) {
+ METAL_SPI_REGB(METAL_SIFIVE_SPI0_TXDATA) = tx_buf[i];
+ } else {
+ METAL_SPI_REGB(METAL_SIFIVE_SPI0_TXDATA) = 0;
+ }
+
+ endwait = metal_time() + METAL_SPI_RXDATA_TIMEOUT;
+
+ while ((rxdata = METAL_SPI_REGW(METAL_SIFIVE_SPI0_RXDATA)) &
+ METAL_SPI_RXDATA_EMPTY) {
+ if (metal_time() > endwait) {
+ METAL_SPI_REGW(METAL_SIFIVE_SPI0_CSMODE) &=
+ ~(METAL_SPI_CSMODE_MASK);
+
+ return 1;
+ }
+ }
+
+ if (rx_buf) {
+ rx_buf[i] = (char)(rxdata & METAL_SPI_TXRXDATA_MASK);
+ }
+ }
+
+ /* Send Dummy data */
+ for (; i < (config->cmd_num + config->addr_num + config->dummy_num); i++) {
+
+ while (METAL_SPI_REGW(METAL_SIFIVE_SPI0_TXDATA) & METAL_SPI_TXDATA_FULL)
+ ;
+
+ if (tx_buf) {
+ METAL_SPI_REGB(METAL_SIFIVE_SPI0_TXDATA) = tx_buf[i];
+ } else {
+ METAL_SPI_REGB(METAL_SIFIVE_SPI0_TXDATA) = 0;
+ }
+
+ endwait = metal_time() + METAL_SPI_RXDATA_TIMEOUT;
+
+ while ((rxdata = METAL_SPI_REGW(METAL_SIFIVE_SPI0_RXDATA)) &
+ METAL_SPI_RXDATA_EMPTY) {
+ if (metal_time() > endwait) {
+ METAL_SPI_REGW(METAL_SIFIVE_SPI0_CSMODE) &=
+ ~(METAL_SPI_CSMODE_MASK);
+ return 1;
+ }
+ }
+ if (rx_buf) {
+ rx_buf[i] = (char)(rxdata & METAL_SPI_TXRXDATA_MASK);
+ }
+ }
+
+ /* switch to Dual/Quad mode */
+ spi_mode_switch(spi, config, MULTI_WIRE_DATA_ONLY);
+
+ for (; i < len; i++) {