diff --git a/canard.c b/canard.c index 796ca66..9997b74 100644 --- a/canard.c +++ b/canard.c @@ -811,6 +811,20 @@ int16_t canardDecodeScalar(const CanardRxTransfer* transfer, { swapByteOrder(&storage.bytes[0], std_byte_length); } + +#if WORD_ADDRESSING_IS_16BITS + /* + * Copying 8-bit array to 64-bit storage + */ + { + uint64_t temp = 0; + for(uint16_t i=0; i 0); + +#if WORD_ADDRESSING_IS_16BITS + /* + * Copying 64-bit storage to 8-bit array + */ + { + uint64_t temp = storage.u64; + for(uint16_t i=0; i> (8*i)) & 0xFFU; + } + } +#endif if (isBigEndian()) { @@ -988,7 +1015,7 @@ CanardPoolAllocatorStatistics canardGetPoolAllocatorStatistics(CanardInstance* i uint16_t canardConvertNativeFloatToFloat16(float value) { - CANARD_ASSERT(sizeof(float) == 4); + CANARD_ASSERT(sizeof(float) == CANARD_SIZEOF_FLOAT); union FP32 { @@ -1032,7 +1059,7 @@ uint16_t canardConvertNativeFloatToFloat16(float value) float canardConvertFloat16ToNativeFloat(uint16_t value) { - CANARD_ASSERT(sizeof(float) == 4); + CANARD_ASSERT(sizeof(float) == CANARD_SIZEOF_FLOAT); union FP32 { @@ -1629,11 +1656,23 @@ void copyBitArray(const uint8_t* src, uint32_t src_offset, uint32_t src_len, const uint8_t max_offset = MAX(src_bit_offset, dst_bit_offset); const uint32_t copy_bits = (uint32_t)MIN(last_bit - src_offset, 8U - max_offset); +#if WORD_ADDRESSING_IS_16BITS + /* + * (uint8_t) same as (uint16_t) + * Mask 0xFF must be used + */ + const uint8_t write_mask = (uint8_t)((uint8_t)((0xFF00U >> copy_bits)&0xFF) >> dst_bit_offset)&0xFF; + const uint8_t src_data = (uint8_t)(((uint32_t)src[src_offset / 8U] << src_bit_offset) >> dst_bit_offset)&0xFF; + + dst[dst_offset / 8U] = + (uint8_t)(((uint32_t)dst[dst_offset / 8U] & (uint32_t)~write_mask) | (uint32_t)(src_data & write_mask))&0xFF; +#else const uint8_t write_mask = (uint8_t)((uint8_t)(0xFF00U >> copy_bits) >> dst_bit_offset); const uint8_t src_data = (uint8_t)(((uint32_t)src[src_offset / 8U] << src_bit_offset) >> dst_bit_offset); dst[dst_offset / 8U] = (uint8_t)(((uint32_t)dst[dst_offset / 8U] & (uint32_t)~write_mask) | (uint32_t)(src_data & write_mask)); +#endif src_offset += copy_bits; dst_offset += copy_bits; @@ -1750,8 +1789,16 @@ CANARD_INTERNAL bool isBigEndian(void) #else union { +#if WORD_ADDRESSING_IS_16BITS + /* + * with 16-bit memory addressing u8b[0]=u16a, u8b[1]=NOTHING + */ + uint32_t a; + uint16_t b[2]; +#else uint16_t a; uint8_t b[2]; +#endif } u; u.a = 1; return u.b[1] == 1; // Some don't... diff --git a/canard_internals.h b/canard_internals.h index 29315db..c147c94 100644 --- a/canard_internals.h +++ b/canard_internals.h @@ -43,6 +43,47 @@ extern "C" { # define CANARD_INTERNAL static #endif +/* + * Some MCUs like TMS320 have 16-bits addressing, so + * 1. (uint8_t) same (uint16_t) + * 2. sizeof(float) is 2 + * 3. union not same like STM32, because type uint8_t does not exist in hardware + * + * union + * { + * uint64_t u8; + * uint64_t u16; + * uint64_t u32; + * uint64_t u64; + * uint8_t bytes[8]; + * } storage; + * + * address:| bytes: | u64: | u32: | u16: | u8: + * 0x00 | bytes[0] | (u64 )&0xFF | (u32 )&0xFF | u16 | u8 + * 0x01 | bytes[1] | (u64>>16)&0xFF | (u32>>16)&0xFF | + * 0x02 | bytes[2] | (u64>>32)&0xFF | + * 0x03 | bytes[3] | (u64>>48)&0xFF | + * 0x04 | bytes[4] | + * 0x05 | bytes[5] | + * 0x06 | bytes[6] | + * 0x07 | bytes[7] | + * + */ +#ifndef WORD_ADDRESSING_IS_16BITS +#if defined(__TI_COMPILER_VERSION__) || defined(__TMS320C2000__) +#define WORD_ADDRESSING_IS_16BITS 1 +#else +#define WORD_ADDRESSING_IS_16BITS 0 +#endif +#endif + +#if WORD_ADDRESSING_IS_16BITS +# define uint8_t uint16_t +# define int8_t int16_t +# define CANARD_SIZEOF_FLOAT 2 +#else +# define CANARD_SIZEOF_FLOAT 4 +#endif CANARD_INTERNAL CanardRxState* traverseRxStates(CanardInstance* ins, uint32_t transfer_descriptor);