diff options
Diffstat (limited to 'fw/fe310/eos/soc/spi.c')
-rw-r--r-- | fw/fe310/eos/soc/spi.c | 54 |
1 files changed, 32 insertions, 22 deletions
diff --git a/fw/fe310/eos/soc/spi.c b/fw/fe310/eos/soc/spi.c index b722c7e..351c9c8 100644 --- a/fw/fe310/eos/soc/spi.c +++ b/fw/fe310/eos/soc/spi.c @@ -57,10 +57,11 @@ int eos_spi_init(uint8_t wakeup_cause) { eos_intr_set_priority(INT_SPI1_BASE, IRQ_PRIORITY_SPI_XCHG); SPI1_REG(SPI_REG_SCKMODE) = SPI_MODE0; - SPI1_REG(SPI_REG_FMT) = SPI_FMT_PROTO(SPI_PROTO_S) | - SPI_FMT_ENDIAN(SPI_ENDIAN_MSB) | - SPI_FMT_DIR(SPI_DIR_RX) | - SPI_FMT_LEN(8); + SPI1_REG(SPI_REG_FMT) = \ + SPI_FMT_PROTO(SPI_PROTO_S) | + SPI_FMT_ENDIAN(SPI_ENDIAN_MSB) | + SPI_FMT_DIR(SPI_DIR_RX) | + SPI_FMT_LEN(8); /* for spi 9bit protocol */ GPIO_REG(GPIO_OUTPUT_EN) |= (1 << IOF_SPI1_SCK); @@ -69,8 +70,6 @@ int eos_spi_init(uint8_t wakeup_cause) { eos_spi_enable(); - // There is no way here to change the CS polarity. - // SPI1_REG(SPI_REG_CSDEF) = 0xFFFF; return EOS_OK; } @@ -117,7 +116,6 @@ void eos_spi_set_handler(unsigned char evt, eos_evt_handler_t handler) { if (evt && (evt <= EOS_SPI_MAX_EVT)) evt_handler[evt - 1] = handler; } -__attribute__ ((section (".itim"))) void _eos_spi_xchg_init(unsigned char *buffer, uint16_t len, uint8_t flags) { spi_state_flags &= 0xF0; spi_state_flags |= (SPI_FLAG_XCHG | flags); @@ -127,7 +125,7 @@ void _eos_spi_xchg_init(unsigned char *buffer, uint16_t len, uint8_t flags) { spi_state_idx_rx = 0; } -static void spi_xchg_finish(void) { +static void spi_wait4xchg(void) { uint8_t done = 0; while (!done) { @@ -140,7 +138,7 @@ static void spi_xchg_finish(void) { } void eos_spi_xchg(unsigned char *buffer, uint16_t len, uint8_t flags) { - if (spi_in_xchg) spi_xchg_finish(); + if (spi_in_xchg) spi_wait4xchg(); spi_in_xchg = 1; _eos_spi_xchg_init(buffer, len, flags); @@ -150,7 +148,6 @@ void eos_spi_xchg(unsigned char *buffer, uint16_t len, uint8_t flags) { SPI1_REG(SPI_REG_IE) = SPI_IP_TXWM; } -__attribute__ ((section (".itim"))) void eos_spi_handle_xchg(void) { int i; uint16_t sz_chunk = MIN(spi_state_len - spi_state_idx_tx, SPI_SIZE_CHUNK); @@ -162,15 +159,21 @@ void eos_spi_handle_xchg(void) { } spi_state_idx_tx += i; - for (i=0; i<spi_state_idx_tx - spi_state_idx_rx; i++) { - volatile uint32_t x = SPI1_REG(SPI_REG_RXFIFO); - if (x & SPI_RXFIFO_EMPTY) break; - spi_state_buf[spi_state_idx_rx+i] = x & 0xFF; + if (!(spi_state_flags & EOS_SPI_FLAG_TX)) { + for (i=0; i<spi_state_idx_tx - spi_state_idx_rx; i++) { + volatile uint32_t x = SPI1_REG(SPI_REG_RXFIFO); + if (x & SPI_RXFIFO_EMPTY) break; + spi_state_buf[spi_state_idx_rx+i] = x & 0xFF; + } + spi_state_idx_rx += i; } - spi_state_idx_rx += i; if (spi_state_idx_tx == spi_state_len) { - if ((spi_state_idx_rx == spi_state_len) || (spi_state_flags & EOS_SPI_FLAG_TX)) { + if ((spi_state_flags & EOS_SPI_FLAG_TX) || (spi_state_idx_rx == spi_state_len)) { + if ((spi_state_flags & EOS_SPI_FLAG_TX) && (SPI1_REG(SPI_REG_TXCTRL) != SPI_TXWM(1))) { + SPI1_REG(SPI_REG_TXCTRL) = SPI_TXWM(1); + return; + } spi_state_flags &= ~SPI_FLAG_XCHG; if (!(spi_state_flags & EOS_SPI_FLAG_MORE)) eos_spi_cs_clear(); SPI1_REG(SPI_REG_IE) = 0x0; @@ -182,7 +185,6 @@ void eos_spi_handle_xchg(void) { } } -__attribute__ ((section (".itim"))) void eos_spi_cs_set(void) { /* cs low */ if (SPI1_REG(SPI_REG_CSMODE) == SPI_CSMODE_OFF) { @@ -192,7 +194,6 @@ void eos_spi_cs_set(void) { } } -__attribute__ ((section (".itim"))) void eos_spi_cs_clear(void) { /* cs high */ if (SPI1_REG(SPI_REG_CSMODE) == SPI_CSMODE_OFF) { @@ -355,12 +356,21 @@ uint32_t eos_spi_xchg32(uint32_t data, uint8_t flags) { } void eos_spi_flush(void) { - volatile uint32_t x = 0; + if (spi_in_xchg) { + spi_wait4xchg(); + } else { + SPI1_REG(SPI_REG_TXCTRL) = SPI_TXWM(1); + while (!(SPI1_REG(SPI_REG_IP) & SPI_IP_TXWM)); + while (!(SPI1_REG(SPI_REG_RXFIFO) & SPI_RXFIFO_EMPTY)); + } - if (spi_in_xchg) spi_xchg_finish(); + /* + volatile uint32_t x = 0; - SPI1_REG(SPI_REG_TXCTRL) = SPI_TXWM(1); while (!x) { - if (SPI1_REG(SPI_REG_IP) & SPI_IP_TXWM) x = SPI1_REG(SPI_REG_RXFIFO) & SPI_RXFIFO_EMPTY; + if (SPI1_REG(SPI_REG_IP) & SPI_IP_TXWM) { + x = SPI1_REG(SPI_REG_RXFIFO) & SPI_RXFIFO_EMPTY; + } } + */ } |