/** * @file tests/can_lowlevel.cpp * @brief CAN Lowlevel * @date Sep 5, 2015 * @author jjacobs * @copyright 2015 Dual Inventive Technology Centre B.V. */ #include "tests/can.h" #include #include static struct di_can_ctx ctx; static int test_send_cb_cnt = 0; static int test_recv_cb_cnt = 0; DI_CAN_FRAME_RX_DECL_ARRAY(test_can_frames, DI_CAN_CFG_FRAME_SIZE); void test_reset_cnt(void) { test_send_cb_cnt = 0; test_recv_cb_cnt = 0; } static di_errno_t test_can_recv_err_cb(struct di_can_frame_rx *frame) { (void)frame; return DNE_CAN_IO; } static di_errno_t test_can_recv_cb(struct di_can_frame_rx *frame) { frame->canid = 0x12345678; frame->size = 8; memset(frame->buf, 0x88, frame->size); test_recv_cb_cnt++; return DNOK; } static di_errno_t test_can_send_cb(const struct di_can_frame_tx *frame) { (void)frame; test_send_cb_cnt++; return DNOK; } TEST(time, init) { di_time_init(); } /** * Test if CAN context recv and send callback is called * the correct count */ TEST(can_lowlevel, send_recv_cb_count) { struct di_can_frame_tx test_frame_tx; struct di_can_frame_rx test_frame_rx; uint8_t test_data8[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; uint8_t test_data16[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; test_frame_tx.canid = 0; test_frame_tx.size = sizeof(test_data8); test_frame_tx.buf = test_data8; di_can_callback_set_recv(&ctx, test_can_recv_cb); di_can_callback_set_send(&ctx, test_can_send_cb); /* Call it directly */ ctx.recv(&test_frame_rx); ctx.send(&test_frame_tx); ASSERT_EQ(1, test_recv_cb_cnt); ASSERT_EQ(1, test_send_cb_cnt); test_reset_cnt(); /* Call from CAN lowlevel API */ ASSERT_EQ(DNE_CAN_NOBUFS, di_can_lowlevel_recv(&ctx)); di_can_lowlevel_send(&ctx, &test_frame_tx); ASSERT_EQ(1, test_recv_cb_cnt); ASSERT_EQ(1, test_send_cb_cnt); test_reset_cnt(); /* Send 16 byte can message using lowlevel The lowlevel layer doesn't care about more than 8 bytes because of CAN-bus limitiation */ test_frame_tx.canid = 0; test_frame_tx.size = sizeof(test_data16); test_frame_tx.buf = test_data16; di_can_lowlevel_send(&ctx, &test_frame_tx); ASSERT_EQ(1, test_send_cb_cnt); test_reset_cnt(); } /** * Test if recv fails * * No unused buffers (unitialized frame subsystem) * * Receive callback returns error */ TEST(can_lowlevel, recv_error) { di_can_callback_set_recv(&ctx, test_can_recv_err_cb); di_can_frame_init(&ctx, NULL, 0); ASSERT_EQ(DNE_CAN_NOBUFS, di_can_lowlevel_recv(&ctx)); di_can_frame_init(&ctx, test_can_frames, DI_CAN_CFG_FRAME_SIZE); ASSERT_EQ(DNE_CAN_IO, di_can_lowlevel_recv(&ctx)); } /** * Receive can message into the frame subsystem and check ready flag */ TEST(can_lowlevel, recv) { struct di_can_frame_rx *frame; di_can_callback_set_recv(&ctx, test_can_recv_cb); di_can_frame_init(&ctx, test_can_frames, DI_CAN_CFG_FRAME_SIZE); ASSERT_EQ(DNOK, di_can_lowlevel_recv(&ctx)); /* Check if frame is actualy in the ready queue */ frame = di_can_frame_get_ready(&ctx); ASSERT_NE((void *)NULL, frame); ASSERT_EQ(0x12345678U, frame->canid); ASSERT_EQ(8U, frame->size); di_can_frame_return_unused(frame); }