2121#include "driver/can.h"
2222#include "driver/gpio.h"
2323
24+ #include "../lib/isotp/isotp.h"
25+ #include "../lib/isotp/isotp_defines.h"
26+
27+ static const char * TAG = "can" ;
28+
2429bool update_bms_received = false;
2530bool update_mppt_received = false;
2631
2732#if CONFIG_THINGSET_CAN
2833
34+ #define ISOTP_BUFSIZE 512
35+
36+ /* Alloc IsoTpLink statically in RAM */
37+ static IsoTpLink isotp_link ;
38+
39+ /* Alloc send and receive buffer statically in RAM */
40+ static uint8_t isotp_recv_buf [ISOTP_BUFSIZE ];
41+ static uint8_t isotp_send_buf [ISOTP_BUFSIZE ];
42+
43+ uint32_t can_addr_client = 0xF1 ; // this device
44+ uint32_t can_addr_server = 0x14 ; // select MPPT or BMS
45+
2946// buffer for JSON string generated from received data objects via CAN
3047static char json_buf [500 ];
3148
@@ -101,7 +118,8 @@ static int generate_json_string(char *buf, size_t len, DataObject *objs, size_t
101118 switch (objs [i ].raw_data [0 ]) {
102119 case CAN_TS_T_TRUE :
103120 case CAN_TS_T_FALSE :
104- pos += snprintf (& buf [pos ], len - pos , "%d" , (objs [i ].raw_data [0 ] == CAN_TS_T_TRUE ) ? 1 : 0 );
121+ pos += snprintf (& buf [pos ], len - pos , "%d" ,
122+ (objs [i ].raw_data [0 ] == CAN_TS_T_TRUE ) ? 1 : 0 );
105123 break ;
106124 case CAN_TS_T_POS_INT32 :
107125 value_abs =
@@ -160,7 +178,6 @@ static int generate_json_string(char *buf, size_t len, DataObject *objs, size_t
160178 return pos ;
161179}
162180
163-
164181char * get_mppt_json_data ()
165182{
166183 generate_json_string (json_buf , sizeof (json_buf ),
@@ -184,69 +201,106 @@ void can_setup()
184201 gpio_set_level (CONFIG_GPIO_CAN_STB , 0 );
185202#endif
186203
187- if (can_driver_install (& g_config , & t_config , & f_config ) == ESP_OK ) {
188- printf ("CAN driver installed\n" );
189- }
190- else {
191- printf ("Failed to install CAN driver\n" );
204+ if (can_driver_install (& g_config , & t_config , & f_config ) != ESP_OK ) {
205+ ESP_LOGE (TAG , "Failed to install CAN driver" );
192206 return ;
193207 }
194208
195- if (can_start () == ESP_OK ) {
196- printf ("CAN driver started\n" );
197- }
198- else {
199- printf ("Failed to start CAN driver\n" );
209+ if (can_start () != ESP_OK ) {
210+ ESP_LOGE (TAG , "Failed to start CAN driver" );
200211 return ;
201212 }
213+
214+ /* Initialize link with the CAN ID we send with */
215+ isotp_init_link (& isotp_link , can_addr_server << 8 | can_addr_client | 0x1ada << 16 ,
216+ isotp_send_buf , sizeof (isotp_send_buf ), isotp_recv_buf , sizeof (isotp_recv_buf ));
202217}
203218
204219void can_receive_task (void * arg )
205220{
206221 can_message_t message ;
207- //unsigned int msg_priority; // currently not used
208- unsigned int node_id ;
209- unsigned int data_object_id ;
222+ unsigned int device_addr ;
223+ unsigned int data_node_id ;
224+
225+ uint8_t payload [500 ];
210226
211227 while (1 ) {
212228 if (can_receive (& message , pdMS_TO_TICKS (10000 )) == ESP_OK ) {
213229
214- // ThingSet publication message format: https://thingset.github.io/spec/can
215- //msg_priority = message.identifier >> 26;
216- node_id = message .identifier & 0x000000FF ;
217- data_object_id = (message .identifier >> 8 ) & 0x000000FF ;
218-
219- if (node_id == 0 ) {
220- for (int i = 0 ; i < sizeof (data_obj_bms )/sizeof (DataObject ); i ++ ) {
221- if (data_obj_bms [i ].id == data_object_id ) {
222- memcpy (data_obj_bms [i ].raw_data , message .data , message .data_length_code );
223- data_obj_bms [i ].len = message .data_length_code ;
224- }
230+ /* checking for CAN ID used to receive ISO-TP frames */
231+ if (message .identifier == (can_addr_client << 8 | can_addr_server | 0x1ada << 16 )) {
232+ ESP_LOGI (TAG , "ISO TP msg part received" );
233+ isotp_on_can_message (& isotp_link , message .data , message .data_length_code );
234+
235+ /* process multiple frame transmissions and timeouts */
236+ isotp_poll (& isotp_link );
237+
238+ /* extract received data */
239+ uint16_t out_size ;
240+ int ret = isotp_receive (& isotp_link , payload , sizeof (payload ) - 1 , & out_size );
241+ if (ret == ISOTP_RET_OK ) {
242+ payload [out_size ] = '\0' ;
243+ ESP_LOGI (TAG , "Received %d bytes via ISO-TP: %s" , out_size , payload );
244+ /* ToDo: handle received message */
225245 }
226- update_bms_received = true;
227246 }
228- else if (node_id == 10 ) {
229- for (int i = 0 ; i < sizeof (data_obj_mppt )/sizeof (DataObject ); i ++ ) {
230- if (data_obj_mppt [i ].id == data_object_id ) {
231- memcpy (data_obj_mppt [i ].raw_data , message .data , message .data_length_code );
232- data_obj_mppt [i ].len = message .data_length_code ;
247+ else {
248+ // ThingSet publication message format: https://thingset.github.io/spec/can
249+ device_addr = message .identifier & 0x000000FF ;
250+ data_node_id = (message .identifier >> 8 ) & 0x0000FFFF ;
251+
252+ if (device_addr == 0 ) {
253+ for (int i = 0 ; i < sizeof (data_obj_bms ) / sizeof (DataObject ); i ++ ) {
254+ if (data_obj_bms [i ].id == data_node_id ) {
255+ memcpy (data_obj_bms [i ].raw_data , message .data ,
256+ message .data_length_code );
257+ data_obj_bms [i ].len = message .data_length_code ;
258+ }
233259 }
260+ update_bms_received = true;
261+ }
262+ else if (device_addr == 10 ) {
263+ for (int i = 0 ; i < sizeof (data_obj_mppt ) / sizeof (DataObject ); i ++ ) {
264+ if (data_obj_mppt [i ].id == data_node_id ) {
265+ memcpy (data_obj_mppt [i ].raw_data , message .data ,
266+ message .data_length_code );
267+ data_obj_mppt [i ].len = message .data_length_code ;
268+ }
269+ }
270+ update_mppt_received = true;
234271 }
235- update_mppt_received = true;
236- }
237272
238- printf ("CAN msg node %u, data object 0x%.2x = 0x" ,
239- node_id , data_object_id );
240- if (!( message .flags & CAN_MSG_FLAG_RTR ) ) {
241- for ( int i = 0 ; i < message . data_length_code ; i ++ ) {
242- printf ( "%.2x" , message . data [ i ]);
273+ printf ("CAN device addr %u, data node 0x%.2x = 0x" , device_addr , data_node_id );
274+ if (!( message . flags & CAN_MSG_FLAG_RTR )) {
275+ for ( int i = 0 ; i < message .data_length_code ; i ++ ) {
276+ printf ( "%.2x" , message . data [ i ]);
277+ }
243278 }
279+ printf ("\n" );
244280 }
245- printf ("\n" );
246281 }
247282 }
248283}
249284
285+ /* dummy task to send regular requests for testing */
286+ void isotp_task (void * arg )
287+ {
288+ //uint8_t ts_request[] = { 0x01, 0x18, 0x70, 0xA0 };
289+ uint8_t ts_request [] = "?output" ;
290+
291+ while (1 ) {
292+
293+ int ret = isotp_send (& isotp_link , ts_request , strlen ((char * )ts_request ));
294+ if (ISOTP_RET_OK == ret ) {
295+ printf ("ISOTP Send OK\n" );
296+ } else {
297+ printf ("ISOTP Send ERROR\n" );
298+ }
299+
300+ vTaskDelay (3000 / portTICK_PERIOD_MS );
301+ }
302+ }
303+
250304#else /* not CONFIG_THINGSET_CAN */
251305
252306char * get_mppt_json_data ()
0 commit comments