add TUP_MCU_STRICT_ALIGN macro that manually pick bytes for lpc55 port1 that is m4 but cannot unaligned acces on usb ram
This commit is contained in:
		| @@ -47,13 +47,13 @@ | ||||
| #define U16_TO_U8S_BE(u16)    TU_U16_HIGH(u16), TU_U16_LOW(u16) | ||||
| #define U16_TO_U8S_LE(u16)    TU_U16_LOW(u16), TU_U16_HIGH(u16) | ||||
|  | ||||
| #define U32_B1_U8(u32)        ((uint8_t) ((((uint32_t) u32) >> 24) & 0x000000ff)) // MSB | ||||
| #define U32_B2_U8(u32)        ((uint8_t) ((((uint32_t) u32) >> 16) & 0x000000ff)) | ||||
| #define U32_B3_U8(u32)        ((uint8_t) ((((uint32_t) u32) >>  8) & 0x000000ff)) | ||||
| #define U32_B4_U8(u32)        ((uint8_t) (((uint32_t)  u32)        & 0x000000ff)) // LSB | ||||
| #define TU_U32_BYTE3(u32)     ((uint8_t) ((((uint32_t) u32) >> 24) & 0x000000ff)) // MSB | ||||
| #define TU_U32_BYTE2(u32)     ((uint8_t) ((((uint32_t) u32) >> 16) & 0x000000ff)) | ||||
| #define TU_U32_BYTE1(u32)     ((uint8_t) ((((uint32_t) u32) >>  8) & 0x000000ff)) | ||||
| #define TU_U32_BYTE0(u32)     ((uint8_t) (((uint32_t)  u32)        & 0x000000ff)) // LSB | ||||
|  | ||||
| #define U32_TO_U8S_BE(u32)    U32_B1_U8(u32), U32_B2_U8(u32), U32_B3_U8(u32), U32_B4_U8(u32) | ||||
| #define U32_TO_U8S_LE(u32)    U32_B4_U8(u32), U32_B3_U8(u32), U32_B2_U8(u32), U32_B1_U8(u32) | ||||
| #define U32_TO_U8S_BE(u32)    TU_U32_BYTE3(u32), TU_U32_BYTE2(u32), TU_U32_BYTE1(u32), TU_U32_BYTE0(u32) | ||||
| #define U32_TO_U8S_LE(u32)    TU_U32_BYTE0(u32), TU_U32_BYTE1(u32), TU_U32_BYTE2(u32), TU_U32_BYTE3(u32) | ||||
|  | ||||
| #define TU_BIT(n)             (1U << (n)) | ||||
|  | ||||
| @@ -81,9 +81,9 @@ | ||||
| #define tu_varclr(_var)          tu_memclr(_var, sizeof(*(_var))) | ||||
|  | ||||
| //------------- Bytes -------------// | ||||
| TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_u32(uint8_t b1, uint8_t b2, uint8_t b3, uint8_t b4) | ||||
| TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_u32(uint8_t b3, uint8_t b2, uint8_t b1, uint8_t b0) | ||||
| { | ||||
|   return ( ((uint32_t) b1) << 24) | ( ((uint32_t) b2) << 16) | ( ((uint32_t) b3) << 8) | b4; | ||||
|   return ( ((uint32_t) b3) << 24) | ( ((uint32_t) b2) << 16) | ( ((uint32_t) b1) << 8) | b0; | ||||
| } | ||||
|  | ||||
| TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_u16(uint8_t high, uint8_t low) | ||||
| @@ -91,8 +91,13 @@ TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_u16(uint8_t high, uint8_t low) | ||||
|   return (uint16_t) ((((uint16_t) high) << 8) | low); | ||||
| } | ||||
|  | ||||
| TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_u16_high(uint16_t u16) { return (uint8_t) (((uint16_t) (u16 >> 8)) & 0x00ff); } | ||||
| TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_u16_low (uint16_t u16) { return (uint8_t) (u16 & 0x00ff); } | ||||
| TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_u32_byte3(uint32_t u32) { return TU_U32_BYTE3(u32); } | ||||
| TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_u32_byte2(uint32_t u32) { return TU_U32_BYTE2(u32); } | ||||
| TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_u32_byte1(uint32_t u32) { return TU_U32_BYTE1(u32); } | ||||
| TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_u32_byte0(uint32_t u32) { return TU_U32_BYTE0(u32); } | ||||
|  | ||||
| TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_u16_high(uint16_t u16) { return TU_U16_HIGH(u16); } | ||||
| TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_u16_low (uint16_t u16) { return TU_U16_LOW(u16); } | ||||
|  | ||||
| //------------- Bits -------------// | ||||
| TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_bit_set  (uint32_t value, uint8_t pos) { return value | TU_BIT(pos);                  } | ||||
| @@ -141,6 +146,8 @@ static inline uint8_t tu_log2(uint32_t value) | ||||
| //------------- Unaligned Access -------------// | ||||
| #if TUP_ARCH_STRICT_ALIGN | ||||
|  | ||||
| // Rely on compiler to generate correct code for unaligned access | ||||
|  | ||||
| typedef struct { uint16_t val; } TU_ATTR_PACKED tu_unaligned_uint16_t; | ||||
| typedef struct { uint32_t val; } TU_ATTR_PACKED tu_unaligned_uint32_t; | ||||
|  | ||||
| @@ -168,8 +175,44 @@ TU_ATTR_ALWAYS_INLINE static inline void tu_unaligned_write16(void* mem, uint16_ | ||||
|   ua16->val = value; | ||||
| } | ||||
|  | ||||
| #elif TUP_MCU_STRICT_ALIGN | ||||
|  | ||||
| // MCU such as LPC_IP3511 Highspeed cannot access unaligned memory on USB_RAM although it is ARM M4. | ||||
| // We have to manually pick up bytes since tu_unaligned_uint32_t will still generate unaligned code | ||||
| // NOTE: volatile cast to memory to prevent compiler to optimize and generate unaligned code | ||||
| // TODO Big Endian may need minor changes | ||||
| TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_unaligned_read32(const void* mem) | ||||
| { | ||||
|   volatile uint8_t const* buf8 = (uint8_t const*) mem; | ||||
|   return tu_u32(buf8[3], buf8[2], buf8[1], buf8[0]); | ||||
| } | ||||
|  | ||||
| TU_ATTR_ALWAYS_INLINE static inline void tu_unaligned_write32(void* mem, uint32_t value) | ||||
| { | ||||
|   volatile uint8_t* buf8 = (uint8_t*) mem; | ||||
|   buf8[0] = tu_u32_byte0(value); | ||||
|   buf8[1] = tu_u32_byte1(value); | ||||
|   buf8[2] = tu_u32_byte2(value); | ||||
|   buf8[3] = tu_u32_byte3(value); | ||||
| } | ||||
|  | ||||
| TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_unaligned_read16(const void* mem) | ||||
| { | ||||
|   volatile uint8_t const* buf8 = (uint8_t const*) mem; | ||||
|   return tu_u16(buf8[1], buf8[0]); | ||||
| } | ||||
|  | ||||
| TU_ATTR_ALWAYS_INLINE static inline void tu_unaligned_write16(void* mem, uint16_t value) | ||||
| { | ||||
|   volatile uint8_t* buf8 = (uint8_t*) mem; | ||||
|   buf8[0] = tu_u16_low(value); | ||||
|   buf8[1] = tu_u16_high(value); | ||||
| } | ||||
|  | ||||
|  | ||||
| #else | ||||
|  | ||||
| // MCU that could access unaligned memory natively | ||||
| TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_unaligned_read32  (const void* mem           ) { return *((uint32_t*) mem);  } | ||||
| TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_unaligned_read16  (const void* mem           ) { return *((uint16_t*) mem);  } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 hathach
					hathach