Si4735 Radio Library

Dependencies:   mbed

Committer:
bwilson30
Date:
Wed Oct 12 17:01:38 2011 +0000
Revision:
0:42c032fc907a

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
bwilson30 0:42c032fc907a 1 /* mbed Si4735 Library
bwilson30 0:42c032fc907a 2 * Brett Wilson and Brett Berry
bwilson30 0:42c032fc907a 3 * Georgia Tech ECE 4180
bwilson30 0:42c032fc907a 4 * Note: this code has only been tested for FM.
bwilson30 0:42c032fc907a 5 * Ported from ...
bwilson30 0:42c032fc907a 6
bwilson30 0:42c032fc907a 7 * Arduino Si4735 Library
bwilson30 0:42c032fc907a 8 * Written by Ryan Owens for SparkFun Electronics
bwilson30 0:42c032fc907a 9 * 5/17/11
bwilson30 0:42c032fc907a 10 *
bwilson30 0:42c032fc907a 11 * This library is for use with the SparkFun Si4735 Shield
bwilson30 0:42c032fc907a 12 * Released under the 'Buy Me a Beer' license
bwilson30 0:42c032fc907a 13 * (If we ever meet, you buy me a beer)
bwilson30 0:42c032fc907a 14 *
bwilson30 0:42c032fc907a 15 * See the header file for better function documentation.
bwilson30 0:42c032fc907a 16 *
bwilson30 0:42c032fc907a 17 * See the example sketches to learn how to use the library in your code.
bwilson30 0:42c032fc907a 18 */
bwilson30 0:42c032fc907a 19
bwilson30 0:42c032fc907a 20 #include "Si4735.h"
bwilson30 0:42c032fc907a 21 #include "mbed.h"
bwilson30 0:42c032fc907a 22
bwilson30 0:42c032fc907a 23 //This is just a constructor.
bwilson30 0:42c032fc907a 24 Si4735::Si4735(PinName sda, PinName scl, PinName RST_) :
bwilson30 0:42c032fc907a 25 _RST_(RST_) {
bwilson30 0:42c032fc907a 26 i2c_ = new I2C(sda, scl);
bwilson30 0:42c032fc907a 27 i2c_->frequency(100000);
bwilson30 0:42c032fc907a 28 }
bwilson30 0:42c032fc907a 29
bwilson30 0:42c032fc907a 30
bwilson30 0:42c032fc907a 31 void Si4735::begin(char mode){
bwilson30 0:42c032fc907a 32 _mode = mode;
bwilson30 0:42c032fc907a 33 //Set the initial volume level.
bwilson30 0:42c032fc907a 34 _currentVolume=63;
bwilson30 0:42c032fc907a 35
bwilson30 0:42c032fc907a 36 // Reset the Si4735
bwilson30 0:42c032fc907a 37 _RST_ = 0;
bwilson30 0:42c032fc907a 38 wait(.2);
bwilson30 0:42c032fc907a 39 _RST_ = 1;
bwilson30 0:42c032fc907a 40 wait(.2);
bwilson30 0:42c032fc907a 41
bwilson30 0:42c032fc907a 42
bwilson30 0:42c032fc907a 43 //Send the POWER_UP command
bwilson30 0:42c032fc907a 44 switch(_mode){
bwilson30 0:42c032fc907a 45 case FM:
bwilson30 0:42c032fc907a 46 sprintf(command, "%c%c%c", 0x01, 0x10, 0x05);
bwilson30 0:42c032fc907a 47 break;
bwilson30 0:42c032fc907a 48 case AM:
bwilson30 0:42c032fc907a 49 case SW:
bwilson30 0:42c032fc907a 50 case LW:
bwilson30 0:42c032fc907a 51 sprintf(command, "%c%c%c", 0x01, 0x11, 0x05);
bwilson30 0:42c032fc907a 52 break;
bwilson30 0:42c032fc907a 53 default:
bwilson30 0:42c032fc907a 54 return;
bwilson30 0:42c032fc907a 55 }
bwilson30 0:42c032fc907a 56 sendCommand(command, 3);
bwilson30 0:42c032fc907a 57 wait(.2);
bwilson30 0:42c032fc907a 58
bwilson30 0:42c032fc907a 59 // Set the RCLK to 32768Hz
bwilson30 0:42c032fc907a 60 sprintf(command, "%c%c%c%c%c%c", 0x12, 0x00, 0x02, 0x01, 0x80, 0x00);
bwilson30 0:42c032fc907a 61 sendCommand(command, 6);
bwilson30 0:42c032fc907a 62 wait(.2);
bwilson30 0:42c032fc907a 63
bwilson30 0:42c032fc907a 64 // Set default frequency to 99.7 MHz FM
bwilson30 0:42c032fc907a 65 sprintf(command, "%c%c%c%c", 0x20, 0x00, 0x26, 0xF2);
bwilson30 0:42c032fc907a 66 sendCommand(command, 4);
bwilson30 0:42c032fc907a 67 wait(.2);
bwilson30 0:42c032fc907a 68
bwilson30 0:42c032fc907a 69 //Set the volume to the current value.
bwilson30 0:42c032fc907a 70 sprintf(command, "%c%c%c%c%c%c", 0x12, 0x00, 0x40, 0x00, 0x00, _currentVolume);
bwilson30 0:42c032fc907a 71 sendCommand(command, 6);
bwilson30 0:42c032fc907a 72 wait(.2);
bwilson30 0:42c032fc907a 73
bwilson30 0:42c032fc907a 74 //Disable Mute
bwilson30 0:42c032fc907a 75 sprintf(command, "%c%c%c%c%c%c", 0x12, 0x00, 0x40, 0x01, 0x00, 0x00);
bwilson30 0:42c032fc907a 76 sendCommand(command, 6);
bwilson30 0:42c032fc907a 77 wait(.2);
bwilson30 0:42c032fc907a 78
bwilson30 0:42c032fc907a 79 //Set the seek band for the desired mode (AM and FM can use default values)
bwilson30 0:42c032fc907a 80 switch(_mode){
bwilson30 0:42c032fc907a 81 case SW:
bwilson30 0:42c032fc907a 82 //Set the lower band limit for Short Wave Radio to 2300 kHz
bwilson30 0:42c032fc907a 83 sprintf(command, "%c%c%c%c%c%c", 0x12, 0x00, 0x34, 0x00, 0x08, 0xFC);
bwilson30 0:42c032fc907a 84 sendCommand(command, 6);
bwilson30 0:42c032fc907a 85 wait(.001);
bwilson30 0:42c032fc907a 86 //Set the upper band limit for Short Wave Radio to 23000kHz
bwilson30 0:42c032fc907a 87 sprintf(command, "%c%c%c%c%c%c", 0x12, 0x00, 0x34, 0x01, 0x59, 0xD8);
bwilson30 0:42c032fc907a 88 sendCommand(command, 6);
bwilson30 0:42c032fc907a 89 wait(.001);
bwilson30 0:42c032fc907a 90 break;
bwilson30 0:42c032fc907a 91 case LW:
bwilson30 0:42c032fc907a 92 //Set the lower band limit for Long Wave Radio to 152 kHz
bwilson30 0:42c032fc907a 93 sprintf(command, "%c%c%c%c%c%c", 0x12, 0x00, 0x34, 0x00, 0x00, 0x99);
bwilson30 0:42c032fc907a 94 sendCommand(command, 6);
bwilson30 0:42c032fc907a 95 wait(.001);
bwilson30 0:42c032fc907a 96 //Set the upper band limit for Long Wave Radio to 279 kHz
bwilson30 0:42c032fc907a 97 sprintf(command, "%c%c%c%c%c%c", 0x12, 0x00, 0x34, 0x01, 0x01, 0x17);
bwilson30 0:42c032fc907a 98 sendCommand(command, 6);
bwilson30 0:42c032fc907a 99 wait(.001);
bwilson30 0:42c032fc907a 100 break;
bwilson30 0:42c032fc907a 101 default:
bwilson30 0:42c032fc907a 102 break;
bwilson30 0:42c032fc907a 103 }
bwilson30 0:42c032fc907a 104
bwilson30 0:42c032fc907a 105 }
bwilson30 0:42c032fc907a 106
bwilson30 0:42c032fc907a 107 /*
bwilson30 0:42c032fc907a 108 * Description: Tunes the Si4735 to a frequency
bwilson30 0:42c032fc907a 109 *
bwilson30 0:42c032fc907a 110 * Params: int frequency - The desired frequency in kHz
bwilson30 0:42c032fc907a 111 *
bwilson30 0:42c032fc907a 112 * Returns: True if tune was successful
bwilson30 0:42c032fc907a 113 * False if tune was unsuccessful
bwilson30 0:42c032fc907a 114 */
bwilson30 0:42c032fc907a 115 bool Si4735::tuneFrequency(int frequency){
bwilson30 0:42c032fc907a 116 //Split the desired frequency into two character for use in the
bwilson30 0:42c032fc907a 117 //set frequency command.
bwilson30 0:42c032fc907a 118 char highByte = frequency >> 8;
bwilson30 0:42c032fc907a 119 char lowByte = frequency & 0x00FF;
bwilson30 0:42c032fc907a 120
bwilson30 0:42c032fc907a 121 //Depending on the current mode, set the new frequency.
bwilson30 0:42c032fc907a 122 switch(_mode){
bwilson30 0:42c032fc907a 123 case FM:
bwilson30 0:42c032fc907a 124 sprintf(command, "%c%c%c%c", 0x20, 0x00, highByte, lowByte);
bwilson30 0:42c032fc907a 125 break;
bwilson30 0:42c032fc907a 126 case AM:
bwilson30 0:42c032fc907a 127 case SW:
bwilson30 0:42c032fc907a 128 case LW:
bwilson30 0:42c032fc907a 129 sprintf(command, "%c%c%c%c", 0x40, 0x00, highByte, lowByte);
bwilson30 0:42c032fc907a 130 break;
bwilson30 0:42c032fc907a 131 default:
bwilson30 0:42c032fc907a 132 break;
bwilson30 0:42c032fc907a 133 }
bwilson30 0:42c032fc907a 134 sendCommand(command, 4);
bwilson30 0:42c032fc907a 135 wait(.1);
bwilson30 0:42c032fc907a 136
bwilson30 0:42c032fc907a 137 return true;
bwilson30 0:42c032fc907a 138 }
bwilson30 0:42c032fc907a 139
bwilson30 0:42c032fc907a 140 //This function does not work unless you bypass the buffer chip!
bwilson30 0:42c032fc907a 141 int Si4735::getFrequency(void){
bwilson30 0:42c032fc907a 142 char data[8];
bwilson30 0:42c032fc907a 143 int freq = 0;
bwilson30 0:42c032fc907a 144 // FM only
bwilson30 0:42c032fc907a 145 i2c_->start();
bwilson30 0:42c032fc907a 146 i2c_->write(address_write);
bwilson30 0:42c032fc907a 147 i2c_->write(0x22);
bwilson30 0:42c032fc907a 148 i2c_->write(0x00);
bwilson30 0:42c032fc907a 149 i2c_->stop();
bwilson30 0:42c032fc907a 150 i2c_->start();
bwilson30 0:42c032fc907a 151 i2c_->write(address_read);
bwilson30 0:42c032fc907a 152 for (int i=0; i<8; i++)
bwilson30 0:42c032fc907a 153 data[i] = i2c_->read(1);
bwilson30 0:42c032fc907a 154 //i2c_->read(address_read, data, 8, false);
bwilson30 0:42c032fc907a 155 i2c_->stop();
bwilson30 0:42c032fc907a 156 freq = data[2];
bwilson30 0:42c032fc907a 157 freq = (freq << 8) | data[3];
bwilson30 0:42c032fc907a 158 return freq;
bwilson30 0:42c032fc907a 159 }
bwilson30 0:42c032fc907a 160
bwilson30 0:42c032fc907a 161 bool Si4735::seekUp(void){
bwilson30 0:42c032fc907a 162 //Use the current mode selection to seek up.
bwilson30 0:42c032fc907a 163 switch(_mode){
bwilson30 0:42c032fc907a 164 case FM:
bwilson30 0:42c032fc907a 165 sprintf(command, "%c%c", 0x21, 0x0C);
bwilson30 0:42c032fc907a 166 sendCommand(command, 2);
bwilson30 0:42c032fc907a 167 break;
bwilson30 0:42c032fc907a 168 case AM:
bwilson30 0:42c032fc907a 169 case SW:
bwilson30 0:42c032fc907a 170 case LW:
bwilson30 0:42c032fc907a 171 sprintf(command, "%c%c%c%c%c%c", 0x41, 0x0C, 0x00, 0x00, 0x00, 0x00);
bwilson30 0:42c032fc907a 172 sendCommand(command, 6);
bwilson30 0:42c032fc907a 173 break;
bwilson30 0:42c032fc907a 174 default:
bwilson30 0:42c032fc907a 175 break;
bwilson30 0:42c032fc907a 176 }
bwilson30 0:42c032fc907a 177 wait(.001);
bwilson30 0:42c032fc907a 178 return true;
bwilson30 0:42c032fc907a 179 }
bwilson30 0:42c032fc907a 180
bwilson30 0:42c032fc907a 181 bool Si4735::seekDown(void){
bwilson30 0:42c032fc907a 182 //Use the current mode selection to seek down.
bwilson30 0:42c032fc907a 183 switch(_mode){
bwilson30 0:42c032fc907a 184 case FM:
bwilson30 0:42c032fc907a 185 sprintf(command, "%c%c", 0x21, 0x04);
bwilson30 0:42c032fc907a 186 sendCommand(command, 2);
bwilson30 0:42c032fc907a 187 break;
bwilson30 0:42c032fc907a 188 case AM:
bwilson30 0:42c032fc907a 189 case SW:
bwilson30 0:42c032fc907a 190 case LW:
bwilson30 0:42c032fc907a 191 sprintf(command, "%c%c%c%c%c%c", 0x41, 0x04, 0x00, 0x00, 0x00, 0x00);
bwilson30 0:42c032fc907a 192 sendCommand(command, 6);
bwilson30 0:42c032fc907a 193 break;
bwilson30 0:42c032fc907a 194 default:
bwilson30 0:42c032fc907a 195 break;
bwilson30 0:42c032fc907a 196 }
bwilson30 0:42c032fc907a 197 wait(.001);
bwilson30 0:42c032fc907a 198 return true;
bwilson30 0:42c032fc907a 199 }
bwilson30 0:42c032fc907a 200
bwilson30 0:42c032fc907a 201 void Si4735::volumeUp(void){
bwilson30 0:42c032fc907a 202 //If we're not at the maximum volume yet, increase the volume
bwilson30 0:42c032fc907a 203 if(_currentVolume < 63){
bwilson30 0:42c032fc907a 204 _currentVolume+=1;
bwilson30 0:42c032fc907a 205 //Set the volume to the current value.
bwilson30 0:42c032fc907a 206 sprintf(command, "%c%c%c%c%c%c", 0x12, 0x00, 0x40, 0x00, 0x00, _currentVolume);
bwilson30 0:42c032fc907a 207 sendCommand(command, 6);
bwilson30 0:42c032fc907a 208 wait(.01);
bwilson30 0:42c032fc907a 209 }
bwilson30 0:42c032fc907a 210 }
bwilson30 0:42c032fc907a 211
bwilson30 0:42c032fc907a 212 void Si4735::volumeDown(void){
bwilson30 0:42c032fc907a 213 //If we're not at the maximum volume yet, increase the volume
bwilson30 0:42c032fc907a 214 if(_currentVolume > 0){
bwilson30 0:42c032fc907a 215 _currentVolume-=1;
bwilson30 0:42c032fc907a 216 //Set the volume to the current value.
bwilson30 0:42c032fc907a 217 sprintf(command, "%c%c%c%c%c%c", 0x12, 0x00, 0x40, 0x00, 0x00, _currentVolume);
bwilson30 0:42c032fc907a 218 sendCommand(command, 6);
bwilson30 0:42c032fc907a 219 wait(.01);
bwilson30 0:42c032fc907a 220 }
bwilson30 0:42c032fc907a 221 }
bwilson30 0:42c032fc907a 222
bwilson30 0:42c032fc907a 223 void Si4735::mute(void){
bwilson30 0:42c032fc907a 224 //Disable Mute
bwilson30 0:42c032fc907a 225 sprintf(command, "%c%c%c%c%c%c", 0x12, 0x00, 0x40, 0x01, 0x00, 0x03);
bwilson30 0:42c032fc907a 226 sendCommand(command, 6);
bwilson30 0:42c032fc907a 227 wait(.001);
bwilson30 0:42c032fc907a 228 }
bwilson30 0:42c032fc907a 229
bwilson30 0:42c032fc907a 230 void Si4735::unmute(void){
bwilson30 0:42c032fc907a 231 //Disable Mute
bwilson30 0:42c032fc907a 232 sprintf(command, "%c%c%c%c%c%c", 0x12, 0x00, 0x40, 0x01, 0x00, 0x00);
bwilson30 0:42c032fc907a 233 sendCommand(command, 6);
bwilson30 0:42c032fc907a 234 wait(.001);
bwilson30 0:42c032fc907a 235 }
bwilson30 0:42c032fc907a 236
bwilson30 0:42c032fc907a 237 /*char Si4735::getStatus(void){
bwilson30 0:42c032fc907a 238 char response;
bwilson30 0:42c032fc907a 239 bool ack1, ack2;
bwilson30 0:42c032fc907a 240 i2c_->start();
bwilson30 0:42c032fc907a 241 ack1 = i2c_->write(address_); //Send i2c address and wait for ack (true) to proceed
bwilson30 0:42c032fc907a 242 response = spi_->write(0xA0); //read a single byte
bwilson30 0:42c032fc907a 243 _cs_ = 1;
bwilson30 0:42c032fc907a 244 wait(.001);
bwilson30 0:42c032fc907a 245 return response;
bwilson30 0:42c032fc907a 246 }*/
bwilson30 0:42c032fc907a 247 /*void Si4735::getResponse(char * response){
bwilson30 0:42c032fc907a 248
bwilson30 0:42c032fc907a 249 }*/
bwilson30 0:42c032fc907a 250
bwilson30 0:42c032fc907a 251 void Si4735::end(void){
bwilson30 0:42c032fc907a 252 sprintf(command, "%c", 0x11);
bwilson30 0:42c032fc907a 253 sendCommand(command, 1);
bwilson30 0:42c032fc907a 254 wait(.001);
bwilson30 0:42c032fc907a 255 }
bwilson30 0:42c032fc907a 256
bwilson30 0:42c032fc907a 257 /*******************************************
bwilson30 0:42c032fc907a 258 *
bwilson30 0:42c032fc907a 259 * Private Functions
bwilson30 0:42c032fc907a 260 *
bwilson30 0:42c032fc907a 261 *******************************************/
bwilson30 0:42c032fc907a 262
bwilson30 0:42c032fc907a 263 void Si4735::sendCommand(char * command, int length){
bwilson30 0:42c032fc907a 264 //ack = i2c_->write(address_write, command, length, false);
bwilson30 0:42c032fc907a 265 i2c_->start();
bwilson30 0:42c032fc907a 266 bool ack = i2c_->write(address_write);
bwilson30 0:42c032fc907a 267 for(int i=0; i<length; i++)
bwilson30 0:42c032fc907a 268 ack = i2c_->write(command[i]);
bwilson30 0:42c032fc907a 269 char CTS = i2c_->read(1);
bwilson30 0:42c032fc907a 270 i2c_->stop();
bwilson30 0:42c032fc907a 271 }