Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
RN52.cpp@7:2df2c6e8c0df, 2016-01-14 (annotated)
- Committer:
- petter
- Date:
- Thu Jan 14 22:20:38 2016 +0000
- Revision:
- 7:2df2c6e8c0df
- Parent:
- 6:c454f88524d6
- Child:
- 8:beb6c399490a
Improved handling of RN52 track metadata
Who changed what in which revision?
User | Revision | Line number | New 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 | 6:c454f88524d6 | 25 | |
petter | 6:c454f88524d6 | 26 | //make sure event pin is pulled low |
petter | 6:c454f88524d6 | 27 | if(event_pin == 0) { |
petter | 6:c454f88524d6 | 28 | char response[10]; |
petter | 6:c454f88524d6 | 29 | serial.printf(GETSTATUS); |
petter | 6:c454f88524d6 | 30 | capture_response(response); |
petter | 6:c454f88524d6 | 31 | } |
petter | 0:6cf6e566c0da | 32 | } |
petter | 0:6cf6e566c0da | 33 | |
petter | 5:8e468fef2754 | 34 | bool RN52::check_event(RN52_RESULT * result){ |
petter | 6:c454f88524d6 | 35 | clear_serial(); |
petter | 6:c454f88524d6 | 36 | if(event_pin == 0) { |
petter | 7:2df2c6e8c0df | 37 | clear_result(result); |
petter | 5:8e468fef2754 | 38 | get(RN52_GETSTATUS, result); |
petter | 5:8e468fef2754 | 39 | switch (result->event) { |
petter | 4:3041a571b7a7 | 40 | case RN52_CALLER_ID_EVENT: |
petter | 5:8e468fef2754 | 41 | get(RN52_CALLER_ID, result); |
petter | 4:3041a571b7a7 | 42 | break; |
petter | 4:3041a571b7a7 | 43 | case RN52_TRACK_CHANGE_EVENT: |
petter | 5:8e468fef2754 | 44 | get(RN52_TRACK_METADATA, result); |
petter | 4:3041a571b7a7 | 45 | break; |
petter | 4:3041a571b7a7 | 46 | } |
petter | 4:3041a571b7a7 | 47 | return 1; |
petter | 0:6cf6e566c0da | 48 | } |
petter | 0:6cf6e566c0da | 49 | return 0; |
petter | 0:6cf6e566c0da | 50 | } |
petter | 0:6cf6e566c0da | 51 | |
petter | 5:8e468fef2754 | 52 | bool RN52::connect(){ |
petter | 6:c454f88524d6 | 53 | char response[5]; |
petter | 5:8e468fef2754 | 54 | serial.printf(CONNECT); |
petter | 5:8e468fef2754 | 55 | return capture_response(response); |
petter | 5:8e468fef2754 | 56 | } |
petter | 0:6cf6e566c0da | 57 | |
petter | 5:8e468fef2754 | 58 | bool RN52::disconnect(){ |
petter | 6:c454f88524d6 | 59 | char response[5]; |
petter | 5:8e468fef2754 | 60 | serial.printf(DISCONNECT); |
petter | 5:8e468fef2754 | 61 | return capture_response(response); |
petter | 5:8e468fef2754 | 62 | } |
petter | 5:8e468fef2754 | 63 | |
petter | 5:8e468fef2754 | 64 | bool RN52::next_track(){ |
petter | 6:c454f88524d6 | 65 | char response[5]; |
petter | 5:8e468fef2754 | 66 | serial.printf(NEXTTRACK); |
petter | 5:8e468fef2754 | 67 | return capture_response(response); |
petter | 5:8e468fef2754 | 68 | } |
petter | 5:8e468fef2754 | 69 | |
petter | 5:8e468fef2754 | 70 | bool RN52::prev_track(){ |
petter | 6:c454f88524d6 | 71 | char response[5]; |
petter | 5:8e468fef2754 | 72 | serial.printf(PREVTRACK); |
petter | 5:8e468fef2754 | 73 | return capture_response(response); |
petter | 5:8e468fef2754 | 74 | } |
petter | 5:8e468fef2754 | 75 | |
petter | 5:8e468fef2754 | 76 | bool RN52::toggle_play(){ |
petter | 6:c454f88524d6 | 77 | char response[5]; |
petter | 5:8e468fef2754 | 78 | serial.printf(PLAYPAUSE); |
petter | 5:8e468fef2754 | 79 | return capture_response(response); |
petter | 5:8e468fef2754 | 80 | } |
petter | 5:8e468fef2754 | 81 | |
petter | 5:8e468fef2754 | 82 | bool RN52::maxvolume(){ |
petter | 6:c454f88524d6 | 83 | char response[5]; |
petter | 6:c454f88524d6 | 84 | serial.printf(MAXVOLUME); |
petter | 5:8e468fef2754 | 85 | return capture_response(response); |
petter | 0:6cf6e566c0da | 86 | } |
petter | 0:6cf6e566c0da | 87 | |
petter | 0:6cf6e566c0da | 88 | bool RN52::get(RN52_COMMAND cmd, RN52_RESULT * result){ |
petter | 0:6cf6e566c0da | 89 | switch (cmd) { |
petter | 4:3041a571b7a7 | 90 | case RN52_GETSTATUS: { |
petter | 0:6cf6e566c0da | 91 | serial.printf(GETSTATUS); |
petter | 0:6cf6e566c0da | 92 | capture_response(result->response); |
petter | 2:10c60edc8573 | 93 | int response_value = strtoul(result->response, NULL, 16); |
petter | 2:10c60edc8573 | 94 | result->media_connected = (response_value & (1 << 10)) >> 10; //byte 0, bit 2 |
petter | 2:10c60edc8573 | 95 | result->phone_connected = (response_value & (1 << 11)) >> 11; //byte 0, bit 3 |
petter | 2:10c60edc8573 | 96 | result->connection = (RN52_CONNECTION)(response_value & 0x0F); //byte 1, bits 0-3 |
petter | 4:3041a571b7a7 | 97 | switch (response_value & 0x3000) { |
petter | 4:3041a571b7a7 | 98 | case 0x1000: //byte 0, bit 4 |
petter | 4:3041a571b7a7 | 99 | result->event = RN52_CALLER_ID_EVENT; |
petter | 4:3041a571b7a7 | 100 | break; |
petter | 4:3041a571b7a7 | 101 | case 0x2000: //byte 0, bit 5 |
petter | 4:3041a571b7a7 | 102 | result->event = RN52_TRACK_CHANGE_EVENT; |
petter | 4:3041a571b7a7 | 103 | break; |
petter | 4:3041a571b7a7 | 104 | default: |
petter | 7:2df2c6e8c0df | 105 | result->event = RN52_OTHER_EVENT; |
petter | 4:3041a571b7a7 | 106 | break; |
petter | 0:6cf6e566c0da | 107 | } |
petter | 0:6cf6e566c0da | 108 | break; |
petter | 4:3041a571b7a7 | 109 | } //added to create local scope of response_value |
petter | 0:6cf6e566c0da | 110 | case RN52_CALLER_ID: |
petter | 0:6cf6e566c0da | 111 | serial.printf(CALLER_ID); |
petter | 0:6cf6e566c0da | 112 | capture_response(result->response); |
petter | 0:6cf6e566c0da | 113 | //parse the response |
petter | 0:6cf6e566c0da | 114 | break; |
petter | 0:6cf6e566c0da | 115 | case RN52_TRACK_METADATA: |
petter | 6:c454f88524d6 | 116 | serial.printf(TRACK_METADATA); |
petter | 6:c454f88524d6 | 117 | if(capture_response(result->response)) {//AOK |
petter | 6:c454f88524d6 | 118 | while(result->response[4] != '(') { //time(ms) - always the last one |
petter | 6:c454f88524d6 | 119 | capture_response(result->response); |
petter | 6:c454f88524d6 | 120 | switch (result->response[3]) { |
petter | 6:c454f88524d6 | 121 | case 'l': //Title |
petter | 7:2df2c6e8c0df | 122 | copy_response(result->response, result->title, 6); |
petter | 6:c454f88524d6 | 123 | break; |
petter | 6:c454f88524d6 | 124 | case 'i': //Artist |
petter | 7:2df2c6e8c0df | 125 | copy_response(result->response, result->artist, 7); |
petter | 6:c454f88524d6 | 126 | break; |
petter | 6:c454f88524d6 | 127 | case 'u': //Album |
petter | 7:2df2c6e8c0df | 128 | copy_response(result->response, result->album, 6); |
petter | 7:2df2c6e8c0df | 129 | break; |
petter | 6:c454f88524d6 | 130 | case 'r': //Genre |
petter | 7:2df2c6e8c0df | 131 | copy_response(result->response, result->genre, 6); |
petter | 6:c454f88524d6 | 132 | break; |
petter | 6:c454f88524d6 | 133 | case 'c': //TrackNumber or TrackCount |
petter | 6:c454f88524d6 | 134 | { |
petter | 6:c454f88524d6 | 135 | char number_string[5]; |
petter | 6:c454f88524d6 | 136 | if(result->response[5] == 'N') { //TrackNumber |
petter | 7:2df2c6e8c0df | 137 | copy_response(result->response, number_string, 12); |
petter | 6:c454f88524d6 | 138 | result->track_number = strtoul(number_string, NULL, 10); |
petter | 6:c454f88524d6 | 139 | } |
petter | 6:c454f88524d6 | 140 | else { //TrackCount |
petter | 7:2df2c6e8c0df | 141 | copy_response(result->response, number_string, 11); |
petter | 6:c454f88524d6 | 142 | result->track_count = strtoul(number_string, NULL, 10); |
petter | 6:c454f88524d6 | 143 | } |
petter | 6:c454f88524d6 | 144 | } |
petter | 6:c454f88524d6 | 145 | break; |
petter | 6:c454f88524d6 | 146 | case 'e': |
petter | 6:c454f88524d6 | 147 | { |
petter | 7:2df2c6e8c0df | 148 | char duration_string[10]; |
petter | 7:2df2c6e8c0df | 149 | copy_response(result->response, duration_string, 9); |
petter | 6:c454f88524d6 | 150 | result->duration = strtoul(duration_string, NULL, 10); |
petter | 6:c454f88524d6 | 151 | } |
petter | 6:c454f88524d6 | 152 | break; |
petter | 6:c454f88524d6 | 153 | } |
petter | 6:c454f88524d6 | 154 | } |
petter | 6:c454f88524d6 | 155 | clear_serial(); |
petter | 6:c454f88524d6 | 156 | } |
petter | 6:c454f88524d6 | 157 | break; |
petter | 0:6cf6e566c0da | 158 | default: |
petter | 0:6cf6e566c0da | 159 | return 0; |
petter | 0:6cf6e566c0da | 160 | } |
petter | 0:6cf6e566c0da | 161 | return 1; |
petter | 0:6cf6e566c0da | 162 | } |
petter | 0:6cf6e566c0da | 163 | |
petter | 0:6cf6e566c0da | 164 | |
petter | 5:8e468fef2754 | 165 | bool RN52::capture_response(char * str){ |
petter | 0:6cf6e566c0da | 166 | char c = ' '; |
petter | 0:6cf6e566c0da | 167 | char n = 0; |
petter | 0:6cf6e566c0da | 168 | while(c != '\n') { |
petter | 0:6cf6e566c0da | 169 | if(serial.readable()) { |
petter | 0:6cf6e566c0da | 170 | c = serial.getc(); |
petter | 0:6cf6e566c0da | 171 | str[n] = c; |
petter | 0:6cf6e566c0da | 172 | n++; |
petter | 0:6cf6e566c0da | 173 | } |
petter | 0:6cf6e566c0da | 174 | } |
petter | 7:2df2c6e8c0df | 175 | str[n-2] = '\0'; //terminate string before \r\n |
petter | 5:8e468fef2754 | 176 | return (str[0] == 'A'); |
petter | 6:c454f88524d6 | 177 | } |
petter | 6:c454f88524d6 | 178 | |
petter | 6:c454f88524d6 | 179 | void RN52::clear_serial(){ |
petter | 6:c454f88524d6 | 180 | while(serial.readable()) { |
petter | 6:c454f88524d6 | 181 | serial.getc(); |
petter | 6:c454f88524d6 | 182 | } |
petter | 7:2df2c6e8c0df | 183 | } |
petter | 7:2df2c6e8c0df | 184 | |
petter | 7:2df2c6e8c0df | 185 | void RN52::copy_response(char * source, char * destination, char offset){ |
petter | 7:2df2c6e8c0df | 186 | int n = 0; |
petter | 7:2df2c6e8c0df | 187 | while(source[n+offset+1] != '\0') { //remove carraige return in the end |
petter | 7:2df2c6e8c0df | 188 | destination[n] = source[n+offset]; |
petter | 7:2df2c6e8c0df | 189 | n++; |
petter | 7:2df2c6e8c0df | 190 | } |
petter | 7:2df2c6e8c0df | 191 | destination[n] = '\0'; //end string where carriage was |
petter | 7:2df2c6e8c0df | 192 | } |
petter | 7:2df2c6e8c0df | 193 | |
petter | 7:2df2c6e8c0df | 194 | void RN52::clear_result(RN52_RESULT * result) { |
petter | 7:2df2c6e8c0df | 195 | result->event = RN52_NO_EVENT; |
petter | 7:2df2c6e8c0df | 196 | result->media_connected = 0; |
petter | 7:2df2c6e8c0df | 197 | result->phone_connected = 0; |
petter | 7:2df2c6e8c0df | 198 | result->connection = RN52_LIMBO; |
petter | 7:2df2c6e8c0df | 199 | result->title[0] = '\0'; |
petter | 7:2df2c6e8c0df | 200 | result->artist[0] = '\0'; |
petter | 7:2df2c6e8c0df | 201 | result->album[0] = '\0'; |
petter | 7:2df2c6e8c0df | 202 | result->genre[0] = '\0'; |
petter | 7:2df2c6e8c0df | 203 | result->duration = 0; |
petter | 7:2df2c6e8c0df | 204 | result->track_number = 0; |
petter | 7:2df2c6e8c0df | 205 | result->track_count = 0; |
petter | 7:2df2c6e8c0df | 206 | result->response[0] = '\0'; |
petter | 0:6cf6e566c0da | 207 | } |