Nuvoton
/
NuMaker-mbed-can
NUMAKER CAN sample
main.cpp@11:36d172d475fa, 2 weeks ago (annotated)
- Committer:
- ccli8
- Date:
- Wed Apr 17 17:47:56 2024 +0800
- Revision:
- 11:36d172d475fa
- Parent:
- 10:33d27c970411
Support loopback mode
To enable loopback mode, both TX and RX are required to enable.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
cyliang | 0:df0aeb0c8f2c | 1 | #include "cmsis_os.h" |
cyliang | 0:df0aeb0c8f2c | 2 | #include "mbed.h" |
cyliang | 0:df0aeb0c8f2c | 3 | #include "CAN.h" |
cyliang | 0:df0aeb0c8f2c | 4 | |
cyliang | 0:df0aeb0c8f2c | 5 | |
cyliang | 0:df0aeb0c8f2c | 6 | DigitalOut led1(LED1, 1); //LED R OFF |
cyliang | 0:df0aeb0c8f2c | 7 | DigitalOut led2(LED2, 1); //LED G OFF |
cyliang | 0:df0aeb0c8f2c | 8 | DigitalOut led3(LED3, 1); //LED B OFF |
cyliang | 0:df0aeb0c8f2c | 9 | |
cyliang | 0:df0aeb0c8f2c | 10 | #define CAN_TX_MODE_TEST 0 |
cyliang | 0:df0aeb0c8f2c | 11 | #define CAN_RX_MODE_TEST 1 |
ccli8 |
11:36d172d475fa | 12 | #define CAN_LOOPBACK_MODE_TEST 0 |
ccli8 |
11:36d172d475fa | 13 | #if CAN_LOOPBACK_MODE_TEST && (!CAN_TX_MODE_TEST || !CAN_RX_MODE_TEST) |
ccli8 |
11:36d172d475fa | 14 | #error "Either TX or RX not enabled for loopback mode" |
ccli8 |
11:36d172d475fa | 15 | #endif |
ccli8 |
11:36d172d475fa | 16 | |
ccli8 |
6:b9714e564dee | 17 | /* WARNING: Don't enable interrupt mode on receive side. It is not supported on Nuvoton targets. */ |
ccli8 |
6:b9714e564dee | 18 | #define CAN_RX_IRQ_EN 0 |
cyliang | 0:df0aeb0c8f2c | 19 | #define LED_ALL_OFF led1=led2=led3=1 |
cyliang | 0:df0aeb0c8f2c | 20 | |
cyliang | 0:df0aeb0c8f2c | 21 | #define MSG_NUM_INDEX 5 // 0 ~ 31 |
cyliang | 0:df0aeb0c8f2c | 22 | #define CAN_DEV_ID 0x1AC |
cyliang | 0:df0aeb0c8f2c | 23 | |
cyliang | 0:df0aeb0c8f2c | 24 | #if defined(TARGET_NUMAKER_PFM_NUC472) |
ccli8 |
5:499978915868 | 25 | CAN canObj(PA_0, PA_1); // Internal in the board |
cyliang | 0:df0aeb0c8f2c | 26 | #elif defined(TARGET_NUMAKER_PFM_M453) |
ccli8 |
5:499978915868 | 27 | CAN canObj(PA_13, PA_12); // Internal in the board |
ccli8 |
5:499978915868 | 28 | #elif defined(TARGET_NUMAKER_PFM_M487) |
cyliang | 7:956b6cf0b070 | 29 | CAN canObj(D9, D8); // (rd, td) Change to match external attachment |
ccli8 |
6:b9714e564dee | 30 | #elif defined(TARGET_NUMAKER_IOT_M487) |
ccli8 |
6:b9714e564dee | 31 | CAN canObj(A0, A1); // Change to match external attachment |
cyliang | 7:956b6cf0b070 | 32 | #elif defined(TARGET_NUMAKER_IOT_M467) |
cyliang | 8:7310cfa7f71c | 33 | CAN canObj(A0, A1); // CAN1(rd, td) Change to match external attachment |
cyliang | 8:7310cfa7f71c | 34 | //CAN canObj(D9, D8); // CAN0 |
cyliang | 0:df0aeb0c8f2c | 35 | #endif |
cyliang | 0:df0aeb0c8f2c | 36 | |
cyliang | 0:df0aeb0c8f2c | 37 | CANMessage canMsg; |
cyliang | 0:df0aeb0c8f2c | 38 | |
cyliang | 0:df0aeb0c8f2c | 39 | osThreadId mainThreadID; |
cyliang | 0:df0aeb0c8f2c | 40 | |
cyliang | 0:df0aeb0c8f2c | 41 | static int read_MsgObj() |
cyliang | 0:df0aeb0c8f2c | 42 | { |
cyliang | 0:df0aeb0c8f2c | 43 | int i=0; |
cyliang | 0:df0aeb0c8f2c | 44 | |
cyliang | 0:df0aeb0c8f2c | 45 | i = canObj.read(canMsg, MSG_NUM_INDEX); |
cyliang | 0:df0aeb0c8f2c | 46 | |
cyliang | 0:df0aeb0c8f2c | 47 | switch (canMsg.data[0]) |
cyliang | 0:df0aeb0c8f2c | 48 | { |
cyliang | 0:df0aeb0c8f2c | 49 | case 0: |
cyliang | 0:df0aeb0c8f2c | 50 | LED_ALL_OFF; |
cyliang | 0:df0aeb0c8f2c | 51 | led1=0; |
cyliang | 0:df0aeb0c8f2c | 52 | break; |
cyliang | 0:df0aeb0c8f2c | 53 | |
cyliang | 0:df0aeb0c8f2c | 54 | case 1: |
cyliang | 0:df0aeb0c8f2c | 55 | LED_ALL_OFF; |
cyliang | 0:df0aeb0c8f2c | 56 | led2=0; |
cyliang | 0:df0aeb0c8f2c | 57 | break; |
cyliang | 0:df0aeb0c8f2c | 58 | |
cyliang | 0:df0aeb0c8f2c | 59 | case 2: |
cyliang | 0:df0aeb0c8f2c | 60 | LED_ALL_OFF; |
cyliang | 0:df0aeb0c8f2c | 61 | led3=0; |
cyliang | 0:df0aeb0c8f2c | 62 | break; |
cyliang | 0:df0aeb0c8f2c | 63 | |
cyliang | 0:df0aeb0c8f2c | 64 | default: |
cyliang | 0:df0aeb0c8f2c | 65 | LED_ALL_OFF; |
cyliang | 0:df0aeb0c8f2c | 66 | break; |
cyliang | 0:df0aeb0c8f2c | 67 | } |
cyliang | 0:df0aeb0c8f2c | 68 | |
cyliang | 0:df0aeb0c8f2c | 69 | return i; |
cyliang | 0:df0aeb0c8f2c | 70 | } |
cyliang | 0:df0aeb0c8f2c | 71 | |
cyliang | 0:df0aeb0c8f2c | 72 | void irq_callback(void) |
cyliang | 0:df0aeb0c8f2c | 73 | { |
ccli8 |
6:b9714e564dee | 74 | /* Wake up receive task */ |
ccli8 |
6:b9714e564dee | 75 | osSignalSet(mainThreadID, 0x06); |
cyliang | 0:df0aeb0c8f2c | 76 | } |
cyliang | 0:df0aeb0c8f2c | 77 | |
cyliang | 0:df0aeb0c8f2c | 78 | int main() { |
ccli8 |
6:b9714e564dee | 79 | #if CAN_TX_MODE_TEST |
ccli8 |
6:b9714e564dee | 80 | printf("CAN sender sample\r\n"); |
ccli8 |
6:b9714e564dee | 81 | #endif |
ccli8 |
6:b9714e564dee | 82 | |
ccli8 |
6:b9714e564dee | 83 | #if CAN_RX_MODE_TEST |
ccli8 |
6:b9714e564dee | 84 | printf("CAN receiver sample\r\n"); |
ccli8 |
6:b9714e564dee | 85 | #endif |
ccli8 |
6:b9714e564dee | 86 | |
cyliang | 0:df0aeb0c8f2c | 87 | int i=0; |
cyliang | 0:df0aeb0c8f2c | 88 | char data[8]={0}; |
cyliang | 0:df0aeb0c8f2c | 89 | |
cyliang | 0:df0aeb0c8f2c | 90 | mainThreadID = osThreadGetId(); |
cyliang | 0:df0aeb0c8f2c | 91 | |
cyliang | 0:df0aeb0c8f2c | 92 | /* Set Frequency 1khz~1000khz */ |
cyliang | 0:df0aeb0c8f2c | 93 | canObj.frequency(1000000); |
cyliang | 0:df0aeb0c8f2c | 94 | |
cyliang | 0:df0aeb0c8f2c | 95 | #if CAN_RX_MODE_TEST |
cyliang | 0:df0aeb0c8f2c | 96 | |
cyliang | 0:df0aeb0c8f2c | 97 | #if CAN_RX_IRQ_EN |
cyliang | 0:df0aeb0c8f2c | 98 | /* Attach irq function */ |
cyliang | 0:df0aeb0c8f2c | 99 | canObj.attach(irq_callback, CAN::RxIrq); |
cyliang | 0:df0aeb0c8f2c | 100 | #endif |
ccli8 |
10:33d27c970411 | 101 | |
ccli8 |
10:33d27c970411 | 102 | /* According to link below, filter #0 will accept any message, and |
ccli8 |
10:33d27c970411 | 103 | * no other filters can accept messages without re-configuring filter #0. |
ccli8 |
10:33d27c970411 | 104 | * https://os.mbed.com/questions/85183/How-to-use-CAN-filter-function |
ccli8 |
10:33d27c970411 | 105 | * |
ccli8 |
10:33d27c970411 | 106 | * Re-configure filter #0 to accept message ID 0 only. |
ccli8 |
10:33d27c970411 | 107 | */ |
ccli8 |
10:33d27c970411 | 108 | canObj.filter(0, 0xFFFFFFFF); |
ccli8 |
10:33d27c970411 | 109 | |
cyliang | 0:df0aeb0c8f2c | 110 | canObj.filter(CAN_DEV_ID, 0, CANStandard, MSG_NUM_INDEX); |
cyliang | 0:df0aeb0c8f2c | 111 | |
cyliang | 0:df0aeb0c8f2c | 112 | #endif |
ccli8 |
11:36d172d475fa | 113 | |
ccli8 |
11:36d172d475fa | 114 | #if CAN_LOOPBACK_MODE_TEST |
ccli8 |
11:36d172d475fa | 115 | if (!canObj.mode(CAN::SilentTest)) { |
ccli8 |
11:36d172d475fa | 116 | printf("CAN: Configure to SilentTest mode failed\n\n"); |
ccli8 |
11:36d172d475fa | 117 | return EXIT_FAILURE; |
ccli8 |
11:36d172d475fa | 118 | } |
ccli8 |
11:36d172d475fa | 119 | #endif |
ccli8 |
11:36d172d475fa | 120 | |
cyliang | 0:df0aeb0c8f2c | 121 | while (true) |
cyliang | 0:df0aeb0c8f2c | 122 | { |
cyliang | 0:df0aeb0c8f2c | 123 | |
cyliang | 0:df0aeb0c8f2c | 124 | |
cyliang | 0:df0aeb0c8f2c | 125 | #if CAN_TX_MODE_TEST |
cyliang | 0:df0aeb0c8f2c | 126 | |
cyliang | 0:df0aeb0c8f2c | 127 | canObj.write(CANMessage(CAN_DEV_ID, data)); |
cyliang | 0:df0aeb0c8f2c | 128 | |
cyliang | 0:df0aeb0c8f2c | 129 | if(data[0] == 2) |
cyliang | 0:df0aeb0c8f2c | 130 | data[0]=0; |
cyliang | 0:df0aeb0c8f2c | 131 | else |
cyliang | 0:df0aeb0c8f2c | 132 | data[0]++; |
ccli8 |
9:bb7099cd4943 | 133 | |
cyliang | 0:df0aeb0c8f2c | 134 | memset(&data[1], data[0], 7); |
ccli8 |
9:bb7099cd4943 | 135 | ThisThread::sleep_for(1000ms); |
ccli8 |
9:bb7099cd4943 | 136 | |
cyliang | 0:df0aeb0c8f2c | 137 | #endif |
cyliang | 0:df0aeb0c8f2c | 138 | |
cyliang | 0:df0aeb0c8f2c | 139 | #if CAN_RX_MODE_TEST |
ccli8 |
6:b9714e564dee | 140 | |
ccli8 |
6:b9714e564dee | 141 | #if (CAN_RX_IRQ_EN) |
cyliang | 0:df0aeb0c8f2c | 142 | /* Wait for receive task to wakeup */ |
ccli8 |
6:b9714e564dee | 143 | osSignalWait(0x06, osWaitForever); |
cyliang | 0:df0aeb0c8f2c | 144 | #endif |
ccli8 |
6:b9714e564dee | 145 | if (!read_MsgObj()) { |
ccli8 |
6:b9714e564dee | 146 | continue; |
ccli8 |
6:b9714e564dee | 147 | } |
ccli8 |
6:b9714e564dee | 148 | |
cyliang | 0:df0aeb0c8f2c | 149 | printf("Read ID=%8X, Type=%s, DLC=%d,Data=",canMsg.id,canMsg.format?"EXT":"STD",canMsg.len); |
cyliang | 0:df0aeb0c8f2c | 150 | for(i=0; i<canMsg.len; i++) |
cyliang | 0:df0aeb0c8f2c | 151 | printf("%02X,",canMsg.data[i]); |
cyliang | 0:df0aeb0c8f2c | 152 | printf("\r\n"); |
cyliang | 0:df0aeb0c8f2c | 153 | #endif |
cyliang | 0:df0aeb0c8f2c | 154 | } |
cyliang | 0:df0aeb0c8f2c | 155 | |
cyliang | 0:df0aeb0c8f2c | 156 | } |