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
- Committer:
- petter
- Date:
- 2016-01-31
- Revision:
- 14:3f4098e94c29
- Parent:
- 13:968af0520530
- Child:
- 15:82c3cc87bd02
File content as of revision 14:3f4098e94c29:
#include "RN52.h"
#include "mbed.h"
// RN52 action command definitions
#define PLAYPAUSE "AP\r"
#define NEXTTRACK "AT+\r"
#define PREVTRACK "AT-\r"
#define CONNECT "B\r"
#define DISCONNECT "@,1\r"
#define REBOOT "R,1\r"
#define VOLUMEUP "AV+\r"
#define MAXVOLUME "SS,0F\r"
#define GETSTATUS "Q\r"
#define ASSISTANT "P\r"
#define CALLER_ID "T\r"
#define TRACK_METADATA "AD\r"
#define RESPONSE_TIMEOUT 30 //ms
Serial serial(p13, p14); // tx, rx
DigitalIn event_pin(p20);
DigitalOut enable_pin(p5);
Timer responsetime;
char temp_response[255];
void RN52::init(){
enable();
serial.baud(115200);
printf("Serial baudrate set\r\n");
//make sure event pin is pulled low
if(event_pin == 0) {
serial.printf(GETSTATUS);
capture_response(temp_response);
}
}
void RN52::enable(){
enable_pin = 1;
}
void RN52::disable(){
enable_pin = 0;
serial.printf(REBOOT);
capture_response(temp_response);
}
bool RN52::check_event(RN52_RESULT * result){
clear_serial();
if(event_pin == 0) {
clear_result(result);
get_status(result);
switch (result->event) {
case RN52_CALLER_ID_EVENT:
get_caller_id(result);
break;
case RN52_TRACK_CHANGE_EVENT:
get_track_metadata(result);
break;
}
return 1;
}
return 0;
}
bool RN52::connect(){
serial.printf(CONNECT);
return capture_response(temp_response);
}
bool RN52::disconnect(){
serial.printf(DISCONNECT);
return capture_response(temp_response);
}
bool RN52::next_track(){
serial.printf(NEXTTRACK);
return capture_response(temp_response);
}
bool RN52::prev_track(){
serial.printf(PREVTRACK);
return capture_response(temp_response);
}
bool RN52::toggle_play(){
serial.printf(PLAYPAUSE);
return capture_response(temp_response);
}
bool RN52::maxvolume(){
serial.printf(MAXVOLUME);
return capture_response(temp_response);
}
bool RN52::get_status(RN52_RESULT * result){
serial.printf(GETSTATUS);
capture_response(result->response);
int response_value = strtoul(result->response, NULL, 16);
result->media_connected = (response_value & (1 << 10)) >> 10; //byte 0, bit 2
result->phone_connected = (response_value & (1 << 11)) >> 11; //byte 0, bit 3
result->connection = (RN52_CONNECTION)(response_value & 0x0F); //byte 1, bits 0-3
switch (response_value & 0x3000) {
case 0x1000: //byte 0, bit 4
result->event = RN52_CALLER_ID_EVENT;
break;
case 0x2000: //byte 0, bit 5
result->event = RN52_TRACK_CHANGE_EVENT;
break;
default:
result->event = RN52_OTHER_EVENT;
break;
}
return 1;
}
bool RN52::get_caller_id(RN52_RESULT * result){
serial.printf(CALLER_ID);
capture_response(result->response);
//parse the response
return 1;
}
bool RN52::get_track_metadata(RN52_RESULT * result){
serial.printf(TRACK_METADATA);
if(capture_response(result->response)) {//AOK
while(result->response[3] != 'e') { //time(ms) - always the last one
capture_response(result->response);
switch (result->response[3]) {
case 'l': //Title
copy_response(result->response, result->title, 6);
break;
case 'i': //Artist
copy_response(result->response, result->artist, 7);
break;
case 'u': //Album
copy_response(result->response, result->album, 6);
break;
case 'r': //Genre
copy_response(result->response, result->genre, 6);
break;
case 'c': //TrackNumber or TrackCount
{
char number_string[5];
if(result->response[5] == 'N') { //TrackNumber
copy_response(result->response, number_string, 12);
result->track_number = strtoul(number_string, NULL, 10);
}
else { //TrackCount
copy_response(result->response, number_string, 11);
result->track_count = strtoul(number_string, NULL, 10);
}
}
break;
case 'e': //time(ms) - always the last one
{
char duration_string[10];
copy_response(result->response, duration_string, 9);
result->duration = strtoul(duration_string, NULL, 10);
}
break;
}
}
clear_serial();
}
return 1;
}
bool RN52::capture_response(char * str){
responsetime.reset();
responsetime.start();
char c = ' ';
char n = 0;
while(c != '\n') {
if(serial.readable()) {
c = serial.getc();
str[n] = c;
n++;
}
else if(responsetime.read_ms() > RESPONSE_TIMEOUT) {
clear_serial();
printf("timeout occured\r\n last response: %s\r\n", str);
return 0;
}
}
str[n-2] = '\0'; //terminate string before \r\n
return (str[0] == 'A');
}
void RN52::clear_serial(){
while(serial.readable()) {
serial.getc();
}
}
void RN52::copy_response(char * source, char * destination, char offset){
int n = 0;
while(source[n+offset+1] != '\0') { //remove carraige return in the end
destination[n] = source[n+offset];
n++;
}
destination[n] = '\0'; //end string where carriage was
}
void RN52::clear_result(RN52_RESULT * result) {
result->event = RN52_NO_EVENT;
result->media_connected = 0;
result->phone_connected = 0;
result->connection = RN52_NOT_SET;
result->title[0] = '\0';
result->artist[0] = '\0';
result->album[0] = '\0';
result->genre[0] = '\0';
result->duration = 0;
result->track_number = 1;
result->track_count = 1;
result->response[0] = '\0';
}