Skip to content

Commit

Permalink
support 16 bit addressing MCUs
Browse files Browse the repository at this point in the history
  • Loading branch information
Ivan Prishchepa authored and tridge committed Jun 4, 2023
1 parent e4a7814 commit 790a5db
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 2 deletions.
63 changes: 61 additions & 2 deletions canard.c
Original file line number Diff line number Diff line change
Expand Up @@ -774,6 +774,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<std_byte_length; i++)
{
temp |= (((uint64_t)storage.bytes[i] & 0xFFU) << (8*i));
}
storage.u64 = temp;
}
#endif

/*
* Extending the sign bit if needed. I miss templates.
Expand Down Expand Up @@ -904,6 +918,19 @@ void canardEncodeScalar(void* destination,
}

CANARD_ASSERT(std_byte_length > 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<std_byte_length; i++)
{
storage.bytes[i] = (temp >> (8*i)) & 0xFFU;
}
}
#endif

if (isBigEndian())
{
Expand Down Expand Up @@ -951,7 +978,13 @@ CanardPoolAllocatorStatistics canardGetPoolAllocatorStatistics(CanardInstance* i

uint16_t canardConvertNativeFloatToFloat16(float value)
{
CANARD_ASSERT(sizeof(float) == 4);
CANARD_ASSERT(sizeof(float) ==
#if WORD_ADDRESSING_IS_16BITS
2
#else
4
#endif
);

union FP32
{
Expand Down Expand Up @@ -995,7 +1028,13 @@ uint16_t canardConvertNativeFloatToFloat16(float value)

float canardConvertFloat16ToNativeFloat(uint16_t value)
{
CANARD_ASSERT(sizeof(float) == 4);
CANARD_ASSERT(sizeof(float) ==
#if WORD_ADDRESSING_IS_16BITS
2
#else
4
#endif
);

union FP32
{
Expand Down Expand Up @@ -1592,11 +1631,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;
Expand Down Expand Up @@ -1713,8 +1764,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...
Expand Down
39 changes: 39 additions & 0 deletions canard.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,45 @@
extern "C" {
#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
#endif

/// Libcanard version. API will be backwards compatible within the same major version.
#define CANARD_VERSION_MAJOR 0
#define CANARD_VERSION_MINOR 2
Expand Down

0 comments on commit 790a5db

Please sign in to comment.