Si4735 Radio Library

Dependencies:   mbed

Revision:
0:42c032fc907a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Si4735.cpp	Wed Oct 12 17:01:38 2011 +0000
@@ -0,0 +1,271 @@
+/* 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();
+  }