Petter Bellander / Mbed 2 deprecated Saab-BT

Dependencies:   mbed

RN52.cpp

Committer:
petter
Date:
2016-01-13
Revision:
6:c454f88524d6
Parent:
5:8e468fef2754
Child:
7:2df2c6e8c0df

File content as of revision 6:c454f88524d6:

#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"


Serial serial(p13, p14);  // tx, rx
DigitalIn event_pin(p20);

void RN52::init(){
    serial.baud(115200);
    printf("Serial baudrate set\r\n");
    
    //make sure event pin is pulled low
    if(event_pin == 0) {
        char response[10];
        serial.printf(GETSTATUS);
        capture_response(response);
    }
}

bool RN52::check_event(RN52_RESULT * result){
    clear_serial();
    if(event_pin == 0) {
        get(RN52_GETSTATUS, result);
        switch (result->event) {
            case RN52_CALLER_ID_EVENT:
                get(RN52_CALLER_ID, result);
                break;
            case RN52_TRACK_CHANGE_EVENT:
                get(RN52_TRACK_METADATA, result);
                break;
        }
        return 1;   
    }
    return 0;
}

bool RN52::connect(){
    char response[5];
    serial.printf(CONNECT);
    return capture_response(response);
}

bool RN52::disconnect(){
    char response[5];
    serial.printf(DISCONNECT);
    return capture_response(response);
}

bool RN52::next_track(){
    char response[5];
    serial.printf(NEXTTRACK);
    return capture_response(response);
}

bool RN52::prev_track(){
    char response[5];
    serial.printf(PREVTRACK);
    return capture_response(response);
}

bool RN52::toggle_play(){
    char response[5];
    serial.printf(PLAYPAUSE);
    return capture_response(response);
}

bool RN52::maxvolume(){
    char response[5];
    serial.printf(MAXVOLUME);
    return capture_response(response);
}

bool RN52::get(RN52_COMMAND cmd, RN52_RESULT * result){
    switch (cmd) {
        case RN52_GETSTATUS: {
            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_NO_EVENT;
                    break;
            }
            break;
        } //added to create local scope of response_value
        case RN52_CALLER_ID:
            serial.printf(CALLER_ID);
            capture_response(result->response);
            //parse the response
            break;
        case RN52_TRACK_METADATA:
                serial.printf(TRACK_METADATA);
                if(capture_response(result->response)) {//AOK
                    while(result->response[4] != '(') { //time(ms) - always the last one
                        capture_response(result->response);
                        switch (result->response[3]) {
                            case 'l': //Title
                                for( int n = 0; n < STRING_BUFFER_LENGTH-6; n=n+1 ) {
                                    result->title[n] = result->response[n+6]; 
                                }
                                break;
                            case 'i': //Artist
                                for( int n = 0; n < STRING_BUFFER_LENGTH-7; n=n+1 ) {
                                    result->artist[n] = result->response[n+7]; 
                                }
                                break; 
                            case 'u': //Album
                                for( int n = 0; n < STRING_BUFFER_LENGTH-6; n=n+1 ) {
                                    result->album[n] = result->response[n+6]; 
                                }
                                break;
                            case 'r': //Genre
                                for( int n = 0; n < STRING_BUFFER_LENGTH-6; n=n+1 ) {
                                    result->genre[n] = result->response[n+6]; 
                                }
                                break;
                            case 'c': //TrackNumber or TrackCount
                                {
                                    char number_string[5];
                                    if(result->response[5] == 'N') { //TrackNumber
                                        for( int n = 0; n < 5; n=n+1 ) {
                                               number_string[n] = result->response[n+12]; 
                                        }
                                        result->track_number = strtoul(number_string, NULL, 10);
                                    }
                                    else { //TrackCount
                                        for( int n = 0; n < 5; n=n+1 ) {
                                               number_string[n] = result->response[n+11]; 
                                        }
                                        result->track_count = strtoul(number_string, NULL, 10);
                                    }
                                }
                                break;
                            case 'e':
                                {
                                    char duration_string[10];
                                    for( int n = 0; n < 10; n=n+1 ) {
                                           duration_string[n] = result->response[n+9]; 
                                    }
                                    result->duration = strtoul(duration_string, NULL, 10);
                                }
                                break;                                   
                        }
                    
                    }
                    clear_serial();
                }
                break;
        default:
            return 0;
    }
    return 1;
}



bool RN52::capture_response(char * str){        
    char c = ' ';
    char n = 0;
    while(c != '\n') {
        if(serial.readable()) {
            c = serial.getc();
            str[n] = c;
            n++;
        }   
    }
    str[n] = '\0';
    return (str[0] == 'A');
}

void RN52::clear_serial(){
    while(serial.readable()) {
        serial.getc();
    }
}