summaryrefslogtreecommitdiff
path: root/fw/fe310/eos/soc/spi.c
diff options
context:
space:
mode:
Diffstat (limited to 'fw/fe310/eos/soc/spi.c')
-rw-r--r--fw/fe310/eos/soc/spi.c54
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;
+ }
}
+ */
}