]> git.karo-electronics.de Git - karo-tx-redboot.git/blobdiff - packages/devs/serial/arm/at91/v2_0/src/at91_serial.c
unified MX27, MX25, MX37 trees
[karo-tx-redboot.git] / packages / devs / serial / arm / at91 / v2_0 / src / at91_serial.c
index af9ffad54eddd7a87d91e0e78ace703adc4b9c3b..20e7a8eedb7a692f5edc9adcac87727ccd90b10b 100644 (file)
@@ -325,6 +325,13 @@ at91_serial_config_port(serial_channel *chan, cyg_serial_info_t *new_config, boo
       AT91_US_CR_RxENAB | AT91_US_CR_TxENAB | AT91_US_CR_RSTATUS | AT91_US_CR_STTTO
     );
 
+    // Enable the DMA is the control register exists
+#ifdef AT91_US_PTCR
+    HAL_WRITE_UINT32(base + AT91_US_PTCR, 
+                     AT91_US_PTCR_RXTEN |
+                     AT91_US_PTCR_TXTEN);
+#endif
+                     
     if (new_config != &chan->config) {
         chan->config = *new_config;
     }
@@ -369,7 +376,13 @@ at91_serial_lookup(struct cyg_devtab_entry **tab,
                   const char *name)
 {
     serial_channel * const chan = (serial_channel *) (*tab)->priv;
-
+    
+#ifdef AT91_PMC_PCER
+    // Enable the peripheral clock to the device
+    at91_serial_info * const at91_chan = (at91_serial_info *)chan->dev_priv;
+    HAL_WRITE_UINT32(AT91_PMC+AT91_PMC_PCER, 
+                     (1 << at91_chan->int_num));
+#endif
     (chan->callbacks->serial_init)(chan);  // Really only required for interrupt driven devices
     return ENOERR;
 }
@@ -511,7 +524,8 @@ at91_serial_ISR(cyg_vector_t vector, cyg_addrword_t data)
     at91_serial_info * const at91_chan = (at91_serial_info *) chan->dev_priv;
     const CYG_ADDRWORD base = at91_chan->base;
     CYG_WORD32 stat, mask;
-
+    cyg_uint32 retcode = 0;
+    
     HAL_READ_UINT32(base + AT91_US_CSR, stat);
     HAL_READ_UINT32(base + AT91_US_IMR, mask);
     stat &= mask;
@@ -527,14 +541,17 @@ at91_serial_ISR(cyg_vector_t vector, cyg_addrword_t data)
             (CYG_ADDRESS) at91_chan->rcv_buffer[at91_chan->curbuf]
                 + at91_chan->rcv_chunk_size + RCVBUF_EXTRA - x
         );
+        retcode = CYG_ISR_CALL_DSR;
     }
 
-    if (stat & (AT91_US_IER_TxRDY | AT91_US_IER_ENDTX))
+    if (stat & (AT91_US_IER_TxRDY | AT91_US_IER_ENDTX)) {
       HAL_WRITE_UINT32(base + AT91_US_IDR, AT91_US_IER_TxRDY | AT91_US_IER_ENDTX);
-
+      retcode = CYG_ISR_CALL_DSR;
+    }
     at91_chan->stat |= stat;
+
     cyg_drv_interrupt_acknowledge(vector);
-    return CYG_ISR_CALL_DSR;
+    return retcode;
 }
 
 // Serial I/O - high level interrupt handler (DSR)
@@ -554,10 +571,12 @@ at91_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
     if (stat & (AT91_US_IER_ENDRX | AT91_US_IER_TIMEOUT)) {
         const cyg_uint8 cb = at91_chan->curbuf, nb = cb ^ 0x01;
         const cyg_uint8 * p = at91_chan->rcv_buffer[cb], * end;
+        cyg_uint32 temp_word;
 
         at91_chan->curbuf = nb;
         HAL_WRITE_UINT32(base + AT91_US_RCR, 0);
-        HAL_READ_UINT32(base + AT91_US_RPR, (CYG_ADDRESS) end);
+        HAL_READ_UINT32(base + AT91_US_RPR, temp_word);
+        end = (const cyg_uint8 *)temp_word;
         HAL_WRITE_UINT32(base + AT91_US_RTO, RCV_TIMEOUT);
        HAL_WRITE_UINT32(base + AT91_US_CR, AT91_US_CR_RSTATUS | AT91_US_CR_STTTO);
         HAL_WRITE_UINT32(base + AT91_US_RPR, (CYG_ADDRESS) at91_chan->rcv_buffer[nb]);
@@ -592,7 +611,6 @@ at91_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
                 default:
                     // Buffer full or unknown error, can't do anything about it
                     // Discard data
-                    CYG_FAIL("Serial receiver buffer overflow");
                     p = end;
                     break;
             }