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
- Committer:
- petter
- Date:
- 2016-03-18
- Revision:
- 16:7bb8b161e00b
- Parent:
- 15:82c3cc87bd02
File content as of revision 16:7bb8b161e00b:
// Inspired from BlueSaab // Project/Hardware: http://bluesaab.blogspot.com/ // Code: https://github.com/kveilands/SAAB-CDC/tree/master/SAAB-CDC // I-Bus information from http://pikkupossu.1g.fi/tomi/projects/i-bus/i-bus.html // Due to power saving functions special firmware required http://mbed.org/users/simon/notebook/interface-powerdown/ /**** TODO **** Fix sleep mode Implement caller ID retreival Change some public functions to private for both CDC & RN52 Instead of sending &res to RN52, add public variables for all data to be communicated rn52.check_event should return event instead of writing to res, (remove if and use switch directly in handle_bt_input **** END TODO****/ #include "mbed.h" #include "PowerControl/PowerControl.h" #include "PowerControl/EthernetPowerControl.h" #include "CDC.h" #include "RN52.h" CDC cdc; RN52 rn52; RN52_RESULT res; Ticker wakeup; Serial pc(USBTX, USBRX); // tx, rx DigitalOut led3(LED3, 0); DigitalOut led4(LED4, 0); bool active = 1; void handle_pc_input(); void handle_cdc_input(); void handle_bt_input(); void check_for_wakeup(); int main() { printf("Petters BT CDC-emulator\r\n"); printf("Initializing\r\n"); printf("Disabling unused peripherals to decrease power consumption\r\n"); PHY_PowerDown(); // Power down Ethernet interface - saves around 175mW 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/ rn52.init(); cdc.init(); printf("Adding wakeup routine\r\n"); wakeup.attach(&check_for_wakeup, 0.5); printf("Starting loop\r\n"); while(1) { if(active) { handle_pc_input(); handle_cdc_input(); handle_bt_input(); } else { sleep(); } } } void check_for_wakeup(){ if(!active) { led4 = !led4; IBUS_COMMAND cmd = IBUS_OTHER_MESSAGE; while(cmd != IBUS_HEAD_UNIT_OFF) { cmd = cdc.get_cmd(); if(cmd == IBUS_HEAD_UNIT_ON) { active = 1; cdc.enable(); rn52.enable(); } } } } void handle_pc_input() { //Debug connection to PC if(pc.readable()) { switch (pc.getc()) { case 'p': if(rn52.toggle_play()) { printf("play/pause\r\n"); } break; case 'v': printf("volume up\r\n"); rn52.maxvolume(); break; case 'n': printf("next track\r\n"); rn52.next_track(); break; case 'q': printf("getting status\r\n"); rn52.get_status(&res); printf("%s\r\n", res.response); break; case 't': rn52.get_caller_id(&res); printf("%s\r\n", res.response); break; case 'c': rn52.config("Saab 9-5"); printf("configuring RN52\r\n"); break; case 'm': rn52.get_track_metadata(&res); printf("Getting metadata\r\n"); printf("title: %s\r\n", res.title); printf("artist: %s\r\n", res.artist); printf("album: %s\r\n", res.album); printf("genre: %s\r\n", res.genre); printf("duration: %i\r\n", res.duration); printf("track_count: %i\r\n", res.track_count); printf("track_number: %i\r\n", res.track_number); break; } } } void handle_cdc_input() { switch (cdc.get_cmd()) { case IBUS_HEAD_UNIT_OFF: active = 0; cdc.disable(); rn52.disable(); break; case IBUS_NEXT: cdc.display("PLAY_PAUSE"); rn52.toggle_play(); break; case IBUS_CDC_ON: cdc.display("CDC_ON"); rn52.connect(); break; case IBUS_CDC_OFF: cdc.display("CDC_OFF"); break; case IBUS_SKIP_FW: cdc.display("SKIP_FW"); rn52.next_track(); break; case IBUS_SKIP_BW: cdc.display("SKIP_BW"); rn52.prev_track(); break; case IBUS_SET: cdc.display("SET"); break; case IBUS_CLEAR: cdc.display("CLEAR"); break; } } void handle_bt_input() { if(rn52.check_event(&res)) { switch (res.event) { case RN52_CALLER_ID_EVENT: //printf("Caller ID event\r\n"); break; case RN52_TRACK_CHANGE_EVENT: cdc.reset_elapsed_time(); cdc.display(res.title); cdc.set_track((char)res.track_number); break; case RN52_OTHER_EVENT: //no specific event occured, check connection status switch(res.connection) { case RN52_CONNECTABLE_DISCOVERABLE: cdc.display("BT REDO"); break; case RN52_CONNECTED: cdc.display("BT ANSLUTEN"); rn52.maxvolume(); break; case RN52_AUDIO_STREAMING: cdc.display(res.title); cdc.start_elapsed_time(); break; } if(res.connection != RN52_AUDIO_STREAMING) { cdc.stop_elapsed_time(); } } } }