Hi,
I forgot to mention that the signal 'TRDY' is treated as the threshold of 'tx' FIFO buffer. So we need special attentions around 'TRDY', for example,
// assign readyfordata = TRDY;
assign readyfordata = ~tx_fifo_full;
// assign write_tx_holding = data_wr_strobe & TRDY;
assign write_tx_holding = data_wr_strobe;
// if (data_wr_strobe & ~TRDY)
if (data_wr_strobe & tx_fifo_full)
// You wrote when I wasn't ready.
TOE <= 1;
etc.
And there was a bug in the driver 'altspi.c'.
# ifdef MMC_SPI_FIFO
if (hw->mode == SPI_FIFO) {
if (hw->txd_count < hw->len) {
if (spsta & ALTERA_SPI_STATUS_TRDY_MSK) {
txd_limit = ((hw->len - hw->txd_count) > MMC_SPI_FIFO_DEPTH / 2) ? hw->txd_count + MMC_SPI_FIFO_DEPTH / 2 : hw->len;
for (count = hw->txd_count; count < txd_limit; count++, hw->txd_count++)
writel(hw_txbyte(hw, count), hw->base + ALTERA_SPI_TXDATA);
} else {
count = hw->txd_count++; // <--- Here!
writel(hw_txbyte(hw, count), hw->base + ALTERA_SPI_TXDATA);
}
} else {
if (hw->count == hw->len) {
complete(&hw->done);
}
}
} else {
Kazu