Petter Bellander / Mbed 2 deprecated Saab-BT

Dependencies:   mbed

Committer:
petter
Date:
Fri Jan 15 22:10:11 2016 +0000
Revision:
10:8be92db98bf4
Parent:
9:9a4c81493a3d
Child:
11:74844f6ca8cf
First test of multiple rows in display

Who changed what in which revision?

UserRevisionLine numberNew contents of line
petter 0:6cf6e566c0da 1 // I-Bus information from http://pikkupossu.1g.fi/tomi/projects/i-bus/i-bus.html
petter 0:6cf6e566c0da 2 // 290h - Steering wheel and SID buttons | Rx
petter 0:6cf6e566c0da 3 // 328h - SID audio text | Tx
petter 0:6cf6e566c0da 4 // 32Ch - ACC to SID text
petter 0:6cf6e566c0da 5 // 32Fh - TWICE to SID text
petter 0:6cf6e566c0da 6 // 337h - SPA to SID text
petter 0:6cf6e566c0da 7 // 348h - SID audio text control | Tx
petter 0:6cf6e566c0da 8 // 34Ch - ACC to SID text control
petter 0:6cf6e566c0da 9 // 34Fh - TWICE to SID text control
petter 0:6cf6e566c0da 10 // 357h - SPA to SID text control
petter 0:6cf6e566c0da 11 // 368h - SID text priority | Tx
petter 0:6cf6e566c0da 12 // 3C0h - CD Changer control | Rx
petter 0:6cf6e566c0da 13 // 3C8h - CD Changer information | Tx
petter 0:6cf6e566c0da 14 // 430h - SID beep request | Tx
petter 0:6cf6e566c0da 15 // 6A1h - Audio head unit | Rx
petter 0:6cf6e566c0da 16 // 6A2h - CD changer | Tx
petter 0:6cf6e566c0da 17 // 320h - Doors, central locking and seat belts | Rx
petter 0:6cf6e566c0da 18
petter 0:6cf6e566c0da 19 /** Includes **/
petter 0:6cf6e566c0da 20 #include "CDC.h"
petter 0:6cf6e566c0da 21
petter 0:6cf6e566c0da 22 /** Various constants used for identifying the CDC **/
petter 0:6cf6e566c0da 23 #define CDC_APL_ADR 0x11
petter 0:6cf6e566c0da 24 #define CDC_SID_FUNCTION_ID 0x19
petter 0:6cf6e566c0da 25
petter 0:6cf6e566c0da 26 /** TX IDs: **/
petter 0:6cf6e566c0da 27 #define GENERAL_STATUS_CDC 0x3C8
petter 0:6cf6e566c0da 28 #define DISPLAY_RESOURCE_REQ 0x348 // 'Stolen' from the IHU since the CDC doesn't send this message
petter 0:6cf6e566c0da 29 #define WRITE_TEXT_ON_DISPLAY 0x328 // 'Stolen' from the IHU since the CDC doesn't send this message
petter 0:6cf6e566c0da 30 #define NODE_STATUS_TX 0x6A2
petter 0:6cf6e566c0da 31 #define SOUND_REQUEST 0x430
petter 0:6cf6e566c0da 32
petter 0:6cf6e566c0da 33 /** RX IDs: **/
petter 0:6cf6e566c0da 34 #define LOCK_STATUS 0x320
petter 0:6cf6e566c0da 35 #define IHU_BUTTONS 0x3C0
petter 0:6cf6e566c0da 36 #define DISPLAY_RESOURCE_GRANT 0x368
petter 0:6cf6e566c0da 37 #define NODE_STATUS_RX 0x6A1
petter 0:6cf6e566c0da 38 #define STEERING_WHEEL_BUTTONS 0x290
petter 0:6cf6e566c0da 39
petter 0:6cf6e566c0da 40
petter 0:6cf6e566c0da 41 /** Variables: **/
petter 0:6cf6e566c0da 42 bool cdc_active = false; // True while our module, the simulated CDC, is active.
petter 0:6cf6e566c0da 43 bool mute = false;
petter 10:8be92db98bf4 44 char active_row_SID = 2;
petter 0:6cf6e566c0da 45 int toggle_shuffle = 1;
petter 6:c454f88524d6 46 int ninefive_cmd[] = {0x32,0x00,0x00,0x16,0x01,0x02,0x00,0x00,-1};
petter 0:6cf6e566c0da 47 int beep_cmd[] = {0x80,0x04,0x00,0x00,0x00,0x00,0x00,0x00,-1};
petter 0:6cf6e566c0da 48 int cdc_status_cmd[] = {0xE0,0x00,0x01,0x41,0x01,0x00,0x00,0xD0,-1};
petter 10:8be92db98bf4 49 int display_request_cmd[3][9] = {
petter 10:8be92db98bf4 50 {CDC_APL_ADR,0x00,0x05,CDC_SID_FUNCTION_ID,0x00,0x00,0x00,0x00,-1}, //whole display
petter 10:8be92db98bf4 51 {CDC_APL_ADR,0x01,0x05,CDC_SID_FUNCTION_ID,0x00,0x00,0x00,0x00,-1}, //only row 1
petter 10:8be92db98bf4 52 {CDC_APL_ADR,0x02,0x05,CDC_SID_FUNCTION_ID,0x00,0x00,0x00,0x00,-1}, //only row 2
petter 10:8be92db98bf4 53 };
petter 0:6cf6e566c0da 54 //int display_clear_cmd[] = {CDC_APL_ADR,0x02,0xFF,CDC_SID_FUNCTION_ID,0x00,0x00,0x00,0x00,-1};
petter 0:6cf6e566c0da 55
petter 0:6cf6e566c0da 56 /** Com: **/
petter 0:6cf6e566c0da 57 CAN can(p9, p10);
petter 0:6cf6e566c0da 58 CANMessage CAN_TxMsg;
petter 0:6cf6e566c0da 59 CANMessage CAN_RxMsg;
petter 10:8be92db98bf4 60 CANMessage CAN_DispMsg[2][3];
petter 0:6cf6e566c0da 61
petter 0:6cf6e566c0da 62 /** I/O: **/
petter 0:6cf6e566c0da 63 DigitalOut led1(LED1, 0);
petter 0:6cf6e566c0da 64 DigitalOut led2(LED2, 0);
petter 0:6cf6e566c0da 65
petter 2:10c60edc8573 66 /** Timers: **/
petter 2:10c60edc8573 67 Timer playback;
petter 2:10c60edc8573 68
petter 0:6cf6e566c0da 69 /******************************************************************************
petter 0:6cf6e566c0da 70 * PUBLIC METHODS
petter 0:6cf6e566c0da 71 ******************************************************************************/
petter 0:6cf6e566c0da 72
petter 0:6cf6e566c0da 73 /** Initializes CDC **/
petter 0:6cf6e566c0da 74 void CDC::init() {
petter 0:6cf6e566c0da 75 can.frequency(47619);
petter 0:6cf6e566c0da 76 printf("CAN Frequency set\r\n");
petter 0:6cf6e566c0da 77 CAN_wrFilter(1, LOCK_STATUS);
petter 0:6cf6e566c0da 78 CAN_wrFilter(1, IHU_BUTTONS);
petter 0:6cf6e566c0da 79 CAN_wrFilter(1, DISPLAY_RESOURCE_GRANT);
petter 0:6cf6e566c0da 80 CAN_wrFilter(1, NODE_STATUS_RX);
petter 0:6cf6e566c0da 81 CAN_wrFilter(1, STEERING_WHEEL_BUTTONS);
petter 0:6cf6e566c0da 82 CAN_wrFilter(1, DISPLAY_RESOURCE_REQ);
petter 0:6cf6e566c0da 83 printf("CAN Filters set\r\n");
petter 0:6cf6e566c0da 84
petter 0:6cf6e566c0da 85 CAN_TxMsg.len = 8;
petter 10:8be92db98bf4 86 CAN_DispMsg[0][0].len = 8;
petter 10:8be92db98bf4 87 CAN_DispMsg[0][1].len = 8;
petter 10:8be92db98bf4 88 CAN_DispMsg[0][2].len = 8;
petter 10:8be92db98bf4 89 CAN_DispMsg[1][0].len = 8;
petter 10:8be92db98bf4 90 CAN_DispMsg[1][1].len = 8;
petter 10:8be92db98bf4 91 CAN_DispMsg[1][2].len = 8;
petter 10:8be92db98bf4 92 CAN_DispMsg[0][0].id = WRITE_TEXT_ON_DISPLAY;
petter 10:8be92db98bf4 93 CAN_DispMsg[0][1].id = WRITE_TEXT_ON_DISPLAY;
petter 10:8be92db98bf4 94 CAN_DispMsg[0][2].id = WRITE_TEXT_ON_DISPLAY;
petter 10:8be92db98bf4 95 CAN_DispMsg[1][0].id = WRITE_TEXT_ON_DISPLAY;
petter 10:8be92db98bf4 96 CAN_DispMsg[1][1].id = WRITE_TEXT_ON_DISPLAY;
petter 10:8be92db98bf4 97 CAN_DispMsg[1][2].id = WRITE_TEXT_ON_DISPLAY;
petter 10:8be92db98bf4 98 CAN_DispMsg[0][0].data[0] = 0x42; // order, new
petter 10:8be92db98bf4 99 CAN_DispMsg[1][0].data[0] = 0x42; // order, new
petter 10:8be92db98bf4 100 CAN_DispMsg[0][1].data[0] = 0x01; // order
petter 10:8be92db98bf4 101 CAN_DispMsg[1][1].data[0] = 0x01; // order
petter 10:8be92db98bf4 102 CAN_DispMsg[0][2].data[0] = 0x00; // order
petter 10:8be92db98bf4 103 CAN_DispMsg[1][2].data[0] = 0x00; // order
petter 10:8be92db98bf4 104 CAN_DispMsg[0][0].data[1] = 0x96; // Address of the SID
petter 10:8be92db98bf4 105 CAN_DispMsg[1][0].data[1] = 0x96; // Address of the SID
petter 10:8be92db98bf4 106 CAN_DispMsg[0][1].data[1] = 0x96; // Address of the SID
petter 10:8be92db98bf4 107 CAN_DispMsg[1][1].data[1] = 0x96; // Address of the SID
petter 10:8be92db98bf4 108 CAN_DispMsg[0][2].data[1] = 0x96; // Address of the SID
petter 10:8be92db98bf4 109 CAN_DispMsg[1][2].data[1] = 0x96; // Address of the SID
petter 10:8be92db98bf4 110 CAN_DispMsg[0][0].data[2] = 0x01; // Writing to row 1
petter 10:8be92db98bf4 111 CAN_DispMsg[1][0].data[2] = 0x02; // Writing to row 2
petter 10:8be92db98bf4 112 CAN_DispMsg[0][1].data[2] = 0x01; // Writing to row 1
petter 10:8be92db98bf4 113 CAN_DispMsg[1][1].data[2] = 0x02; // Writing to row 2
petter 10:8be92db98bf4 114 CAN_DispMsg[0][2].data[2] = 0x01; // Writing to row 1
petter 10:8be92db98bf4 115 CAN_DispMsg[1][2].data[2] = 0x02; // Writing to row 2
petter 9:9a4c81493a3d 116 display("PETTERS BT", 2);
petter 0:6cf6e566c0da 117 }
petter 0:6cf6e566c0da 118
petter 0:6cf6e566c0da 119 /** Handles an incoming (RX) frame **/
petter 0:6cf6e566c0da 120 IBUS_COMMAND CDC::get_cmd() {
petter 0:6cf6e566c0da 121 if(can.read(CAN_RxMsg)) {
petter 0:6cf6e566c0da 122 led2 = !led2;
petter 0:6cf6e566c0da 123 CAN_TxMsg.data[0]++;
petter 0:6cf6e566c0da 124 switch (CAN_RxMsg.id) {
petter 0:6cf6e566c0da 125 case LOCK_STATUS:
petter 0:6cf6e566c0da 126 {
petter 0:6cf6e566c0da 127 int locked = (CAN_RxMsg.data[1] >> 7) & 1;
petter 0:6cf6e566c0da 128 if(locked){
petter 0:6cf6e566c0da 129 return IBUS_DOORS_LOCKED;
petter 0:6cf6e566c0da 130 }
petter 0:6cf6e566c0da 131 else{
petter 0:6cf6e566c0da 132 return IBUS_DOORS_UNLOCKED;
petter 0:6cf6e566c0da 133 }
petter 0:6cf6e566c0da 134 }
petter 0:6cf6e566c0da 135 case DISPLAY_RESOURCE_REQ:
petter 10:8be92db98bf4 136 send_can_frame(DISPLAY_RESOURCE_REQ, display_request_cmd[active_row_SID]);
petter 2:10c60edc8573 137 update_elapsed_time();
petter 0:6cf6e566c0da 138 send_can_frame(GENERAL_STATUS_CDC, cdc_status_cmd);
petter 0:6cf6e566c0da 139 led1 = !led1;
petter 0:6cf6e566c0da 140 break;
petter 0:6cf6e566c0da 141 case NODE_STATUS_RX:
petter 6:c454f88524d6 142 send_can_frame(NODE_STATUS_TX, ninefive_cmd);
petter 0:6cf6e566c0da 143 break;
petter 0:6cf6e566c0da 144 case IHU_BUTTONS:
petter 0:6cf6e566c0da 145 return get_ihu_cmd();
petter 0:6cf6e566c0da 146 case STEERING_WHEEL_BUTTONS:
petter 0:6cf6e566c0da 147 return get_steering_wheel_cmd();
petter 0:6cf6e566c0da 148 case DISPLAY_RESOURCE_GRANT:
petter 10:8be92db98bf4 149 if (CAN_RxMsg.data[1] == CDC_SID_FUNCTION_ID) {
petter 0:6cf6e566c0da 150 //We have been granted the right to write text to the second row in the SID
petter 10:8be92db98bf4 151 display_request_cmd[CAN_RxMsg.data[0]][2] = 0x04;
petter 10:8be92db98bf4 152 display_update(CAN_RxMsg.data[0]);
petter 0:6cf6e566c0da 153 }
petter 10:8be92db98bf4 154 else {
petter 10:8be92db98bf4 155 //Someone else has been granted the display, we need to back down
petter 10:8be92db98bf4 156 display_request_cmd[0][2] = 0x05; //message is considered new
petter 10:8be92db98bf4 157 display_request_cmd[1][2] = 0x05; //message is considered new
petter 10:8be92db98bf4 158 display_request_cmd[2][2] = 0x05; //message is considered new
petter 0:6cf6e566c0da 159 }
petter 0:6cf6e566c0da 160 break;
petter 0:6cf6e566c0da 161 }
petter 0:6cf6e566c0da 162 return IBUS_OTHER_MESSAGE;
petter 0:6cf6e566c0da 163 }
petter 0:6cf6e566c0da 164 return IBUS_NO_MESSAGE;
petter 0:6cf6e566c0da 165 }
petter 0:6cf6e566c0da 166
petter 0:6cf6e566c0da 167 /** Handles the IHU_BUTTONS frame that the IHU sends us when it wants to control some feature of the CDC **/
petter 0:6cf6e566c0da 168 IBUS_COMMAND CDC::get_ihu_cmd() {
petter 0:6cf6e566c0da 169 bool event = (CAN_RxMsg.data[0] == 0x80);
petter 0:6cf6e566c0da 170 if (!event) {
petter 0:6cf6e566c0da 171 //Ignore the message if it wasn't sent on event
petter 0:6cf6e566c0da 172 return IBUS_OTHER_MESSAGE;
petter 0:6cf6e566c0da 173 }
petter 0:6cf6e566c0da 174 switch (CAN_RxMsg.data[1]) {
petter 0:6cf6e566c0da 175 case 0x24: // CDC = ON (CD/RDM button has been pressed twice)
petter 0:6cf6e566c0da 176 cdc_active = true;
petter 0:6cf6e566c0da 177 return IBUS_CDC_ON;
petter 0:6cf6e566c0da 178 case 0x14: // CDC = OFF (Back to Radio or Tape mode)
petter 0:6cf6e566c0da 179 cdc_active = false;
petter 0:6cf6e566c0da 180 return IBUS_CDC_OFF;
petter 0:6cf6e566c0da 181 }
petter 0:6cf6e566c0da 182 if (cdc_active) {
petter 0:6cf6e566c0da 183 switch (CAN_RxMsg.data[1]) {
petter 0:6cf6e566c0da 184 case 0x35: // Track up
petter 0:6cf6e566c0da 185 return IBUS_SKIP_FW;
petter 0:6cf6e566c0da 186 case 0x36: // Track down
petter 0:6cf6e566c0da 187 return IBUS_SKIP_BW;
petter 0:6cf6e566c0da 188 }
petter 0:6cf6e566c0da 189 }
petter 0:6cf6e566c0da 190 return IBUS_OTHER_MESSAGE;
petter 0:6cf6e566c0da 191 }
petter 0:6cf6e566c0da 192
petter 0:6cf6e566c0da 193 /** Handles the STEERING_WHEEL_BUTTONS frame * TODO connect the SID button events to actions **/
petter 0:6cf6e566c0da 194 IBUS_COMMAND CDC::get_steering_wheel_cmd() {
petter 0:6cf6e566c0da 195
petter 0:6cf6e566c0da 196 bool event = (CAN_RxMsg.data[0] == 0x80);
petter 0:6cf6e566c0da 197 if (!event) {
petter 0:6cf6e566c0da 198 //Ignore the message if it wasn't sent on event
petter 0:6cf6e566c0da 199 return IBUS_OTHER_MESSAGE;
petter 0:6cf6e566c0da 200 }
petter 0:6cf6e566c0da 201 if (!cdc_active) {
petter 0:6cf6e566c0da 202 return IBUS_OTHER_MESSAGE;
petter 0:6cf6e566c0da 203 }
petter 0:6cf6e566c0da 204 switch (CAN_RxMsg.data[4]) {
petter 0:6cf6e566c0da 205 case 0x04: // NXT button on wheel
petter 0:6cf6e566c0da 206 return IBUS_NEXT;
petter 0:6cf6e566c0da 207 case 0x10: // Seek+ button on wheel
petter 0:6cf6e566c0da 208 return IBUS_SKIP_FW;
petter 0:6cf6e566c0da 209 case 0x08: // Seek- button on wheel
petter 0:6cf6e566c0da 210 return IBUS_SKIP_BW;
petter 0:6cf6e566c0da 211 case 0x40: // Vol+ button on wheel
petter 0:6cf6e566c0da 212 return IBUS_VOLUME_UP;
petter 0:6cf6e566c0da 213 case 0x80: // Vol- button on wheel
petter 0:6cf6e566c0da 214 return IBUS_VOLUME_DOWN;
petter 0:6cf6e566c0da 215 }
petter 0:6cf6e566c0da 216 switch (CAN_RxMsg.data[5]) {
petter 0:6cf6e566c0da 217 case 0x40: // SET button on SID
petter 0:6cf6e566c0da 218 return IBUS_SET;
petter 0:6cf6e566c0da 219 case 0x80: // CLEAR button on SID
petter 0:6cf6e566c0da 220 return IBUS_CLEAR;
petter 0:6cf6e566c0da 221 }
petter 0:6cf6e566c0da 222 return IBUS_OTHER_MESSAGE;
petter 0:6cf6e566c0da 223 }
petter 0:6cf6e566c0da 224
petter 0:6cf6e566c0da 225
petter 0:6cf6e566c0da 226
petter 0:6cf6e566c0da 227 /** Writes the provided text on the SID. NOTE the character set used by the SID is slightly nonstandard. "Normal" characters should work fine. **/
petter 9:9a4c81493a3d 228 void CDC::display(char text[], char row) {
petter 0:6cf6e566c0da 229 if (!text) {
petter 0:6cf6e566c0da 230 return;
petter 0:6cf6e566c0da 231 }
petter 0:6cf6e566c0da 232
petter 0:6cf6e566c0da 233 //Notify the SID that we want to display a message
petter 10:8be92db98bf4 234 switch (row) {
petter 10:8be92db98bf4 235 case 1:
petter 10:8be92db98bf4 236 active_row_SID = 0; //both row 1 & 2
petter 10:8be92db98bf4 237 break;
petter 10:8be92db98bf4 238 case 2:
petter 10:8be92db98bf4 239 active_row_SID = 2;
petter 10:8be92db98bf4 240 break;
petter 10:8be92db98bf4 241 }
petter 10:8be92db98bf4 242 send_can_frame(DISPLAY_RESOURCE_REQ, display_request_cmd[active_row_SID]);
petter 0:6cf6e566c0da 243
petter 0:6cf6e566c0da 244 // Copy the provided string and make sure we have a new array of the correct length:
petter 0:6cf6e566c0da 245 char display_text[15];
petter 0:6cf6e566c0da 246 int i, n;
petter 0:6cf6e566c0da 247 n = strlen(text);
petter 0:6cf6e566c0da 248 if(n > 15) {
petter 0:6cf6e566c0da 249 n = 15;
petter 0:6cf6e566c0da 250 }
petter 0:6cf6e566c0da 251 for (i = 0; i < n; i++) {
petter 0:6cf6e566c0da 252 display_text[i] = text[i];
petter 0:6cf6e566c0da 253 }
petter 9:9a4c81493a3d 254 for (i = n; i < 15; i++) {
petter 0:6cf6e566c0da 255 display_text[i] = 0;
petter 0:6cf6e566c0da 256 }
petter 0:6cf6e566c0da 257
petter 10:8be92db98bf4 258 CAN_DispMsg[row-1][0].data[2] = 0x82; // Sent on basetime, writing to row 2, message changed
petter 10:8be92db98bf4 259 CAN_DispMsg[row-1][0].data[3] = display_text[0];
petter 10:8be92db98bf4 260 CAN_DispMsg[row-1][0].data[4] = display_text[1];
petter 10:8be92db98bf4 261 CAN_DispMsg[row-1][0].data[5] = display_text[2];
petter 10:8be92db98bf4 262 CAN_DispMsg[row-1][0].data[6] = display_text[3];
petter 10:8be92db98bf4 263 CAN_DispMsg[row-1][0].data[7] = display_text[4];
petter 0:6cf6e566c0da 264
petter 10:8be92db98bf4 265 CAN_DispMsg[row-1][1].data[3] = display_text[5];
petter 10:8be92db98bf4 266 CAN_DispMsg[row-1][1].data[4] = display_text[6];
petter 10:8be92db98bf4 267 CAN_DispMsg[row-1][1].data[5] = display_text[7];
petter 10:8be92db98bf4 268 CAN_DispMsg[row-1][1].data[6] = display_text[8];
petter 10:8be92db98bf4 269 CAN_DispMsg[row-1][1].data[7] = display_text[9];
petter 0:6cf6e566c0da 270
petter 10:8be92db98bf4 271 CAN_DispMsg[row-1][2].data[3] = display_text[10];
petter 10:8be92db98bf4 272 CAN_DispMsg[row-1][2].data[4] = display_text[11];
petter 10:8be92db98bf4 273 CAN_DispMsg[row-1][2].data[5] = display_text[12];
petter 10:8be92db98bf4 274 CAN_DispMsg[row-1][2].data[6] = display_text[13];
petter 10:8be92db98bf4 275 CAN_DispMsg[row-1][2].data[7] = display_text[14];
petter 0:6cf6e566c0da 276 }
petter 0:6cf6e566c0da 277
petter 0:6cf6e566c0da 278 /** Writes the provided text on the SID. NOTE the character set used by the SID is slightly nonstandard. "Normal" characters should work fine. **/
petter 10:8be92db98bf4 279 void CDC::display_update(char row) {
petter 10:8be92db98bf4 280 switch(row) {
petter 10:8be92db98bf4 281 case 0: //send both rows
petter 10:8be92db98bf4 282 can.write(CAN_DispMsg[0][0]);
petter 10:8be92db98bf4 283 can.write(CAN_DispMsg[0][1]);
petter 10:8be92db98bf4 284 can.write(CAN_DispMsg[0][2]);
petter 10:8be92db98bf4 285 can.write(CAN_DispMsg[1][0]);
petter 10:8be92db98bf4 286 can.write(CAN_DispMsg[1][1]);
petter 10:8be92db98bf4 287 can.write(CAN_DispMsg[1][2]);
petter 10:8be92db98bf4 288 CAN_DispMsg[0][0].data[2] = 0x02; // Message not changed next transmission unless display() is called
petter 10:8be92db98bf4 289 CAN_DispMsg[1][0].data[2] = 0x02; // Message not changed next transmission unless display() is called
petter 10:8be92db98bf4 290 break;
petter 10:8be92db98bf4 291 case 1: //send row 1
petter 10:8be92db98bf4 292 can.write(CAN_DispMsg[0][0]);
petter 10:8be92db98bf4 293 can.write(CAN_DispMsg[0][1]);
petter 10:8be92db98bf4 294 can.write(CAN_DispMsg[0][2]);
petter 10:8be92db98bf4 295 CAN_DispMsg[0][0].data[2] = 0x02; // Message not changed next transmission unless display() is called
petter 10:8be92db98bf4 296 break;
petter 10:8be92db98bf4 297 case 2: //send row 2
petter 10:8be92db98bf4 298 can.write(CAN_DispMsg[1][0]);
petter 10:8be92db98bf4 299 can.write(CAN_DispMsg[1][1]);
petter 10:8be92db98bf4 300 can.write(CAN_DispMsg[1][2]);
petter 10:8be92db98bf4 301 CAN_DispMsg[1][0].data[2] = 0x02; // Message not changed next transmission unless display() is called
petter 10:8be92db98bf4 302 break;
petter 10:8be92db98bf4 303 }
petter 10:8be92db98bf4 304
petter 0:6cf6e566c0da 305 }
petter 0:6cf6e566c0da 306
petter 2:10c60edc8573 307 /** Sets the elapsed time in the cdc_status message **/
petter 2:10c60edc8573 308 void CDC::update_elapsed_time() {
petter 2:10c60edc8573 309 cdc_status_cmd[5] = (char)(((int)playback.read())/60);
petter 2:10c60edc8573 310 cdc_status_cmd[6] = (char)(((int)playback.read())%60);
petter 2:10c60edc8573 311 }
petter 2:10c60edc8573 312
petter 2:10c60edc8573 313 /** Resets the elapsed time in the cdc_status message **/
petter 2:10c60edc8573 314 void CDC::reset_elapsed_time() {
petter 2:10c60edc8573 315 playback.reset();
petter 2:10c60edc8573 316 }
petter 2:10c60edc8573 317
petter 2:10c60edc8573 318 /** Stops the elapsed time in the cdc_status message **/
petter 2:10c60edc8573 319 void CDC::stop_elapsed_time() {
petter 2:10c60edc8573 320 playback.stop();
petter 2:10c60edc8573 321 }
petter 2:10c60edc8573 322
petter 2:10c60edc8573 323 /** Starts the elapsed time in the cdc_status message **/
petter 2:10c60edc8573 324 void CDC::start_elapsed_time() {
petter 2:10c60edc8573 325 playback.start();
petter 0:6cf6e566c0da 326 }
petter 0:6cf6e566c0da 327
petter 6:c454f88524d6 328 /** Sets the current track number as playing **/
petter 6:c454f88524d6 329 void CDC::set_track(char track_number) {
petter 6:c454f88524d6 330 cdc_status_cmd[4] = track_number;
petter 6:c454f88524d6 331 }
petter 6:c454f88524d6 332
petter 0:6cf6e566c0da 333
petter 0:6cf6e566c0da 334 /** Formats and puts a frame on CAN bus **/
petter 0:6cf6e566c0da 335 void CDC::send_can_frame(int message_id, int *msg) {
petter 0:6cf6e566c0da 336 CAN_TxMsg.id = message_id;
petter 0:6cf6e566c0da 337 int i = 0;
petter 0:6cf6e566c0da 338 while (msg[i] != -1) {
petter 0:6cf6e566c0da 339 CAN_TxMsg.data[i] = msg[i];
petter 0:6cf6e566c0da 340 i++;
petter 0:6cf6e566c0da 341 }
petter 0:6cf6e566c0da 342 can.write(CAN_TxMsg);
petter 0:6cf6e566c0da 343 }
petter 0:6cf6e566c0da 344
petter 0:6cf6e566c0da 345 /** DEBUG: Prints the CAN TX frame to serial output **/
petter 0:6cf6e566c0da 346 void CDC::print_can_frame(CANMessage *msg){
petter 0:6cf6e566c0da 347 printf("CAN message %X:", msg->id);
petter 0:6cf6e566c0da 348 for (int i = 0; i < msg->len; i++) {
petter 0:6cf6e566c0da 349 printf(" %X", msg->data[i]);
petter 0:6cf6e566c0da 350 }
petter 0:6cf6e566c0da 351 printf("\r\n");
petter 0:6cf6e566c0da 352 }
petter 0:6cf6e566c0da 353
petter 0:6cf6e566c0da 354 /*----------------------------------------------------------------------------
petter 0:6cf6e566c0da 355 setup acceptance filter. CAN controller (1..2)
petter 0:6cf6e566c0da 356 *----------------------------------------------------------------------------*/
petter 0:6cf6e566c0da 357 void CDC::CAN_wrFilter(uint32_t ctrl, uint32_t id) {
petter 0:6cf6e566c0da 358 static int CAN_std_cnt = 0;
petter 0:6cf6e566c0da 359 static int CAN_ext_cnt = 0;
petter 0:6cf6e566c0da 360 uint32_t buf0, buf1;
petter 0:6cf6e566c0da 361 int cnt1, cnt2, bound1;
petter 0:6cf6e566c0da 362
petter 0:6cf6e566c0da 363 /* Acceptance Filter Memory full */
petter 0:6cf6e566c0da 364 if ((((CAN_std_cnt + 1) >> 1) + CAN_ext_cnt) >= 512)
petter 0:6cf6e566c0da 365 return; /* error: objects full */
petter 0:6cf6e566c0da 366
petter 0:6cf6e566c0da 367 /* Setup Acceptance Filter Configuration
petter 0:6cf6e566c0da 368 Acceptance Filter Mode Register = Off */
petter 0:6cf6e566c0da 369 LPC_CANAF->AFMR = 0x00000001;
petter 0:6cf6e566c0da 370
petter 0:6cf6e566c0da 371 id |= (ctrl-1) << 13; /* Add controller number */
petter 0:6cf6e566c0da 372 id &= 0x0000F7FF; /* Mask out 16-bits of ID */
petter 0:6cf6e566c0da 373
petter 0:6cf6e566c0da 374 /* Move all remaining extended mask entries one place up
petter 0:6cf6e566c0da 375 if new entry will increase standard ID filters list */
petter 0:6cf6e566c0da 376 if ((CAN_std_cnt & 0x0001) == 0 && CAN_ext_cnt != 0) {
petter 0:6cf6e566c0da 377 cnt1 = (CAN_std_cnt >> 1);
petter 0:6cf6e566c0da 378 bound1 = CAN_ext_cnt;
petter 0:6cf6e566c0da 379 buf0 = LPC_CANAF_RAM->mask[cnt1];
petter 0:6cf6e566c0da 380 while (bound1--) {
petter 0:6cf6e566c0da 381 cnt1++;
petter 0:6cf6e566c0da 382 buf1 = LPC_CANAF_RAM->mask[cnt1];
petter 0:6cf6e566c0da 383 LPC_CANAF_RAM->mask[cnt1] = buf0;
petter 0:6cf6e566c0da 384 buf0 = buf1;
petter 0:6cf6e566c0da 385 }
petter 0:6cf6e566c0da 386 }
petter 0:6cf6e566c0da 387
petter 0:6cf6e566c0da 388 if (CAN_std_cnt == 0) { /* For entering first ID */
petter 0:6cf6e566c0da 389 LPC_CANAF_RAM->mask[0] = 0x0000FFFF | (id << 16);
petter 0:6cf6e566c0da 390 } else if (CAN_std_cnt == 1) { /* For entering second ID */
petter 0:6cf6e566c0da 391 if ((LPC_CANAF_RAM->mask[0] >> 16) > id)
petter 0:6cf6e566c0da 392 LPC_CANAF_RAM->mask[0] = (LPC_CANAF_RAM->mask[0] >> 16) | (id << 16);
petter 0:6cf6e566c0da 393 else
petter 0:6cf6e566c0da 394 LPC_CANAF_RAM->mask[0] = (LPC_CANAF_RAM->mask[0] & 0xFFFF0000) | id;
petter 0:6cf6e566c0da 395 } else {
petter 0:6cf6e566c0da 396 /* Find where to insert new ID */
petter 0:6cf6e566c0da 397 cnt1 = 0;
petter 0:6cf6e566c0da 398 cnt2 = CAN_std_cnt;
petter 0:6cf6e566c0da 399 bound1 = (CAN_std_cnt - 1) >> 1;
petter 0:6cf6e566c0da 400 while (cnt1 <= bound1) { /* Loop through standard existing IDs */
petter 0:6cf6e566c0da 401 if ((LPC_CANAF_RAM->mask[cnt1] >> 16) > id) {
petter 0:6cf6e566c0da 402 cnt2 = cnt1 * 2;
petter 0:6cf6e566c0da 403 break;
petter 0:6cf6e566c0da 404 }
petter 0:6cf6e566c0da 405 if ((LPC_CANAF_RAM->mask[cnt1] & 0x0000FFFF) > id) {
petter 0:6cf6e566c0da 406 cnt2 = cnt1 * 2 + 1;
petter 0:6cf6e566c0da 407 break;
petter 0:6cf6e566c0da 408 }
petter 0:6cf6e566c0da 409 cnt1++; /* cnt1 = U32 where to insert new ID */
petter 0:6cf6e566c0da 410 } /* cnt2 = U16 where to insert new ID */
petter 0:6cf6e566c0da 411
petter 0:6cf6e566c0da 412 if (cnt1 > bound1) { /* Adding ID as last entry */
petter 0:6cf6e566c0da 413 if ((CAN_std_cnt & 0x0001) == 0) /* Even number of IDs exists */
petter 0:6cf6e566c0da 414 LPC_CANAF_RAM->mask[cnt1] = 0x0000FFFF | (id << 16);
petter 0:6cf6e566c0da 415 else /* Odd number of IDs exists */
petter 0:6cf6e566c0da 416 LPC_CANAF_RAM->mask[cnt1] = (LPC_CANAF_RAM->mask[cnt1] & 0xFFFF0000) | id;
petter 0:6cf6e566c0da 417 } else {
petter 0:6cf6e566c0da 418 buf0 = LPC_CANAF_RAM->mask[cnt1]; /* Remember current entry */
petter 0:6cf6e566c0da 419 if ((cnt2 & 0x0001) == 0) /* Insert new mask to even address */
petter 0:6cf6e566c0da 420 buf1 = (id << 16) | (buf0 >> 16);
petter 0:6cf6e566c0da 421 else /* Insert new mask to odd address */
petter 0:6cf6e566c0da 422 buf1 = (buf0 & 0xFFFF0000) | id;
petter 0:6cf6e566c0da 423
petter 0:6cf6e566c0da 424 LPC_CANAF_RAM->mask[cnt1] = buf1; /* Insert mask */
petter 0:6cf6e566c0da 425
petter 0:6cf6e566c0da 426 bound1 = CAN_std_cnt >> 1;
petter 0:6cf6e566c0da 427 /* Move all remaining standard mask entries one place up */
petter 0:6cf6e566c0da 428 while (cnt1 < bound1) {
petter 0:6cf6e566c0da 429 cnt1++;
petter 0:6cf6e566c0da 430 buf1 = LPC_CANAF_RAM->mask[cnt1];
petter 0:6cf6e566c0da 431 LPC_CANAF_RAM->mask[cnt1] = (buf1 >> 16) | (buf0 << 16);
petter 0:6cf6e566c0da 432 buf0 = buf1;
petter 0:6cf6e566c0da 433 }
petter 0:6cf6e566c0da 434
petter 0:6cf6e566c0da 435 if ((CAN_std_cnt & 0x0001) == 0) /* Even number of IDs exists */
petter 0:6cf6e566c0da 436 LPC_CANAF_RAM->mask[cnt1] = (LPC_CANAF_RAM->mask[cnt1] & 0xFFFF0000) | (0x0000FFFF);
petter 0:6cf6e566c0da 437 }
petter 0:6cf6e566c0da 438 }
petter 0:6cf6e566c0da 439 CAN_std_cnt++;
petter 0:6cf6e566c0da 440
petter 0:6cf6e566c0da 441 /* Calculate std ID start address (buf0) and ext ID start address (buf1) */
petter 0:6cf6e566c0da 442 buf0 = ((CAN_std_cnt + 1) >> 1) << 2;
petter 0:6cf6e566c0da 443 buf1 = buf0 + (CAN_ext_cnt << 2);
petter 0:6cf6e566c0da 444
petter 0:6cf6e566c0da 445 /* Setup acceptance filter pointers */
petter 0:6cf6e566c0da 446 LPC_CANAF->SFF_sa = 0;
petter 0:6cf6e566c0da 447 LPC_CANAF->SFF_GRP_sa = buf0;
petter 0:6cf6e566c0da 448 LPC_CANAF->EFF_sa = buf0;
petter 0:6cf6e566c0da 449 LPC_CANAF->EFF_GRP_sa = buf1;
petter 0:6cf6e566c0da 450 LPC_CANAF->ENDofTable = buf1;
petter 0:6cf6e566c0da 451
petter 0:6cf6e566c0da 452 LPC_CANAF->AFMR = 0x00000000; /* Use acceptance filter */
petter 0:6cf6e566c0da 453 }