1 | volatile uint16_t id_tag = 0x068F;
|
2 | volatile uint16_t adc_data_buffer[64];
|
3 |
|
4 | ISR(CANIT_vect)
|
5 | {
|
6 | cli();
|
7 |
|
8 | uint8_t rx_data[8];
|
9 | uint16_t meanValue = 0;
|
10 | uint8_t channel;
|
11 | uint8_t rx_dlc = CANCDMOB & ((1<<DLC3)|(1<<DLC2)|(1<<DLC1)|(1<<DLC0));
|
12 |
|
13 | CANPAGE = CANHPMOB & 0xF0;
|
14 | for (uint8_t data_index = 0; data_index < rx_dlc; data_index++)
|
15 | *(rx_data + data_index) = CANMSG;
|
16 |
|
17 | can_clear_mob();
|
18 |
|
19 | switch(rx_data[0]){
|
20 | case (1):
|
21 | for (int i=0; i<64; i++)
|
22 | txCan(adc_data_buffer[i], i);
|
23 | break;
|
24 |
|
25 | case (2):
|
26 | if (rx_data[1] >= 64){ // --- invalid channel number
|
27 | channel = 0xE2;
|
28 | meanValue = 0;
|
29 | }
|
30 | else {
|
31 | channel = rx_data[1];
|
32 | meanValue = adc_data_buffer[channel];
|
33 | }
|
34 | txCan(meanValue, channel);
|
35 | break;
|
36 |
|
37 | } // switch (rx_data[0])
|
38 |
|
39 | rxCan();
|
40 | sei();
|
41 | }
|
42 |
|
43 | void rxCan(void)
|
44 | {
|
45 | can_msg rx_data_msg;
|
46 |
|
47 | rx_data_msg.status = 0;
|
48 | rx_data_msg.ext = 0; // CAN 2.0A
|
49 | rx_data_msg.id = id_tag; // CAN Identifier
|
50 | rx_data_msg.dlc = 2; // Data Length
|
51 | rx_data_msg.cmd = RX_DATA_MASKED; // Receive Data frame
|
52 |
|
53 | // --- use first free MOb
|
54 | // --- if no MOb is available wait for one
|
55 | rx_data_msg.handle = 0x00;
|
56 |
|
57 | can_config_mob(&rx_data_msg);
|
58 | }
|
59 |
|
60 | void txCan(uint16_t tx_data, uint8_t channel)
|
61 | {
|
62 | can_msg tx_data_msg;
|
63 | uint8_t tx_data_buffer[4];
|
64 | uint8_t chk = 0;
|
65 |
|
66 | tx_data_buffer[0] = channel;
|
67 | tx_data_buffer[1] = (uint8_t)(tx_data >> 8);
|
68 | tx_data_buffer[2] = (uint8_t)(tx_data);
|
69 |
|
70 | // --- calculate 8-bit LRC
|
71 | for (int i=0; i<3; i++)
|
72 | chk = chk^tx_data_buffer[i];
|
73 | tx_data_buffer[3] = chk;
|
74 |
|
75 | tx_data_msg.status = 0;
|
76 | tx_data_msg.pt_data = tx_data_buffer;
|
77 | tx_data_msg.ext = 0; // CAN 2.0A
|
78 | tx_data_msg.id = id_tag; // CAN Identifier
|
79 | tx_data_msg.dlc = 4; // Data Length
|
80 | tx_data_msg.cmd = TX_DATA; // Transmit
|
81 |
|
82 | // --- use first free MOb
|
83 | // --- if no MOb is available wait for one
|
84 | tx_data_msg.handle = can_get_free_mob();
|
85 | while(tx_data_msg.handle == NO_MOB)
|
86 | tx_data_msg.handle = can_get_free_mob_ext();
|
87 |
|
88 | can_config_mob(&tx_data_msg);
|
89 | }
|
90 |
|
91 | void can_clear_mob(void)
|
92 | {
|
93 | // --- Set all MOb registers to 0
|
94 | CANIDM4 = 0x00; CANIDM3 = 0x00; CANIDM2 = 0x00; CANIDM1 = 0x00;
|
95 | CANIDT4 = 0x00; CANIDT3 = 0x00; CANIDT2 = 0x00; CANIDT1 = 0x00;
|
96 | CANSTMOB=0x00;
|
97 | CANCDMOB = 0;
|
98 | for (int num_data = 0; num_data < 8; num_data++)
|
99 | CANMSG = 0;
|
100 | }
|
101 |
|
102 | void can_config_mob (can_msg* mob_conf)
|
103 | {
|
104 | CANPAGE = (mob_conf->handle << 4);
|
105 | can_clear_mob(); // to be sure MOb is cleared
|
106 |
|
107 | switch(mob_conf->cmd){
|
108 |
|
109 | case TX_DATA:
|
110 | can_set_id(mob_conf->ext, mob_conf->id);
|
111 | for (int cpt=0; cpt<mob_conf->dlc; cpt++)
|
112 | CANMSG = *(mob_conf->pt_data + cpt);
|
113 | CANCDMOB |= (mob_conf->dlc);
|
114 | CANCDMOB |= (1 << CONMOB0); }
|
115 | break;
|
116 |
|
117 | case RX_DATA_MASKED:
|
118 | can_set_id(mob_conf->ext, mob_conf->id);
|
119 | CANIDM4=0xFD; CANIDM3=0xFF; CANIDM2=0xFF; CANIDM1=0xFF;
|
120 | CANIDT4 &= ~(1<<RTRTAG)
|
121 | CANCDMOB |= (mob_conf->dlc);
|
122 | CANCDMOB |= (2 << CONMOB0); }
|
123 | break;
|
124 | }
|