C2: Add LIN message support

This commit is contained in:
David Rebbe
2026-04-15 15:50:33 -04:00
committed by Kyle Schwarz
parent 6dc005fcea
commit f5f6d0828b
11 changed files with 1199 additions and 12 deletions
+130
View File
@@ -216,3 +216,133 @@ icsneoc2_error_t icsneoc2_message_is_can(icsneoc2_message_t* message, bool* is_c
return icsneoc2_error_success;
}
icsneoc2_error_t icsneoc2_message_is_lin(icsneoc2_message_t* message, bool* is_lin) {
if(!message || !is_lin) {
return icsneoc2_error_invalid_parameters;
}
*is_lin = std::dynamic_pointer_cast<LINMessage>(message->message) != nullptr;
return icsneoc2_error_success;
}
icsneoc2_error_t icsneoc2_message_lin_create(icsneoc2_message_t** message, uint8_t id) {
if(!message) {
return icsneoc2_error_invalid_parameters;
}
try {
*message = new icsneoc2_message_t;
(*message)->message = std::make_shared<LINMessage>(id);
} catch(const std::bad_alloc&) {
return icsneoc2_error_out_of_memory;
}
return icsneoc2_error_success;
}
icsneoc2_error_t icsneoc2_message_lin_props_get(const icsneoc2_message_t* message,
uint8_t* id, uint8_t* protected_id, uint8_t* checksum,
icsneoc2_lin_msg_type_t* msg_type, bool* is_enhanced_checksum) {
if(!message) {
return icsneoc2_error_invalid_parameters;
}
auto lin_msg = std::dynamic_pointer_cast<LINMessage>(message->message);
if(!lin_msg) {
return icsneoc2_error_invalid_type;
}
if(id) {
*id = lin_msg->ID;
}
if(protected_id) {
*protected_id = lin_msg->protectedID;
}
if(checksum) {
*checksum = lin_msg->checksum;
}
if(msg_type) {
*msg_type = static_cast<icsneoc2_lin_msg_type_t>(lin_msg->linMsgType);
}
if(is_enhanced_checksum) {
*is_enhanced_checksum = lin_msg->isEnhancedChecksum;
}
return icsneoc2_error_success;
}
icsneoc2_error_t icsneoc2_message_lin_props_set(icsneoc2_message_t* message,
const uint8_t* id, const uint8_t* checksum,
const icsneoc2_lin_msg_type_t* msg_type, const bool* is_enhanced_checksum) {
if(!message) {
return icsneoc2_error_invalid_parameters;
}
auto lin_msg = std::dynamic_pointer_cast<LINMessage>(message->message);
if(!lin_msg) {
return icsneoc2_error_invalid_type;
}
if(id) {
lin_msg->ID = *id & 0x3Fu;
lin_msg->protectedID = lin_msg->calcProtectedID(lin_msg->ID);
}
if(checksum) {
lin_msg->checksum = *checksum;
}
if(msg_type) {
lin_msg->linMsgType = static_cast<LINMessage::Type>(*msg_type);
}
if(is_enhanced_checksum) {
lin_msg->isEnhancedChecksum = *is_enhanced_checksum;
}
return icsneoc2_error_success;
}
icsneoc2_error_t icsneoc2_message_lin_err_flags_get(const icsneoc2_message_t* message, icsneoc2_lin_err_flags_t* err_flags) {
if(!message || !err_flags) {
return icsneoc2_error_invalid_parameters;
}
auto lin_msg = std::dynamic_pointer_cast<LINMessage>(message->message);
if(!lin_msg) {
return icsneoc2_error_invalid_type;
}
*err_flags = 0;
if(lin_msg->errFlags.ErrRxBreakOnly) *err_flags |= ICSNEOC2_LIN_ERR_RX_BREAK_ONLY;
if(lin_msg->errFlags.ErrRxBreakSyncOnly) *err_flags |= ICSNEOC2_LIN_ERR_RX_BREAK_SYNC_ONLY;
if(lin_msg->errFlags.ErrTxRxMismatch) *err_flags |= ICSNEOC2_LIN_ERR_TX_RX_MISMATCH;
if(lin_msg->errFlags.ErrRxBreakNotZero) *err_flags |= ICSNEOC2_LIN_ERR_RX_BREAK_NOT_ZERO;
if(lin_msg->errFlags.ErrRxBreakTooShort) *err_flags |= ICSNEOC2_LIN_ERR_RX_BREAK_TOO_SHORT;
if(lin_msg->errFlags.ErrRxSyncNot55) *err_flags |= ICSNEOC2_LIN_ERR_RX_SYNC_NOT_55;
if(lin_msg->errFlags.ErrRxDataLenOver8) *err_flags |= ICSNEOC2_LIN_ERR_RX_DATA_LEN_OVER_8;
if(lin_msg->errFlags.ErrFrameSync) *err_flags |= ICSNEOC2_LIN_ERR_FRAME_SYNC;
if(lin_msg->errFlags.ErrFrameMessageID) *err_flags |= ICSNEOC2_LIN_ERR_FRAME_MESSAGE_ID;
if(lin_msg->errFlags.ErrFrameResponderData) *err_flags |= ICSNEOC2_LIN_ERR_FRAME_RESPONDER_DATA;
if(lin_msg->errFlags.ErrChecksumMatch) *err_flags |= ICSNEOC2_LIN_ERR_CHECKSUM_MATCH;
return icsneoc2_error_success;
}
icsneoc2_error_t icsneoc2_message_lin_status_flags_get(const icsneoc2_message_t* message, icsneoc2_lin_status_flags_t* status_flags) {
if(!message || !status_flags) {
return icsneoc2_error_invalid_parameters;
}
auto lin_msg = std::dynamic_pointer_cast<LINMessage>(message->message);
if(!lin_msg) {
return icsneoc2_error_invalid_type;
}
*status_flags = 0;
if(lin_msg->statusFlags.TxChecksumEnhanced) *status_flags |= ICSNEOC2_LIN_STATUS_TX_CHECKSUM_ENHANCED;
if(lin_msg->statusFlags.TxCommander) *status_flags |= ICSNEOC2_LIN_STATUS_TX_COMMANDER;
if(lin_msg->statusFlags.TxResponder) *status_flags |= ICSNEOC2_LIN_STATUS_TX_RESPONDER;
if(lin_msg->statusFlags.TxAborted) *status_flags |= ICSNEOC2_LIN_STATUS_TX_ABORTED;
if(lin_msg->statusFlags.UpdateResponderOnce) *status_flags |= ICSNEOC2_LIN_STATUS_UPDATE_RESPONDER_ONCE;
if(lin_msg->statusFlags.HasUpdatedResponderOnce) *status_flags |= ICSNEOC2_LIN_STATUS_HAS_UPDATED_RESPONDER_ONCE;
if(lin_msg->statusFlags.BusRecovered) *status_flags |= ICSNEOC2_LIN_STATUS_BUS_RECOVERED;
if(lin_msg->statusFlags.BreakOnly) *status_flags |= ICSNEOC2_LIN_STATUS_BREAK_ONLY;
return icsneoc2_error_success;
}
icsneoc2_error_t icsneoc2_message_lin_calc_checksum(icsneoc2_message_t* message) {
if(!message) {
return icsneoc2_error_invalid_parameters;
}
auto lin_msg = std::dynamic_pointer_cast<LINMessage>(message->message);
if(!lin_msg) {
return icsneoc2_error_invalid_type;
}
LINMessage::calcChecksum(*lin_msg);
return icsneoc2_error_success;
}