A mbed Port of 'Sparkfun Si4703 Arduino Library'.
SparkFun-Si4703.cpp@5:bc6f2d389038, 2018-11-30 (annotated)
- Committer:
- mzcs
- Date:
- Fri Nov 30 03:39:48 2018 +0000
- Revision:
- 5:bc6f2d389038
- Parent:
- 4:651f1a1b639e
.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
mzcs | 4:651f1a1b639e | 1 | #include "mbed.h" |
mzcs | 4:651f1a1b639e | 2 | #include "SparkFun-Si4703.h" |
mzcs | 4:651f1a1b639e | 3 | |
mzcs | 4:651f1a1b639e | 4 | Si4703_Breakout::Si4703_Breakout(PinName sdioPin, PinName sclkPin, PinName resetPin, Serial *pc) |
mzcs | 4:651f1a1b639e | 5 | { |
mzcs | 4:651f1a1b639e | 6 | _resetPin = resetPin; |
mzcs | 4:651f1a1b639e | 7 | _sdioPin = sdioPin; |
mzcs | 4:651f1a1b639e | 8 | _sclkPin = sclkPin; |
mzcs | 4:651f1a1b639e | 9 | |
mzcs | 4:651f1a1b639e | 10 | this->pc = pc; |
mzcs | 4:651f1a1b639e | 11 | } |
mzcs | 4:651f1a1b639e | 12 | |
mzcs | 4:651f1a1b639e | 13 | void Si4703_Breakout::powerOn() |
mzcs | 4:651f1a1b639e | 14 | { |
mzcs | 4:651f1a1b639e | 15 | si4703_init(); |
mzcs | 4:651f1a1b639e | 16 | } |
mzcs | 4:651f1a1b639e | 17 | |
mzcs | 4:651f1a1b639e | 18 | void Si4703_Breakout::powerOff() |
mzcs | 4:651f1a1b639e | 19 | { |
mzcs | 4:651f1a1b639e | 20 | // a Minimal Power-Down Sequence - According To SI AN230 (rev. 0.9), p.13 - Table 4 |
mzcs | 4:651f1a1b639e | 21 | |
mzcs | 4:651f1a1b639e | 22 | readRegisters(); |
mzcs | 4:651f1a1b639e | 23 | si4703_registers[POWERCFG] &= ~(1<<DMUTE); // 'Enable Mute' |
mzcs | 4:651f1a1b639e | 24 | updateRegisters(); |
mzcs | 4:651f1a1b639e | 25 | |
mzcs | 5:bc6f2d389038 | 26 | readRegisters(); |
mzcs | 4:651f1a1b639e | 27 | si4703_registers[POWERCFG] |= (1<<ENABLE); // 'Enable IC' |
mzcs | 4:651f1a1b639e | 28 | updateRegisters(); |
mzcs | 4:651f1a1b639e | 29 | |
mzcs | 5:bc6f2d389038 | 30 | readRegisters(); |
mzcs | 4:651f1a1b639e | 31 | si4703_registers[POWERCFG] |= (1<<DISABLE); // & 'Disable IC' |
mzcs | 4:651f1a1b639e | 32 | updateRegisters(); |
mzcs | 4:651f1a1b639e | 33 | |
mzcs | 4:651f1a1b639e | 34 | // Notice : This Does NOT Perform a Reset of The IC. |
mzcs | 4:651f1a1b639e | 35 | } |
mzcs | 4:651f1a1b639e | 36 | |
mzcs | 4:651f1a1b639e | 37 | void Si4703_Breakout::setChannel(int channel) |
mzcs | 4:651f1a1b639e | 38 | { |
mzcs | 4:651f1a1b639e | 39 | uint8_t ack; |
mzcs | 4:651f1a1b639e | 40 | //Freq(MHz) = 0.1 (in Europe) * Channel + 87.5MHz |
mzcs | 4:651f1a1b639e | 41 | //97.3 = 0.1 * Chan + 87.5 |
mzcs | 4:651f1a1b639e | 42 | //9.8 / 0.1 = 98 |
mzcs | 4:651f1a1b639e | 43 | int newChannel = channel * 10; //973 * 10 = 9730 |
mzcs | 4:651f1a1b639e | 44 | newChannel -= 8750; //9730 - 8750 = 980 |
mzcs | 4:651f1a1b639e | 45 | newChannel /= 10; //980 / 10 = 98 |
mzcs | 4:651f1a1b639e | 46 | |
mzcs | 4:651f1a1b639e | 47 | //These steps come from AN230 page 20 rev 0.5 |
mzcs | 4:651f1a1b639e | 48 | readRegisters(); |
mzcs | 4:651f1a1b639e | 49 | si4703_registers[CHANNEL] &= 0xFE00; //Clear out the channel bits |
mzcs | 4:651f1a1b639e | 50 | si4703_registers[CHANNEL] |= newChannel; //Mask in the new channel |
mzcs | 4:651f1a1b639e | 51 | si4703_registers[CHANNEL] |= (1<<TUNE); //Set the TUNE bit to start |
mzcs | 4:651f1a1b639e | 52 | updateRegisters(); |
mzcs | 4:651f1a1b639e | 53 | |
mzcs | 4:651f1a1b639e | 54 | wait_ms(60); //Wait 60ms - you can use or skip this delay |
mzcs | 4:651f1a1b639e | 55 | |
mzcs | 4:651f1a1b639e | 56 | //Poll to see if STC is set |
mzcs | 4:651f1a1b639e | 57 | while(1) { |
mzcs | 4:651f1a1b639e | 58 | ack = readRegisters(); |
mzcs | 4:651f1a1b639e | 59 | wait_ms(1); // Just In Case... |
mzcs | 4:651f1a1b639e | 60 | if (( (si4703_registers[STATUSRSSI] & (1<<STC)) != 0) || (ack != SUCCESS)) break; //Tuning complete! (or FAILED) |
mzcs | 4:651f1a1b639e | 61 | } |
mzcs | 4:651f1a1b639e | 62 | |
mzcs | 4:651f1a1b639e | 63 | readRegisters(); |
mzcs | 4:651f1a1b639e | 64 | si4703_registers[CHANNEL] &= ~(1<<TUNE); //Clear the tune after a tune has completed |
mzcs | 4:651f1a1b639e | 65 | updateRegisters(); |
mzcs | 4:651f1a1b639e | 66 | |
mzcs | 4:651f1a1b639e | 67 | //Wait for the si4703 to clear the STC as well |
mzcs | 4:651f1a1b639e | 68 | while(1) { |
mzcs | 4:651f1a1b639e | 69 | ack = readRegisters(); |
mzcs | 4:651f1a1b639e | 70 | wait_ms(1); // Just In Case... |
mzcs | 4:651f1a1b639e | 71 | if (( (si4703_registers[STATUSRSSI] & (1<<STC)) == 0) || (ack != SUCCESS)) break; //Tuning complete! (or FAILED) |
mzcs | 4:651f1a1b639e | 72 | } |
mzcs | 4:651f1a1b639e | 73 | } |
mzcs | 4:651f1a1b639e | 74 | |
mzcs | 4:651f1a1b639e | 75 | int Si4703_Breakout::seekUp() |
mzcs | 4:651f1a1b639e | 76 | { |
mzcs | 4:651f1a1b639e | 77 | return seek(SEEK_UP); |
mzcs | 4:651f1a1b639e | 78 | } |
mzcs | 4:651f1a1b639e | 79 | |
mzcs | 4:651f1a1b639e | 80 | int Si4703_Breakout::seekDown() |
mzcs | 4:651f1a1b639e | 81 | { |
mzcs | 4:651f1a1b639e | 82 | return seek(SEEK_DOWN); |
mzcs | 4:651f1a1b639e | 83 | } |
mzcs | 4:651f1a1b639e | 84 | |
mzcs | 4:651f1a1b639e | 85 | void Si4703_Breakout::setVolume(int volume) |
mzcs | 4:651f1a1b639e | 86 | { |
mzcs | 4:651f1a1b639e | 87 | readRegisters(); //Read the current register set |
mzcs | 4:651f1a1b639e | 88 | if(volume < 0) volume = 0; |
mzcs | 4:651f1a1b639e | 89 | if (volume > 15) volume = 15; |
mzcs | 4:651f1a1b639e | 90 | si4703_registers[SYSCONFIG2] &= 0xFFF0; //Clear volume bits |
mzcs | 4:651f1a1b639e | 91 | si4703_registers[SYSCONFIG2] |= volume; //Set new volume |
mzcs | 4:651f1a1b639e | 92 | updateRegisters(); //Update |
mzcs | 4:651f1a1b639e | 93 | } |
mzcs | 4:651f1a1b639e | 94 | |
mzcs | 4:651f1a1b639e | 95 | uint8_t Si4703_Breakout::getVolume() |
mzcs | 4:651f1a1b639e | 96 | { |
mzcs | 4:651f1a1b639e | 97 | readRegisters(); //Read the current register set |
mzcs | 4:651f1a1b639e | 98 | |
mzcs | 4:651f1a1b639e | 99 | return (si4703_registers[SYSCONFIG2] & 0x000F); |
mzcs | 4:651f1a1b639e | 100 | } |
mzcs | 4:651f1a1b639e | 101 | |
mzcs | 4:651f1a1b639e | 102 | /* |
mzcs | 4:651f1a1b639e | 103 | void Si4703_Breakout::readRDS(char* buffer, long timeout) |
mzcs | 4:651f1a1b639e | 104 | { |
mzcs | 4:651f1a1b639e | 105 | long endTime = millis() + timeout; |
mzcs | 4:651f1a1b639e | 106 | boolean completed[] = {false, false, false, false}; |
mzcs | 4:651f1a1b639e | 107 | int completedCount = 0; |
mzcs | 4:651f1a1b639e | 108 | while(completedCount < 4 && millis() < endTime) { |
mzcs | 4:651f1a1b639e | 109 | readRegisters(); |
mzcs | 4:651f1a1b639e | 110 | if(si4703_registers[STATUSRSSI] & (1<<RDSR)){ |
mzcs | 4:651f1a1b639e | 111 | // ls 2 bits of B determine the 4 letter pairs |
mzcs | 4:651f1a1b639e | 112 | // once we have a full set return |
mzcs | 4:651f1a1b639e | 113 | // if you get nothing after 20 readings return with empty string |
mzcs | 4:651f1a1b639e | 114 | uint16_t b = si4703_registers[RDSB]; |
mzcs | 4:651f1a1b639e | 115 | int index = b & 0x03; |
mzcs | 4:651f1a1b639e | 116 | if (! completed[index] && b < 500) |
mzcs | 4:651f1a1b639e | 117 | { |
mzcs | 4:651f1a1b639e | 118 | completed[index] = true; |
mzcs | 4:651f1a1b639e | 119 | completedCount ++; |
mzcs | 4:651f1a1b639e | 120 | char Dh = (si4703_registers[RDSD] & 0xFF00) >> 8; |
mzcs | 4:651f1a1b639e | 121 | char Dl = (si4703_registers[RDSD] & 0x00FF); |
mzcs | 4:651f1a1b639e | 122 | buffer[index * 2] = Dh; |
mzcs | 4:651f1a1b639e | 123 | buffer[index * 2 +1] = Dl; |
mzcs | 4:651f1a1b639e | 124 | // Serial.print(si4703_registers[RDSD]); Serial.print(" "); |
mzcs | 4:651f1a1b639e | 125 | // Serial.print(index);Serial.print(" "); |
mzcs | 4:651f1a1b639e | 126 | // Serial.write(Dh); |
mzcs | 4:651f1a1b639e | 127 | // Serial.write(Dl); |
mzcs | 4:651f1a1b639e | 128 | // Serial.println(); |
mzcs | 4:651f1a1b639e | 129 | } |
mzcs | 4:651f1a1b639e | 130 | delay(40); //Wait for the RDS bit to clear |
mzcs | 4:651f1a1b639e | 131 | } |
mzcs | 4:651f1a1b639e | 132 | else { |
mzcs | 4:651f1a1b639e | 133 | delay(30); //From AN230, using the polling method 40ms should be sufficient amount of time between checks |
mzcs | 4:651f1a1b639e | 134 | } |
mzcs | 4:651f1a1b639e | 135 | } |
mzcs | 4:651f1a1b639e | 136 | if (millis() >= endTime) { |
mzcs | 4:651f1a1b639e | 137 | buffer[0] ='\0'; |
mzcs | 4:651f1a1b639e | 138 | return; |
mzcs | 4:651f1a1b639e | 139 | } |
mzcs | 4:651f1a1b639e | 140 | |
mzcs | 4:651f1a1b639e | 141 | buffer[8] = '\0'; |
mzcs | 4:651f1a1b639e | 142 | } |
mzcs | 4:651f1a1b639e | 143 | */ |
mzcs | 4:651f1a1b639e | 144 | |
mzcs | 4:651f1a1b639e | 145 | |
mzcs | 4:651f1a1b639e | 146 | |
mzcs | 4:651f1a1b639e | 147 | //To get the Si4703 inito 2-wire mode, SEN needs to be high and SDIO needs to be low after a reset |
mzcs | 4:651f1a1b639e | 148 | //The breakout board has SEN pulled high, but also has SDIO pulled high. Therefore, after a normal power up |
mzcs | 4:651f1a1b639e | 149 | //The Si4703 will be in an unknown state. RST must be controlled |
mzcs | 4:651f1a1b639e | 150 | void Si4703_Breakout::si4703_init() |
mzcs | 4:651f1a1b639e | 151 | { |
mzcs | 4:651f1a1b639e | 152 | _reset_ = new DigitalOut(_resetPin); |
mzcs | 4:651f1a1b639e | 153 | _sdio_ = new DigitalOut(_sdioPin); |
mzcs | 4:651f1a1b639e | 154 | |
mzcs | 4:651f1a1b639e | 155 | _sdio_->write(0); //A low SDIO indicates a 2-wire interface |
mzcs | 4:651f1a1b639e | 156 | _reset_->write(0); //Put Si4703 into reset |
mzcs | 4:651f1a1b639e | 157 | wait_ms(1); //Some delays while we allow pins to settle |
mzcs | 4:651f1a1b639e | 158 | _reset_->write(1); //Bring Si4703 out of reset with SDIO set to low and SEN pulled high with on-board resistor |
mzcs | 4:651f1a1b639e | 159 | wait_ms(1); //Allow Si4703 to come out of reset |
mzcs | 4:651f1a1b639e | 160 | |
mzcs | 4:651f1a1b639e | 161 | //Now that the unit is reset and I2C inteface mode, we need to begin I2C |
mzcs | 4:651f1a1b639e | 162 | i2c_ = new I2C(_sdioPin, _sclkPin); |
mzcs | 4:651f1a1b639e | 163 | i2c_->frequency(100000); |
mzcs | 4:651f1a1b639e | 164 | /// |
mzcs | 4:651f1a1b639e | 165 | |
mzcs | 4:651f1a1b639e | 166 | readRegisters(); //Read the current register set |
mzcs | 4:651f1a1b639e | 167 | si4703_registers[0x07] = 0x8100; //Enable the oscillator, from AN230 page 9, rev 0.61 (works) |
mzcs | 4:651f1a1b639e | 168 | updateRegisters(); //Update |
mzcs | 4:651f1a1b639e | 169 | |
mzcs | 4:651f1a1b639e | 170 | wait_ms(500); //Wait for clock to settle - from AN230 page 9 |
mzcs | 4:651f1a1b639e | 171 | |
mzcs | 4:651f1a1b639e | 172 | readRegisters(); //Read the current register set |
mzcs | 4:651f1a1b639e | 173 | si4703_registers[POWERCFG] = 0x4001; //Enable the IC |
mzcs | 4:651f1a1b639e | 174 | // si4703_registers[POWERCFG] |= (1<<SMUTE) | (1<<DMUTE); //Disable Mute, disable softmute |
mzcs | 4:651f1a1b639e | 175 | si4703_registers[SYSCONFIG1] |= (1<<RDS); //Enable RDS |
mzcs | 4:651f1a1b639e | 176 | |
mzcs | 4:651f1a1b639e | 177 | si4703_registers[SYSCONFIG1] |= (1<<DE); //50μS Europe setup |
mzcs | 4:651f1a1b639e | 178 | si4703_registers[SYSCONFIG2] |= (1<<SPACE0); //100kHz channel spacing for Europe |
mzcs | 4:651f1a1b639e | 179 | |
mzcs | 4:651f1a1b639e | 180 | si4703_registers[SYSCONFIG2] &= 0xFFF0; //Clear volume bits |
mzcs | 4:651f1a1b639e | 181 | si4703_registers[SYSCONFIG2] |= 0x0001; //Set volume to lowest |
mzcs | 4:651f1a1b639e | 182 | |
mzcs | 4:651f1a1b639e | 183 | // SI AN230 page 40 - Table 23 ('Good Quality Stations Only' Settings) |
mzcs | 4:651f1a1b639e | 184 | si4703_registers[SYSCONFIG2] |= (0xC<<SEEKTH); |
mzcs | 4:651f1a1b639e | 185 | si4703_registers[SYSCONFIG3] |= (0x7<<SKSNR); |
mzcs | 4:651f1a1b639e | 186 | si4703_registers[SYSCONFIG3] |= (0xF<<SKCNT); |
mzcs | 4:651f1a1b639e | 187 | /// |
mzcs | 4:651f1a1b639e | 188 | updateRegisters(); //Update |
mzcs | 4:651f1a1b639e | 189 | |
mzcs | 4:651f1a1b639e | 190 | wait_ms(110); //Max powerup time, from datasheet page 13 |
mzcs | 4:651f1a1b639e | 191 | |
mzcs | 4:651f1a1b639e | 192 | } |
mzcs | 4:651f1a1b639e | 193 | |
mzcs | 4:651f1a1b639e | 194 | //Read the entire register control set from 0x00 to 0x0F |
mzcs | 4:651f1a1b639e | 195 | uint8_t Si4703_Breakout::readRegisters(){ |
mzcs | 4:651f1a1b639e | 196 | |
mzcs | 4:651f1a1b639e | 197 | //Si4703 begins reading from register upper register of 0x0A and reads to 0x0F, then loops to 0x00. |
mzcs | 4:651f1a1b639e | 198 | // Wire.requestFrom(SI4703, 32); //We want to read the entire register set from 0x0A to 0x09 = 32 uint8_ts. |
mzcs | 4:651f1a1b639e | 199 | char data[32]; |
mzcs | 4:651f1a1b639e | 200 | uint8_t ack = i2c_->read(SI4703, data, 32); //Read in these 32 uint8_ts |
mzcs | 4:651f1a1b639e | 201 | |
mzcs | 4:651f1a1b639e | 202 | if (ack != 0) { //We have a problem! |
mzcs | 4:651f1a1b639e | 203 | return(FAIL); |
mzcs | 4:651f1a1b639e | 204 | } |
mzcs | 4:651f1a1b639e | 205 | |
mzcs | 4:651f1a1b639e | 206 | //Remember, register 0x0A comes in first so we have to shuffle the array around a bit |
mzcs | 4:651f1a1b639e | 207 | for (int y=0; y<6; y++) |
mzcs | 4:651f1a1b639e | 208 | { |
mzcs | 4:651f1a1b639e | 209 | si4703_registers[0x0A+y] = 0; |
mzcs | 4:651f1a1b639e | 210 | si4703_registers[0x0A+y] = data[(y*2)+1]; |
mzcs | 4:651f1a1b639e | 211 | si4703_registers[0x0A+y] |= (data[(y*2)] << 8); |
mzcs | 4:651f1a1b639e | 212 | } |
mzcs | 4:651f1a1b639e | 213 | |
mzcs | 4:651f1a1b639e | 214 | for (int y=0; y<10; y++) |
mzcs | 4:651f1a1b639e | 215 | { |
mzcs | 4:651f1a1b639e | 216 | si4703_registers[y] = 0; |
mzcs | 4:651f1a1b639e | 217 | si4703_registers[y] = data[(12)+(y*2)+1]; |
mzcs | 4:651f1a1b639e | 218 | si4703_registers[y] |= (data[(12)+(y*2)] << 8); |
mzcs | 4:651f1a1b639e | 219 | } |
mzcs | 4:651f1a1b639e | 220 | //We're done! |
mzcs | 4:651f1a1b639e | 221 | /// |
mzcs | 4:651f1a1b639e | 222 | return(SUCCESS); |
mzcs | 4:651f1a1b639e | 223 | } |
mzcs | 4:651f1a1b639e | 224 | |
mzcs | 4:651f1a1b639e | 225 | //Write the current 9 control registers (0x02 to 0x07) to the Si4703 |
mzcs | 4:651f1a1b639e | 226 | //It's a little weird, you don't write an I2C address |
mzcs | 4:651f1a1b639e | 227 | //The Si4703 assumes you are writing to 0x02 first, then increments |
mzcs | 4:651f1a1b639e | 228 | uint8_t Si4703_Breakout::updateRegisters() { |
mzcs | 4:651f1a1b639e | 229 | |
mzcs | 4:651f1a1b639e | 230 | char data[12]; |
mzcs | 4:651f1a1b639e | 231 | |
mzcs | 4:651f1a1b639e | 232 | //First we send the 0x02 to 0x07 control registers |
mzcs | 4:651f1a1b639e | 233 | //In general, we should not write to registers 0x08 and 0x09 |
mzcs | 4:651f1a1b639e | 234 | for(int regSpot = 0x02 ; regSpot < 0x08 ; regSpot++) { |
mzcs | 4:651f1a1b639e | 235 | data[(regSpot-2)*2] = si4703_registers[regSpot] >> 8; |
mzcs | 4:651f1a1b639e | 236 | data[((regSpot-2)*2)+1] = si4703_registers[regSpot] & 0x00FF; |
mzcs | 4:651f1a1b639e | 237 | } |
mzcs | 4:651f1a1b639e | 238 | |
mzcs | 4:651f1a1b639e | 239 | uint8_t ack = i2c_->write(SI4703, data, 12); // a write command automatically begins with register 0x02 so no need to send a write-to address |
mzcs | 4:651f1a1b639e | 240 | |
mzcs | 4:651f1a1b639e | 241 | if(ack != 0) { //We have a problem! |
mzcs | 4:651f1a1b639e | 242 | return(FAIL); |
mzcs | 4:651f1a1b639e | 243 | } |
mzcs | 4:651f1a1b639e | 244 | |
mzcs | 4:651f1a1b639e | 245 | return(SUCCESS); |
mzcs | 4:651f1a1b639e | 246 | } |
mzcs | 4:651f1a1b639e | 247 | |
mzcs | 4:651f1a1b639e | 248 | //Returns The Value of a Register |
mzcs | 4:651f1a1b639e | 249 | uint16_t Si4703_Breakout::getRegister(uint8_t regNum) |
mzcs | 4:651f1a1b639e | 250 | { |
mzcs | 4:651f1a1b639e | 251 | readRegisters(); |
mzcs | 4:651f1a1b639e | 252 | return si4703_registers[regNum]; |
mzcs | 4:651f1a1b639e | 253 | // No Error Status Checking |
mzcs | 4:651f1a1b639e | 254 | } |
mzcs | 4:651f1a1b639e | 255 | |
mzcs | 4:651f1a1b639e | 256 | //Seeks out the next available station |
mzcs | 4:651f1a1b639e | 257 | //Returns the freq if it made it |
mzcs | 4:651f1a1b639e | 258 | //Returns zero if failed |
mzcs | 4:651f1a1b639e | 259 | int Si4703_Breakout::seek(bool seekDirection){ |
mzcs | 4:651f1a1b639e | 260 | uint8_t ack; |
mzcs | 4:651f1a1b639e | 261 | readRegisters(); |
mzcs | 4:651f1a1b639e | 262 | //Set seek mode wrap bit |
mzcs | 4:651f1a1b639e | 263 | si4703_registers[POWERCFG] |= (1<<SKMODE); //Disallow wrap - if you disallow wrap, you may want to tune to 87.5 first |
mzcs | 4:651f1a1b639e | 264 | //si4703_registers[POWERCFG] &= ~(1<<SKMODE); //Allow wrap |
mzcs | 4:651f1a1b639e | 265 | if(seekDirection == SEEK_DOWN) si4703_registers[POWERCFG] &= ~(1<<SEEKUP); //Seek down is the default upon reset |
mzcs | 4:651f1a1b639e | 266 | else si4703_registers[POWERCFG] |= 1<<SEEKUP; //Set the bit to seek up |
mzcs | 4:651f1a1b639e | 267 | |
mzcs | 4:651f1a1b639e | 268 | si4703_registers[POWERCFG] |= (1<<SEEK); //Start seek |
mzcs | 4:651f1a1b639e | 269 | updateRegisters(); //Seeking will now start |
mzcs | 4:651f1a1b639e | 270 | |
mzcs | 4:651f1a1b639e | 271 | //Poll to see if STC is set |
mzcs | 4:651f1a1b639e | 272 | while(1) { |
mzcs | 4:651f1a1b639e | 273 | ack = readRegisters(); |
mzcs | 4:651f1a1b639e | 274 | wait_ms(1); // Just In Case... |
mzcs | 4:651f1a1b639e | 275 | if (((si4703_registers[STATUSRSSI] & (1<<STC)) != 0) || (ack != SUCCESS)) break; //Tuning complete! (or FAILED) |
mzcs | 4:651f1a1b639e | 276 | } |
mzcs | 4:651f1a1b639e | 277 | |
mzcs | 4:651f1a1b639e | 278 | readRegisters(); |
mzcs | 4:651f1a1b639e | 279 | int valueSFBL = si4703_registers[STATUSRSSI] & (1<<SFBL); //Store the value of SFBL |
mzcs | 4:651f1a1b639e | 280 | si4703_registers[POWERCFG] &= ~(1<<SEEK); //Clear the seek bit after seek has completed |
mzcs | 4:651f1a1b639e | 281 | updateRegisters(); |
mzcs | 4:651f1a1b639e | 282 | |
mzcs | 4:651f1a1b639e | 283 | //Wait for the si4703 to clear the STC as well |
mzcs | 4:651f1a1b639e | 284 | while(1) { |
mzcs | 4:651f1a1b639e | 285 | ack = readRegisters(); |
mzcs | 4:651f1a1b639e | 286 | wait_ms(1); // Just In Case... |
mzcs | 4:651f1a1b639e | 287 | if (((si4703_registers[STATUSRSSI] & (1<<STC)) == 0) || (ack != SUCCESS)) break; //Tuning complete! (or FAILED) |
mzcs | 4:651f1a1b639e | 288 | } |
mzcs | 4:651f1a1b639e | 289 | |
mzcs | 4:651f1a1b639e | 290 | if(valueSFBL) { //The bit was set indicating we hit a band limit or failed to find a station |
mzcs | 4:651f1a1b639e | 291 | return(0); |
mzcs | 4:651f1a1b639e | 292 | } |
mzcs | 4:651f1a1b639e | 293 | return getChannel(); |
mzcs | 4:651f1a1b639e | 294 | } |
mzcs | 4:651f1a1b639e | 295 | |
mzcs | 4:651f1a1b639e | 296 | //Reads the current channel from READCHAN |
mzcs | 4:651f1a1b639e | 297 | //Returns a number like 973 for 97.3MHz |
mzcs | 4:651f1a1b639e | 298 | int Si4703_Breakout::getChannel() { |
mzcs | 4:651f1a1b639e | 299 | readRegisters(); |
mzcs | 4:651f1a1b639e | 300 | int channel = (si4703_registers[READCHAN] & 0x03FF); //Mask out everything but the lower 10 bits |
mzcs | 4:651f1a1b639e | 301 | //Freq(MHz) = 0.100(in Europe) * Channel + 87.5MHz |
mzcs | 4:651f1a1b639e | 302 | //X = 0.1 * Chan + 87.5 |
mzcs | 4:651f1a1b639e | 303 | channel += 875; //98 + 875 = 973 ( for 97.3 MHz ) |
mzcs | 4:651f1a1b639e | 304 | return(channel); |
mzcs | 4:651f1a1b639e | 305 | } |
mzcs | 4:651f1a1b639e | 306 | |
mzcs | 4:651f1a1b639e | 307 | void Si4703_Breakout::printRegs() { |
mzcs | 4:651f1a1b639e | 308 | readRegisters(); |
mzcs | 4:651f1a1b639e | 309 | for (int x=0; x<16; x++) { pc->printf("Reg# 0x%X = 0x%X\r\n",x,si4703_registers[x]); wait_ms(1); } |
mzcs | 4:651f1a1b639e | 310 | } |