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