Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions include/canmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ class CanMap: CanCallback
void HandleRx(uint32_t canId, uint32_t data[2], uint8_t dlc) override;
void Clear();
void SendAll();
bool SendByIndex(uint8_t ididx);
int AddSend(Param::PARAM_NUM param, uint32_t canId, uint8_t offsetBits, int8_t length, float gain);
int AddRecv(Param::PARAM_NUM param, uint32_t canId, uint8_t offsetBits, int8_t length, float gain);
int AddSend(Param::PARAM_NUM param, uint32_t canId, uint8_t offsetBits, int8_t length, float gain, int8_t offset);
Expand Down Expand Up @@ -96,6 +97,7 @@ class CanMap: CanCallback
CANIDMAP canRecvMap[MAX_MESSAGES];
CANPOS canPosMap[MAX_ITEMS + 1]; //Last item is a "tail"

bool Send(CANIDMAP *map);
void ClearMap(CANIDMAP *canMap);
int Add(CANIDMAP *canMap, Param::PARAM_NUM param, uint32_t canId, uint8_t offsetBits, int8_t length, float gain, int8_t offset);
uint32_t SaveToFlash(uint32_t baseAddress, uint32_t* data, int len);
Expand Down
139 changes: 77 additions & 62 deletions src/canmap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,70 +181,17 @@ void CanMap::SendAll()
{
forEachCanMap(curMap, canSendMap)
{
uint32_t data[2] = { 0 }; //Had an issue with uint64_t, otherwise would have used that
uint8_t maxBit = 0;

forEachPosMap(curPos, curMap)
{
if (isSaving) return; //Only send mapped messages when not currently saving to flash

float val = Param::GetFloat((Param::PARAM_NUM)curPos->mapParam);

val *= curPos->gain;
val += curPos->offset;
// convert to a signed integer value before storing in an unsigned to
// avoid sign-extension problems when we start shifting and masking
uint32_t ival = (int32_t)val;
uint8_t numBits = ABS(curPos->numBits);
ival &= (1UL << numBits) - 1;

if (curPos->numBits < 0) // big-endian
{
//Swap byte order
const uint8_t* bptr = (uint8_t*)&ival;
ival = (bptr[0] << 24) | (bptr[1] << 16) | (bptr[2] << 8) | bptr[3];

if (curPos->offsetBits < 32) //all data in first word
{
data[0] |= ival >> (31 - curPos->offsetBits);
}
else if ((curPos->offsetBits + curPos->numBits) >= 31) //all data in second word
{
data[1] |= ival >> (63 - curPos->offsetBits);
}
else //data spans across both words
{
data[0] |= ival << (curPos->offsetBits - 31);
data[1] |= ival >> (63 - curPos->offsetBits);
}
maxBit = MAX(maxBit, curPos->offsetBits);
}
else // little-endian
{
if (curPos->offsetBits > 31)
{
// data entirely in the second word
data[1] |= ival << (curPos->offsetBits - 32);
}
else if ((curPos->offsetBits + curPos->numBits) <= 32)
{
// data entirely in the first word
data[0] |= ival << curPos->offsetBits;
}
else
{
// data spans both words
data[0] |= ival << curPos->offsetBits;
data[1] |= ival >> (32 - curPos->offsetBits);
}
maxBit = MAX(maxBit, curPos->offsetBits + curPos->numBits);
}
}
if (!Send(curMap))
return;
}
}

uint8_t numBytes = (maxBit + 7) / 8;
bool CanMap::SendByIndex(uint8_t ididx)
{
if (ididx >= MAX_MESSAGES || canSendMap[ididx].first == MAX_ITEMS)
return false;

canHardware->Send(curMap->canId, data, numBytes);
}
return Send(&canSendMap[ididx]);
}

/** \brief Add periodic CAN message
Expand Down Expand Up @@ -529,6 +476,74 @@ void CanMap::IterateCanMap(void (*callback)(Param::PARAM_NUM, uint32_t, uint8_t,
/****************** Private methods and ISRs ********************/


bool CanMap::Send(CANIDMAP *map)
{
uint32_t data[2] = { 0 }; //Had an issue with uint64_t, otherwise would have used that
uint8_t maxBit = 0;

forEachPosMap(curPos, map)
{
if (isSaving) return false; //Only send mapped messages when not currently saving to flash

float val = Param::GetFloat((Param::PARAM_NUM)curPos->mapParam);

val *= curPos->gain;
val += curPos->offset;
// convert to a signed integer value before storing in an unsigned to
// avoid sign-extension problems when we start shifting and masking
uint32_t ival = (int32_t)val;
uint8_t numBits = ABS(curPos->numBits);
ival &= (1UL << numBits) - 1;

if (curPos->numBits < 0) // big-endian
{
//Swap byte order
const uint8_t* bptr = (uint8_t*)&ival;
ival = (bptr[0] << 24) | (bptr[1] << 16) | (bptr[2] << 8) | bptr[3];

if (curPos->offsetBits < 32) //all data in first word
{
data[0] |= ival >> (31 - curPos->offsetBits);
}
else if ((curPos->offsetBits + curPos->numBits) >= 31) //all data in second word
{
data[1] |= ival >> (63 - curPos->offsetBits);
}
else //data spans across both words
{
data[0] |= ival << (curPos->offsetBits - 31);
data[1] |= ival >> (63 - curPos->offsetBits);
}
maxBit = MAX(maxBit, curPos->offsetBits);
}
else // little-endian
{
if (curPos->offsetBits > 31)
{
// data entirely in the second word
data[1] |= ival << (curPos->offsetBits - 32);
}
else if ((curPos->offsetBits + curPos->numBits) <= 32)
{
// data entirely in the first word
data[0] |= ival << curPos->offsetBits;
}
else
{
// data spans both words
data[0] |= ival << curPos->offsetBits;
data[1] |= ival >> (32 - curPos->offsetBits);
}
maxBit = MAX(maxBit, curPos->offsetBits + curPos->numBits);
}
}

uint8_t numBytes = (maxBit + 7) / 8;

canHardware->Send(map->canId, data, numBytes);
return true;
}

void CanMap::ClearMap(CANIDMAP *canMap)
{
for (int i = 0; i < MAX_MESSAGES; i++)
Expand Down
17 changes: 17 additions & 0 deletions test/test_canmap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -611,6 +611,22 @@ static void remove_at_max_messages_is_safe()
ASSERT(canId == 0x300);
}

static void send_map_by_index_sends_only_selected_message()
{
canMap->AddSend(Param::ocurlim, 0x101, 0, 8, 1.0, 0);
canMap->AddSend(Param::amp, 0x102, 0, 8, 1.0, 0);
Param::SetFloat(Param::ocurlim, 0x11);
Param::SetFloat(Param::amp, 0x22);

ASSERT(canMap->SendByIndex(1));
ASSERT(canStub->m_canId == 0x102);
ASSERT(canStub->m_data[0] == 0x22);
ASSERT(canStub->m_len == 1);

ASSERT(!canMap->SendByIndex(2));
ASSERT(!canMap->SendByIndex(MAX_MESSAGES));
}

static void create_and_delete_complex_map_once()
{
canMap->AddSend(Param::amp, 257, 24, 8, -1.00, 0);
Expand Down Expand Up @@ -1204,4 +1220,5 @@ REGISTER_TEST(
create_and_delete_complex_map_once,
get_map_at_max_messages_returns_null,
remove_at_max_messages_is_safe,
send_map_by_index_sends_only_selected_message,
RECEIVE_TESTS);
Loading