About CT2KLib Library
CT2KLib library was developed to automatically handle both J1939 and NMEA2000 communication protocols according to their specification.
The library doesn't automatically decode and handle any of the PGNs that are NOT defined as mandatory in either J1939 or NMEA2000.
It is up to the user to make the decodes manually by using the Callback Mechanisms.
CT2KLib Library is fully NMEA2000 Level A compliant and passes all the NMEA2000 Level A certification tests.
- Note: CT2KLib passes all certification tests when run in default state, without additional PGNs installed. If the user installs other PGNs, they will need to add callbacks to handle the NMEA2000 Level A Requirements. See below.
You can find the Module Breakdown Here
CT2KLib Example application (SDKC only)
Both SDKC Color and Monochrome come with a Starter Application showing how the library can be used and to ease the development process.
The Starter App can be found in SDKC_ROOT/SDK/ProjectTemplates folder.
NMEA2000 and J1939 Automatically Supported PGNs
- The library automatically supports all the Mandatory PGNs and communication protocols required by NMEA2000 Level A and J1939.
Minimum Message Implementation Support:
| Message Name | PGN | Supported Mode |
| Address Claim | ISO 060928 | NMEA2000 and J1939 |
| Product Information | NMEA 126996 | NMEA2000 Only |
| Configuration Information | NMEA 126998 | NMEA2000 Only |
| Request Group Function | NMEA 126208 | NMEA2000 Only |
| Command Group Function | NMEA 126208 | NMEA2000 Only |
| Acknowledge Group Function | NMEA 126208 | NMEA2000 Only |
| Acknowledge | ISO 059392 | NMEA2000 and J1939 |
| Request | ISO 059904 | NMEA2000 and J1939 |
| TX/RX PGN List Group Function | NMEA 126464 | NMEA2000 Only |
| Heartbeat | NMEA 126993 | NMEA2000 Only |
| Commanded Address | ISO 065240 | NMEA2000 and J1939 |
| Transport Protocol, Data Transfer | ISO 060160 | NMEA2000 and J1939 |
| Transport Protocol | ISO 060416 | NMEA2000 and J1939 |
| Configuration Information | NMEA 126998 | NMEA2000 Only |
Note: The NMEA2000 Request/Command/Acknowledge is automatically handled by the library for the above PGNs and should not be overrided using callbacks.
Note: The Requirements stated within the PDF C.2.43 Field Programmability of Name Instance Field can now be met by the library if you register for a callback
and accept the changes using CT2KRegisterCallbackOnCommandedNameChange() this will allow CT2KLib to accept the command from another device on the network.
If you provide the following (After filling in where the information is available, it should meet the requirements)
| Field | Method | Implimentation |
| Device Instance | Through Group Function 126208 | Any changes that include any commanded parameters other than device instance or system instance will be NACK'ed. |
| System Instance | Through Group Function 126208 | Any changes that include any commanded parameters other than device instance or system instance will be NACK'ed. |
| System Instance | Through Group Function 126208 | Changes to Either the Upper Device Instance field or Lower Device Instance field without the other half will be NACK'ed. (You must set both the Upper and Lower in the same command.) |
Adding the Library to a Project (SDKC only)
Please see the detailed instructions under the relevant SDK Documentation folder.
Using the Library under SDKQ (SDKQ only)
- In order to use the library under SDKQ, an instance of the library must first be acquired.
- This is done using the following code snippet: SDKQ::CT2KLibQt* m_ct2kLib = SDKQ::CT2KLibQt::instance();
- For The rest of the library usage, use the functions from SDKQCT2Klib.h (C++ for SDKQ) file and not the ones from CT2KLib.h (C for SDKC).
- Rest of the usage is described below.
Using the Library (SDKC and SDKQ)
- The order to use the library it must first be initialised. The Library initalisation is done by calling the void CT2KLibInit(INPUT_PARAMS_T* inputParams, PORTS_CONFIG_T* ports, uint32_t numberOfPorts) function.
- The inputParams is a pointer to a structure containing the Packet Definition and memory the library will use/allocate.
- If inputParams structure is initialised to ZERO and the library will automatically update it for NMEA2000 mode in order for the library to pass certification requirements on it's own (no other PGNs and callbacks registered).
- If inputParams is initialised to ZERO in J1939 mode, the library will not update it automatically.
- The values for this structure should always be specified by the user and calculated based on what the application will require.
- It is Highly Recommended to use the INPUT_PARAMS_T CT2KLibGetPGNTableRequiredMemorySize(const PGNDesc *pDesc, uint32_t tableSize, uint16_t numberOfPorts) function. This function will return the Optimum Memory Size per PGN Table required by the Library to work correctly. It will return a INPUT_PARAMS_T structure containing all the memory size requiremenets to use the PGN table on the specified number of CAN ports. In case of using multiple PGN Tables, run this function for each PGN Table and add all the results in a single INPUT_PARAMS_T structure and pass it to void CT2KLibInit(INPUT_PARAMS_T* inputParams, PORTS_CONFIG_T* ports, uint32_t numberOfPorts) function.
- PORTS_CONFIG_T is a structure containing the Port Configuration Parameters.
- The numberOfPorts specifies the size of the ports array passed in.
- For both NMEA2000 and J1939 the Device Name is required to be set next:
- This is done by using the CTCAN_STATUS CT2KLibSetAddress(CAN_PORTS_T i8Port, DEVNAME *pName, NETADDR u8SeedAddress) function.
- Before using this function a DEVNAME variable containing the Device information must be created.
- For NMEA2000 the Product Information should be set next:
- This is done by using the void CT2KLibSetAppProductInfo(CAN_PORTS_T i8Port, CTLIB_PROD_INFO *pProdInfo) function.
- Before using this function a CTLIB_PROD_INFO variable containing the Product information must be created.
- All the PGNs that will be supported must be added to the library using the CTCAN_STATUS CT2KLibInstallPGNTable(CAN_PORTS_T portNumber, const PGNDesc* pDesc, uint16_t tableSize) function.
- The pDesc variable must be declared before using the function and must be a STATIC variable (declared with the "static" keyword). The PGN Table is installed per port!
- The "DIRECTION" variable (part of PGNDesc structure) is used both in NMEA2000 and J1939 mode. It is used to calculate the optimum memory size needed by the library for each PGN table. In NMEA200 it is also used in the "TX/RX PGN List Group Function" PGN (126464).
- The "PGN_LIST_MODE_T" variable (part of PGNDesc structure) is used to filter if the PGN is a J1939 or NMEA2000 PGN in order to allow mixing both modes. In NMEA2000 it is also used in the "TX/RX PGN List Group Function" PGN (126464)
- Optionally use the CTCAN_STATUS CT2KLibSnoopNetwork(CAN_PORTS_T i8Port) function to enumerate all the existing nodes on the BUS. The nodes will respond back with the Address Claim PGN.
- The Receiving Callback functions should be used for Decoding the received messages.
- Start the Library using the CTCAN_STATUS CT2KLibStart() function.
- Optionally use:
- For a complete view on how to use the library, please see the template Projects.
J1939 and NMEA2000 Message Support (Send/Receive)
- The library supports sending and receiving frames using the following protocols:
| Protocol | Mode |
| Single-Packets Frames | NMEA2000 and J1939 |
| Fast-Packets Frames | NMEA2000 only |
| Broadcast (BAM) Multi-Packets Frames | NMEA2000 and J1939 |
| Peer-to-Peer (CMDT) Multi-Packets Frames | NMEA2000 and J1939 |
I. Sending Messages/Frames
- For Single-Packets and Fast-Packets:
- Use the CTCAN_STATUS CT2KLibSendPGN(CAN_PORTS_T i8Port, NETADDR u8DestAddr, PGN i32PGN, void *pData, uint16_t u16DataLen, PGNDOB** ppRetDOB) function to send a Single/Fast Packet Message with the specified PGN using the library.
- Note: Fast-Packets should be used ONLY in NMEA2000 mode as J1939 doesn't define it in the specification.
- For Multi-Packets:
- Use the CTCAN_STATUS CT2KLibSendPGNMultiPkt(CAN_PORTS_T i8Port, NETADDR u8DestAddr, PGN i32PGN, void *pData, uint16_t u16DataLen, MLTIPCKTSENDCALLBACK multiPktClbk, uint32_t u32Userdata, BOOL isBAM) function to send a Multi Packet Message with the specified PGN using the library.
- Note: Both BAM (Broadcast) and CMDT (Peer-to-peer) messages are supported.
- The MLTIPCKTSENDCALLBACK multiPktClbk is a special callback that is triggered only ONCE when that Multi-packet is finished sending (finished sending the last frame).
- The u32Userdata is a value that can be sent to the callback.
II. Receiving Messages/Frames
- Receiving Single-Packets, Fast-Packets and Multi-Packets is handled automatically by the library.
- If a message with a specific PGN is received and both that PGN and a callback are registered, the library will pass the frame data on to the callback.
J1939 and NMEA2000 Callback Support
- Use the CTCAN_STATUS CT2KSetPGNReceiveCallback(CAN_PORTS_T i8Port, PGN i32PGN, RCVRCB rCB, uint32_t u32Userdata) function to register a callback on a "PGN receive" message.
- Note: Registering for callbacks is supported both before and after the Library is started.
- Use the CTCAN_STATUS CT2KSetPGNISORequestReceivedCallback(CAN_PORTS_T i8Port, PGN i32PGN, ISOCallback_EA00 regCB, uint32_t u32UserData) function to register a callback when a specific PGN is being requested (ISO request) for transmitting.
- Note: Registering for callbacks is supported both before and after the Library is started.
- Use the CTCAN_STATUS CT2KLibAddrClaimReceiveCallback(CTLIB_ADDRCLAIM_CB AddrClaimCB) function to register a callback that will be triggered when the device makes the Address Claim.
- Note: Registering for callbacks is supported both before and after the Library is started.