aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorinmarket <andrewh@inmarket.com.au>2015-11-12 18:33:12 +1000
committerinmarket <andrewh@inmarket.com.au>2015-11-12 18:33:12 +1000
commitd403294cb430c1dfb811880a3b8280a616c3d279 (patch)
tree502faabc1a5c63808075fd4efc44dabef6351905
parent2928950e47903d09c418427f107d5854cea20638 (diff)
downloaduGFX-d403294cb430c1dfb811880a3b8280a616c3d279.tar.gz
uGFX-d403294cb430c1dfb811880a3b8280a616c3d279.tar.bz2
uGFX-d403294cb430c1dfb811880a3b8280a616c3d279.zip
More endian updates. Images should now work for any endian machine even strange ones.
-rw-r--r--gfx.h22
-rw-r--r--src/gdisp/gdisp_image.c45
-rw-r--r--src/gdisp/gdisp_image_support.h52
3 files changed, 99 insertions, 20 deletions
diff --git a/gfx.h b/gfx.h
index a6eb9cf7..aeced09e 100644
--- a/gfx.h
+++ b/gfx.h
@@ -269,8 +269,10 @@
#define GFX_CPU_ENDIAN GFX_CPU_ENDIAN_UNKNOWN
#endif
#define GFX_CPU_ENDIAN_UNKNOWN 0 //**< Unknown endianness
- #define GFX_CPU_ENDIAN_LITTLE 0x04030201 //**< Little Endian
- #define GFX_CPU_ENDIAN_BIG 0x01020304 //**< Big Endian
+ #define GFX_CPU_ENDIAN_LITTLE 0x03020100 //**< Little endian
+ #define GFX_CPU_ENDIAN_BIG 0x00010203 //**< Big endian
+ #define GFX_CPU_ENDIAN_WBDWL 0x02030001 //**< Words are big endian, DWords are little endian eg. Honeywell 316
+ #define GFX_CPU_ENDIAN_WLDWB 0x01000302 //**< Words are little endian, DWords are big endian eg PDP-11
/** @} */
/** @} */
@@ -369,14 +371,18 @@
#if GFX_CPU_ENDIAN == GFX_CPU_ENDIAN_UNKNOWN
#undef GFX_CPU_ENDIAN
#if (defined(__BYTE_ORDER__)&&(__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)) \
- || defined(__LITTLE_ENDIAN__) \
- || defined(__LITTLE_ENDIAN) \
- || defined(_LITTLE_ENDIAN)
+ || defined(__LITTLE_ENDIAN__) || defined(__LITTLE_ENDIAN) || defined(_LITTLE_ENDIAN) \
+ || defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) \
+ || defined(__THUMBEL__) \
+ || defined(__AARCH64EL__) \
+ || defined(__ARMEL__)
#define GFX_CPU_ENDIAN GFX_CPU_ENDIAN_LITTLE
#elif (defined(__BYTE_ORDER__)&&(__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)) \
- || defined(__BIG_ENDIAN__) \
- || defined(__BIG_ENDIAN) \
- || defined(_BIG_ENDIAN)
+ || defined(__BIG_ENDIAN__) || defined(__BIG_ENDIAN) || defined(_BIG_ENDIAN) \
+ || defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) \
+ || defined(__THUMBEB__) \
+ || defined(__AARCH64EB__) \
+ || defined(__ARMEB__)
#define GFX_CPU_ENDIAN GFX_CPU_ENDIAN_BIG
#else
#define GFX_CPU_ENDIAN GFX_CPU_ENDIAN_UNKNOWN
diff --git a/src/gdisp/gdisp_image.c b/src/gdisp/gdisp_image.c
index 7da3d90e..87d11065 100644
--- a/src/gdisp/gdisp_image.c
+++ b/src/gdisp/gdisp_image.c
@@ -191,8 +191,49 @@ void gdispImageFree(gdispImage *img, void *ptr, size_t sz) {
#endif
}
-#if GFX_CPU_ENDIAN != GFX_CPU_ENDIAN_LITTLE && GFX_CPU_ENDIAN != GFX_CPU_ENDIAN_BIG
- const uint8_t gdispImageEndianArray[4] = { 1, 2, 3, 4 };
+#if GFX_CPU_ENDIAN != GFX_CPU_ENDIAN_LITTLE && GFX_CPU_ENDIAN != GFX_CPU_ENDIAN_BIG \
+ && GFX_CPU_ENDIAN != GFX_CPU_ENDIAN_WBDWL && GFX_CPU_ENDIAN != GFX_CPU_ENDIAN_WLDWB
+
+ union wbyteorder_u {
+ uint8_t b[2];
+ uint32_t w;
+ };
+ union dwbyteorder_u {
+ uint8_t b[4];
+ uint32_t l;
+ };
+
+ uint16_t gdispImageH16toLE16(uint16_t w) {
+ union wbyteorder_u we;
+
+ we.w = w;
+ return (((uint16_t)we.b[0]))|(((uint16_t)we.b[1]) << 8);
+ }
+ uint16_t gdispImageH16toBE16(uint16_t dw) {
+ union wbyteorder_u we;
+
+ we.w = w;
+ return (((uint16_t)we.b[0]) << 8)|(((uint16_t)we.b[1]));
+ }
+
+ uint32_t gdispImageH32toLE32(uint32_t dw) {
+ union dwbyteorder_u we;
+
+ we.l = dw;
+ return (((uint32_t)we.b[0]))
+ |(((uint32_t)we.b[1]) << 8)
+ |(((uint32_t)we.b[2]) << 16)
+ |(((uint32_t)we.b[3]) << 24);
+ }
+ uint32_t gdispImageH32toBE32(uint32_t dw) {
+ union dwbyteorder_u we;
+
+ we.l = dw;
+ return (((uint32_t)we.b[0]) << 24)
+ |(((uint32_t)we.b[1]) << 16)
+ |(((uint32_t)we.b[2]) << 8)
+ |(((uint32_t)we.b[3]));
+ }
#endif
#endif /* GFX_USE_GDISP && GDISP_NEED_IMAGE */
diff --git a/src/gdisp/gdisp_image_support.h b/src/gdisp/gdisp_image_support.h
index a853f9e4..fee07e3b 100644
--- a/src/gdisp/gdisp_image_support.h
+++ b/src/gdisp/gdisp_image_support.h
@@ -23,6 +23,9 @@
#define gdispImageSwap16(w) ((((uint16_t)(w))>>8)|(((uint16_t)(w))<<8))
#define gdispImageSwap32(dw) ((((uint32_t)(w))>>24)|((((uint32_t)(w))&0x00FF0000)>>8)\
|((((uint32_t)(w))&0x0000FF00)<<8)|(((uint32_t)(w))<<24))
+#define gdispImageSwapWords32(dw) ((((uint32_t)(w))>>16)|(((uint32_t)(w))<<16))
+#define gdispImageSwapBytes32(dw) (((((uint32_t)(w))&0xFF000000)>>8)|((((uint32_t)(w))&0x00FF0000)<<8)\
+ |((((uint32_t)(w))&0x0000FF00)>>8)|(((uint32_t)(w))<<8))
/*
* Get a uint16_t/uint32_t from memory in the required endianness.
@@ -70,24 +73,53 @@
* Change a uint16 or uint32 already in a register to the required endianness.
*/
#if GFX_CPU_ENDIAN == GFX_CPU_ENDIAN_LITTLE
+ #define gdispImageH16toLE16(w) (w)
+ #define gdispImageH16toBE16(w) gdispImageSwap16(w)
+ #define gdispImageH32toLE32(dw) (dw)
+ #define gdispImageH32toBE32(dw) gdispImageSwap32(dw)
#define gdispImageMakeLE16(w)
+ #define gdispImageMakeBE16(w) { w = gdispImageH16toBE16(w); }
#define gdispImageMakeLE32(dw)
- #define gdispImageMakeBE16(w) { w = gdispImageSwap16(w); }
- #define gdispImageMakeBE32(dw) { dw = gdispImageSwap32(dw); }
+ #define gdispImageMakeBE32(dw) { dw = gdispImageH32toBE32(dw); }
#elif GFX_CPU_ENDIAN == GFX_CPU_ENDIAN_BIG
- #define gdispImageMakeLE16(w) { w = gdispImageSwap16(w); }
- #define gdispImageMakeLE32(dw) { dw = gdispImageSwap32(dw); }
+ #define gdispImageH16toLE16(w) gdispImageSwap16(w)
+ #define gdispImageH16toBE16(w) (w)
+ #define gdispImageH32toLE32(dw) gdispImageSwap32(dw)
+ #define gdispImageH32toBE32(dw) (dw)
+ #define gdispImageMakeLE16(w) { w = gdispImageH16toLE16(w); }
#define gdispImageMakeBE16(w)
+ #define gdispImageMakeLE32(dw) { dw = gdispImageH32toLE32(dw); }
#define gdispImageMakeBE32(dw)
+#elif GFX_CPU_ENDIAN == GFX_CPU_ENDIAN_WBDWL
+ #define gdispImageH16toLE16(w) gdispImageSwap16(w)
+ #define gdispImageH16toBE16(w) (w)
+ #define gdispImageH32toLE32(dw) gdispImageSwapBytes32(dw)
+ #define gdispImageH32toBE32(dw) gdispImageSwapWords32(dw)
+ #define gdispImageMakeLE16(w) { w = gdispImageH16toLE16(w); }
+ #define gdispImageMakeBE16(w)
+ #define gdispImageMakeLE32(dw) { dw = gdispImageH32toLE32(dw); }
+ #define gdispImageMakeBE32(dw) { dw = gdispImageH32toBE32(dw); }
+#elif GFX_CPU_ENDIAN == GFX_CPU_ENDIAN_WLDWB
+ #define gdispImageH16toLE16(w) (w)
+ #define gdispImageH16toBE16(w) gdispImageSwap16(w)
+ #define gdispImageH32toLE32(dw) gdispImageSwapWords32(dw)
+ #define gdispImageH32toBE32(dw) gdispImageSwapBytes32(dw)
+ #define gdispImageMakeLE16(w)
+ #define gdispImageMakeBE16(w) { w = gdispImageH16toBE16(w); }
+ #define gdispImageMakeLE32(dw) { dw = gdispImageH32toLE32(dw); }
+ #define gdispImageMakeBE32(dw) { dw = gdispImageH32toBE32(dw); }
#else
- #define gdispImageEndianness() (*(uint32_t *)&gdispImageEndianArray)
-
- #define gdispImageMakeLE16(w) { if (gdispImageEndianness() != GFX_CPU_ENDIAN_LITTLE) w = gdispImageSwap16(w); }
- #define gdispImageMakeLE32(dw) { if (gdispImageEndianness() != GFX_CPU_ENDIAN_LITTLE) dw = gdispImageSwap32(dw); }
- #define gdispImageMakeBE16(w) { if (gdispImageEndianness() != GFX_CPU_ENDIAN_BIG) w = gdispImageSwap16(w); }
- #define gdispImageMakeBE32(dw) { if (gdispImageEndianness() != GFX_CPU_ENDIAN_BIG) dw = gdispImageSwap32(dw); }
+ uint16_t gdispImageH16toLE16(uint16_t w);
+ uint16_t gdispImageH16toBE16(uint16_t w);
+ uint32_t gdispImageH32toLE32(uint32_t dw);
+ uint32_t gdispImageH32toBE32(uint32_t dw);
+ #define gdispImageMakeLE16(w) { w = gdispImageH16toLE16(w); }
+ #define gdispImageMakeBE16(w) { w = gdispImageH16toBE16(w); }
+ #define gdispImageMakeLE32(dw) { dw = gdispImageH32toLE32(dw); }
+ #define gdispImageMakeBE32(dw) { dw = gdispImageH32toBE32(dw); }
#endif
+
#ifdef __cplusplus
extern "C" {