/* * Main.c * * Created on: 30 juli 2023 * Author: Daniel Mårtensson */ #include /* Include Open SAE J1939 */ #include "Open_SAE_J1939/Open_SAE_J1939.h" void Callback_Function_Traffic(uint32_t ID, uint8_t DLC, uint8_t data[], bool is_TX) { /* Print if it is TX or RX */ printf("%s\t", is_TX ? "TX" : "RX"); /* Print ID as hex */ printf("%08X\t", ID); /* Print the data */ uint8_t i; for (i = 0U; i < DLC; i++) { printf("%X\t", data[i]); } /* Print the non-data */ for (i = DLC; i < 8U; i++) { printf("%X\t", 0U); } /* New line */ printf("\n"); } /* Apply your delay here */ void Callback_Function_Delay(uint8_t delay){ /* Place your hardware delay here e.g HAL_Delay(delay); for STM32 */ } int main() { /* Create our J1939 structure with two ECU */ J1939 j1939_1 = { 0 }; J1939 j1939_2 = { 0 }; /* Important to sent all non-address to 0xFF - Else we cannot use ECU address 0x0 */ uint8_t i; for (i = 0; i < 255; i++) { j1939_1.other_ECU_address[i] = 0xFF; j1939_2.other_ECU_address[i] = 0xFF; } /* Set the ECU address */ j1939_1.information_this_ECU.this_ECU_address = 0x80; /* From 0 to 253 because 254 = error address and 255 = broadcast address */ j1939_2.information_this_ECU.this_ECU_address = 0x90; /* Set NAME for ECU 1 */ j1939_1.information_this_ECU.this_name.identity_number = 100; /* From 0 to 2097151 */ j1939_1.information_this_ECU.this_name.manufacturer_code = 300; /* From 0 to 2047 */ j1939_1.information_this_ECU.this_name.function_instance = 10; /* From 0 to 31 */ j1939_1.information_this_ECU.this_name.ECU_instance = 2; /* From 0 to 7 */ j1939_1.information_this_ECU.this_name.function = FUNCTION_VDC_MODULE; /* From 0 to 255 */ j1939_1.information_this_ECU.this_name.vehicle_system = 100; /* From 0 to 127 */ j1939_1.information_this_ECU.this_name.arbitrary_address_capable = 0; /* From 0 to 1 */ j1939_1.information_this_ECU.this_name.industry_group = INDUSTRY_GROUP_CONSTRUCTION; /* From 0 to 7 */ j1939_1.information_this_ECU.this_name.vehicle_system_instance = 10; /* From 0 to 15 */ /* Set NAME for ECU 2 */ j1939_2.information_this_ECU.this_name.identity_number = 1000; /* From 0 to 2097151 */ j1939_2.information_this_ECU.this_name.manufacturer_code = 400; /* From 0 to 2047 */ j1939_2.information_this_ECU.this_name.function_instance = 20; /* From 0 to 31 */ j1939_2.information_this_ECU.this_name.ECU_instance = 1; /* From 0 to 7 */ j1939_2.information_this_ECU.this_name.function = FUNCTION_VDC_MODULE; /* From 0 to 255 */ j1939_2.information_this_ECU.this_name.vehicle_system = 50; /* From 0 to 127 */ j1939_2.information_this_ECU.this_name.arbitrary_address_capable = 0; /* From 0 to 1 */ j1939_2.information_this_ECU.this_name.industry_group = INDUSTRY_GROUP_GLOBAL; /* From 0 to 7 */ j1939_2.information_this_ECU.this_name.vehicle_system_instance = 10; /* From 0 to 15 */ /* Set the traffic function */ CAN_Set_Callback_Functions(NULL, NULL, Callback_Function_Traffic, Callback_Function_Delay); /* First let ECU 1 and ECU 2 know each other - This should be done at the startup of every ECU */ SAE_J1939_Response_Request_Address_Claimed(&j1939_1); SAE_J1939_Response_Request_Address_Claimed(&j1939_2); /* Let ECU 2 read and then ECU 1 */ Open_SAE_J1939_Listen_For_Messages(&j1939_2); Open_SAE_J1939_Listen_For_Messages(&j1939_1); /* Print information */ printf("How many external ECU are connected according to ECU 1: %i and the NAME came from address = 0x%x\n", j1939_1.number_of_other_ECU, j1939_1.from_other_ecu_name.from_ecu_address); printf("How many external ECU are connected according to ECU 2: %i and the NAME came from address = 0x%x\n", j1939_2.number_of_other_ECU, j1939_2.from_other_ecu_name.from_ecu_address); /* Set NAME for ECU 2 by using Commanded Address. Also change the ECU address from 0x90 to 0x91 */ SAE_J1939_Send_Commanded_Address(&j1939_1, 0x90, 0x91, 5000, 500, 30, 5, FUNCTION_AUXILIARY_VALVES_CONTROL, 50, 0, INDUSTRY_GROUP_AGRICULTURAL_AND_FORESTRY, 15); /* Listen for messages - The reason why it looks like this is because ECU 1 and ECU 2 shares the same CAN-bus buffer - In CAN bus application, you don't need this mess */ Open_SAE_J1939_Listen_For_Messages(&j1939_2); /* Read TP CM with control byte RTS from ECU 1 to ECU 2 */ Open_SAE_J1939_Listen_For_Messages(&j1939_1); /* Read control byte CTS response from ECU 2 */ Open_SAE_J1939_Listen_For_Messages(&j1939_2); /* Read TP DT package 1 from ECU 1 */ Open_SAE_J1939_Listen_For_Messages(&j1939_2); /* Read TP DT package 2 from ECU 1 */ Open_SAE_J1939_Listen_For_Messages(&j1939_2); /* Read one more package */ Open_SAE_J1939_Listen_For_Messages(&j1939_1); /* Read the send request of delete address from ECU 2 */ Open_SAE_J1939_Listen_For_Messages(&j1939_1); /* Read the new address from ECU 2 */ /* Print information */ printf("Identity number = %i\nManufacturer code = %i\nFunction instance = %i\nECU instance = %i\nFunction = %i\nVehicle system = %i\nArbitrary address capable = %i\nIndustry group = %i\nVehicle system instance = %i\nNew ECU address = 0x%X\n" , j1939_2.information_this_ECU.this_name.identity_number , j1939_2.information_this_ECU.this_name.manufacturer_code , j1939_2.information_this_ECU.this_name.function_instance , j1939_2.information_this_ECU.this_name.ECU_instance , j1939_2.information_this_ECU.this_name.function , j1939_2.information_this_ECU.this_name.vehicle_system , j1939_2.information_this_ECU.this_name.arbitrary_address_capable , j1939_2.information_this_ECU.this_name.industry_group , j1939_2.information_this_ECU.this_name.vehicle_system_instance , j1939_2.information_this_ECU.this_ECU_address); printf("How many external ECU are connected according to ECU 1: %i and the NAME came from address = 0x%X\n", j1939_1.number_of_other_ECU, j1939_1.from_other_ecu_name.from_ecu_address); printf("How many external ECU are connected according to ECU 2: %i and the NAME came from address = 0x%X\n", j1939_2.number_of_other_ECU, j1939_2.from_other_ecu_name.from_ecu_address); return 0; }