Si4735 Radio Library

Dependencies:   mbed

Si4735.cpp

Committer:
bwilson30
Date:
2011-10-12
Revision:
0:42c032fc907a

File content as of revision 0:42c032fc907a:

/* mbed Si4735 Library
 * Brett Wilson and Brett Berry
 * Georgia Tech ECE 4180
 * Note: this code has only been tested for FM. 
 * Ported from ...

 * Arduino Si4735 Library
 * Written by Ryan Owens for SparkFun Electronics
 * 5/17/11
 *
 * This library is for use with the SparkFun Si4735 Shield
 * Released under the 'Buy Me a Beer' license
 * (If we ever meet, you buy me a beer)
 *
 * See the header file for better function documentation.
 *
 * See the example sketches to learn how to use the library in your code.
*/

#include "Si4735.h"
#include "mbed.h"

//This is just a constructor.
Si4735::Si4735(PinName sda, PinName scl, PinName RST_) :
    _RST_(RST_) {
    i2c_ = new I2C(sda, scl);
    i2c_->frequency(100000);
}


void Si4735::begin(char mode){
    _mode = mode;
    //Set the initial volume level.
    _currentVolume=63;

    // Reset the Si4735
    _RST_ = 0;
    wait(.2);
    _RST_ = 1;
    wait(.2);
    
    
    //Send the POWER_UP command
    switch(_mode){
        case FM:
            sprintf(command, "%c%c%c", 0x01, 0x10, 0x05);
            break;
        case AM:
        case SW:
        case LW:
            sprintf(command, "%c%c%c", 0x01, 0x11, 0x05);
            break;
        default:
            return;
    }
    sendCommand(command, 3);
    wait(.2);
    
    // Set the RCLK to 32768Hz
    sprintf(command, "%c%c%c%c%c%c", 0x12, 0x00, 0x02, 0x01, 0x80, 0x00);
    sendCommand(command, 6);
    wait(.2);
    
    // Set default frequency to 99.7 MHz FM
    sprintf(command, "%c%c%c%c", 0x20, 0x00, 0x26, 0xF2);
    sendCommand(command, 4);
    wait(.2);
    
    //Set the volume to the current value.
    sprintf(command, "%c%c%c%c%c%c", 0x12, 0x00, 0x40, 0x00, 0x00, _currentVolume);
    sendCommand(command, 6);
    wait(.2);

    //Disable Mute
    sprintf(command, "%c%c%c%c%c%c", 0x12, 0x00, 0x40, 0x01, 0x00, 0x00);
    sendCommand(command, 6);
    wait(.2);

    //Set the seek band for the desired mode (AM and FM can use default values)
    switch(_mode){
        case SW:
            //Set the lower band limit for Short Wave Radio to 2300 kHz
            sprintf(command, "%c%c%c%c%c%c", 0x12, 0x00, 0x34, 0x00, 0x08, 0xFC);
            sendCommand(command, 6);
            wait(.001);
            //Set the upper band limit for Short Wave Radio to 23000kHz
            sprintf(command, "%c%c%c%c%c%c", 0x12, 0x00, 0x34, 0x01, 0x59, 0xD8);
            sendCommand(command, 6);            
            wait(.001);
            break;
        case LW:
            //Set the lower band limit for Long Wave Radio to 152 kHz
            sprintf(command, "%c%c%c%c%c%c", 0x12, 0x00, 0x34, 0x00, 0x00, 0x99);
            sendCommand(command, 6);
            wait(.001);
            //Set the upper band limit for Long Wave Radio to 279 kHz
            sprintf(command, "%c%c%c%c%c%c", 0x12, 0x00, 0x34, 0x01, 0x01, 0x17);
            sendCommand(command, 6);
            wait(.001);            
            break;
        default:
            break;
    }
    
}

/*
* Description: Tunes the Si4735 to a frequency
*
* Params: int frequency - The desired frequency in kHz
*
* Returns: True if tune was successful
*            False if tune was unsuccessful
*/
bool Si4735::tuneFrequency(int frequency){
    //Split the desired frequency into two character for use in the
    //set frequency command.
    char highByte = frequency >> 8;
    char lowByte = frequency & 0x00FF;
    
    //Depending on the current mode, set the new frequency.
    switch(_mode){
        case FM:
            sprintf(command, "%c%c%c%c", 0x20, 0x00, highByte, lowByte);
            break;
        case AM:
        case SW:
        case LW:
            sprintf(command, "%c%c%c%c", 0x40, 0x00, highByte, lowByte);
            break;
        default:
            break;
    }
    sendCommand(command, 4);
    wait(.1);
    
    return true;
}

//This function does not work unless you bypass the buffer chip!
int Si4735::getFrequency(void){
    char data[8];
    int freq = 0;
    // FM only
    i2c_->start();
    i2c_->write(address_write);
    i2c_->write(0x22);
    i2c_->write(0x00);
    i2c_->stop();
    i2c_->start();
    i2c_->write(address_read);
    for (int i=0; i<8; i++)
        data[i] = i2c_->read(1);
    //i2c_->read(address_read, data, 8, false);
    i2c_->stop();
    freq = data[2];
    freq = (freq << 8) | data[3];
    return freq;
}

bool Si4735::seekUp(void){
    //Use the current mode selection to seek up.
    switch(_mode){
        case FM:
            sprintf(command, "%c%c", 0x21, 0x0C);
            sendCommand(command, 2);
            break;
        case AM:
        case SW:
        case LW:
            sprintf(command, "%c%c%c%c%c%c", 0x41, 0x0C, 0x00, 0x00, 0x00, 0x00);
            sendCommand(command, 6);
            break;
        default:
            break;
    }
    wait(.001);
    return true;
}

bool Si4735::seekDown(void){
    //Use the current mode selection to seek down.
    switch(_mode){
        case FM:
            sprintf(command, "%c%c", 0x21, 0x04);
            sendCommand(command, 2);
            break;
        case AM:
        case SW:
        case LW:
            sprintf(command, "%c%c%c%c%c%c", 0x41, 0x04, 0x00, 0x00, 0x00, 0x00);
            sendCommand(command, 6);
            break;
        default:
            break;
    }
    wait(.001);
    return true;
}

void Si4735::volumeUp(void){
    //If we're not at the maximum volume yet, increase the volume
    if(_currentVolume < 63){
        _currentVolume+=1;
        //Set the volume to the current value.
        sprintf(command, "%c%c%c%c%c%c", 0x12, 0x00, 0x40, 0x00, 0x00, _currentVolume);
        sendCommand(command, 6);
        wait(.01);        
    }
}

void Si4735::volumeDown(void){
    //If we're not at the maximum volume yet, increase the volume
    if(_currentVolume > 0){
        _currentVolume-=1;
        //Set the volume to the current value.
        sprintf(command, "%c%c%c%c%c%c", 0x12, 0x00, 0x40, 0x00, 0x00, _currentVolume);
        sendCommand(command, 6);
        wait(.01);        
    }
}

void Si4735::mute(void){
    //Disable Mute
    sprintf(command, "%c%c%c%c%c%c", 0x12, 0x00, 0x40, 0x01, 0x00, 0x03);
    sendCommand(command, 6);
    wait(.001);
}

void Si4735::unmute(void){
    //Disable Mute
    sprintf(command, "%c%c%c%c%c%c", 0x12, 0x00, 0x40, 0x01, 0x00, 0x00);
    sendCommand(command, 6);
    wait(.001);
}

/*char Si4735::getStatus(void){
    char response;
    bool ack1, ack2;
    i2c_->start();
    ack1 = i2c_->write(address_);  //Send i2c address and wait for ack (true) to proceed
    response = spi_->write(0xA0);  //read a single byte
    _cs_ = 1;
    wait(.001);
    return response;
}*/
/*void Si4735::getResponse(char * response){
    
}*/

void Si4735::end(void){
    sprintf(command, "%c", 0x11);
    sendCommand(command, 1);
    wait(.001);
}

/*******************************************
*
* Private Functions
*
*******************************************/

void Si4735::sendCommand(char * command, int length){
  //ack = i2c_->write(address_write, command, length, false);
  i2c_->start();
  bool ack = i2c_->write(address_write);
  for(int i=0; i<length; i++)
    ack = i2c_->write(command[i]);        
  char CTS = i2c_->read(1);
  i2c_->stop();
  }