sxa

Dependents:   MP3333 B18_MP3_PLAYER B18_MP3_PLAYER B18_MP3_PLAYER

player.cpp

Committer:
PKnevermind
Date:
2015-12-09
Revision:
3:934d5e72990a
Parent:
2:6f21eae5f456

File content as of revision 3:934d5e72990a:

#include "player.h"
#include "SDFileSystem.h"
#include "MPU9250.h"
#include "SPI_TFT_ILI9341.h"
#include "stdio.h"
#include "string"
#include "Arial12x12.h"
#include "Arial24x23.h"
#include "Arial28x28.h"
#include "font_big.h"

SDFileSystem sd(D11, D12, D13, D9, "sd"); // the pinout on the mbed Cool
vs10xx vs1053(D11, D12, D13, D6, D7, D2, D8 );//mosi,miso,sclk,xcs,xdcs,dreq,xreset
DigitalOut red(A0);
DigitalOut green(A2);
DigitalOut blue(A1);
DigitalIn Mode(A5);

MPU9250 mpu9250;
playerStatetype  playerState;
ctrlStatetype ctrlState;
static unsigned char fileBuf[65536];
unsigned char *bufptr;

extern unsigned char p1[];
extern unsigned char p2[];
extern unsigned char p3[];

char list[20][50];          //song list
char index = 0;      //song play index
char index_MAX;      //how many song in all
unsigned char vlume = 0x40;   //vlume
unsigned char vlumeflag = 0;  //set vlume flag
float sum = 0;
uint32_t sumCount = 0;
char buffer[14];
uint8_t dato_leido[2];
uint8_t whoami;
Timer t;
int check = 0;

int mark=20;
SPI_TFT_ILI9341 TFT(PA_7,PA_6,PA_5,PA_13,PA_14,PA_15,"TFT"); // mosi, miso, sclk, cs, reset, dc


void Player::begin(void)
{
    DirHandle *dir;
    struct dirent *ptr;
    FileHandle *fp;

    vs1053.reset();
    dir = opendir("/sd");
    printf("\r\n**********playing list**********\r\n");
    unsigned char i = 0,j=0;
    while(((ptr = dir->readdir()) != NULL)&&(i <20)) {
        if(strstr(ptr->d_name,".mp3")||strstr(ptr->d_name,".MP3")) {
            fp =sd.open(ptr->d_name, O_RDONLY);
            if(fp != NULL) {
                char *byte = ptr->d_name;
                j=0;
                while(*byte) {
                    list[i][j++]  = *byte++;
                }
                printf("%2d . %s\r\n", i+1,list[i++]);
                fp->close();
            }
        }
    }
    index_MAX = i-1;
    dir->closedir();
    printf("\r\n");
}

/*  This function plays back an audio file.  */
void Player::playFile(char *file)
{
    int bytes;        // How many bytes in buffer left
    int n;
    int x=0;
    check = mode();

    playerState = PS_PLAY;
    GREEN();
    vs1053.setFreq(24000000);     //hight speed
    FileHandle *fp =sd.open(file, O_RDONLY);
    if(fp == NULL) {
        printf("Could not open %s\r\n",file);

    } else {

        /* Main playback loop */
        while((bytes = fp->read(fileBuf,32000)) > 0) {
            bufptr = fileBuf;

            // actual audio data gets sent to VS10xx.
            while(bytes > 0) {
                n = (bytes < 32)?bytes:32;
                vs1053.writeData(bufptr,n);
                bytes -= n;
                bufptr += n;
                if(playerState == PS_STOP)break;
                else if(mode() != check){
                    check = mode();
                    if(mode() == 0)letplay();
                    else print_list();
                }
                else if(!mode()) {
                    if(getGY()>50){
                        playerState = PS_PAUSE;
                        cry();
                    }
                    else if(getGX()<-30) {
                        playerState = PS_STOP;
                        angry();
                        x = 1;
                    } else if(getGX()>30) {
                        playerState = PS_STOP;
                        angry();
                        x = 2;
                    }
                }
                while(playerState == PS_PAUSE) {
                    wait(0.2);
                    RED();
                    if(getGY()<-50){
                        playerState = PS_PLAY;
                        GREEN();
                    }
                }
            }
            if(playerState == PS_STOP)break;
        }
        fp->close();
        vs1053.softReset();
    }
    if(x == 1|| x==0){
        wait(0.6);
        if(index != index_MAX)index++;
        else index = 0;
    }
    else if(x == 2){
        wait(0.6);
        if(index != 0)index--;
        else index = index_MAX;
    }
}

void Set32(unsigned char *d, unsigned int n)
{
    int i;
    for (i=0; i<4; i++) {
        *d++ = (unsigned char)n;
        n >>= 8;
    }
}

void Player::RED()
{
    red = 1;
    green = 0;
    blue = 0;
}

void Player::GREEN()
{
    red = 0 ;
    green = 1;
    blue = 0;
}

void Player::BLUE()
{
    red = 0;
    green = 0;
    blue = 1;
}

int Player::getGY()
{
    // If intPin goes high, all data registers have new data
    if(mpu9250.readByte(MPU9250_ADDRESS, INT_STATUS) & 0x01) {  // On interrupt, check if data ready interrupt

        mpu9250.readAccelData(accelCount);  // Read the x/y/z adc values
        // Now we'll calculate the accleration value into actual g's
        if (I2Cstate != 0) //error on I2C
            printf("I2C error ocurred while reading accelerometer data. I2Cstate = %d \n\r", I2Cstate);
        else { // I2C read or write ok
            I2Cstate = 1;
            ax = (float)accelCount[0]*aRes - accelBias[0];  // get actual g value, this depends on scale being set
            ay = (float)accelCount[1]*aRes - accelBias[1];
            az = (float)accelCount[2]*aRes - accelBias[2];
        }

        mpu9250.readGyroData(gyroCount);  // Read the x/y/z adc values
        // Calculate the gyro value into actual degrees per second
        if (I2Cstate != 0) //error on I2C
            printf("I2C error ocurred while reading gyrometer data. I2Cstate = %d \n\r", I2Cstate);
        else { // I2C read or write ok
            I2Cstate = 1;
            gx = (float)gyroCount[0]*gRes - gyroBias[0];  // get actual gyro value, this depends on scale being set
            gy = (float)gyroCount[1]*gRes - gyroBias[1];
            gz = (float)gyroCount[2]*gRes - gyroBias[2];
        }

        mpu9250.readMagData(magCount);  // Read the x/y/z adc values
        // Calculate the magnetometer values in milliGauss
        // Include factory calibration per data sheet and user environmental corrections
        if (I2Cstate != 0) //error on I2C
            printf("I2C error ocurred while reading magnetometer data. I2Cstate = %d \n\r", I2Cstate);
        else { // I2C read or write ok
            I2Cstate = 1;
            mx = (float)magCount[0]*mRes*magCalibration[0] - magbias[0];  // get actual magnetometer value, this depends on scale being set
            my = (float)magCount[1]*mRes*magCalibration[1] - magbias[1];
            mz = (float)magCount[2]*mRes*magCalibration[2] - magbias[2];
        }

        mpu9250.getCompassOrientation(orientation);
    }

    //Now = t.read_us();
    //deltat = (float)((Now - lastUpdate)/1000000.0f) ; // set integration time by time elapsed since last filter update
    //lastUpdate = Now;
    //sum += deltat;
    //sumCount++;

    // Pass gyro rate as rad/s
    // mpu9250.MadgwickQuaternionUpdate(ax, ay, az, gx*PI/180.0f, gy*PI/180.0f, gz*PI/180.0f,  my,  mx, mz);
    mpu9250.MahonyQuaternionUpdate(ax, ay, az, gx*PI/180.0f, gy*PI/180.0f, gz*PI/180.0f, my, mx, mz);

    return gy;
}

int Player::getGX()
{
    // If intPin goes high, all data registers have new data
    if(mpu9250.readByte(MPU9250_ADDRESS, INT_STATUS) & 0x01) {  // On interrupt, check if data ready interrupt

        mpu9250.readAccelData(accelCount);  // Read the x/y/z adc values
        // Now we'll calculate the accleration value into actual g's
        if (I2Cstate != 0) //error on I2C
            printf("I2C error ocurred while reading accelerometer data. I2Cstate = %d \n\r", I2Cstate);
        else { // I2C read or write ok
            I2Cstate = 1;
            ax = (float)accelCount[0]*aRes - accelBias[0];  // get actual g value, this depends on scale being set
            ay = (float)accelCount[1]*aRes - accelBias[1];
            az = (float)accelCount[2]*aRes - accelBias[2];
        }

        mpu9250.readGyroData(gyroCount);  // Read the x/y/z adc values
        // Calculate the gyro value into actual degrees per second
        if (I2Cstate != 0) //error on I2C
            printf("I2C error ocurred while reading gyrometer data. I2Cstate = %d \n\r", I2Cstate);
        else { // I2C read or write ok
            I2Cstate = 1;
            gx = (float)gyroCount[0]*gRes - gyroBias[0];  // get actual gyro value, this depends on scale being set
            gy = (float)gyroCount[1]*gRes - gyroBias[1];
            gz = (float)gyroCount[2]*gRes - gyroBias[2];
        }

        mpu9250.readMagData(magCount);  // Read the x/y/z adc values
        // Calculate the magnetometer values in milliGauss
        // Include factory calibration per data sheet and user environmental corrections
        if (I2Cstate != 0) //error on I2C
            printf("I2C error ocurred while reading magnetometer data. I2Cstate = %d \n\r", I2Cstate);
        else { // I2C read or write ok
            I2Cstate = 1;
            mx = (float)magCount[0]*mRes*magCalibration[0] - magbias[0];  // get actual magnetometer value, this depends on scale being set
            my = (float)magCount[1]*mRes*magCalibration[1] - magbias[1];
            mz = (float)magCount[2]*mRes*magCalibration[2] - magbias[2];
        }

        mpu9250.getCompassOrientation(orientation);
    }

    //Now = t.read_us();
    //deltat = (float)((Now - lastUpdate)/1000000.0f) ; // set integration time by time elapsed since last filter update
    //lastUpdate = Now;
    //sum += deltat;
    //sumCount++;

    // Pass gyro rate as rad/s
    // mpu9250.MadgwickQuaternionUpdate(ax, ay, az, gx*PI/180.0f, gy*PI/180.0f, gz*PI/180.0f,  my,  mx, mz);
    mpu9250.MahonyQuaternionUpdate(ax, ay, az, gx*PI/180.0f, gy*PI/180.0f, gz*PI/180.0f, my, mx, mz);

    return gx;
}

void Player::setup()
{
//___ Set up I2C: use fast (400 kHz) I2C ___
    i2c.frequency(400000);

    printf("CPU SystemCoreClock is %d Hz\r\n", SystemCoreClock);

    t.start(); // Timer ON

    // Read the WHO_AM_I register, this is a good test of communication
    whoami = mpu9250.readByte(MPU9250_ADDRESS, WHO_AM_I_MPU9250);

    printf("I AM 0x%x\n\r", whoami);
    printf("I SHOULD BE 0x71\n\r");
    if (I2Cstate != 0) // error on I2C
        printf("I2C failure while reading WHO_AM_I register");

    if (whoami == 0x71) { // WHO_AM_I should always be 0x71
        printf("MPU9250 WHO_AM_I is 0x%x\n\r", whoami);
        printf("MPU9250 is online...\n\r");
        sprintf(buffer, "0x%x", whoami);
        wait(1);

        mpu9250.resetMPU9250(); // Reset registers to default in preparation for device calibration

        mpu9250.MPU9250SelfTest(SelfTest); // Start by performing self test and reporting values (accelerometer and gyroscope self test)

        mpu9250.calibrateMPU9250(gyroBias, accelBias); // Calibrate gyro and accelerometer, load biases in bias registers

        wait(2);

        // Initialize device for active mode read of acclerometer, gyroscope, and temperature
        mpu9250.initMPU9250();


        // Initialize device for active mode read of magnetometer, 16 bit resolution, 100Hz.
        mpu9250.initAK8963(magCalibration);
        wait(1);
    }

    else { // Connection failure
        while(1) ; // Loop forever if communication doesn't happen
    }

    mpu9250.getAres(); // Get accelerometer sensitivity
    mpu9250.getGres(); // Get gyro sensitivity
    mpu9250.getMres(); // Get magnetometer sensitivity
    magbias[0] = +470.;  // User environmental x-axis correction in milliGauss, should be automatically calculated
    magbias[1] = +120.;  // User environmental x-axis correction in milliGauss
    magbias[2] = +125.;  // User environmental x-axis correction in milliGauss
}

int Player::mode()
{
    int m = Mode.read();
    return m;
}

void Player::letplay()
{
    TFT.cls();
    TFT.foreground(White);
    TFT.background(Black);
    TFT.cls();
    TFT.set_orientation(1);
    TFT.Bitmap(60,1,200,173,p1);
}

void Player::angry()
{
    TFT.cls();
    TFT.foreground(White);
    TFT.background(Black);
    TFT.cls();
    TFT.set_orientation(1);
    TFT.Bitmap(60,1,200,173,p2);
}

void Player::cry()
{
    TFT.cls();
    TFT.foreground(White);
    TFT.background(Black);
    TFT.cls();
    TFT.set_orientation(1);
    TFT.Bitmap(60,1,200,173,p3);
}

void Player::print_list()
{
    int a=0,b=0;
    TFT.claim(stdout);
    TFT.cls();
    TFT.foreground(White);
    TFT.background(Black);
    TFT.cls();

    TFT.set_orientation(3);
    TFT.set_font((unsigned char*) Arial28x28);
    TFT.locate(150,120);
    TFT.printf("Manual Mode:");
    TFT.cls();
    TFT.set_orientation(3);
    TFT.set_font((unsigned char*) Arial12x12);
    //list[5]='\0';
    do {
        TFT.locate(5,b);
        TFT.printf("%2d . %s\r\n", a+1,list[a]);
        a++;
        b=b+23;
    } while(a<5);
}

void Player::select_list()
{
    if(mark>=96) {
        mark=10;
    }
    TFT.cls();
    print_list();
    TFT.set_orientation(0);
    TFT.fillcircle(mark,20,10,Red);

    mark=mark+23;
}