changeset 3206:1f3f5c905da8

Enhanced endianness support for devices with big and little endian, added support for MPC5xxx in addition to Kinetis
author vae
date Fri, 22 Feb 2013 19:38:45 +0000
parents b3af38677ed2
children 323cb5ba4487
files packages/hal/misc/freescale/edma/current/ChangeLog packages/hal/misc/freescale/edma/current/include/freescale_edma.h packages/hal/misc/freescale/edma/current/src/hal_freescale_edma.c
diffstat 3 files changed, 115 insertions(+), 61 deletions(-) [+]
line wrap: on
line diff
--- a/packages/hal/misc/freescale/edma/current/ChangeLog
+++ b/packages/hal/misc/freescale/edma/current/ChangeLog
@@ -1,3 +1,10 @@
+2013-02-06  Stefan Singer <stefan.singer@freescale.com> 
+		+ Ilija Kocho <ilijak@siva.com.mk>
+
+	* enhanced endianness support for devices with big and little endian
+	* added support for MPC5xxx in addition to Kinetis
+	(see Bugzilla 1001752).
+	
 2012-05-04  Ilija Kocho  <ilijak@siva.com.mk>
 
 	* cdl/hal_freescale_edma.cdl
--- a/packages/hal/misc/freescale/edma/current/include/freescale_edma.h
+++ b/packages/hal/misc/freescale/edma/current/include/freescale_edma.h
@@ -10,7 +10,7 @@
 // ####ECOSGPLCOPYRIGHTBEGIN####                                            
 // -------------------------------------------                              
 // This file is part of eCos, the Embedded Configurable Operating System.   
-// Copyright (C) 2011 Free Software Foundation, Inc.                        
+// Copyright (C) 2011, 2013 Free Software Foundation, Inc.                        
 //
 // eCos is free software; you can redistribute it and/or modify it under    
 // the terms of the GNU General Public License as published by the Free     
@@ -89,37 +89,21 @@ typedef volatile struct cyghwr_hal_frees
 //---------------------------------------------------------------------------
 // eDMA
 
-// Indices for cyghwr_hal_freescale_edma_t::dchpri[]
-enum {
-    FREESCALE_DMA_PRI_CH3,  FREESCALE_DMA_PRI_CH2,
-    FREESCALE_DMA_PRI_CH1,  FREESCALE_DMA_PRI_CH0,
-    FREESCALE_DMA_PRI_CH7,  FREESCALE_DMA_PRI_CH6,
-    FREESCALE_DMA_PRI_CH5,  FREESCALE_DMA_PRI_CH4,
-    FREESCALE_DMA_PRI_CH11, FREESCALE_DMA_PRI_CH10,
-    FREESCALE_DMA_PRI_CH9,  FREESCALE_DMA_PRI_CH8,
-    FREESCALE_DMA_PRI_CH15, FREESCALE_DMA_PRI_CH14,
-    FREESCALE_DMA_PRI_CH13, FREESCALE_DMA_PRI_CH12
-#if CYGNUM_HAL_FREESCALE_EDMA_CHAN_NUM > 16
-    ,
-    FREESCALE_DMA_PRI_CH19, FREESCALE_DMA_PRI_CH18,
-    FREESCALE_DMA_PRI_CH17, FREESCALE_DMA_PRI_CH16,
-    FREESCALE_DMA_PRI_CH23, FREESCALE_DMA_PRI_CH22,
-    FREESCALE_DMA_PRI_CH21, FREESCALE_DMA_PRI_CH20,
-    FREESCALE_DMA_PRI_CH27, FREESCALE_DMA_PRI_CH26,
-    FREESCALE_DMA_PRI_CH25, FREESCALE_DMA_PRI_CH24,
-    FREESCALE_DMA_PRI_CH31, FREESCALE_DMA_PRI_CH30,
-    FREESCALE_DMA_PRI_CH29, FREESCALE_DMA_PRI_CH28
-#endif
-};
-
 // Transfer control descriptor
 typedef volatile struct cyghwr_hal_freescale_edma_tcd_s
                            cyghwr_hal_freescale_edma_tcd_t;
 #define CYGBLD_FREESCALE_EDMA_TCD_ALIGN CYGBLD_ATTRIB_ALIGN(32)
 struct cyghwr_hal_freescale_edma_tcd_s {
     volatile void* saddr;             //  Source Address
+
+#if (CYG_BYTEORDER == CYG_MSBFIRST)  // AKA Big endian
+    cyg_uint16 attr;         //  Transfer Attributes
+    cyg_uint16 soff;         //  Signed Source Address Offset
+#else // AKA Little endian
     cyg_uint16 soff;         //  Signed Source Address Offset
     cyg_uint16 attr;         //  Transfer Attributes
+#endif
+
     union {
         cyg_uint32 mlno;     //  Minor Byte Count (Minor Loop Dis)
         //  Signed Minor Loop Off:
@@ -128,44 +112,75 @@ struct cyghwr_hal_freescale_edma_tcd_s {
     } nbytes;
     cyg_uint32 slast;         //  Last Source Address Adjustment
     volatile void *daddr;              //  Destination Address
+
+#if (CYG_BYTEORDER == CYG_MSBFIRST)  // AKA Big endian
+
+    union {                   //  Current Minor Loop Link:
+        cyg_uint16 elinkyes;  //  Major Loop Count (Ch Lnkng Ena)
+        cyg_uint16 elinkno;   //  Major Loop Count (Ch Lnkng Dis)
+    } citer;
+    cyg_uint16 doff;          //  Signed Destination Address Offset
+#else // AKA Little endian
     cyg_uint16 doff;          //  Signed Destination Address Offset
     union {                   //  Current Minor Loop Link:
         cyg_uint16 elinkyes;  //  Major Loop Count (Ch Lnkng Ena)
         cyg_uint16 elinkno;   //  Major Loop Count (Ch Lnkng Dis)
     } citer;
+#endif
+
     union {
         cyg_uint32 dlast;     //  Last Dst Addr Adj/Scat Gath Addr
         cyghwr_hal_freescale_edma_tcd_t *sga;  //  Last Dst Addr Adj/Scat Gath Addr
-    };
+    } dlast_sga;
+
+#if (CYG_BYTEORDER == CYG_MSBFIRST)  // AKA Big endian
+    union {                   //  Beginning Minor Loop Link:
+        cyg_uint16 elinkno;   //  Major Loop Cnt (Ch Lnkng Dis)
+        cyg_uint16 elinkyes;  //  Major Loop Cnt (Ch Lnkng Ena)
+    } biter;
+    cyg_uint16 csr;           //  Control and Status
+#else // AKA Little endian
     cyg_uint16 csr;           //  Control and Status
     union {                   //  Beginning Minor Loop Link:
         cyg_uint16 elinkno;   //  Major Loop Cnt (Ch Lnkng Dis)
         cyg_uint16 elinkyes;  //  Major Loop Cnt (Ch Lnkng Ena)
     } biter;
+#endif
 };
 
 // DMA - Peripheral register structure
 typedef volatile struct cyghwr_hal_freescale_edma_s {
-    cyg_uint32 cr;                   // Control Register
-    cyg_uint32 es;                   // Error Status Register
-    cyg_uint32 reserved_0;
-    cyg_uint32 erq;                  // Enable Request Register
-    cyg_uint32 reserved_1;
-    cyg_uint32 eei;                  // Enable Error Interrupt Register
-    cyg_uint8  ceei;                 // Clear Enable Error Interrupt Register
-    cyg_uint8  seei;                 // Set Enable Error Interrupt Register
-    cyg_uint8  cerq;                 // Clear Enable Request Register
-    cyg_uint8  serq;                 // Set Enable Request Register
-    cyg_uint8  cdne;                 // Clear DONE Status Bit Register
-    cyg_uint8  ssrt;                 // Set START Bit Register
-    cyg_uint8  cerr;                 // Clear Error Register
-    cyg_uint8  cint;                 // Clear Interrupt Request Register
-    cyg_uint32 reserved_2;
-    cyg_uint32 irq;                  // Interrupt Request Register
-    cyg_uint32 reserved_3;
-    cyg_uint32 err;                  // Error Register
-    cyg_uint32 reserved_4;
-    cyg_uint32 hrs;                  // Hardware Request Status Register
+    cyg_uint32 cr;                   // Control Register			// 0x0000
+    cyg_uint32 es;                   // Error Status Register			// 0x0004
+    cyg_uint32 reserved_0;							// 0x0008
+    cyg_uint32 erq;                  // Enable Request Register			// 0x000C
+    cyg_uint32 reserved_1;							// 0x0010
+    cyg_uint32 eei;                  // Enable Error Interrupt Register		// 0x0014
+#if (CYG_BYTEORDER == CYG_MSBFIRST)  // AKA Big endian
+    cyg_uint8  serq;                 // Set Enable Request Register		// 0x0018
+    cyg_uint8  cerq;                 // Clear Enable Request Register		// 0x0019
+    cyg_uint8  seei;                 // Set Enable Error Interrupt Register	// 0x001A  
+    cyg_uint8  ceei;                 // Clear Enable Error Interrupt Register	// 0x001B
+    cyg_uint8  cint;                 // Clear Interrupt Request Register	// 0x001C
+    cyg_uint8  cerr;                 // Clear Error Register			// 0x001D
+    cyg_uint8  ssrt;                 // Set START Bit Register			// 0x001E
+    cyg_uint8  cdne;                 // Clear DONE Status Bit Register		// 0x001F
+#else // AKA Little endian
+    cyg_uint8  ceei;                 // Clear Enable Error Interrupt Register	
+    cyg_uint8  seei;                 // Set Enable Error Interrupt Register	
+    cyg_uint8  cerq;                 // Clear Enable Request Register		
+    cyg_uint8  serq;                 // Set Enable Request Register		
+    cyg_uint8  cdne;                 // Clear DONE Status Bit Register		
+    cyg_uint8  ssrt;                 // Set START Bit Register			
+    cyg_uint8  cerr;                 // Clear Error Register			
+    cyg_uint8  cint;                 // Clear Interrupt Request Register	
+#endif    
+    cyg_uint32 reserved_2;							// 0x0020
+    cyg_uint32 irq;                  // Interrupt Request Register		// 0x0024
+    cyg_uint32 reserved_3;							// 0x0028
+    cyg_uint32 err;                  // Error Register				// 0x002C
+    cyg_uint32 reserved_4;							// 0x0030
+    cyg_uint32 hrs;                  // Hardware Request Status Register	// 0x0034
     cyg_uint8  reserved_5[0x8100 - (0x8034 + 4)];
     cyg_uint8  dchpri[CYGNUM_HAL_FREESCALE_EDMA_CHAN_NUM]; // Priorities
     cyg_uint8  reserved_6[0x9000 - 0x8100 - CYGNUM_HAL_FREESCALE_EDMA_CHAN_NUM];
@@ -460,56 +475,56 @@ hal_freescale_edma_tcd_diag(cyghwr_hal_f
 hal_freescale_edma_transfer_diag (cyghwr_hal_freescale_edma_t *edma_p,
                                   cyg_uint8 chan_i, cyg_bool recurse);
 
-__externC inline void
+CYGBLD_FORCE_INLINE void
 hal_freescale_edma_erq_enable(cyghwr_hal_freescale_edma_t *edma_p,
                               cyg_uint8 chan_i)
 {
     edma_p->serq = chan_i;
 }
 
-__externC inline void
+CYGBLD_FORCE_INLINE void
 hal_freescale_edma_erq_disable(cyghwr_hal_freescale_edma_t *edma_p,
                                cyg_uint8 chan_i)
 {
     edma_p->cerq = chan_i;
 }
 
-__externC inline void
+CYGBLD_FORCE_INLINE void
 hal_freescale_edma_cleardone(cyghwr_hal_freescale_edma_t *edma_p,
                               cyg_uint8 chan_i)
 {
     edma_p->cdne = chan_i;
 }
 
-__externC inline void
+CYGBLD_FORCE_INLINE void
 hal_freescale_edma_irq_enable(cyghwr_hal_freescale_edma_t *edma_p,
                               cyg_uint8 chan_i)
 {
     edma_p->seei = chan_i;
 }
 
-__externC inline void
+CYGBLD_FORCE_INLINE void
 hal_freescale_edma_irq_disable(cyghwr_hal_freescale_edma_t *edma_p,
                                cyg_uint8 chan_i)
 {
     edma_p->ceei = chan_i;
 }
 
-__externC inline void
+CYGBLD_FORCE_INLINE void
 hal_freescale_edma_irq_clear(cyghwr_hal_freescale_edma_t *edma_p,
                                cyg_uint8 chan_i)
 {
     edma_p->cint = chan_i;
 }
 
-__externC inline void
+CYGBLD_FORCE_INLINE void
 hal_freescale_edma_transfer_clear(cyghwr_hal_freescale_edma_t *edma_p,
                                   cyg_uint8 chan_i)
 {
     edma_p->tcd[chan_i].csr &= ~FREESCALE_EDMA_CSR_DONE_M;
 }
 
-__externC inline void
+CYGBLD_FORCE_INLINE void
 hal_freescale_edma_transfer_start(cyghwr_hal_freescale_edma_t *edma_p,
                                   cyg_uint8 chan_i)
 {
--- a/packages/hal/misc/freescale/edma/current/src/hal_freescale_edma.c
+++ b/packages/hal/misc/freescale/edma/current/src/hal_freescale_edma.c
@@ -8,7 +8,7 @@
 // ####ECOSGPLCOPYRIGHTBEGIN####                                            
 // -------------------------------------------                              
 // This file is part of eCos, the Embedded Configurable Operating System.   
-// Copyright (C) 2011 Free Software Foundation, Inc.                        
+// Copyright (C) 2011, 2013 Free Software Foundation, Inc.                        
 //
 // eCos is free software; you can redistribute it and/or modify it under    
 // the terms of the GNU General Public License as published by the Free     
@@ -64,7 +64,35 @@
 #include <cyg/hal/hal_if.h>             // HAL header
 #include <cyg/hal/freescale_edma.h>     // Freescale eDMA defs
 
-// Channel priority register index
+// Channel priority register indexing
+#if (CYG_BYTEORDER == CYG_MSBFIRST)  // AKA Big endian
+
+#define EDMA_CHAN_PRIORITY_I(__chan_i) (__chan_i)
+
+#else  // AKA Big endian
+// Indices for cyghwr_hal_freescale_edma_t::dchpri[]
+enum {
+    FREESCALE_DMA_PRI_CH3,  FREESCALE_DMA_PRI_CH2,
+    FREESCALE_DMA_PRI_CH1,  FREESCALE_DMA_PRI_CH0,
+    FREESCALE_DMA_PRI_CH7,  FREESCALE_DMA_PRI_CH6,
+    FREESCALE_DMA_PRI_CH5,  FREESCALE_DMA_PRI_CH4,
+    FREESCALE_DMA_PRI_CH11, FREESCALE_DMA_PRI_CH10,
+    FREESCALE_DMA_PRI_CH9,  FREESCALE_DMA_PRI_CH8,
+    FREESCALE_DMA_PRI_CH15, FREESCALE_DMA_PRI_CH14,
+    FREESCALE_DMA_PRI_CH13, FREESCALE_DMA_PRI_CH12
+#if CYGNUM_HAL_FREESCALE_EDMA_CHAN_NUM > 16
+    ,
+    FREESCALE_DMA_PRI_CH19, FREESCALE_DMA_PRI_CH18,
+    FREESCALE_DMA_PRI_CH17, FREESCALE_DMA_PRI_CH16,
+    FREESCALE_DMA_PRI_CH23, FREESCALE_DMA_PRI_CH22,
+    FREESCALE_DMA_PRI_CH21, FREESCALE_DMA_PRI_CH20,
+    FREESCALE_DMA_PRI_CH27, FREESCALE_DMA_PRI_CH26,
+    FREESCALE_DMA_PRI_CH25, FREESCALE_DMA_PRI_CH24,
+    FREESCALE_DMA_PRI_CH31, FREESCALE_DMA_PRI_CH30,
+    FREESCALE_DMA_PRI_CH29, FREESCALE_DMA_PRI_CH28
+#endif
+};
+
 const cyg_uint8 const PRICHAN_I[CYGNUM_HAL_FREESCALE_EDMA_CHAN_NUM] =
 {
     FREESCALE_DMA_PRI_CH0,  FREESCALE_DMA_PRI_CH1,
@@ -88,6 +116,10 @@ const cyg_uint8 const PRICHAN_I[CYGNUM_H
 #endif
 };
 
+#define EDMA_CHAN_PRIORITY_I(__chan_i) (PRICHAN_I[__chan_i])
+
+#endif
+
 // Find an eDMA channel with given priority
 static volatile cyg_uint8*
 hal_freescale_edma_find_chan_with_pri(cyghwr_hal_freescale_edma_t *edma_p,
@@ -145,14 +177,14 @@ hal_freescale_edma_init_1chan(
     }
 
     if((chan_p->dma_prio != FREESCALE_EDMA_DCHPRI_ASIS) &&
-       (edma_p->dchpri[PRICHAN_I[chan_p->dma_chan_i]] != chan_p->dma_prio))
+       (edma_p->dchpri[EDMA_CHAN_PRIORITY_I(chan_p->dma_chan_i)] != chan_p->dma_prio))
     {
         group_i = chan_p->dma_chan_i >= CYGNUM_HAL_FREESCALE_EDMA_GROUP_SIZE ? 1 : 0;
         if((prev_ch_reqprio_p =
             hal_freescale_edma_find_chan_with_pri(edma_p, chan_p->dma_prio, group_i)))
         {
-            oldprio = edma_p->dchpri[PRICHAN_I[chan_p->dma_chan_i]];
-            edma_p->dchpri[PRICHAN_I[chan_p->dma_chan_i]] = chan_p->dma_prio;
+            oldprio = edma_p->dchpri[EDMA_CHAN_PRIORITY_I(chan_p->dma_chan_i)];
+            edma_p->dchpri[EDMA_CHAN_PRIORITY_I(chan_p->dma_chan_i)] = chan_p->dma_prio;
             *prev_ch_reqprio_p = oldprio;
         }
     }
@@ -249,7 +281,7 @@ hal_freescale_edma_diag(const cyghwr_hal
             diag_printf("Chan %2d: CHCFG=0x%02x (%2d) DCHPRI=0x%02x dmamux[%c]=%p", chan_i,
                         dmamux_p->chcfg[chan_i % 16],
                         FREESCALE_DMAMUX_CHCFG_SOURCE(dmamux_p->chcfg[chan_i % 16]),
-                        edma_p->dchpri[PRICHAN_I[chan_i]],
+                        edma_p->dchpri[EDMA_CHAN_PRIORITY_I(chan_i)],
                         CYGHWR_IO_FREESCALE_DMAMUX0_P == dmamux_p ? '0' : (
 #if CYGNUM_HAL_FREESCALE_EDMA_CHAN_NUM > CYGNUM_HAL_FREESCALE_EDMA_GROUP_SIZE
                         CYGHWR_IO_FREESCALE_DMAMUX1_P == dmamux_p ? '1' :
@@ -298,7 +330,7 @@ void hal_freescale_edma_tcd_diag(cyghwr_
                     tcd_p->slast, tcd_p->slast);
         diag_printf("%s    %s=%d [%p]\n", prefix,
                     (tcd_p->csr & FREESCALE_EDMA_CSR_ESG_M) ? "sga" : "dlast",
-                    tcd_p->dlast, tcd_p->sga);
+                    tcd_p->dlast_sga.dlast, tcd_p->dlast_sga.sga);
         diag_printf("%s    biter = %d, citer = %d\n", prefix,
                     tcd_p->biter.elinkno, tcd_p->citer.elinkno);
         diag_printf("%s    CSR=0x%04x\n", prefix, tcd_p->csr);
@@ -311,7 +343,7 @@ void hal_freescale_edma_transfer_diag(cy
     cyghwr_hal_freescale_edma_tcd_t *tcd_p;
     const char *prefix = "";
 
-    for(tcd_p = &edma_p->tcd[chan_i]; tcd_p; tcd_p = tcd_p->sga){
+    for(tcd_p = &edma_p->tcd[chan_i]; tcd_p; tcd_p = tcd_p->dlast_sga.sga){
         hal_freescale_edma_tcd_diag(tcd_p, chan_i, prefix);
         if(!(recurse && (tcd_p->csr & FREESCALE_EDMA_CSR_ESG_M)))
             break;