Improve SPI transfer..
1 files changed, 25 insertions(+), 18 deletions(-)

M platform_samd_spi.c
M platform_samd_spi.c +25 -18
@@ 159,30 159,38 @@ samd_spi_intr_exchange(CTL_SPI_BUS_t *se
     return;
   }
 
+  ctl_global_interrupts_disable();
+
   super->request.txc = tx;
   super->request.rxc = rx;
   super->request.len = len;
 
   ctl_events_set_clear(&super->events, 0, TRANSFER_DONE_EVENT|ERROR_EVENT);
 
-  dev->SPI.INTENSET.bit.TXC = 0;
+  dev->SPI.INTENCLR.bit.TXC = 1;
   dev->SPI.INTENSET.bit.RXC = 1;
 #if !defined(_SAMD20_)
   dev->SPI.INTENSET.bit.ERROR = 1;
 #endif
 
-  if (dev->SPI.INTFLAG.bit.DRE) {
-    if (super->request.txc) {
-      dev->SPI.DATA.bit.DATA = *(super->request.txc);
-      (super->request.txc)++;
-    } else {
-      dev->SPI.DATA.bit.DATA = super->core.__protocol.idle;
+  uint32_t wait_timeout = 0;
+  const uint32_t TIMEOUT_MAX = 100'000;
+  while(!dev->SPI.INTFLAG.bit.DRE) {
+    wait_timeout++;
+    if (wait_timeout > TIMEOUT_MAX) {
+      ctl_global_interrupts_enable();
+      return;
     }
-    super->request.state = SPI_RECEIVE_STATE;
+  }
+
+  if (super->request.txc) {
+    dev->SPI.DATA.bit.DATA = *(super->request.txc);
+    (super->request.txc)++;
   } else {
-    dev->SPI.INTENSET.bit.DRE = 1;
-    super->request.state = SPI_SEND_STATE;
+    dev->SPI.DATA.bit.DATA = super->core.__protocol.idle;
   }
+  super->request.state = SPI_RECEIVE_STATE;
+  ctl_global_interrupts_enable();
 
   wait_status = ctl_events_wait(CTL_EVENT_WAIT_ANY_EVENTS_WITH_AUTO_CLEAR,
     &super->events, TRANSFER_DONE_EVENT|ERROR_EVENT,

          
@@ 432,6 440,7 @@ static void spi_interrupt_handler(uint8_
     if (self->request.len == 0) {
       ctl_events_set_clear(&self->events, ERROR_EVENT, 0);
       dev->SPI.INTENCLR.bit.DRE = 1;
+      dev->SPI.INTENCLR.bit.RXC = 1;
       self->request.state = TRANSFER_DONE_STATE;
     } else {
       self->request.len--;

          
@@ 441,18 450,16 @@ static void spi_interrupt_handler(uint8_
         dev->SPI.INTENCLR.bit.DRE = 1;
         ctl_events_set_clear(&self->events, TRANSFER_DONE_EVENT, 0);
       } else {
-
-        dev->SPI.INTENSET.bit.DRE = 1;
-        if (!write_done)
+        if (!write_done && (int_flag & DRE_BIT))
         {
-          if (int_flag & DRE_BIT)
-          {
-            dev->SPI.DATA.bit.DATA = self->request.txc ? *self->request.txc++ : self->core.__protocol.idle;
-            self->request.state = SPI_RECEIVE_STATE;
-          }
+          dev->SPI.INTENCLR.reg = DRE_BIT;
+          dev->SPI.INTENSET.reg = RXC_BIT;
+          dev->SPI.DATA.bit.DATA = self->request.txc ? *self->request.txc++ : self->core.__protocol.idle;
+          self->request.state = SPI_RECEIVE_STATE;
         }
         else
         {
+          dev->SPI.INTENSET.bit.DRE = 1;
           self->request.state = SPI_SEND_STATE;
         }
       }