Skip to content
Open
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
37 changes: 35 additions & 2 deletions firmware/RAMNV1/Core/Inc/ramn_j1939.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,23 +89,56 @@
#define J1939_MANUFACTURER_NEBRASKA_TEST 522
#define J1939_MANUFACTURER_DLG_TEST 251

/* Per-ECU primary source address for J1939 Address Claim */
#define J1939_ECUA_IDENTITY 0xEC0A /* Identity number: EC0A */
#define J1939_ECUB_IDENTITY 0xEC0B /* Identity number: EC0B */
#define J1939_ECUC_IDENTITY 0xEC0C /* Identity number: EC0C */
#define J1939_ECUD_IDENTITY 0xEC0D /* Identity number: EC0D */

/* Per-ECU primary source address for J1939 Address Claim and diagnostic routing */
#if defined(TARGET_ECUA)
#define J1939_ECU_SA J1939_SA_HEADWAY_CTRL /* 42 */
#define J1939_ECU_FUNCTION J1939_FUNCTION_HEADWAY_CTRL /* 32 */
#define J1939_ECU_IDENTITY J1939_ECUA_IDENTITY
#define J1939_ECU_MANUFACTURER J1939_MANUFACTURER_NEVADA_TEST
#define J1939_ECU_KWP_SA J1939_ECU_SA
#define J1939_ECU_XCP_SA J1939_ECU_SA
#define J1939_ECU_KWP_XCP_SA J1939_ECU_SA
#elif defined(TARGET_ECUB)
#define J1939_ECU_SA J1939_SA_STEERING_CTRL /* 19 */
#define J1939_ECU_FUNCTION J1939_FUNCTION_STEERING_CTRL /* 16 */
#define J1939_ECU_FUNCTION J1939_FUNCTION_CHASSIS_CTRL /* 52: Chassis Controller */
#define J1939_ECU_IDENTITY J1939_ECUB_IDENTITY
#define J1939_ECU_MANUFACTURER J1939_MANUFACTURER_ISOBUS_TEST
#define J1939_ECU_KWP_SA J1939_ECU_SA
#define J1939_ECU_XCP_SA J1939_ECU_SA
#define J1939_ECU_KWP_XCP_SA J1939_ECU_SA
#elif defined(TARGET_ECUC)
#define J1939_ECU_SA J1939_SA_POWERTRAIN_CTRL /* 90 */
#define J1939_ECU_FUNCTION J1939_FUNCTION_ELECTRIC_POWERTRAIN /* 80 */
#define J1939_ECU_IDENTITY J1939_ECUC_IDENTITY
#define J1939_ECU_MANUFACTURER J1939_MANUFACTURER_NEBRASKA_TEST
#define J1939_ECU_KWP_SA J1939_ECU_SA
#define J1939_ECU_XCP_SA J1939_ECU_SA
#define J1939_ECU_KWP_XCP_SA J1939_ECU_SA
#elif defined(TARGET_ECUD)
#define J1939_ECU_SA J1939_SA_BODY_CTRL /* 33 */
#define J1939_ECU_FUNCTION J1939_FUNCTION_BODY_CTRL /* 26 */
#define J1939_ECU_IDENTITY J1939_ECUD_IDENTITY
#define J1939_ECU_MANUFACTURER J1939_MANUFACTURER_DLG_TEST
#define J1939_ECU_KWP_SA J1939_ECU_SA
#define J1939_ECU_XCP_SA J1939_ECU_SA
#define J1939_ECU_KWP_XCP_SA J1939_ECU_SA
#else
/* Fallback definitions when no TARGET_ECUx macro is defined.
* This branch exists specifically for IDE code assistance / indexers,
* static analysis tools, and standalone / mock compilation units.
* Defaults safely to the primary ECU D (Body Controller) configuration. */
#define J1939_ECU_SA J1939_SA_BODY_CTRL
#define J1939_ECU_FUNCTION J1939_FUNCTION_BODY_CTRL
#define J1939_ECU_IDENTITY J1939_ECUD_IDENTITY
#define J1939_ECU_MANUFACTURER J1939_MANUFACTURER_DLG_TEST
#define J1939_ECU_KWP_SA J1939_ECU_SA
#define J1939_ECU_XCP_SA J1939_ECU_SA
#define J1939_ECU_KWP_XCP_SA J1939_ECU_SA
#endif

/* Proprietary A Payload Definitions */
Expand Down
28 changes: 19 additions & 9 deletions firmware/RAMNV1/Core/Src/ramn_j1939.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,30 +33,40 @@ static uint32_t J1939_MakeId(uint8_t prio, uint8_t pf, uint8_t da, uint8_t sa)
}

/*
* J1939 NAME (8 bytes).
* J1939 NAME (8 bytes, transmitted Least Significant Byte (LSB) first per SAE J1939-81).
*
* CAN Data Byte layout (Little-Endian / LSB first):
* Byte 0: Identity Number bits 7-0
* Byte 1: Identity Number bits 15-8
* Byte 2: Identity Number bits 20-16 (bits 4-0), Manufacturer Code bits 2-0 (bits 7-5)
* Byte 3: Manufacturer Code bits 10-3
* Byte 4: ECU Instance bits 2-0 (bits 2-0), Function Instance bits 4-0 (bits 7-3)
* Byte 5: Function (bits 7-0)
* Byte 6: Reserved bit 48 (bit 0, must be 0), Vehicle System bits 6-0 (bits 7-1)
* Byte 7: Vehicle System Instance bits 3-0 (bits 3-0), Industry Group bits 2-0 (bits 6-4), Arbitrary Address Capable (bit 7)
*/
static const uint8_t j1939_name[8] = {
#if defined(TARGET_ECUA)
0x10, 0x02, J1939_ECU_FUNCTION, 0x00, 0x0F, 0xA0, 0x00, 0x01 /* Identity=1, MC=125, Function=32 (Headway Ctrl) */
0x0A, 0xEC, 0xA0, 0x0F, 0x00, J1939_ECU_FUNCTION, 0x02, 0x10 /* Identity=0xEC0A, MC=125, Function=32 (Headway Ctrl) */
#elif defined(TARGET_ECUB)
0x10, 0x02, J1939_ECU_FUNCTION, 0x00, 0x3F, 0x60, 0x00, 0x02 /* Identity=2, MC=507, Function=16 (Steering Ctrl) */
0x0B, 0xEC, 0x60, 0x3F, 0x00, J1939_ECU_FUNCTION, 0x02, 0x10 /* Identity=0xEC0B, MC=507, Function=52 (Chassis Ctrl) */
#elif defined(TARGET_ECUC)
0x10, 0x02, J1939_ECU_FUNCTION, 0x00, 0x41, 0x40, 0x00, 0x03 /* Identity=3, MC=522, Function=80 (Powertrain Ctrl) */
0x0C, 0xEC, 0x40, 0x41, 0x00, J1939_ECU_FUNCTION, 0x02, 0x10 /* Identity=0xEC0C, MC=522, Function=80 (Powertrain Ctrl) */
#elif defined(TARGET_ECUD)
0x10, 0x02, J1939_ECU_FUNCTION, 0x00, 0x1F, 0x60, 0x00, 0x04 /* Identity=4, MC=251, Function=26 (Body Ctrl) */
0x0D, 0xEC, 0x60, 0x1F, 0x00, J1939_ECU_FUNCTION, 0x02, 0x10 /* Identity=0xEC0D, MC=251, Function=26 (Body Ctrl) */
#endif
};

/* ECU Identification string for PGN 64965 (fields delimited by '*') */
static const char j1939_ecu_id[] =
#if defined(TARGET_ECUA)
"RAMN*ECU_A*0001*UNIT1*";
"RAMN*ECU_A*EC0A*UNIT1*";
#elif defined(TARGET_ECUB)
"RAMN*ECU_B*0002*UNIT2*";
"RAMN*ECU_B*EC0B*UNIT2*";
#elif defined(TARGET_ECUC)
"RAMN*ECU_C*0003*UNIT3*";
"RAMN*ECU_C*EC0C*UNIT3*";
#elif defined(TARGET_ECUD)
"RAMN*ECU_D*0004*UNIT4*";
"RAMN*ECU_D*EC0D*UNIT4*";
#else
"RAMN*ECU_UNKNOWN*";
#endif
Expand Down
10 changes: 9 additions & 1 deletion firmware/RAMNV1/Core/Src/ramn_kwp2000.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,17 @@
#define KWP_COMMAND_CONTROL_DTC_SETTINGS 0x85
#define KWP_COMMAND_RESPONSE_ON_EVENT 0x86

// KWP Errors
// KWP Errors (ISO 14230-3)
#define KWP_NRC_SERVICE_NOT_SUPPORTED 0x11
#define KWP_NRC_SUBFUNCTION_NOT_SUPPORTED_IF 0x12
#define KWP_NRC_INCORRECT_MESSAGE_LENGTH 0x13
#define KWP_NRC_CONDITIONS_NOT_CORRECT 0x22
#define KWP_NRC_REQUEST_SEQUENCE_ERROR 0x24
#define KWP_NRC_REQUEST_OUT_OF_RANGE 0x31
#define KWP_NRC_SECURITY_ACCESS_DENIED 0x33
#define KWP_NRC_INVALID_KEY 0x35
#define KWP_NRC_EXCEED_NUMBER_OF_ATTEMPTS 0x36
#define KWP_NRC_REQUIRED_TIME_DELAY_NOT_EXPIRED 0x37

// TODO: refactor module
// Common pointer to avoid passing answer data as argument each sub-function
Expand Down
8 changes: 4 additions & 4 deletions firmware/RAMNV1/Core/Src/ramn_xcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -409,12 +409,12 @@ RAMN_Bool_t RAMN_XCP_ProcessRxCANMessage(const FDCAN_RxHeaderTypeDef* pHeader, c

// Accept XCP over both addressing schemes regardless of the live traffic profile:
// J1939 proprietary-A (PF 0xEF, physical, TSA 0x3F or 0x5A) or standard 11-bit XCP_RX_CANID.
if (pHeader->IdType == FDCAN_EXTENDED_ID && pf == 0xEF && da == J1939_ECU_SA)
if (pHeader->IdType == FDCAN_EXTENDED_ID && pf == 0xEF && da == J1939_ECU_XCP_SA)
{
// Avoid ECUC (SA 0x5A) responding to itself if another ECU is using TSA 0x5A
if ((sa == 0x3F || sa == 0x5A) && (sa != J1939_ECU_SA))
// Avoid responding to self if tester uses same SA
if ((sa == 0x3F || sa == 0x5A) && (sa != J1939_ECU_XCP_SA))
{
RAMN_XCP_TxMsgHeader.Identifier = J1939_UCAST_ID(prio, 0xEF00, sa, J1939_ECU_SA);
RAMN_XCP_TxMsgHeader.Identifier = J1939_UCAST_ID(prio, 0xEF00, sa, J1939_ECU_XCP_SA);
RAMN_XCP_TxMsgHeader.IdType = FDCAN_EXTENDED_ID;
matched = True;
}
Expand Down
2 changes: 1 addition & 1 deletion scripts/tests/build_testing_libs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ touch scripts/tests/mocks/eeprom_emul_conf.h

echo "Compiling Serdes Shared Library..."
# Both codecs (RAMN_*_Default and RAMN_*_J1939) live in the single library; tests pick by suffix.
gcc $CFLAGS -D__MAIN_H $INCLUDES -o scripts/tests/librbd_can_db.so firmware/RAMNV1/Core/Src/ramn_can_database.c
gcc $CFLAGS -D__MAIN_H -include stddef.h -include string.h $INCLUDES -o scripts/tests/librbd_can_db.so firmware/RAMNV1/Core/Src/ramn_can_database.c

echo "Compiling ECU-specific Diagnostic Shared Libraries..."

Expand Down
9 changes: 9 additions & 0 deletions scripts/tests/mocks/ramn_diag_mocks.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,15 @@ size_t xStreamBufferSend(StreamBufferHandle_t xStreamBuffer, const void *pvTxDat
RAMN_KWP_ISOTPHandler.txSize = ans_size;
RAMN_KWP_ISOTPHandler.txStatus = ISOTP_TX_TRANSFERRING;
RAMN_KWP_Continue_TX(0);
// Complete any multi-frame transfer the same way a tester would: after the
// FirstFrame, feed a FlowControl "Continue To Send" and pump ConsecutiveFrames.
for (int guard = 0; (RAMN_KWP_ISOTPHandler.txStatus != ISOTP_TX_IDLE) && (guard < 8192); guard++) {
if (RAMN_KWP_ISOTPHandler.txStatus == ISOTP_TX_WAITING_FLAG) {
uint8_t fc[3] = {0x30, 0x00, 0x00}; // FlowControl: CTS, BS=0, STmin=0
RAMN_ISOTP_ProcessRxMsg(&RAMN_KWP_ISOTPHandler, 3, fc, False, 0);
}
RAMN_KWP_Continue_TX(0);
}
}
kwp_expected = 0;
}
Expand Down
16 changes: 8 additions & 8 deletions scripts/tests/test_j1939_protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,17 +49,17 @@

# J1939 NAME per ECU: (function, identity_number) — all other fields zero
ECU_NAME_FIELDS = {
'A': {'function': 42, 'identity': 1},
'B': {'function': 19, 'identity': 2},
'C': {'function': 90, 'identity': 3},
'D': {'function': 33, 'identity': 4},
'A': {'function': 42, 'identity': 0xEC0A},
'B': {'function': 52, 'identity': 0xEC0B},
'C': {'function': 90, 'identity': 0xEC0C},
'D': {'function': 33, 'identity': 0xEC0D},
}

ECU_ID_STRINGS = {
'A': "RAMN*ECU_A*0001*UNIT1*",
'B': "RAMN*ECU_B*0002*UNIT2*",
'C': "RAMN*ECU_C*0003*UNIT3*",
'D': "RAMN*ECU_D*0004*UNIT4*",
'A': "RAMN*ECU_A*EC0A*UNIT1*",
'B': "RAMN*ECU_B*EC0B*UNIT2*",
'C': "RAMN*ECU_C*EC0C*UNIT3*",
'D': "RAMN*ECU_D*EC0D*UNIT4*",
}

# ---------------------------------------------------------------------------
Expand Down
Loading