Simulated the CD changer of a Saab to implement a bluetooth connection to the car stereo. Control of playback device (phone) with steering wheel buttons. Needs a RN52 bluetooth transciever and a CAN transiever. So far only audio playback and control via steering wheel buttons implemented. Hands free calling planned.
main.cpp@16:7bb8b161e00b, 2016-03-18 (annotated)
- Committer:
- petter
- Date:
- Fri Mar 18 20:58:36 2016 +0000
- Revision:
- 16:7bb8b161e00b
- Parent:
- 15:82c3cc87bd02
Added can.monitor in a trial to get the sleep mode working
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
petter | 0:6cf6e566c0da | 1 | // Inspired from BlueSaab |
petter | 0:6cf6e566c0da | 2 | // Project/Hardware: http://bluesaab.blogspot.com/ |
petter | 0:6cf6e566c0da | 3 | // Code: https://github.com/kveilands/SAAB-CDC/tree/master/SAAB-CDC |
petter | 0:6cf6e566c0da | 4 | // I-Bus information from http://pikkupossu.1g.fi/tomi/projects/i-bus/i-bus.html |
petter | 0:6cf6e566c0da | 5 | |
petter | 11:74844f6ca8cf | 6 | // Due to power saving functions special firmware required http://mbed.org/users/simon/notebook/interface-powerdown/ |
petter | 11:74844f6ca8cf | 7 | |
petter | 16:7bb8b161e00b | 8 | /**** TODO **** |
petter | 16:7bb8b161e00b | 9 | Fix sleep mode |
petter | 16:7bb8b161e00b | 10 | Implement caller ID retreival |
petter | 16:7bb8b161e00b | 11 | Change some public functions to private for both CDC & RN52 |
petter | 16:7bb8b161e00b | 12 | Instead of sending &res to RN52, add public variables for all data to be communicated |
petter | 16:7bb8b161e00b | 13 | rn52.check_event should return event instead of writing to res, (remove if and use switch directly in handle_bt_input |
petter | 16:7bb8b161e00b | 14 | |
petter | 16:7bb8b161e00b | 15 | **** END TODO****/ |
petter | 16:7bb8b161e00b | 16 | |
petter | 0:6cf6e566c0da | 17 | #include "mbed.h" |
petter | 11:74844f6ca8cf | 18 | #include "PowerControl/PowerControl.h" |
petter | 11:74844f6ca8cf | 19 | #include "PowerControl/EthernetPowerControl.h" |
petter | 11:74844f6ca8cf | 20 | |
petter | 0:6cf6e566c0da | 21 | #include "CDC.h" |
petter | 0:6cf6e566c0da | 22 | #include "RN52.h" |
petter | 0:6cf6e566c0da | 23 | |
petter | 0:6cf6e566c0da | 24 | CDC cdc; |
petter | 0:6cf6e566c0da | 25 | RN52 rn52; |
petter | 0:6cf6e566c0da | 26 | RN52_RESULT res; |
petter | 13:968af0520530 | 27 | |
petter | 11:74844f6ca8cf | 28 | Ticker wakeup; |
petter | 0:6cf6e566c0da | 29 | Serial pc(USBTX, USBRX); // tx, rx |
petter | 13:968af0520530 | 30 | DigitalOut led3(LED3, 0); |
petter | 13:968af0520530 | 31 | DigitalOut led4(LED4, 0); |
petter | 11:74844f6ca8cf | 32 | bool active = 1; |
petter | 0:6cf6e566c0da | 33 | |
petter | 8:beb6c399490a | 34 | void handle_pc_input(); |
petter | 8:beb6c399490a | 35 | void handle_cdc_input(); |
petter | 8:beb6c399490a | 36 | void handle_bt_input(); |
petter | 11:74844f6ca8cf | 37 | void check_for_wakeup(); |
petter | 8:beb6c399490a | 38 | |
petter | 8:beb6c399490a | 39 | int main() { |
petter | 8:beb6c399490a | 40 | printf("Petters BT CDC-emulator\r\n"); |
petter | 8:beb6c399490a | 41 | printf("Initializing\r\n"); |
petter | 11:74844f6ca8cf | 42 | printf("Disabling unused peripherals to decrease power consumption\r\n"); |
petter | 11:74844f6ca8cf | 43 | PHY_PowerDown(); // Power down Ethernet interface - saves around 175mW |
petter | 11:74844f6ca8cf | 44 | semihost_powerdown(); // If you don't need the PC host USB interface power down magic USB interface chip - saves around 150mW | Needs new firmware (URL below) and USB cable not connected http://mbed.org/users/simon/notebook/interface-powerdown/ |
petter | 13:968af0520530 | 45 | rn52.init(); |
petter | 8:beb6c399490a | 46 | cdc.init(); |
petter | 11:74844f6ca8cf | 47 | printf("Adding wakeup routine\r\n"); |
petter | 14:3f4098e94c29 | 48 | wakeup.attach(&check_for_wakeup, 0.5); |
petter | 8:beb6c399490a | 49 | printf("Starting loop\r\n"); |
petter | 8:beb6c399490a | 50 | while(1) { |
petter | 11:74844f6ca8cf | 51 | if(active) { |
petter | 11:74844f6ca8cf | 52 | handle_pc_input(); |
petter | 11:74844f6ca8cf | 53 | handle_cdc_input(); |
petter | 11:74844f6ca8cf | 54 | handle_bt_input(); |
petter | 11:74844f6ca8cf | 55 | } |
petter | 11:74844f6ca8cf | 56 | else { |
petter | 11:74844f6ca8cf | 57 | sleep(); |
petter | 11:74844f6ca8cf | 58 | } |
petter | 8:beb6c399490a | 59 | } |
petter | 8:beb6c399490a | 60 | } |
petter | 8:beb6c399490a | 61 | |
petter | 11:74844f6ca8cf | 62 | void check_for_wakeup(){ |
petter | 11:74844f6ca8cf | 63 | if(!active) { |
petter | 13:968af0520530 | 64 | led4 = !led4; |
petter | 11:74844f6ca8cf | 65 | IBUS_COMMAND cmd = IBUS_OTHER_MESSAGE; |
petter | 13:968af0520530 | 66 | while(cmd != IBUS_HEAD_UNIT_OFF) { |
petter | 11:74844f6ca8cf | 67 | cmd = cdc.get_cmd(); |
petter | 11:74844f6ca8cf | 68 | if(cmd == IBUS_HEAD_UNIT_ON) { |
petter | 11:74844f6ca8cf | 69 | active = 1; |
petter | 15:82c3cc87bd02 | 70 | cdc.enable(); |
petter | 13:968af0520530 | 71 | rn52.enable(); |
petter | 13:968af0520530 | 72 | } |
petter | 13:968af0520530 | 73 | } |
petter | 11:74844f6ca8cf | 74 | } |
petter | 11:74844f6ca8cf | 75 | } |
petter | 8:beb6c399490a | 76 | |
petter | 5:8e468fef2754 | 77 | void handle_pc_input() { |
petter | 5:8e468fef2754 | 78 | //Debug connection to PC |
petter | 5:8e468fef2754 | 79 | if(pc.readable()) { |
petter | 5:8e468fef2754 | 80 | switch (pc.getc()) { |
petter | 5:8e468fef2754 | 81 | case 'p': |
petter | 5:8e468fef2754 | 82 | if(rn52.toggle_play()) { |
petter | 5:8e468fef2754 | 83 | printf("play/pause\r\n"); |
petter | 5:8e468fef2754 | 84 | } |
petter | 5:8e468fef2754 | 85 | break; |
petter | 5:8e468fef2754 | 86 | case 'v': |
petter | 5:8e468fef2754 | 87 | printf("volume up\r\n"); |
petter | 5:8e468fef2754 | 88 | rn52.maxvolume(); |
petter | 5:8e468fef2754 | 89 | break; |
petter | 5:8e468fef2754 | 90 | case 'n': |
petter | 5:8e468fef2754 | 91 | printf("next track\r\n"); |
petter | 5:8e468fef2754 | 92 | rn52.next_track(); |
petter | 5:8e468fef2754 | 93 | break; |
petter | 5:8e468fef2754 | 94 | case 'q': |
petter | 5:8e468fef2754 | 95 | printf("getting status\r\n"); |
petter | 8:beb6c399490a | 96 | rn52.get_status(&res); |
petter | 7:2df2c6e8c0df | 97 | printf("%s\r\n", res.response); |
petter | 5:8e468fef2754 | 98 | break; |
petter | 5:8e468fef2754 | 99 | case 't': |
petter | 8:beb6c399490a | 100 | rn52.get_caller_id(&res); |
petter | 7:2df2c6e8c0df | 101 | printf("%s\r\n", res.response); |
petter | 5:8e468fef2754 | 102 | break; |
petter | 15:82c3cc87bd02 | 103 | case 'c': |
petter | 15:82c3cc87bd02 | 104 | rn52.config("Saab 9-5"); |
petter | 15:82c3cc87bd02 | 105 | printf("configuring RN52\r\n"); |
petter | 15:82c3cc87bd02 | 106 | break; |
petter | 15:82c3cc87bd02 | 107 | case 'm': |
petter | 15:82c3cc87bd02 | 108 | rn52.get_track_metadata(&res); |
petter | 15:82c3cc87bd02 | 109 | printf("Getting metadata\r\n"); |
petter | 15:82c3cc87bd02 | 110 | printf("title: %s\r\n", res.title); |
petter | 15:82c3cc87bd02 | 111 | printf("artist: %s\r\n", res.artist); |
petter | 15:82c3cc87bd02 | 112 | printf("album: %s\r\n", res.album); |
petter | 15:82c3cc87bd02 | 113 | printf("genre: %s\r\n", res.genre); |
petter | 15:82c3cc87bd02 | 114 | printf("duration: %i\r\n", res.duration); |
petter | 15:82c3cc87bd02 | 115 | printf("track_count: %i\r\n", res.track_count); |
petter | 15:82c3cc87bd02 | 116 | printf("track_number: %i\r\n", res.track_number); |
petter | 15:82c3cc87bd02 | 117 | break; |
petter | 5:8e468fef2754 | 118 | } |
petter | 5:8e468fef2754 | 119 | } |
petter | 5:8e468fef2754 | 120 | } |
petter | 5:8e468fef2754 | 121 | |
petter | 5:8e468fef2754 | 122 | void handle_cdc_input() { |
petter | 5:8e468fef2754 | 123 | switch (cdc.get_cmd()) { |
petter | 11:74844f6ca8cf | 124 | case IBUS_HEAD_UNIT_OFF: |
petter | 13:968af0520530 | 125 | active = 0; |
petter | 14:3f4098e94c29 | 126 | cdc.disable(); |
petter | 13:968af0520530 | 127 | rn52.disable(); |
petter | 5:8e468fef2754 | 128 | break; |
petter | 5:8e468fef2754 | 129 | case IBUS_NEXT: |
petter | 15:82c3cc87bd02 | 130 | cdc.display("PLAY_PAUSE"); |
petter | 5:8e468fef2754 | 131 | rn52.toggle_play(); |
petter | 5:8e468fef2754 | 132 | break; |
petter | 5:8e468fef2754 | 133 | case IBUS_CDC_ON: |
petter | 15:82c3cc87bd02 | 134 | cdc.display("CDC_ON"); |
petter | 5:8e468fef2754 | 135 | rn52.connect(); |
petter | 5:8e468fef2754 | 136 | break; |
petter | 5:8e468fef2754 | 137 | case IBUS_CDC_OFF: |
petter | 15:82c3cc87bd02 | 138 | cdc.display("CDC_OFF"); |
petter | 5:8e468fef2754 | 139 | break; |
petter | 5:8e468fef2754 | 140 | case IBUS_SKIP_FW: |
petter | 15:82c3cc87bd02 | 141 | cdc.display("SKIP_FW"); |
petter | 5:8e468fef2754 | 142 | rn52.next_track(); |
petter | 5:8e468fef2754 | 143 | break; |
petter | 5:8e468fef2754 | 144 | case IBUS_SKIP_BW: |
petter | 15:82c3cc87bd02 | 145 | cdc.display("SKIP_BW"); |
petter | 5:8e468fef2754 | 146 | rn52.prev_track(); |
petter | 5:8e468fef2754 | 147 | break; |
petter | 5:8e468fef2754 | 148 | case IBUS_SET: |
petter | 15:82c3cc87bd02 | 149 | cdc.display("SET"); |
petter | 5:8e468fef2754 | 150 | break; |
petter | 5:8e468fef2754 | 151 | case IBUS_CLEAR: |
petter | 15:82c3cc87bd02 | 152 | cdc.display("CLEAR"); |
petter | 5:8e468fef2754 | 153 | break; |
petter | 5:8e468fef2754 | 154 | } |
petter | 5:8e468fef2754 | 155 | } |
petter | 5:8e468fef2754 | 156 | |
petter | 5:8e468fef2754 | 157 | void handle_bt_input() { |
petter | 5:8e468fef2754 | 158 | if(rn52.check_event(&res)) { |
petter | 5:8e468fef2754 | 159 | switch (res.event) { |
petter | 5:8e468fef2754 | 160 | case RN52_CALLER_ID_EVENT: |
petter | 9:9a4c81493a3d | 161 | //printf("Caller ID event\r\n"); |
petter | 5:8e468fef2754 | 162 | break; |
petter | 5:8e468fef2754 | 163 | case RN52_TRACK_CHANGE_EVENT: |
petter | 5:8e468fef2754 | 164 | cdc.reset_elapsed_time(); |
petter | 14:3f4098e94c29 | 165 | cdc.display(res.title); |
petter | 8:beb6c399490a | 166 | cdc.set_track((char)res.track_number); |
petter | 5:8e468fef2754 | 167 | break; |
petter | 8:beb6c399490a | 168 | case RN52_OTHER_EVENT: //no specific event occured, check connection status |
petter | 5:8e468fef2754 | 169 | switch(res.connection) { |
petter | 6:c454f88524d6 | 170 | case RN52_CONNECTABLE_DISCOVERABLE: |
petter | 11:74844f6ca8cf | 171 | cdc.display("BT REDO"); |
petter | 6:c454f88524d6 | 172 | break; |
petter | 5:8e468fef2754 | 173 | case RN52_CONNECTED: |
petter | 11:74844f6ca8cf | 174 | cdc.display("BT ANSLUTEN"); |
petter | 5:8e468fef2754 | 175 | rn52.maxvolume(); |
petter | 5:8e468fef2754 | 176 | break; |
petter | 5:8e468fef2754 | 177 | case RN52_AUDIO_STREAMING: |
petter | 11:74844f6ca8cf | 178 | cdc.display(res.title); |
petter | 5:8e468fef2754 | 179 | cdc.start_elapsed_time(); |
petter | 5:8e468fef2754 | 180 | break; |
petter | 5:8e468fef2754 | 181 | } |
petter | 5:8e468fef2754 | 182 | if(res.connection != RN52_AUDIO_STREAMING) { |
petter | 5:8e468fef2754 | 183 | cdc.stop_elapsed_time(); |
petter | 5:8e468fef2754 | 184 | } |
petter | 5:8e468fef2754 | 185 | } |
petter | 5:8e468fef2754 | 186 | } |
petter | 0:6cf6e566c0da | 187 | } |