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.

Dependencies:   mbed

Committer:
petter
Date:
Mon Jan 04 15:31:12 2016 +0000
Revision:
0:6cf6e566c0da
Child:
1:63db3f3124d4
First commit.; Fully working cdc emulator. Control Playback with steering wheel buttons.; Debug outputs on SID.; Playback information to NAV unit not perfect.; RN52 not upgraded to 1.16 so no handling of track metadata.; No handling of phone profile.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
petter 0:6cf6e566c0da 1 #include "RN52.h"
petter 0:6cf6e566c0da 2 #include "mbed.h"
petter 0:6cf6e566c0da 3
petter 0:6cf6e566c0da 4 // RN52 action command definitions
petter 0:6cf6e566c0da 5 #define PLAYPAUSE "AP\r"
petter 0:6cf6e566c0da 6 #define NEXTTRACK "AT+\r"
petter 0:6cf6e566c0da 7 #define PREVTRACK "AT-\r"
petter 0:6cf6e566c0da 8 #define CONNECT "B\r"
petter 0:6cf6e566c0da 9 #define DISCONNECT "@,1\r"
petter 0:6cf6e566c0da 10 #define REBOOT "R,1\r"
petter 0:6cf6e566c0da 11 #define VOLUMEUP "AV+\r"
petter 0:6cf6e566c0da 12 #define MAXVOLUME "SS,0F\r"
petter 0:6cf6e566c0da 13 #define GETSTATUS "Q\r"
petter 0:6cf6e566c0da 14 #define ASSISTANT "P\r"
petter 0:6cf6e566c0da 15 #define CALLER_ID "T\r"
petter 0:6cf6e566c0da 16 #define TRACK_METADATA "AD\r"
petter 0:6cf6e566c0da 17
petter 0:6cf6e566c0da 18
petter 0:6cf6e566c0da 19 Serial serial(p13, p14); // tx, rx
petter 0:6cf6e566c0da 20 DigitalIn event_pin(p20);
petter 0:6cf6e566c0da 21
petter 0:6cf6e566c0da 22 void RN52::init(){
petter 0:6cf6e566c0da 23 serial.baud(115200);
petter 0:6cf6e566c0da 24 printf("Serial baudrate set\r\n");
petter 0:6cf6e566c0da 25 }
petter 0:6cf6e566c0da 26
petter 0:6cf6e566c0da 27 bool RN52::changed(){
petter 0:6cf6e566c0da 28 static bool last = 0;
petter 0:6cf6e566c0da 29 if(last != event_pin) {
petter 0:6cf6e566c0da 30 last = event_pin;
petter 0:6cf6e566c0da 31 return !event_pin;
petter 0:6cf6e566c0da 32 }
petter 0:6cf6e566c0da 33 last = event_pin;
petter 0:6cf6e566c0da 34 return 0;
petter 0:6cf6e566c0da 35 }
petter 0:6cf6e566c0da 36
petter 0:6cf6e566c0da 37
petter 0:6cf6e566c0da 38 bool RN52::set(RN52_COMMAND cmd){
petter 0:6cf6e566c0da 39 char response[40];
petter 0:6cf6e566c0da 40 switch (cmd) {
petter 0:6cf6e566c0da 41 case RN52_PLAYPAUSE:
petter 0:6cf6e566c0da 42 serial.printf(PLAYPAUSE);
petter 0:6cf6e566c0da 43 break;
petter 0:6cf6e566c0da 44 case RN52_NEXTTRACK:
petter 0:6cf6e566c0da 45 serial.printf(NEXTTRACK);
petter 0:6cf6e566c0da 46 break;
petter 0:6cf6e566c0da 47 case RN52_PREVTRACK:
petter 0:6cf6e566c0da 48 serial.printf(PREVTRACK);
petter 0:6cf6e566c0da 49 break;
petter 0:6cf6e566c0da 50 case RN52_CONNECT:
petter 0:6cf6e566c0da 51 serial.printf(CONNECT);
petter 0:6cf6e566c0da 52 break;
petter 0:6cf6e566c0da 53 case RN52_DISCONNECT:
petter 0:6cf6e566c0da 54 serial.printf(DISCONNECT);
petter 0:6cf6e566c0da 55 break;
petter 0:6cf6e566c0da 56 case RN52_REBOOT:
petter 0:6cf6e566c0da 57 serial.printf(REBOOT);
petter 0:6cf6e566c0da 58 break;
petter 0:6cf6e566c0da 59 case RN52_VOLUMEUP:
petter 0:6cf6e566c0da 60 serial.printf(VOLUMEUP);
petter 0:6cf6e566c0da 61 break;
petter 0:6cf6e566c0da 62 case RN52_MAXVOLUME:
petter 0:6cf6e566c0da 63 serial.printf(MAXVOLUME);
petter 0:6cf6e566c0da 64 break;
petter 0:6cf6e566c0da 65 case RN52_ASSISTANT:
petter 0:6cf6e566c0da 66 serial.printf(ASSISTANT);
petter 0:6cf6e566c0da 67 break;
petter 0:6cf6e566c0da 68 default:
petter 0:6cf6e566c0da 69 return false;
petter 0:6cf6e566c0da 70 }
petter 0:6cf6e566c0da 71 capture_response(response);
petter 0:6cf6e566c0da 72 return (response[0] == 'A');
petter 0:6cf6e566c0da 73 }
petter 0:6cf6e566c0da 74
petter 0:6cf6e566c0da 75 bool RN52::get(RN52_COMMAND cmd, RN52_RESULT * result){
petter 0:6cf6e566c0da 76 switch (cmd) {
petter 0:6cf6e566c0da 77 case RN52_GETSTATUS:
petter 0:6cf6e566c0da 78 serial.printf(GETSTATUS);
petter 0:6cf6e566c0da 79 capture_response(result->response);
petter 0:6cf6e566c0da 80 result->media_connected = (result->response[0] & (1 << 2)) >> 2;
petter 0:6cf6e566c0da 81 result->phone_connected = (result->response[0] & (1 << 3)) >> 23;
petter 0:6cf6e566c0da 82 result->connection = (RN52_CONNECTION)(result->response[0] & 0x0F);
petter 0:6cf6e566c0da 83 if((result->response[0] & (1 << 4)) >> 4) {
petter 0:6cf6e566c0da 84 result->event = RN52_CALLER_ID_EVENT;
petter 0:6cf6e566c0da 85 }
petter 0:6cf6e566c0da 86 else if((result->response[0] & (1 << 5)) >> 5) {
petter 0:6cf6e566c0da 87 result->event = RN52_TRACK_CHANGE_EVENT;
petter 0:6cf6e566c0da 88 }
petter 0:6cf6e566c0da 89 else {
petter 0:6cf6e566c0da 90 result->event = RN52_NO_EVENT;
petter 0:6cf6e566c0da 91 }
petter 0:6cf6e566c0da 92 break;
petter 0:6cf6e566c0da 93 case RN52_CALLER_ID:
petter 0:6cf6e566c0da 94 serial.printf(CALLER_ID);
petter 0:6cf6e566c0da 95 capture_response(result->response);
petter 0:6cf6e566c0da 96 //parse the response
petter 0:6cf6e566c0da 97 break;
petter 0:6cf6e566c0da 98 case RN52_TRACK_METADATA:
petter 0:6cf6e566c0da 99 serial.printf(TRACK_METADATA);
petter 0:6cf6e566c0da 100 capture_response(result->response);
petter 0:6cf6e566c0da 101 //parse the response
petter 0:6cf6e566c0da 102 default:
petter 0:6cf6e566c0da 103 return 0;
petter 0:6cf6e566c0da 104 }
petter 0:6cf6e566c0da 105 return 1;
petter 0:6cf6e566c0da 106 }
petter 0:6cf6e566c0da 107
petter 0:6cf6e566c0da 108
petter 0:6cf6e566c0da 109 void RN52::capture_response(char * str){
petter 0:6cf6e566c0da 110 char c = ' ';
petter 0:6cf6e566c0da 111 char n = 0;
petter 0:6cf6e566c0da 112 while(c != '\n') {
petter 0:6cf6e566c0da 113 if(serial.readable()) {
petter 0:6cf6e566c0da 114 c = serial.getc();
petter 0:6cf6e566c0da 115 str[n] = c;
petter 0:6cf6e566c0da 116 n++;
petter 0:6cf6e566c0da 117 }
petter 0:6cf6e566c0da 118 }
petter 0:6cf6e566c0da 119 str[n] = '\0';
petter 0:6cf6e566c0da 120 }