The J1939 Protocol Stack keeps all PGNs which are handled by the device in a list. The list is added to the J1939 Protocol Stack by the function J1939_PgnAddList(). The elements inside this list are administrated by the user.
PGN Reception
A PGN which shall be received by the J1939 Protocol Stack has to be marked with the symbol J1939_MSG_RCV inside the control field of the structure J1939_PGN_Entry_ts (J1939_PGN_Entry_s::uwControl).
The following example shows the setup of a PGN with a value of 0 which is received by the ECU.
(uint32_t) 0,
(uint16_t) 2000,
(uint16_t) 0,
(uint8_t) 0,
(uint8_t) 0,
(uint16_t) 8,
ECU_Pgn00000
},
#define J1939_PRIORITY_INFO
Definition j1939_defs.h:231
#define J1939_MSG_RCV
Definition j1939_defs.h:248
Upon reception of the TSC1 PDU the function ECU_Pgn00000() is called.
static int16_t ECU_Pgn00000(uint8_t * pubDataV, uint16_t uwSizeV, uint8_t ubSrcAddrV, uint8_t ubNetV)
{
J1939_Payload_ts *ptsPayloadT = (J1939_Payload_ts *) pubDataV;
uint16_t uwSpeedT;
(void) uwSizeV;
(void) ubSrcAddrV;
(void) ubNetV;
uwSpeedT = ptsPayloadT->aubByte[2];
uwSpeedT <<= 8;
uwSpeedT += ptsPayloadT->aubByte[1];
tsECU_ControlS.ubDevice = ubSrcAddrV;
tsECU_ControlS.ubMode = ptsPayloadT->aubByte[0];
tsECU_ControlS.uwSpeed = uwSpeedT;
tsECU_ControlS.ubTorque = ptsPayloadT->aubByte[3];
}
PGN Transmission
A PGN which shall be transmitted by the J1939 Protocol Stack has to be marked with the symbol J1939_MSG_TRM inside the control field of the structure J1939_PGN_Entry_ts (J1939_PGN_Entry_s::uwControl). For a cyclic PGN transmission, the cycle time field (J1939_PGN_Entry_s::uwCycle) is set to a value unequal to zero.
The following example shows the setup of a PGN with a value of 61444 which is transmitted by ECU with a cycle time of 10 ms.
(uint32_t) 61444,
(uint16_t) (PGN_TRANSMISSION_RATE),
(uint16_t) 0,
(uint8_t) 0,
(uint8_t) 0,
(uint16_t) 8,
ECU_Pgn61444
},
#define J1939_MSG_TRM
Definition j1939_defs.h:257
#define J1939_PRIORITY_CTRL
Definition j1939_defs.h:222
After the cycle timer has elapsed, the function ECU_Pgn61444() is called, which is the interface to the application. The following example shows the implementation of the function ECU_Pgn61444().
static int16_t ECU_Pgn61444(uint8_t * pubDataV, uint16_t uwSizeV, uint8_t ubSrcAddrV, uint8_t ubNetV)
{
J1939_Payload_ts *ptsPayloadT = (J1939_Payload_ts *) pubDataV;
static uint16_t uwSpeedS = 200 * 8;
static uint8_t ubTorqueS = (uint8_t) 125;
static uint8_t ubSimDirS = 1;
(void) uwSizeV;
(void) ubSrcAddrV;
(void) ubNetV;
ubTorqueS += (uint8_t) 1;
if (ubTorqueS > ((uint8_t) 200))
{
ubTorqueS = (uint8_t) 125;
}
if (tsECU_ControlS.uwSpeed == (uint16_t) 0)
{
if (ubSimDirS == (uint8_t) 1)
{
uwSpeedS = uwSpeedS + (uint16_t) 8;
if (uwSpeedS / (uint16_t) 8 > (uint16_t) 2200)
{
ubSimDirS = 0;
}
}
else
{
uwSpeedS = uwSpeedS - (uint16_t) 8;
if (uwSpeedS / (uint16_t) 8 < (uint16_t) 200)
{
ubSimDirS = 1;
}
}
}
else
{
if (tsECU_ControlS.uwSpeed > uwSpeedS)
{
uwSpeedS = uwSpeedS + (uint16_t) 8;
}
if (tsECU_ControlS.uwSpeed < uwSpeedS)
{
uwSpeedS = uwSpeedS - (uint16_t) 8;
}
}
ptsPayloadT->aubByte[0] = 0x01;
ptsPayloadT->aubByte[1] = ubTorqueS;
ptsPayloadT->aubByte[2] = ubTorqueS;
ptsPayloadT->aubByte[3] = (uint8_t) uwSpeedS;
ptsPayloadT->aubByte[4] = (uint8_t) (uwSpeedS >> 8);
ptsPayloadT->aubByte[5] = tsECU_ControlS.ubDevice;
ptsPayloadT->aubByte[6] = J1939_UNUSED_UINT8;
ptsPayloadT->aubByte[7] = J1939_UNUSED_UINT8;
}