UART MP3 Voice Module with 8MB Flash Memory / DFR0534

Dependents:   DFR0534_MP3_Test_os5 TYBLE16_MP3_Air

see /users/kenjiArai/notebook/mp3--voice-module-dfr0534/

drf0534.cpp

Committer:
kenjiArai
Date:
2019-12-29
Revision:
0:466200f304c9

File content as of revision 0:466200f304c9:

/*
 * Mbed Library program
 *  UART MP3 Voice Module with 8MB Flash Memory / DFR0534
 *
 * Copyright (c) 2019 Kenji Arai / JH1PJL
 *  http://www.page.sannet.ne.jp/kenjia/index.html
 *  https://os.mbed.com/users/kenjiArai/
 *      Created:    December  28th, 2019
 *      Revised:    December  29th, 2019
 */

/*
    Reference information:
        http://akizukidenshi.com/catalog/g/gM-13708/
        https://wiki.dfrobot.com/Voice_Module_SKU__DFR0534
 */

#include "drf0534.h"
    
#if MBED_MAJOR_VERSION == 2
#define WAIT_MS(x)       wait_ms(x)
#elif  MBED_MAJOR_VERSION == 5
#define WAIT_MS(x)       ThisThread::sleep_for(x)
#else
#error "Running on Unknown OS"
#endif

//#define DEBUG

DFR0534::DFR0534(PinName tx, PinName rx, PinName busy)
    :_mp3(tx, rx), _bsy(busy)
{
    _mp3.baud(9600);
    _mp3.attach(callback(this,&DFR0534::_rx_handler), Serial::RxIrq);
    volume_setting(0);
}

void DFR0534::play_one(uint16_t track_num)
{
    _wait_busy();
    _sum = 0xaa;
    _mp3.putc(_sum);
    WAIT_MS(2);
    _sum += 0x07;
    _mp3.putc(0x07);
    WAIT_MS(2);
    _sum += 0x02;
    _mp3.putc(0x02);
    WAIT_MS(2);
    uint8_t dt = track_num >> 8;
    _sum += dt;
    _mp3.putc(dt);
    WAIT_MS(2);
    dt = (uint8_t)track_num;
    _sum += dt;
    _mp3.putc(dt);
    WAIT_MS(2);
    _mp3.putc(_sum);
}

void DFR0534::volume_setting(uint8_t vol)
{
    _sum = 0xaa;
    _mp3.putc(_sum);
    WAIT_MS(2);
    _sum += 0x13;
    _mp3.putc(0x13);
    WAIT_MS(2);
    _sum += 0x01;
    _mp3.putc(0x01);
    WAIT_MS(2);
    uint8_t dt = vol;
    if (dt > VOL_MAX) {
        dt = VOL_MAX;
    }
    _sum += dt;
    _mp3.putc(dt);
    WAIT_MS(2);
    _mp3.putc(_sum);
}

void DFR0534::volume_increase()
{
    _command(0x14);
}

void DFR0534::volume_decrease()
{
    _command(0x15);
}

void DFR0534::command(enum simple_commands cmds)
{
    _command(cmds);
}

uint16_t DFR0534::total_num_of_audio()
{
    uint16_t dt = 0;
    char c;

    _rxbuf.reset();     // clear buffer
    _command(0x0c);
    WAIT_MS(50);
    for (uint32_t i = 0; i < 6; i++) {
        while(_rxbuf.empty() == true) {;}
        _rxbuf.pop(c);
        _buf[i] = c;
    }
#if defined(DEBUG)
    for (uint32_t i = 0; i < 6; i++) {
        printf("0x%02x, ",_buf[i]);
    }
    printf("\r\n");
#endif
    if (_buf[0] == 0xaa) {
        _sum = 0xaa;
        _sum += _buf[1];
        _sum += _buf[2];
        dt = _buf[3] << 8;
        _sum += _buf[3];
        dt += _buf[4];
        _sum += _buf[4];
        if (_sum == _buf[5]) {
            return dt;  // success
        }
    }
    return 0;   // error
}

uint16_t DFR0534::current_num_of_audio()
{
    uint16_t dt = 0;
    char c;

    _rxbuf.reset();     // clear buffer
    _command(0x0d);
    WAIT_MS(50);
    for (uint32_t i = 0; i < 6; i++) {
        while(_rxbuf.empty() == true) {;}
        _rxbuf.pop(c);
        _buf[i] = c;
    }
#if defined(DEBUG)
    for (uint32_t i = 0; i < 6; i++) {
        printf("0x%02x, ",_buf[i]);
    }
    printf("\r\n");
#endif
    if (_buf[0] == 0xaa) {
        _sum = 0xaa;
        _sum += _buf[1];
        _sum += _buf[2];
        dt = _buf[3] << 8;
        _sum += _buf[3];
        dt += _buf[4];
        _sum += _buf[4];
        if (_sum == _buf[5]) {
            return dt;  // success
        }
    }
    return 0;   // error
}

void DFR0534::get_file_name(char *buf)
{
    uint16_t dt = 0;
    char c, num;
    char *p;

    _rxbuf.reset();     // clear buffer
    _command(0x1e);
    WAIT_MS(50);
    for (uint32_t i = 0; i < 3; i++) {
        while(_rxbuf.empty() == true) {;}
        _rxbuf.pop(c);
        _buf[i] = c;
    }
#if defined(DEBUG)
    for (uint32_t i = 0; i < 3; i++) {
        printf("H: 0x%02x, ",_buf[i]);
    }
    printf("\r\n");
#endif
    if (_buf[0] == 0xaa) {
        _sum = 0xaa;
        _sum += _buf[1];
        _sum += _buf[2];
    } else {    // error
        *buf = 0;
        return;
    }
    num = _buf[2] + 1;
#if defined(DEBUG)
    printf("number = %d\r\n", num);
#endif
    for (uint32_t i = 0; i < num; i++) {
        while(_rxbuf.empty() == true) {;}
        _rxbuf.pop(c);
        _buf[i] = c;
    }
#if defined(DEBUG)
    for (uint32_t i = 0; i < num; i++) {
        printf("T: 0x%02x, ",_buf[i]);
    }
#endif
    num -= 1;
    for (uint32_t i = 0; i < num; i++) {
        _sum += _buf[i];
    }
    if (_sum == _buf[num]) {
#if defined(DEBUG)
        printf("Sum is okay! sum = %d, buf = %d\r\n", _sum, _buf[num]);
#endif
        p = buf;
        for (uint32_t i = 0; i < num; i++) {
            *p++ = _buf[i];
        }
        *p = 0;
#if defined(DEBUG)
        printf("%s\r\n", buf);
    } else {
        printf("Sum is NG! sum = %d, buf = %d\r\n", _sum, _buf[num]);
    }
#else
    }
#endif
}

uint32_t DFR0534::get_play_time()
{
    _rxbuf.reset();     // clear buffer
    _command(0x24);
    return get_time();
}

uint32_t DFR0534::get_play_back_time()
{
    _rxbuf.reset();     // clear buffer
    _command(0x25);
    return get_time();
}

uint32_t DFR0534::get_time()
{
    uint16_t dt = 0;
    char c, h, m, s;

    WAIT_MS(50);
    for (uint32_t i = 0; i < 7; i++) {
        while(_rxbuf.empty() == true) {;}
        _rxbuf.pop(c);
        _buf[i] = c;
    }
#if defined(DEBUG)
    for (uint32_t i = 0; i < 7; i++) {
        printf("0x%02x, ",_buf[i]);
    }
    printf("\r\n");
#endif
    if (_buf[0] == 0xaa) {
        _sum = 0xaa;
        _sum += _buf[1];
        _sum += _buf[2];
        h = _buf[3];
        _sum += _buf[3];
        m = _buf[4];
        _sum += _buf[4];
        s = _buf[5];
        _sum += _buf[5];
        if (_sum == _buf[6]) {
#if defined(DEBUG)
            printf("Sum is okay! sum = %d, buf = %d\r\n", _sum, _buf[6]);
#endif
            // success
            return ((uint32_t)h * 3600 + (uint32_t)m * 60 + (uint32_t)s);
#if defined(DEBUG)
        } else {
            printf("Sum is NG! sum = %d, buf = %d\r\n", _sum, _buf[6]);
        }
#else
        }
#endif
    }
    return 0;   // error
}

// Interrupt Hander
void DFR0534::_rx_handler(void)
{
    while(_mp3.readable()) {
        _rxbuf.push(_mp3.getc());
    }
}

void DFR0534::_command(uint8_t cmd_no)
{
    _sum = 0xaa;
    _mp3.putc(_sum);
    _sum += cmd_no;
    WAIT_MS(2);
    _mp3.putc(cmd_no);
    WAIT_MS(2);
    _mp3.putc(0x00);
    WAIT_MS(2);
    _mp3.putc(_sum);
}

void DFR0534::_command_w_para(uint8_t cmd_no, uint8_t *parameter, uint8_t len)
{
    _sum = 0xaa;
    _mp3.putc(_sum);
    _sum += cmd_no;
    WAIT_MS(2);
    _mp3.putc(cmd_no);
    WAIT_MS(2);
    _mp3.putc(0x00);
    WAIT_MS(2);
    for (uint32_t i = 0; i < len; i++) {
        uint8_t dt = *parameter++;
        _sum += dt;
        _mp3.putc(dt);
        WAIT_MS(2);
    }
    _mp3.putc(_sum);
}

void DFR0534::_wait_busy(void)
{
    while (_bsy.read() == 1) {
        WAIT_MS(20);
    }
}