Sophie Dexter
/
Just4Trionic
Just4Trionic - CAN and BDM FLASH programmer for Saab cars
canutils.cpp@5:1775b4b13232, 2015-04-25 (annotated)
- Committer:
- Just4pLeisure
- Date:
- Sat Apr 25 17:07:08 2015 +0000
- Revision:
- 5:1775b4b13232
- Parent:
- 4:682d96ff6d79
Version 1.5 Is a significant milestone.; ; Supports BDM and CAN read and write of T5.x, T7 and T8 ECU's plus T8 recovery.; A Target Resident Driver for BDM gives a big speed boost.; Supports many alternative replacement FLASH chips for T5.x ECU's;
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Just4pLeisure | 1:d5452e398b76 | 1 | /******************************************************************************* |
Just4pLeisure | 1:d5452e398b76 | 2 | |
Just4pLeisure | 1:d5452e398b76 | 3 | canutils.cpp |
Just4pLeisure | 4:682d96ff6d79 | 4 | (c) 2010, 2012 by Sophie Dexter |
Just4pLeisure | 1:d5452e398b76 | 5 | |
Just4pLeisure | 1:d5452e398b76 | 6 | General purpose CAN bus functions for Just4Trionic by Just4pLeisure |
Just4pLeisure | 1:d5452e398b76 | 7 | Functions that work with the CAN bus directly. Anything to do with the CAN bus |
Just4pLeisure | 1:d5452e398b76 | 8 | must (should anyway) be done by one of these functions. |
Just4pLeisure | 1:d5452e398b76 | 9 | |
Just4pLeisure | 1:d5452e398b76 | 10 | ******************************************************************************** |
Just4pLeisure | 1:d5452e398b76 | 11 | |
Just4pLeisure | 1:d5452e398b76 | 12 | WARNING: Use at your own risk, sadly this software comes with no guarantees. |
Just4pLeisure | 1:d5452e398b76 | 13 | This software is provided 'free' and in good faith, but the author does not |
Just4pLeisure | 1:d5452e398b76 | 14 | accept liability for any damage arising from its use. |
Just4pLeisure | 1:d5452e398b76 | 15 | |
Just4pLeisure | 1:d5452e398b76 | 16 | *******************************************************************************/ |
Just4pLeisure | 1:d5452e398b76 | 17 | |
Just4pLeisure | 1:d5452e398b76 | 18 | #include "canutils.h" |
Just4pLeisure | 1:d5452e398b76 | 19 | |
Just4pLeisure | 1:d5452e398b76 | 20 | //CAN can2(p30, p29); |
Just4pLeisure | 1:d5452e398b76 | 21 | // Use a timer to see if things take too long |
Just4pLeisure | 1:d5452e398b76 | 22 | Timer CANTimer; |
Just4pLeisure | 1:d5452e398b76 | 23 | |
Just4pLeisure | 1:d5452e398b76 | 24 | |
Just4pLeisure | 4:682d96ff6d79 | 25 | //LPC_CANx->MOD |= 1; // Disble CAN controller 2 |
Just4pLeisure | 4:682d96ff6d79 | 26 | //LPC_CANx->MOD |= (1 << 1); // Put into listen only mode |
Just4pLeisure | 4:682d96ff6d79 | 27 | //LPC_CANx->MOD &= ~(1); // Re-enable CAN controller |
Just4pLeisure | 4:682d96ff6d79 | 28 | |
Just4pLeisure | 5:1775b4b13232 | 29 | void can_disable(uint8_t chan) |
Just4pLeisure | 5:1775b4b13232 | 30 | { |
Just4pLeisure | 4:682d96ff6d79 | 31 | // Put a CAN controller into disabled condition |
Just4pLeisure | 4:682d96ff6d79 | 32 | chan == 1 ? LPC_CAN1->MOD |= 1 : LPC_CAN2->MOD |= 1; |
Just4pLeisure | 4:682d96ff6d79 | 33 | } |
Just4pLeisure | 4:682d96ff6d79 | 34 | |
Just4pLeisure | 5:1775b4b13232 | 35 | void can_enable(uint8_t chan) |
Just4pLeisure | 5:1775b4b13232 | 36 | { |
Just4pLeisure | 4:682d96ff6d79 | 37 | // Put a CAN controller in operating mode |
Just4pLeisure | 4:682d96ff6d79 | 38 | chan == 1 ? LPC_CAN1->MOD &= ~(1) : LPC_CAN2->MOD &= ~(1); |
Just4pLeisure | 4:682d96ff6d79 | 39 | } |
Just4pLeisure | 4:682d96ff6d79 | 40 | |
Just4pLeisure | 5:1775b4b13232 | 41 | void can_configure(uint8_t chan, uint32_t baud, bool listen) |
Just4pLeisure | 5:1775b4b13232 | 42 | { |
Just4pLeisure | 4:682d96ff6d79 | 43 | |
Just4pLeisure | 4:682d96ff6d79 | 44 | LPC_CAN_TypeDef *pCANx = (chan == 1) ? LPC_CAN1 : LPC_CAN2; |
Just4pLeisure | 4:682d96ff6d79 | 45 | |
Just4pLeisure | 4:682d96ff6d79 | 46 | uint32_t result; |
Just4pLeisure | 4:682d96ff6d79 | 47 | uint8_t TQU, TSEG1=0, TSEG2=0; |
Just4pLeisure | 4:682d96ff6d79 | 48 | uint16_t BRP=0; |
Just4pLeisure | 4:682d96ff6d79 | 49 | |
Just4pLeisure | 4:682d96ff6d79 | 50 | switch (chan) { |
Just4pLeisure | 4:682d96ff6d79 | 51 | case 1: |
Just4pLeisure | 4:682d96ff6d79 | 52 | LPC_SC->PCONP |= (1 << 13); // Enable CAN controller 1 |
Just4pLeisure | 4:682d96ff6d79 | 53 | LPC_PINCON->PINSEL0 |= (1 << 0); // Pin 9 (port0 bit0) used as Receive |
Just4pLeisure | 4:682d96ff6d79 | 54 | LPC_PINCON->PINSEL0 |= (1 << 2); // Pin 10 (port0 bit1) used as Transmit |
Just4pLeisure | 4:682d96ff6d79 | 55 | break; |
Just4pLeisure | 4:682d96ff6d79 | 56 | case 2: |
Just4pLeisure | 4:682d96ff6d79 | 57 | default: |
Just4pLeisure | 4:682d96ff6d79 | 58 | LPC_SC->PCONP |= (1 << 14); // Enable CAN controller 2 |
Just4pLeisure | 4:682d96ff6d79 | 59 | LPC_PINCON->PINSEL0 |= (1 << 9); // Pin 30 (port0 bit4) used as Receive |
Just4pLeisure | 4:682d96ff6d79 | 60 | LPC_PINCON->PINSEL0 |= (1 << 11); // Pin 29 (port0 bit5) used as Transmit |
Just4pLeisure | 4:682d96ff6d79 | 61 | break; |
Just4pLeisure | 4:682d96ff6d79 | 62 | } |
Just4pLeisure | 4:682d96ff6d79 | 63 | pCANx->MOD = 0x01; // Put into reset mode |
Just4pLeisure | 4:682d96ff6d79 | 64 | |
Just4pLeisure | 4:682d96ff6d79 | 65 | pCANx->IER = 0; // Disable all interrupts |
Just4pLeisure | 4:682d96ff6d79 | 66 | pCANx->GSR = 0; // Clear status register |
Just4pLeisure | 4:682d96ff6d79 | 67 | pCANx->CMR = (1<<1)|(1<<2)|(1<<3); // Clear Receive path, abort anything waiting to send and clear errors |
Just4pLeisure | 4:682d96ff6d79 | 68 | // CANx->CMR = CAN_CMR_AT | CAN_CMR_RRB | CAN_CMR_CDO; |
Just4pLeisure | 4:682d96ff6d79 | 69 | result = pCANx->ICR; // Read interrupt register to clear it |
Just4pLeisure | 4:682d96ff6d79 | 70 | |
Just4pLeisure | 4:682d96ff6d79 | 71 | // Calculate a suitable BTR register setting |
Just4pLeisure | 4:682d96ff6d79 | 72 | // The Bit Rate Pre-scaler (BRP) can be in the range of 1-1024 |
Just4pLeisure | 4:682d96ff6d79 | 73 | // Bit Time can be be between 25 and 8 Time Quanta (TQU) according to CANopen |
Just4pLeisure | 4:682d96ff6d79 | 74 | // Bit Time = SyncSeg(1) + TSEG1(1-16) + TSEG2(1-8) |
Just4pLeisure | 4:682d96ff6d79 | 75 | // SyncSeg is always 1TQU, TSEG2 must be at least 2TQU to be longer than the processing time |
Just4pLeisure | 4:682d96ff6d79 | 76 | // Opinions vary on when to take a sample but a point roughly 2/3 of Bit Time seems OK, TSEG1 is roughly 2*TSEG2 |
Just4pLeisure | 4:682d96ff6d79 | 77 | // Synchronisation Jump width can be 1-4 TQU, a value of 1 seems to be normal |
Just4pLeisure | 4:682d96ff6d79 | 78 | // All register values are -1, e.g. TSEG1 can range from 1-16 TQU, so register values are 0-15 to fit into 4 bits |
Just4pLeisure | 4:682d96ff6d79 | 79 | result = CANsuppliedCLK / baud; |
Just4pLeisure | 4:682d96ff6d79 | 80 | for (TQU=25; TQU>7; TQU--) { |
Just4pLeisure | 4:682d96ff6d79 | 81 | if ((result%TQU)==0) { |
Just4pLeisure | 4:682d96ff6d79 | 82 | BRP = (result/TQU) - 1; |
Just4pLeisure | 4:682d96ff6d79 | 83 | TSEG2 = (TQU/3) - 1; // Subtract 1 |
Just4pLeisure | 4:682d96ff6d79 | 84 | TSEG1 = TQU - (TQU/3) - 2; // Subtract 2 to allow for SyncSeg |
Just4pLeisure | 4:682d96ff6d79 | 85 | break; |
Just4pLeisure | 4:682d96ff6d79 | 86 | } |
Just4pLeisure | 4:682d96ff6d79 | 87 | } |
Just4pLeisure | 4:682d96ff6d79 | 88 | pCANx->BTR = (TSEG2<<20)|(TSEG1<<16)|(0<<14)|BRP; // Set bit timing, SAM = 0, TSEG2, TSEG1, SJW = 1 (0+1), BRP |
Just4pLeisure | 4:682d96ff6d79 | 89 | |
Just4pLeisure | 4:682d96ff6d79 | 90 | can_reset_filters(); // Initialise the Acceptance Filters |
Just4pLeisure | 4:682d96ff6d79 | 91 | can_use_filters(FALSE); // Accept all messages (Acceptance Filters disabled) |
Just4pLeisure | 4:682d96ff6d79 | 92 | // Go :-) |
Just4pLeisure | 4:682d96ff6d79 | 93 | can_rs_pin = listen; // enable/disable CAN driver chip |
Just4pLeisure | 4:682d96ff6d79 | 94 | pCANx->MOD = (listen <<1); // Enable CAN controller in active/listen mode |
Just4pLeisure | 4:682d96ff6d79 | 95 | } |
Just4pLeisure | 4:682d96ff6d79 | 96 | |
Just4pLeisure | 4:682d96ff6d79 | 97 | |
Just4pLeisure | 5:1775b4b13232 | 98 | void can_reset_filters() |
Just4pLeisure | 5:1775b4b13232 | 99 | { |
Just4pLeisure | 4:682d96ff6d79 | 100 | // Initialise the Acceptance Filters |
Just4pLeisure | 4:682d96ff6d79 | 101 | LPC_CANAF->AFMR = 0x01; // Put Acceptance Filter into reset/configuration mode |
Just4pLeisure | 4:682d96ff6d79 | 102 | for (uint16_t i = 0; i < 512; i++) |
Just4pLeisure | 4:682d96ff6d79 | 103 | LPC_CANAF_RAM->mask[i] = 0x00; // Clear the Acceptance Filter memory |
Just4pLeisure | 4:682d96ff6d79 | 104 | LPC_CANAF->SFF_sa = 0x00; // Clear the Acceptance Filter registers |
Just4pLeisure | 4:682d96ff6d79 | 105 | LPC_CANAF->SFF_GRP_sa = 0x00; |
Just4pLeisure | 4:682d96ff6d79 | 106 | LPC_CANAF->EFF_sa = 0x00; |
Just4pLeisure | 4:682d96ff6d79 | 107 | LPC_CANAF->EFF_GRP_sa = 0x00; |
Just4pLeisure | 4:682d96ff6d79 | 108 | LPC_CANAF->ENDofTable = 0x00; |
Just4pLeisure | 4:682d96ff6d79 | 109 | LPC_CANAF->AFMR = 0x00; // Enable Acceptance Filter all messages should be rejected |
Just4pLeisure | 4:682d96ff6d79 | 110 | } |
Just4pLeisure | 4:682d96ff6d79 | 111 | |
Just4pLeisure | 5:1775b4b13232 | 112 | void can_use_filters(bool active) |
Just4pLeisure | 5:1775b4b13232 | 113 | { |
Just4pLeisure | 4:682d96ff6d79 | 114 | active ? LPC_CANAF->AFMR = 0 : LPC_CANAF->AFMR = 2; |
Just4pLeisure | 4:682d96ff6d79 | 115 | } |
Just4pLeisure | 4:682d96ff6d79 | 116 | |
Just4pLeisure | 4:682d96ff6d79 | 117 | /*-------------------------------------------- |
Just4pLeisure | 4:682d96ff6d79 | 118 | setup acceptance filter for CAN controller 2 |
Just4pLeisure | 4:682d96ff6d79 | 119 | original http://www.dragonwake.com/download/LPC1768/Example/CAN/CAN.c |
Just4pLeisure | 4:682d96ff6d79 | 120 | simplified for CAN2 interface and std id (11 bit) only |
Just4pLeisure | 4:682d96ff6d79 | 121 | *--------------------------------------------*/ |
Just4pLeisure | 5:1775b4b13232 | 122 | void can_add_filter(uint8_t chan, uint32_t id) |
Just4pLeisure | 5:1775b4b13232 | 123 | { |
Just4pLeisure | 4:682d96ff6d79 | 124 | |
Just4pLeisure | 4:682d96ff6d79 | 125 | static int CAN_std_cnt = 0; |
Just4pLeisure | 4:682d96ff6d79 | 126 | uint32_t buf0, buf1; |
Just4pLeisure | 4:682d96ff6d79 | 127 | int cnt1, cnt2, bound1; |
Just4pLeisure | 4:682d96ff6d79 | 128 | |
Just4pLeisure | 4:682d96ff6d79 | 129 | /* Acceptance Filter Memory full */ |
Just4pLeisure | 4:682d96ff6d79 | 130 | if (((CAN_std_cnt + 1) >> 1) >= 512) |
Just4pLeisure | 4:682d96ff6d79 | 131 | return; // error: objects full |
Just4pLeisure | 4:682d96ff6d79 | 132 | |
Just4pLeisure | 4:682d96ff6d79 | 133 | /* Setup Acceptance Filter Configuration |
Just4pLeisure | 4:682d96ff6d79 | 134 | Acceptance Filter Mode Register = Off */ |
Just4pLeisure | 4:682d96ff6d79 | 135 | LPC_CANAF->AFMR = 0x00000001; |
Just4pLeisure | 4:682d96ff6d79 | 136 | |
Just4pLeisure | 4:682d96ff6d79 | 137 | id &= 0x000007FF; // Mask out 16-bits of ID |
Just4pLeisure | 4:682d96ff6d79 | 138 | id |= (chan-1) << 13; // Add CAN controller number (1 or 2) |
Just4pLeisure | 4:682d96ff6d79 | 139 | |
Just4pLeisure | 4:682d96ff6d79 | 140 | if (CAN_std_cnt == 0) { /* For entering first ID */ |
Just4pLeisure | 4:682d96ff6d79 | 141 | LPC_CANAF_RAM->mask[0] = 0x0000FFFF | (id << 16); |
Just4pLeisure | 4:682d96ff6d79 | 142 | } else if (CAN_std_cnt == 1) { /* For entering second ID */ |
Just4pLeisure | 4:682d96ff6d79 | 143 | if ((LPC_CANAF_RAM->mask[0] >> 16) > id) |
Just4pLeisure | 4:682d96ff6d79 | 144 | LPC_CANAF_RAM->mask[0] = (LPC_CANAF_RAM->mask[0] >> 16) | (id << 16); |
Just4pLeisure | 4:682d96ff6d79 | 145 | else |
Just4pLeisure | 4:682d96ff6d79 | 146 | LPC_CANAF_RAM->mask[0] = (LPC_CANAF_RAM->mask[0] & 0xFFFF0000) | id; |
Just4pLeisure | 4:682d96ff6d79 | 147 | } else { |
Just4pLeisure | 4:682d96ff6d79 | 148 | /* Find where to insert new ID */ |
Just4pLeisure | 4:682d96ff6d79 | 149 | cnt1 = 0; |
Just4pLeisure | 4:682d96ff6d79 | 150 | cnt2 = CAN_std_cnt; |
Just4pLeisure | 4:682d96ff6d79 | 151 | bound1 = (CAN_std_cnt - 1) >> 1; |
Just4pLeisure | 4:682d96ff6d79 | 152 | while (cnt1 <= bound1) { /* Loop through standard existing IDs */ |
Just4pLeisure | 4:682d96ff6d79 | 153 | if ((LPC_CANAF_RAM->mask[cnt1] >> 16) > id) { |
Just4pLeisure | 4:682d96ff6d79 | 154 | cnt2 = cnt1 * 2; |
Just4pLeisure | 4:682d96ff6d79 | 155 | break; |
Just4pLeisure | 4:682d96ff6d79 | 156 | } |
Just4pLeisure | 4:682d96ff6d79 | 157 | if ((LPC_CANAF_RAM->mask[cnt1] & 0x0000FFFF) > id) { |
Just4pLeisure | 4:682d96ff6d79 | 158 | cnt2 = cnt1 * 2 + 1; |
Just4pLeisure | 4:682d96ff6d79 | 159 | break; |
Just4pLeisure | 4:682d96ff6d79 | 160 | } |
Just4pLeisure | 4:682d96ff6d79 | 161 | cnt1++; /* cnt1 = U32 where to insert new ID */ |
Just4pLeisure | 4:682d96ff6d79 | 162 | } /* cnt2 = U16 where to insert new ID */ |
Just4pLeisure | 4:682d96ff6d79 | 163 | |
Just4pLeisure | 4:682d96ff6d79 | 164 | if (cnt1 > bound1) { /* Adding ID as last entry */ |
Just4pLeisure | 4:682d96ff6d79 | 165 | if ((CAN_std_cnt & 0x0001) == 0) /* Even number of IDs exists */ |
Just4pLeisure | 4:682d96ff6d79 | 166 | LPC_CANAF_RAM->mask[cnt1] = 0x0000FFFF | (id << 16); |
Just4pLeisure | 4:682d96ff6d79 | 167 | else /* Odd number of IDs exists */ |
Just4pLeisure | 4:682d96ff6d79 | 168 | LPC_CANAF_RAM->mask[cnt1] = (LPC_CANAF_RAM->mask[cnt1] & 0xFFFF0000) | id; |
Just4pLeisure | 4:682d96ff6d79 | 169 | } else { |
Just4pLeisure | 4:682d96ff6d79 | 170 | buf0 = LPC_CANAF_RAM->mask[cnt1]; /* Remember current entry */ |
Just4pLeisure | 4:682d96ff6d79 | 171 | if ((cnt2 & 0x0001) == 0) /* Insert new mask to even address */ |
Just4pLeisure | 4:682d96ff6d79 | 172 | buf1 = (id << 16) | (buf0 >> 16); |
Just4pLeisure | 4:682d96ff6d79 | 173 | else /* Insert new mask to odd address */ |
Just4pLeisure | 4:682d96ff6d79 | 174 | buf1 = (buf0 & 0xFFFF0000) | id; |
Just4pLeisure | 4:682d96ff6d79 | 175 | |
Just4pLeisure | 4:682d96ff6d79 | 176 | LPC_CANAF_RAM->mask[cnt1] = buf1; /* Insert mask */ |
Just4pLeisure | 4:682d96ff6d79 | 177 | |
Just4pLeisure | 4:682d96ff6d79 | 178 | bound1 = CAN_std_cnt >> 1; |
Just4pLeisure | 4:682d96ff6d79 | 179 | /* Move all remaining standard mask entries one place up */ |
Just4pLeisure | 4:682d96ff6d79 | 180 | while (cnt1 < bound1) { |
Just4pLeisure | 4:682d96ff6d79 | 181 | cnt1++; |
Just4pLeisure | 4:682d96ff6d79 | 182 | buf1 = LPC_CANAF_RAM->mask[cnt1]; |
Just4pLeisure | 4:682d96ff6d79 | 183 | LPC_CANAF_RAM->mask[cnt1] = (buf1 >> 16) | (buf0 << 16); |
Just4pLeisure | 4:682d96ff6d79 | 184 | buf0 = buf1; |
Just4pLeisure | 4:682d96ff6d79 | 185 | } |
Just4pLeisure | 4:682d96ff6d79 | 186 | |
Just4pLeisure | 4:682d96ff6d79 | 187 | if ((CAN_std_cnt & 0x0001) == 0) /* Even number of IDs exists */ |
Just4pLeisure | 4:682d96ff6d79 | 188 | LPC_CANAF_RAM->mask[cnt1] = (LPC_CANAF_RAM->mask[cnt1] & 0xFFFF0000) | (0x0000FFFF); |
Just4pLeisure | 4:682d96ff6d79 | 189 | } |
Just4pLeisure | 4:682d96ff6d79 | 190 | } |
Just4pLeisure | 4:682d96ff6d79 | 191 | CAN_std_cnt++; |
Just4pLeisure | 4:682d96ff6d79 | 192 | |
Just4pLeisure | 4:682d96ff6d79 | 193 | /* Calculate std ID start address (buf0) and ext ID start address <- none (buf1) */ |
Just4pLeisure | 4:682d96ff6d79 | 194 | buf0 = ((CAN_std_cnt + 1) >> 1) << 2; |
Just4pLeisure | 4:682d96ff6d79 | 195 | /* Setup acceptance filter pointers */ |
Just4pLeisure | 4:682d96ff6d79 | 196 | LPC_CANAF->SFF_sa = 0; |
Just4pLeisure | 4:682d96ff6d79 | 197 | LPC_CANAF->SFF_GRP_sa = buf0; |
Just4pLeisure | 4:682d96ff6d79 | 198 | LPC_CANAF->EFF_sa = buf0; |
Just4pLeisure | 4:682d96ff6d79 | 199 | LPC_CANAF->EFF_GRP_sa = buf0; |
Just4pLeisure | 4:682d96ff6d79 | 200 | LPC_CANAF->ENDofTable = buf0; |
Just4pLeisure | 4:682d96ff6d79 | 201 | |
Just4pLeisure | 4:682d96ff6d79 | 202 | LPC_CANAF->AFMR = 0x00000000; /* Use acceptance filter */ |
Just4pLeisure | 4:682d96ff6d79 | 203 | } // CAN2_wrFilter |
Just4pLeisure | 4:682d96ff6d79 | 204 | |
Just4pLeisure | 4:682d96ff6d79 | 205 | |
Just4pLeisure | 5:1775b4b13232 | 206 | void can_open() |
Just4pLeisure | 5:1775b4b13232 | 207 | { |
Just4pLeisure | 1:d5452e398b76 | 208 | // activate external can transceiver |
Just4pLeisure | 1:d5452e398b76 | 209 | can.reset(); |
Just4pLeisure | 1:d5452e398b76 | 210 | can_rs_pin = 0; |
Just4pLeisure | 1:d5452e398b76 | 211 | } |
Just4pLeisure | 1:d5452e398b76 | 212 | |
Just4pLeisure | 5:1775b4b13232 | 213 | void can_close() |
Just4pLeisure | 5:1775b4b13232 | 214 | { |
Just4pLeisure | 1:d5452e398b76 | 215 | // disable external can transceiver |
Just4pLeisure | 1:d5452e398b76 | 216 | can_rs_pin = 1; |
Just4pLeisure | 1:d5452e398b76 | 217 | can.reset(); |
Just4pLeisure | 1:d5452e398b76 | 218 | } |
Just4pLeisure | 1:d5452e398b76 | 219 | |
Just4pLeisure | 5:1775b4b13232 | 220 | void can_monitor() |
Just4pLeisure | 5:1775b4b13232 | 221 | { |
Just4pLeisure | 4:682d96ff6d79 | 222 | // Put CAN into silent monitoring mode |
Just4pLeisure | 4:682d96ff6d79 | 223 | can.monitor(1); |
Just4pLeisure | 4:682d96ff6d79 | 224 | } |
Just4pLeisure | 4:682d96ff6d79 | 225 | |
Just4pLeisure | 5:1775b4b13232 | 226 | void can_active() |
Just4pLeisure | 5:1775b4b13232 | 227 | { |
Just4pLeisure | 4:682d96ff6d79 | 228 | // Take CAN out of silent monitoring mode |
Just4pLeisure | 4:682d96ff6d79 | 229 | can.monitor(0); |
Just4pLeisure | 4:682d96ff6d79 | 230 | } |
Just4pLeisure | 4:682d96ff6d79 | 231 | |
Just4pLeisure | 5:1775b4b13232 | 232 | uint8_t can_set_speed(uint32_t speed) |
Just4pLeisure | 5:1775b4b13232 | 233 | { |
Just4pLeisure | 1:d5452e398b76 | 234 | // 600kbit/s first - basically sets up CAN interface, but to wrong speed - not sure what else it does |
Just4pLeisure | 1:d5452e398b76 | 235 | // can.frequency(600000); |
Just4pLeisure | 1:d5452e398b76 | 236 | // 615kbit/s direct write of 615 kbit/s speed setting |
Just4pLeisure | 1:d5452e398b76 | 237 | // LPC_CAN2->BTR = 0x370002; |
Just4pLeisure | 1:d5452e398b76 | 238 | return (can.frequency(speed)) ? TERM_OK : TERM_ERR; |
Just4pLeisure | 1:d5452e398b76 | 239 | } |
Just4pLeisure | 1:d5452e398b76 | 240 | |
Just4pLeisure | 3:92dae9083c83 | 241 | // |
Just4pLeisure | 3:92dae9083c83 | 242 | // show_can_message |
Just4pLeisure | 3:92dae9083c83 | 243 | // |
Just4pLeisure | 3:92dae9083c83 | 244 | // Displays a CAN message in the RX buffer if there is one. |
Just4pLeisure | 3:92dae9083c83 | 245 | // |
Just4pLeisure | 3:92dae9083c83 | 246 | // inputs: none |
Just4pLeisure | 3:92dae9083c83 | 247 | // return: bool TRUE if there was a message, FALSE if no message. |
Just4pLeisure | 3:92dae9083c83 | 248 | // |
Just4pLeisure | 5:1775b4b13232 | 249 | extern void show_can_message() |
Just4pLeisure | 5:1775b4b13232 | 250 | { |
Just4pLeisure | 1:d5452e398b76 | 251 | CANMessage can_MsgRx; |
Just4pLeisure | 1:d5452e398b76 | 252 | if (can.read(can_MsgRx)) { |
Just4pLeisure | 3:92dae9083c83 | 253 | CANRXLEDON; |
Just4pLeisure | 1:d5452e398b76 | 254 | printf("w%03x%d", can_MsgRx.id, can_MsgRx.len); |
Just4pLeisure | 3:92dae9083c83 | 255 | for (char i=0; i<can_MsgRx.len; i++) |
Just4pLeisure | 1:d5452e398b76 | 256 | printf("%02x", can_MsgRx.data[i]); |
Just4pLeisure | 4:682d96ff6d79 | 257 | //printf(" %c ", can_MsgRx.data[2]); |
Just4pLeisure | 1:d5452e398b76 | 258 | printf("\r\n"); |
Just4pLeisure | 1:d5452e398b76 | 259 | } |
Just4pLeisure | 3:92dae9083c83 | 260 | return; |
Just4pLeisure | 3:92dae9083c83 | 261 | } |
Just4pLeisure | 3:92dae9083c83 | 262 | |
Just4pLeisure | 3:92dae9083c83 | 263 | // |
Just4pLeisure | 4:682d96ff6d79 | 264 | // show_T5can_message |
Just4pLeisure | 4:682d96ff6d79 | 265 | // |
Just4pLeisure | 4:682d96ff6d79 | 266 | // Displays a Trionic 5 CAN message in the RX buffer if there is one. |
Just4pLeisure | 4:682d96ff6d79 | 267 | // |
Just4pLeisure | 4:682d96ff6d79 | 268 | // inputs: none |
Just4pLeisure | 4:682d96ff6d79 | 269 | // return: bool TRUE if there was a message, FALSE if no message. |
Just4pLeisure | 4:682d96ff6d79 | 270 | // |
Just4pLeisure | 5:1775b4b13232 | 271 | extern void show_T5can_message() |
Just4pLeisure | 5:1775b4b13232 | 272 | { |
Just4pLeisure | 4:682d96ff6d79 | 273 | CANMessage can_MsgRx; |
Just4pLeisure | 4:682d96ff6d79 | 274 | if (can.read(can_MsgRx)) { |
Just4pLeisure | 4:682d96ff6d79 | 275 | CANRXLEDON; |
Just4pLeisure | 4:682d96ff6d79 | 276 | switch (can_MsgRx.id) { |
Just4pLeisure | 4:682d96ff6d79 | 277 | case 0x005: |
Just4pLeisure | 4:682d96ff6d79 | 278 | case 0x006: |
Just4pLeisure | 4:682d96ff6d79 | 279 | case 0x00C: |
Just4pLeisure | 4:682d96ff6d79 | 280 | case 0x008: |
Just4pLeisure | 4:682d96ff6d79 | 281 | printf("w%03x%d", can_MsgRx.id, can_MsgRx.len); |
Just4pLeisure | 4:682d96ff6d79 | 282 | for (char i=0; i<can_MsgRx.len; i++) |
Just4pLeisure | 4:682d96ff6d79 | 283 | printf("%02x", can_MsgRx.data[i]); |
Just4pLeisure | 4:682d96ff6d79 | 284 | printf("\r\n"); |
Just4pLeisure | 4:682d96ff6d79 | 285 | break; |
Just4pLeisure | 4:682d96ff6d79 | 286 | } |
Just4pLeisure | 4:682d96ff6d79 | 287 | } |
Just4pLeisure | 4:682d96ff6d79 | 288 | return; |
Just4pLeisure | 4:682d96ff6d79 | 289 | } |
Just4pLeisure | 4:682d96ff6d79 | 290 | // |
Just4pLeisure | 4:682d96ff6d79 | 291 | // show_T7can_message |
Just4pLeisure | 4:682d96ff6d79 | 292 | // |
Just4pLeisure | 4:682d96ff6d79 | 293 | // Displays a Trionic 7 CAN message in the RX buffer if there is one. |
Just4pLeisure | 4:682d96ff6d79 | 294 | // |
Just4pLeisure | 4:682d96ff6d79 | 295 | // inputs: none |
Just4pLeisure | 4:682d96ff6d79 | 296 | // return: bool TRUE if there was a message, FALSE if no message. |
Just4pLeisure | 4:682d96ff6d79 | 297 | // |
Just4pLeisure | 5:1775b4b13232 | 298 | extern void show_T7can_message() |
Just4pLeisure | 5:1775b4b13232 | 299 | { |
Just4pLeisure | 4:682d96ff6d79 | 300 | CANMessage can_MsgRx; |
Just4pLeisure | 4:682d96ff6d79 | 301 | if (can.read(can_MsgRx)) { |
Just4pLeisure | 4:682d96ff6d79 | 302 | CANRXLEDON; |
Just4pLeisure | 4:682d96ff6d79 | 303 | switch (can_MsgRx.id) { |
Just4pLeisure | 4:682d96ff6d79 | 304 | case 0x1A0: //1A0h - Engine information |
Just4pLeisure | 4:682d96ff6d79 | 305 | case 0x280: //280h - Pedals, reverse gear |
Just4pLeisure | 4:682d96ff6d79 | 306 | case 0x290: //290h - Steering wheel and SID buttons |
Just4pLeisure | 4:682d96ff6d79 | 307 | case 0x2F0: //2F0h - Vehicle speed |
Just4pLeisure | 4:682d96ff6d79 | 308 | case 0x320: //320h - Doors, central locking and seat belts |
Just4pLeisure | 4:682d96ff6d79 | 309 | case 0x370: //370h - Mileage |
Just4pLeisure | 4:682d96ff6d79 | 310 | case 0x3A0: //3A0h - Vehicle speed |
Just4pLeisure | 4:682d96ff6d79 | 311 | case 0x3B0: //3B0h - Head lights |
Just4pLeisure | 4:682d96ff6d79 | 312 | case 0x3E0: //3E0h - Automatic Gearbox |
Just4pLeisure | 4:682d96ff6d79 | 313 | case 0x410: //410h - Light dimmer and light sensor |
Just4pLeisure | 4:682d96ff6d79 | 314 | case 0x430: //430h - SID beep request (interesting for Knock indicator?) |
Just4pLeisure | 4:682d96ff6d79 | 315 | case 0x460: //460h - Engine rpm and speed |
Just4pLeisure | 4:682d96ff6d79 | 316 | case 0x4A0: //4A0h - Steering wheel, Vehicle Identification Number |
Just4pLeisure | 4:682d96ff6d79 | 317 | case 0x520: //520h - ACC, inside temperature |
Just4pLeisure | 4:682d96ff6d79 | 318 | case 0x530: //530h - ACC |
Just4pLeisure | 4:682d96ff6d79 | 319 | case 0x5C0: //5C0h - Coolant temperature, air pressure |
Just4pLeisure | 4:682d96ff6d79 | 320 | case 0x630: //630h - Fuel usage |
Just4pLeisure | 4:682d96ff6d79 | 321 | case 0x640: //640h - Mileage |
Just4pLeisure | 4:682d96ff6d79 | 322 | case 0x7A0: //7A0h - Outside temperature |
Just4pLeisure | 4:682d96ff6d79 | 323 | printf("w%03x%d", can_MsgRx.id, can_MsgRx.len); |
Just4pLeisure | 4:682d96ff6d79 | 324 | for (char i=0; i<can_MsgRx.len; i++) |
Just4pLeisure | 4:682d96ff6d79 | 325 | printf("%02x", can_MsgRx.data[i]); |
Just4pLeisure | 4:682d96ff6d79 | 326 | //printf(" %c ", can_MsgRx.data[2]); |
Just4pLeisure | 4:682d96ff6d79 | 327 | printf("\r\n"); |
Just4pLeisure | 4:682d96ff6d79 | 328 | break; |
Just4pLeisure | 4:682d96ff6d79 | 329 | } |
Just4pLeisure | 4:682d96ff6d79 | 330 | } |
Just4pLeisure | 4:682d96ff6d79 | 331 | return; |
Just4pLeisure | 4:682d96ff6d79 | 332 | } |
Just4pLeisure | 4:682d96ff6d79 | 333 | // |
Just4pLeisure | 4:682d96ff6d79 | 334 | // show_T8can_message |
Just4pLeisure | 4:682d96ff6d79 | 335 | // |
Just4pLeisure | 4:682d96ff6d79 | 336 | // Displays a Trionic 8 CAN message in the RX buffer if there is one. |
Just4pLeisure | 4:682d96ff6d79 | 337 | // |
Just4pLeisure | 4:682d96ff6d79 | 338 | // inputs: none |
Just4pLeisure | 4:682d96ff6d79 | 339 | // return: bool TRUE if there was a message, FALSE if no message. |
Just4pLeisure | 4:682d96ff6d79 | 340 | // |
Just4pLeisure | 5:1775b4b13232 | 341 | extern void show_T8can_message() |
Just4pLeisure | 5:1775b4b13232 | 342 | { |
Just4pLeisure | 4:682d96ff6d79 | 343 | CANMessage can_MsgRx; |
Just4pLeisure | 4:682d96ff6d79 | 344 | if (can.read(can_MsgRx)) { |
Just4pLeisure | 4:682d96ff6d79 | 345 | CANRXLEDON; |
Just4pLeisure | 4:682d96ff6d79 | 346 | switch (can_MsgRx.id) { |
Just4pLeisure | 4:682d96ff6d79 | 347 | case 0x645: // CIM |
Just4pLeisure | 4:682d96ff6d79 | 348 | case 0x7E0: |
Just4pLeisure | 4:682d96ff6d79 | 349 | case 0x7E8: |
Just4pLeisure | 4:682d96ff6d79 | 350 | case 0x311: |
Just4pLeisure | 4:682d96ff6d79 | 351 | case 0x5E8: |
Just4pLeisure | 4:682d96ff6d79 | 352 | //case 0x101: |
Just4pLeisure | 4:682d96ff6d79 | 353 | printf("w%03x%d", can_MsgRx.id, can_MsgRx.len); |
Just4pLeisure | 4:682d96ff6d79 | 354 | for (char i=0; i<can_MsgRx.len; i++) |
Just4pLeisure | 4:682d96ff6d79 | 355 | printf("%02x", can_MsgRx.data[i]); |
Just4pLeisure | 4:682d96ff6d79 | 356 | printf("\r\n"); |
Just4pLeisure | 4:682d96ff6d79 | 357 | break; |
Just4pLeisure | 4:682d96ff6d79 | 358 | } |
Just4pLeisure | 4:682d96ff6d79 | 359 | } |
Just4pLeisure | 4:682d96ff6d79 | 360 | return; |
Just4pLeisure | 4:682d96ff6d79 | 361 | } |
Just4pLeisure | 4:682d96ff6d79 | 362 | |
Just4pLeisure | 4:682d96ff6d79 | 363 | // |
Just4pLeisure | 3:92dae9083c83 | 364 | // silent_can_message |
Just4pLeisure | 3:92dae9083c83 | 365 | // |
Just4pLeisure | 3:92dae9083c83 | 366 | // Turns on the CAN receive LED if there is a CAN message |
Just4pLeisure | 3:92dae9083c83 | 367 | // but doesn't displays anything. |
Just4pLeisure | 3:92dae9083c83 | 368 | // |
Just4pLeisure | 3:92dae9083c83 | 369 | // inputs: none |
Just4pLeisure | 3:92dae9083c83 | 370 | // return: bool TRUE if there was a message, FALSE if no message. |
Just4pLeisure | 3:92dae9083c83 | 371 | // |
Just4pLeisure | 5:1775b4b13232 | 372 | extern void silent_can_message() |
Just4pLeisure | 5:1775b4b13232 | 373 | { |
Just4pLeisure | 3:92dae9083c83 | 374 | CANMessage can_MsgRx; |
Just4pLeisure | 3:92dae9083c83 | 375 | if (can.read(can_MsgRx)) { |
Just4pLeisure | 3:92dae9083c83 | 376 | CANRXLEDON; |
Just4pLeisure | 3:92dae9083c83 | 377 | } |
Just4pLeisure | 3:92dae9083c83 | 378 | return; |
Just4pLeisure | 1:d5452e398b76 | 379 | } |
Just4pLeisure | 1:d5452e398b76 | 380 | |
Just4pLeisure | 1:d5452e398b76 | 381 | // |
Just4pLeisure | 1:d5452e398b76 | 382 | // Sends a CAN Message, returns FALSE if the message wasn't sent in time |
Just4pLeisure | 1:d5452e398b76 | 383 | // |
Just4pLeisure | 1:d5452e398b76 | 384 | // inputs: integer CAN message 'id', pointer to 'frame', integer message length and integer timeout |
Just4pLeisure | 1:d5452e398b76 | 385 | // return: TRUE if the CAN message was sent before the 'timeout' expires |
Just4pLeisure | 1:d5452e398b76 | 386 | // FALSE if 'timeout' expires or the message length is wrong |
Just4pLeisure | 1:d5452e398b76 | 387 | // |
Just4pLeisure | 5:1775b4b13232 | 388 | extern bool can_send_timeout (uint32_t id, char *frame, uint8_t len, uint16_t timeout) |
Just4pLeisure | 5:1775b4b13232 | 389 | { |
Just4pLeisure | 1:d5452e398b76 | 390 | CANTimer.reset(); |
Just4pLeisure | 1:d5452e398b76 | 391 | CANTimer.start(); |
Just4pLeisure | 5:1775b4b13232 | 392 | #ifdef DEBUG |
Just4pLeisure | 5:1775b4b13232 | 393 | printf("ID:%03x Len:%03x", id, len); |
Just4pLeisure | 5:1775b4b13232 | 394 | for (char i=0; i<len; i++) { |
Just4pLeisure | 5:1775b4b13232 | 395 | printf(" %02x", frame[i]); |
Just4pLeisure | 5:1775b4b13232 | 396 | } |
Just4pLeisure | 5:1775b4b13232 | 397 | printf("\n\r"); |
Just4pLeisure | 5:1775b4b13232 | 398 | #endif |
Just4pLeisure | 1:d5452e398b76 | 399 | while (CANTimer.read_ms() < timeout) { |
Just4pLeisure | 1:d5452e398b76 | 400 | if (can.write(CANMessage(id, frame, len))) { |
Just4pLeisure | 1:d5452e398b76 | 401 | CANTimer.stop(); |
Just4pLeisure | 2:bf3a2b29259a | 402 | CANTXLEDON; |
Just4pLeisure | 2:bf3a2b29259a | 403 | // led1 = 1; |
Just4pLeisure | 1:d5452e398b76 | 404 | return TRUE; |
Just4pLeisure | 1:d5452e398b76 | 405 | } |
Just4pLeisure | 1:d5452e398b76 | 406 | } |
Just4pLeisure | 1:d5452e398b76 | 407 | can.reset(); |
Just4pLeisure | 1:d5452e398b76 | 408 | CANTimer.stop(); |
Just4pLeisure | 1:d5452e398b76 | 409 | return FALSE; |
Just4pLeisure | 1:d5452e398b76 | 410 | } |
Just4pLeisure | 1:d5452e398b76 | 411 | |
Just4pLeisure | 1:d5452e398b76 | 412 | // |
Just4pLeisure | 1:d5452e398b76 | 413 | // Waits for a CAN Message with the specified 'id' for a time specified by the 'timeout' |
Just4pLeisure | 1:d5452e398b76 | 414 | // All other messages are ignored |
Just4pLeisure | 1:d5452e398b76 | 415 | // The CAN message frame is returned using the pointer to 'frame' |
Just4pLeisure | 1:d5452e398b76 | 416 | // |
Just4pLeisure | 1:d5452e398b76 | 417 | // inputs: integer CAN message 'id', pointer to 'frame' for returning the data |
Just4pLeisure | 1:d5452e398b76 | 418 | // integer expected length of message, len and integer for the waiting time 'timeout' |
Just4pLeisure | 1:d5452e398b76 | 419 | // |
Just4pLeisure | 1:d5452e398b76 | 420 | // return: TRUE if a qualifying message was received |
Just4pLeisure | 1:d5452e398b76 | 421 | // FALSE if 'timeout' expires or the message length is wrong |
Just4pLeisure | 1:d5452e398b76 | 422 | // |
Just4pLeisure | 5:1775b4b13232 | 423 | extern bool can_wait_timeout (uint32_t id, char *frame, uint8_t len, uint16_t timeout) |
Just4pLeisure | 5:1775b4b13232 | 424 | { |
Just4pLeisure | 1:d5452e398b76 | 425 | CANMessage CANMsgRx; |
Just4pLeisure | 1:d5452e398b76 | 426 | CANTimer.reset(); |
Just4pLeisure | 1:d5452e398b76 | 427 | CANTimer.start(); |
Just4pLeisure | 1:d5452e398b76 | 428 | while (CANTimer.read_ms() < timeout) { |
Just4pLeisure | 1:d5452e398b76 | 429 | if (can.read(CANMsgRx)) { |
Just4pLeisure | 5:1775b4b13232 | 430 | #ifdef DEBUG |
Just4pLeisure | 5:1775b4b13232 | 431 | printf("ID:%03x Len:%03x", CANMsgRx.id, CANMsgRx.len); |
Just4pLeisure | 5:1775b4b13232 | 432 | for (char i=0; i<len; i++) { |
Just4pLeisure | 5:1775b4b13232 | 433 | printf(" %02x", CANMsgRx.data[i]); |
Just4pLeisure | 5:1775b4b13232 | 434 | } |
Just4pLeisure | 5:1775b4b13232 | 435 | printf("\n\r"); |
Just4pLeisure | 5:1775b4b13232 | 436 | #endif |
Just4pLeisure | 2:bf3a2b29259a | 437 | CANRXLEDON; |
Just4pLeisure | 2:bf3a2b29259a | 438 | // led2 = 1; |
Just4pLeisure | 4:682d96ff6d79 | 439 | if (CANMsgRx.id == id || id ==0) { |
Just4pLeisure | 1:d5452e398b76 | 440 | CANTimer.stop(); |
Just4pLeisure | 5:1775b4b13232 | 441 | // if (CANMsgRx.len != len) |
Just4pLeisure | 1:d5452e398b76 | 442 | // return FALSE; |
Just4pLeisure | 1:d5452e398b76 | 443 | for (int i=0; i<len; i++) |
Just4pLeisure | 1:d5452e398b76 | 444 | frame[i] = CANMsgRx.data[i]; |
Just4pLeisure | 1:d5452e398b76 | 445 | return TRUE; |
Just4pLeisure | 1:d5452e398b76 | 446 | } |
Just4pLeisure | 1:d5452e398b76 | 447 | } |
Just4pLeisure | 1:d5452e398b76 | 448 | } |
Just4pLeisure | 1:d5452e398b76 | 449 | can.reset(); |
Just4pLeisure | 1:d5452e398b76 | 450 | CANTimer.stop(); |
Just4pLeisure | 1:d5452e398b76 | 451 | return FALSE; |
Just4pLeisure | 1:d5452e398b76 | 452 | } |