PU2CLR SI470X Arduino Library  1.0.1
Arduino Library for Si470X Devices - By Ricardo Lima Caratti
SI470X.h
Go to the documentation of this file.
1 
2 /**
3  * @mainpage PU2CLR SI470X Arduino Library
4  * @brief PU2CLR SI470X Arduino Library implementation. <br>
5  * @details This is an Arduino library for the SI4702 and SI4703, BROADCAST RECEIVER.<br>
6  * @details It works with I2C protocol and can provide an easier interface for controlling the SI4702/03 devices.<br>
7  *
8  * This library can be freely distributed using the MIT Free Software model.
9  * Copyright (c) 2020 Ricardo Lima Caratti.
10  * Contact: pu2clr@gmail.com
11  */
12 
13 #include <Arduino.h>
14 #include <Wire.h>
15 
16 
17 #define MAX_DELAY_AFTER_OSCILLATOR 500 // Max delay after the crystal oscilator becomes active
18 
19 
20 #define I2C_DEVICE_ADDR 0x10
21 #define OSCILLATOR_TYPE_CRYSTAL 1 // Crystal
22 #define OSCILLATOR_TYPE_REFCLK 0 // Reference clock
23 
24 #define RDS_STANDARD 0 //!< RDS Mode.
25 #define RDS_VERBOSE 1 //!< RDS Mode.
26 #define SI470X_SEEK_DOWN 0 //!< Seek Down Direction
27 #define SI470X_SEEK_UP 1 //!< Seek Up Direction
28 #define SI470X_SEEK_WRAP 0 //
29 #define SI470X_SEEK_STOP 1
30 
31 #define FM_BAND_USA_EU 0 //!< 87.5–108 MHz (US / Europe, Default)
32 #define FM_BAND_JAPAN_WIDE 1 //!< 76–108 MHz (Japan wide band)
33 #define FM_BAND_JAPAN 2 //!< 76–90 MHz (Japan)
34 #define FM_BAND_RESERVED 3 //!< Reserved
35 
36 #define REG00 0x00
37 #define REG01 0x01
38 #define REG02 0x02
39 #define REG03 0x03
40 #define REG04 0x04
41 #define REG05 0x05
42 #define REG06 0x06
43 #define REG07 0x07
44 #define REG08 0x08
45 #define REG09 0x09
46 #define REG0A 0x0A
47 #define REG0B 0x0B
48 #define REG0C 0x0C
49 #define REG0D 0x0D
50 #define REG0E 0x0E
51 #define REG0F 0x0F
52 
53 /**
54  * @defgroup GA01 Union, Structure and Defined Data Types
55  * @brief SI470X Defined Data Types
56  * @details Defined Data Types is a way to represent the SI470X registers information
57  * @details Some information appears to be inaccurate due to translation problems from Chinese to English.
58  * @details The information shown here was extracted from Datasheet:
59  * @details SI470X stereo FM digital tuning radio documentation.
60  * @details Other information seems incomplete even in the original Chinese Datasheet.
61  * @details For example: Reg 10 (0x0A). There is no information about it. The Reg11 and 12 seem wrong
62  */
63 
64 /**
65  * @ingroup GA01
66  * @brief Device ID
67  *
68  */
69 typedef union {
70  struct {
71  uint16_t MFGID : 12; //!< Manufacturer ID.
72  uint16_t PN: 4; //!< Part Number.
73  } refined;
75 } si470x_reg00;
76 
77 /**
78  * @ingroup GA01
79  * @brief Chip ID
80  *
81  */
82 typedef union {
83  struct
84  {
85  uint16_t FIRMWARE : 6; //!< Firmware Version.
86  uint16_t DEV : 4; //!< 0 before powerup; 0001 after powerup = Si4702; 1000 before powerup = Si4703; 1001 after powerup = Si4703.
87  uint16_t REV : 6; //!< Chip Version; 0x04 = Rev C
88  } refined;
90 } si470x_reg01;
91 
92 /**
93  * @ingroup GA01
94  * @brief Power Configuratio
95  *
96  */
97 typedef union {
98  struct
99  {
100  uint8_t ENABLE : 1; //!< Powerup Enable; Refer to “4.9. Reset, Powerup, and Powerdown”; Default = 0.
101  uint8_t RESERVED1 : 5; //!< Reserved; Always write to 0.
102  uint8_t DISABLE : 1; //!< Powerup Disable; Refer to “4.9. Reset, Powerup, and Powerdown”; Default = 0.
103  uint8_t RESERVED2 : 1; //!< Reserved; Always write to 0.
104  uint8_t SEEK : 1; //!< 0 = Disable (default); 1 = Enable;
105  uint8_t SEEKUP : 1; //!< Seek Direction; 0 = Seek down (default); 1 = Seek up.
106  uint8_t SKMODE : 1; //!< Seek Mode; 0 = Wrap at the upper or lower band limit and continue seeking (default); 1 = Stop seeking at the upper or lower band limit.
107  uint8_t RDSM : 1; //!< RDS Mode; 0 = Standard (default); 1 = Verbose; Refer to “4.4. RDS/RBDS Processor and Functionality”.
108  uint8_t RESERVED3 : 1; //!< Reserved; Always write to 0.
109  uint8_t MONO : 1; //!< Mono Select; 0 = Stereo (default); 1 = Force mono.
110  uint8_t DMUTE : 1; //!< Mute Disable; 0 = Mute enable (default); 1 = Mute disable.
111  uint8_t DSMUTE : 1; //!< Softmute Disable; 0 = Softmute enable (default); 1 = Softmute disable.
112  } refined;
114 } si470x_reg02;
115 
116 /**
117  * @ingroup GA01
118  * @brief Channe
119  * @details Channel value for tune operation. If BAND 05h[7:6] = 00, then Freq (MHz) = Spacing (MHz) x Channel + 87.5 MHz.
120  * @details If BAND 05h[7:6] = 01, BAND 05h[7:6] = 10, then Freq (MHz) = Spacing (MHz) x Channel + 76 MHz.
121  * @details CHAN[9:0] is not updated during a seek operation. READCHAN[9:0] provides the current tuned channel and is updated during a seek operation and after a seek or tune operation completes. Channel spacing is set with the bits SPACE 05h[5:4].
122  * @details The tune operation begins when the TUNE bit is set high. The STC bit is set high when the tune operation completes. The STC bit must be set low by setting the TUNE bit low before the next tune or seek may begin.
123  */
124 typedef union {
125  struct
126  {
127  uint16_t CHAN : 10; //!< Channel Select;
128  uint16_t RESERVED : 5; //!< Reserved; Always write to 0;
129  uint16_t TUNE : 1; //!< Tune. 0 = Disable (default); 1 = Enable.
130  } refined;
132 } si470x_reg03;
133 
134 /**
135  * @ingroup GA01
136  * @brief System Configuration 1
137  * @details Setting STCIEN = 1 will generate a 5 ms low pulse on GPIO2 when the STC 0Ah[14] bit is set.
138  * @details Setting RDSIEN = 1 will generate a 5 ms low pulse on GPIO2 when the RDSR 0Ah[15] bit is set.
139  * @details Setting STCIEN = 1 and GPIO2[1:0] = 01 will generate a 5 ms low pulse on GPIO2 when the STC 0Ah[14] bit is set.
140  * | BLNDADJ value | Description |
141  * | ------------ | ----------- |
142  * | 0 | 31–49 RSSI dBμV (default) |
143  * | 1 | 37–55 RSSI dBμV (+6 dB) |
144  * | 2 | 19–37 RSSI dBμV (–12 dB) |
145  * | 3 | 25–43 RSSI dBμV (–6 dB) |
146  *
147  */
148 typedef union {
149  struct
150  {
151  uint8_t GPIO1 : 2; //!< General Purpose I/O 1; 00 = High impedance (default); 01 = Reserved; 10 = Low; 11 = High.
152  uint8_t GPIO2 : 2; //!< General Purpose I/O 2. 00 = High impedance (default); 01 = Reserved; 10 = Low; 11 = High.
153  uint8_t GPIO3 : 2; //!< General Purpose I/O 2. 00 = High impedance (default); 01 = Reserved; 10 = Low; 11 = High.
154  uint8_t BLNDADJ : 2; //!< Stereo/Mono Blend Level Adjustment. Sets the RSSI range for stereo/mono blend. See table above.
155  uint8_t RESERVED1 : 2; //!< Reserved; Always write to 0.
156  uint8_t AGCD : 1; //!< AGC Disable; 0 = AGC enable (default); 1 = AGC disable.
157  uint8_t DE : 1; //!< De-emphasis; 0 = 75 μs. Used in USA (default); 1 = 50 μs. Used in Europe, Australia, Japan.
158  uint8_t RDS : 1; //!< RDS Enable; 0 = Disable (default); 1 = Enable.
159  uint8_t RESERVED2 : 1; //!< Reserved; Always write to 0.
160  uint8_t STCIEN : 1; //!< Seek/Tune Complete Interrupt Enable; 0 = Disable Interrupt (default); 1 = Enable Interrupt.
161  uint8_t RDSIEN : 1; //!< RDS Interrupt Enable; 0 = Disable Interrupt (default); 1 = Enable Interrupt.
162  } refined;
164 } si470x_reg04;
165 
166 /**
167  * @ingroup GA01
168  * @brief System Configuration 2
169  * @details SEEKTH presents the logarithmic RSSI threshold for the seek operation. The Si4702/03-C19 will not validate channels with RSSI below the SEEKTH value. SEEKTH is one of multiple parameters that can be used to validate channels. For more information, see "AN284: Si4700/01 Firmware 15 Seek Adjustability and Set- tings."
170  *
171  * | BAND value | Description |
172  * | ---------- | ----------- |
173  * | 0 | 00 = 87.5–108 MHz (USA, Europe) (Default) |
174  * | 1 | 01 = 76–108 MHz (Japan wide band) |
175  * | 2 | 10 = 76–90 MHz (Japan) |
176  * | 3 | 11 = Reserved |
177  */
178 typedef union {
179  struct
180  {
181  uint8_t VOLUME : 4; //!< Relative value of volume is shifted –30 dBFS with the VOLEXT 06h[8] bit; 0000 = mute (default);
182  uint8_t SPACE : 2; //!< Channel Spacing; 00 = 200 kHz (USA, Australia) (default); 01 = 100 kHz (Europe, Japan); 10 = 50 kHz.
183  uint8_t BAND : 2; //!< Band Select. See table above.
184  uint8_t SEEKTH; //!< RSSI Seek Threshold. 0x00 = min RSSI (default); 0x7F = max RSSI.
185  } refined;
187 } si470x_reg05;
188 
189 /**
190  * @ingroup GA01
191  * @brief System Configuration 3
192  * @details The VOLEXT bit attenuates the output by 30 dB. With the bit set to 0, the 15 volume settings adjust the volume between 0 and –28 dBFS. With the bit set to 1, the 15 volume set- tings adjust the volume between –30 and –58 dBFS.
193  * @details Refer to 4.5. "Stereo Audio Processing" on page 16.
194  *
195  * | Softmute Attenuation | Description |
196  * | 0 | 16 dB (default) |
197  * | 1 | 14 dB |
198  * | 2 | 12 dB |
199  * | 3 | 10 dB |
200  *
201  * | Softmute Attack/Recover Rate | Description |
202  * | 0 | fastest (default) |
203  * | 1 | fast |
204  * | 2 | slow |
205  * | 3 | slowest |
206  *
207  */
208 typedef union {
209  struct
210  {
211  uint8_t SKCNT : 4; //!< Seek FM Impulse Detection Threshold; 0000 = disabled (default); 0001 = max (most stops); 1111 = min (fewest stops). Allowable number of FM impulses for a valid seek channel.
212  uint8_t SKSNR : 4; //!< Seek SNR Threshold; 0000 = disabled (default); 0001 = min (most stops); 0111 = max (fewest stops); Required channel SNR for a valid seek channel.
213  uint8_t VOLEXT : 1; //!< Extended Volume Range; 0 = disabled (default); 1 = enabled.
214  uint8_t RESERVED : 3; //!< Reserved; Always write to zero.
215  uint8_t SMUTEA : 2; //!< Softmute Attenuation; See table above.
216  uint8_t SMUTER : 2; //!< Softmute Attack/Recover Rate; See table above
217  } refined;
219 } si470x_reg06;
220 
221 /**
222  * @ingroup GA01
223  * @brief Test 1
224  * @details Setting AHIZEN maintains a dc bias of 0.5 x VIO on the LOUT and ROUT pins to pre- vent the ESD diodes from clamping to the VIO or GND rail in response to the output swing of another device.
225  * @details Register 07h containing the AHIZEN bit must not be written during the powerup sequence and high-Z only takes effect when in powerdown and VIO is supplied. Bits 13:0 of register 07h must be preserved as 0x0100 while in pow- erdown and as 0x3C04 while in powerup.
226  * @details The internal crystal oscillator requires an external 32.768 kHz crystal as shown in "Typical Application Schematic" on page 14.
227  * @details The oscillator must be enabled before powerup (ENABLE = 1) as shown in Figure 9, “Initialization Sequence,” on page 21. It should only be disabled after powerdown (ENABLE = 0).
228  * @details Bits 13:0 of register 07h must be preserved as 0x0100 while in powerdown and as 0x3C04 while in powerup. Refer to Si4702/03 Internal Crystal Oscillator Errata.
229  */
230 typedef union {
231  struct
232  {
233  uint16_t RESERVED : 14; //!< Reserved; If written, these bits should be read first and then written with their pre-existing val- ues. Do not write during powerup.
234  uint16_t AHIZEN : 1; //!< Audio High-Z Enable; 0 = Disable (default); 1 = Enable.
235  uint16_t XOSCEN : 1; //!< Crystal Oscillator Enable; 0 = Disable (default); 1 = Enable.
236  } refined;
238 } si470x_reg07;
239 
240 /**
241  * @ingroup GA01
242  * @brief Test 2
243  * @details If written, these bits should be read first and then written with their pre-existing val- ues. Do not write during powerup.
244  */
245 typedef union {
246  struct
247  {
248  uint8_t lowByte; //!< Reserved
249  uint8_t highByte; //!< Reserved
250  } refined;
252 } si470x_reg08;
253 
254 /**
255  * @ingroup GA01
256  * @brief Boot Configuration
257  * @details If written, these bits should be read first and then written with their pre-existing val- ues. Do not write during powerup.
258  */
259 typedef union {
260  struct
261  {
262  uint8_t lowByte; //!< Reserved
263  uint8_t highByte; //!< Reserved
264  } refined;
266 } si470x_reg09;
267 
268 /**
269  * @ingroup GA01
270  * @brief Status RSSI
271  * @details RSSI is measured units of dBμV in 1 dB increments with a maximum of approximately 75 dBμV. Si4702/03-C19 does not report RSSI levels greater than 75 dBuV.
272  * @details AFCRL is updated after a tune or seek operation completes and indicates a valid or invalid channel. During normal operation, AFCRL is updated to reflect changing RF envi- ronments.
273  * @details The SF/BL flag is set high when SKMODE 02h[10] = 0 and the seek operation fails to find a channel qualified as valid according to the seek parameters.
274  * @details The SF/BL flag is set high when SKMODE 02h[10] = 1 and the upper or lower band limit has been reached. The SEEK 02h[8] bit must be set low to clear SF/BL.
275  * @details The seek/tune complete flag is set when the seek or tune operation completes. Setting the SEEK 02h[8] or TUNE 03h[15] bit low will clear STC.
276  *
277  * | RDS Block A Errors | Description |
278  * | ------------------ | ----------- |
279  * | 0 | 0 errors requiring correction |
280  * | 1 | 1–2 errors requiring correction |
281  * | 2 | 3–5 errors requiring correction |
282  * | 3 | 6+ errors or error in checkword, correction not possible |
283  *
284  */
285 typedef union {
286  struct
287  {
288  uint8_t RSSI; //!< RSSI (Received Signal Strength Indicator).
289  uint8_t ST : 1; //!< Stereo Indicator; 0 = Mono; 1 = Stereo.
290  uint8_t BLERA : 2; //!< RDS Block A Errors; See table above.
291  uint8_t RDSS : 1; //!< RDS Synchronized; 0 = RDS decoder not synchronized (default); 1 = RDS decoder synchronized.
292  uint8_t AFCRL : 1; //!< AFC Rail; 0 = AFC not railed; 1 = AFC railed, indicating an invalid channel. Audio output is softmuted when set.
293  uint8_t SF_BL : 1; //!< Seek Fail/Band Limit; 0 = Seek successful; 1 = Seek failure/Band limit reached.
294  uint8_t STC : 1; //!< Seek/Tune Complete; 0 = Not complete (default); 1 = Complete.
295  uint8_t RDSR : 1; //!< RDS Ready; 0 = No RDS group ready (default); 1 = New RDS group ready.
296  } refined;
298 } si470x_reg0a;
299 
300 /**
301  * @ingroup GA01
302  * @brief Read Channel
303  * @details If BAND 05h[7:6] = 00, then Freq (MHz) = Spacing (MHz) x Channel + 87.5 MHz. If BAND 05h[7:6] = 01, BAND 05h[7:6] = 10, then Freq (MHz) = Spacing (MHz) x Channel + 76 MHz.
304  * @details READCHAN[9:0] provides the current tuned channel and is updated during a seek operation and after a seek or tune operation completes. Spacing and channel are set with the bits SPACE 05h[5:4] and CHAN 03h[9:0].
305  *
306  * | RDS block Errors | Description |
307  * | -----------------| ----------- |
308  * | 0 | 0 errors requiring correction |
309  * | 1 | 1–2 errors requiring correction |
310  * | 2 | 3–5 errors requiring correction |
311  * | 3 | 6+ errors or error in checkword, correction not possible |
312  *
313  */
314 typedef union {
315  struct
316  {
317  uint16_t READCHAN : 10; //!< Read Channel.
318  uint16_t BLERD : 2; //!< RDS Block D Errors. See table above.
319  uint16_t BLERC : 2; //!< RDS Block C Errors. See table above.
320  uint16_t BLERB : 2; //!< RDS Block B Errors. See table above.
321  } refined;
323 } si470x_reg0b;
324 
325 /**
326  * @ingroup GA01
327  * @brief RDS Block A
328  *
329  */
330 typedef uint16_t si470x_reg0c; //!< RDS Block A Data.
331 
332 /**
333  * @ingroup GA01
334  * @brief RDS Block B
335  *
336  */
337 typedef uint16_t si470x_reg0d; //!< RDS Block B Data.
338 
339 /**
340  * @ingroup GA01
341  * @brief RDS Block C
342  *
343  */
344 typedef uint16_t si470x_reg0e; //!< RDS Block C Data.
345 
346 /**
347  * @ingroup GA01
348  * @brief RDS Block D
349  *
350  */
351 typedef uint16_t si470x_reg0f; //!< RDS Block D Data.
352 
353 /**
354  * @ingroup GA01
355  * @brief RDS Block B data type
356  *
357  * @details For GCC on System-V ABI on 386-compatible (32-bit processors), the following stands:
358  *
359  * 1) Bit-fields are allocated from right to left (least to most significant).
360  * 2) A bit-field must entirely reside in a storage unit appropriate for its declared type.
361  * Thus a bit-field never crosses its unit boundary.
362  * 3) Bit-fields may share a storage unit with other struct/union members, including members that are not bit-fields.
363  * Of course, struct members occupy different parts of the storage unit.
364  * 4) Unnamed bit-fields' types do not affect the alignment of a structure or union, although individual
365  * bit-fields' member offsets obey the alignment constraints.
366  *
367  * @see also https://en.wikipedia.org/wiki/Radio_Data_System
368  */
369 typedef union {
370  struct
371  {
372  uint8_t address : 2; // Depends on Group Type and Version codes. If 0A or 0B it is the Text Segment Address.
373  uint8_t DI : 1; // Decoder Controll bit
374  uint8_t MS : 1; // Music/Speech
375  uint8_t TA : 1; // Traffic Announcement
376  uint8_t programType : 5; // PTY (Program Type) code
377  uint8_t trafficProgramCode : 1; // (TP) => 0 = No Traffic Alerts; 1 = Station gives Traffic Alerts
378  uint8_t versionCode : 1; // (B0) => 0=A; 1=B
379  uint8_t groupType : 4; // Group Type code.
380  } group0;
381  struct
382  {
383  uint8_t address : 4; // Depends on Group Type and Version codes. If 2A or 2B it is the Text Segment Address.
384  uint8_t textABFlag : 1; // Do something if it chanhes from binary "0" to binary "1" or vice-versa
385  uint8_t programType : 5; // PTY (Program Type) code
386  uint8_t trafficProgramCode : 1; // (TP) => 0 = No Traffic Alerts; 1 = Station gives Traffic Alerts
387  uint8_t versionCode : 1; // (B0) => 0=A; 1=B
388  uint8_t groupType : 4; // Group Type code.
389  } group2;
390  struct
391  {
392  uint8_t content : 4; // Depends on Group Type and Version codes.
393  uint8_t textABFlag : 1; // Do something if it chanhes from binary "0" to binary "1" or vice-versa
394  uint8_t programType : 5; // PTY (Program Type) code
395  uint8_t trafficProgramCode : 1; // (TP) => 0 = No Traffic Alerts; 1 = Station gives Traffic Alerts
396  uint8_t versionCode : 1; // (B0) => 0=A; 1=B
397  uint8_t groupType : 4; // Group Type code.
398  } refined;
400 } si470x_rds_blockb;
401 
402 /**
403  * @ingroup GA01
404  * Group RDS type 4A ( RDS Date and Time)
405  * When group type 4A is used by the station, it shall be transmitted every minute according to EN 50067.
406  * This Structure uses blocks 2,3 and 5 (B,C,D)
407  *
408  * ATTENTION:
409  * To make it compatible with 8, 16 and 32 bits platforms and avoid Crosses boundary, it was necessary to
410  * split minute and hour representation.
411  */
412 typedef union {
413  struct
414  {
415  uint8_t offset : 5; // Local Time Offset
416  uint8_t offset_sense : 1; // Local Offset Sign ( 0 = + , 1 = - )
417  uint8_t minute1 : 2; // UTC Minutes - 2 bits less significant (void “Crosses boundary”).
418  uint8_t minute2 : 4; // UTC Minutes - 4 bits more significant (void “Crosses boundary”)
419  uint8_t hour1 : 4; // UTC Hours - 4 bits less significant (void “Crosses boundary”)
420  uint8_t hour2 : 1; // UTC Hours - 4 bits more significant (void “Crosses boundary”)
421  uint32_t mjd : 17; // Modified Julian Day Code
422  } refined;
424 } si470x_rds_date_time;
425 
426 /**
427  * @ingroup GA01
428  * @brief Converts 16 bits word to two bytes
429  */
430 typedef union {
431  struct
432  {
433  uint8_t lowByte;
434  uint8_t highByte;
435  } refined;
437 } word16_to_bytes;
438 
439 /**
440  * @ingroup GA01
441  * @brief KT0915 Class
442  * @details This class implements all functions that will help you to control the KT0915 devices.
443  *
444  * @author PU2CLR - Ricardo Lima Caratti
445  */
446 class SI470X {
447 
448  private:
449  uint16_t shadowRegisters[17]; //!< shadow registers
450 
451  // Device registers map - References to the shadow registers
452  si470x_reg00 *reg00 = (si470x_reg00 *)&shadowRegisters[REG00];
453  si470x_reg01 *reg01 = (si470x_reg01 *)&shadowRegisters[REG01];
454  si470x_reg02 *reg02 = (si470x_reg02 *)&shadowRegisters[REG02];
455  si470x_reg03 *reg03 = (si470x_reg03 *)&shadowRegisters[REG03];
456  si470x_reg04 *reg04 = (si470x_reg04 *)&shadowRegisters[REG04];
457  si470x_reg05 *reg05 = (si470x_reg05 *)&shadowRegisters[REG05];
458  si470x_reg06 *reg06 = (si470x_reg06 *)&shadowRegisters[REG06];
459  si470x_reg07 *reg07 = (si470x_reg07 *)&shadowRegisters[REG07];
460  si470x_reg08 *reg08 = (si470x_reg08 *)&shadowRegisters[REG08];
461  si470x_reg09 *reg09 = (si470x_reg09 *)&shadowRegisters[REG09];
462  si470x_reg0a *reg0a = (si470x_reg0a *)&shadowRegisters[REG0A];
463  si470x_reg0b *reg0b = (si470x_reg0b *)&shadowRegisters[REG0B];
464  si470x_reg0c *reg0c = (si470x_reg0c *)&shadowRegisters[REG0C];
465  si470x_reg0d *reg0d = (si470x_reg0d *)&shadowRegisters[REG0D];
466  si470x_reg0e *reg0e = (si470x_reg0e *)&shadowRegisters[REG0E];
467  si470x_reg0f *reg0f = (si470x_reg0f *)&shadowRegisters[REG0F];
468 
469  uint16_t startBand[4] = {8750, 7600, 7600, 6400 }; //!< Start FM band limit
470  uint16_t endBand[4] = {10800, 10800, 9000, 10800}; //!< End FM band limit
471  uint16_t fmSpace[4] = {20, 10, 5, 1}; //!< FM channel space
472 
473  protected:
474 
475  char rds_buffer2A[65]; //!< RDS Radio Text buffer - Program Information
476  char rds_buffer2B[33]; //!< RDS Radio Text buffer - Station Informaation
477  char rds_buffer0A[9]; //!< RDS Basic tuning and switching information (Type 0 groups)
478  char rds_time[20]; //!< RDS date time received information
479 
481  int resetPin;
486  int rdsInterruptPin = -1;
490 
491  void reset();
492  void powerUp();
493  void powerDown();
494  void waitAndFinishTune();
495 
496  public:
497  /**
498  * @brief Set the Delay After Crystal On (default 500ms)
499  *
500  * @param ms_value Value in milliseconds
501  */
502  inline void setDelayAfterCrystalOn(uint8_t ms_value) { maxDelayAftarCrystalOn = ms_value; };
503 
504  void getAllRegisters();
505  void setAllRegisters(uint8_t limit = 0x07);
506  void getStatus();
507 
508  /**
509  * @ingroup GA03
510  * @brief Get the Shadown Register object
511  * @details if you want to get the current value of the device register, call getAllRegisters() before calling this function.
512  * @details if you are dealing with the status register (0x0A), you can call getStatus() instead getAllRegisters().
513  * @see setAllRegisters, getAllRegisters, getShadownRegister, getStatus
514  * @param register_number
515  * @return 16 bits word with the Shadown registert
516  */
517  inline uint16_t getShadownRegister(uint8_t register_number) { return shadowRegisters[register_number]; };
518 
519  /**
520  * @ingroup GA03
521  * @brief Sets a given value to the Shadown Register
522  * @details You have to call setAllRegisters() after setting the Shadow Registers to store the value into the device.
523  * @see setAllRegisters, getAllRegisters, getShadownRegister, getStatus
524  * @param register_number register index (from 0x00 to 0x0F)
525  * @param value 16 bits word with the content of the register
526  */
527  void setShadownRegister(uint8_t register_number, uint16_t value)
528  {
529  if (register_number > 0x0F)
530  return;
531  shadowRegisters[register_number] = value;
532  };
533 
534 
535  void setup(int resetPin, int sdaPin, int rdsInterruptPin = -1, int seekInterruptPin = -1, uint8_t oscillator_type = OSCILLATOR_TYPE_CRYSTAL);
536  void setup(int resetPin, int sdaPin, uint8_t oscillator_type);
537  // void setupDebug(int resetPin, int sdaPin, int rdsInterruptPin, int seekInterruptPin, uint8_t oscillator_type, void (*showFunc)(byte v));
538  void setFrequency(uint16_t frequency);
539  void setFrequencyUp();
540  void setFrequencyDown();
544  void setChannel(uint16_t channel);
545  void seek(uint8_t seek_mode, uint8_t direction);
546  void seek(uint8_t seek_mode, uint8_t direction, void (*showFunc)());
547  void setSeekThreshold(uint8_t value);
548 
549  void setBand(uint8_t band = 1);
550  void setSpace(uint8_t space = 0);
551  int getRssi();
552 
553  void setSoftmute(bool value);
554  void setSoftmuteAttack(uint8_t value);
555  void setSoftmuteAttenuation(uint8_t value);
556  void setAgc(bool value);
557 
558  void setMono(bool value);
559 
560  bool isStereo();
561 
567 
568  void setMute(bool value);
569  void setVolume(uint8_t value);
570  uint8_t getVolume();
571  void setVolumeUp();
572  void setVolumeDown();
573  void setExtendedVolumeRange(bool value);
574 
575  void setFmDeemphasis(uint8_t de);
576 
577  void getRdsStatus();
578  void setRdsMode(uint8_t rds_mode = 0);
579  void setRds(bool value);
580  bool getRdsReady();
581 
582  uint8_t getRdsFlagAB(void);
586  void getNext2Block(char *c);
587  void getNext4Block(char *c);
588  char *getRdsText(void);
589  char *getRdsText0A(void);
590  char *getRdsText2A(void);
591  char *getRdsText2B(void);
592  char *getRdsTime();
593  bool getRdsSync();
594 
595 };
si470x_reg02::raw
uint16_t raw
Definition: SI470X.h:113
REG01
#define REG01
Definition: SI470X.h:37
SI470X::rds_time
char rds_time[20]
RDS date time received information.
Definition: SI470X.h:478
si470x_reg01::raw
uint16_t raw
Definition: SI470X.h:89
REG05
#define REG05
Definition: SI470X.h:41
SI470X::setAllRegisters
void setAllRegisters(uint8_t limit=0x07)
Sets values to the device registers from 0x02 to 0x07.
Definition: SI470X.cpp:62
SI470X::getStatus
void getStatus()
Gets the value of the 0x0A register.
Definition: SI470X.cpp:81
SI470X::getShadownRegister
uint16_t getShadownRegister(uint8_t register_number)
Get the Shadown Register object.
Definition: SI470X.h:517
SI470X::getNext2Block
void getNext2Block(char *c)
Process data received from group 2B.
Definition: SI470X.cpp:836
SI470X::getManufacturerId
uint16_t getManufacturerId()
Gets the Manufacturer ID.
Definition: SI470X.cpp:657
REG0F
#define REG0F
Definition: SI470X.h:51
I2C_DEVICE_ADDR
#define I2C_DEVICE_ADDR
Definition: SI470X.h:20
SI470X::rdsInterruptPin
int rdsInterruptPin
Definition: SI470X.h:486
SI470X::powerUp
void powerUp()
Powers the receiver on.
Definition: SI470X.cpp:134
SI470X::maxDelayAftarCrystalOn
uint16_t maxDelayAftarCrystalOn
Definition: SI470X.h:489
REG00
#define REG00
Definition: SI470X.h:36
SI470X::rds_buffer2B
char rds_buffer2B[33]
RDS Radio Text buffer - Station Informaation.
Definition: SI470X.h:476
SI470X::getRealChannel
uint16_t getRealChannel()
Gets the current channel stored in register 0x0B.
Definition: SI470X.cpp:319
SI470X::deviceAddress
int deviceAddress
Definition: SI470X.h:480
SI470X::getRdsFlagAB
uint8_t getRdsFlagAB(void)
Returns the current Text Flag A/B
Definition: SI470X.cpp:782
SI470X::getRdsProgramType
uint8_t getRdsProgramType(void)
Returns the Program Type (extracted from the Block B)
Definition: SI470X.cpp:823
SI470X::setMono
void setMono(bool value)
Sets the Mono true or false (stereo)
Definition: SI470X.cpp:558
SI470X::getNext4Block
void getNext4Block(char *c)
Process data received from group 2A.
Definition: SI470X.cpp:873
SI470X::seek
void seek(uint8_t seek_mode, uint8_t direction)
Seek function.
Definition: SI470X.cpp:349
SI470X::getChipVersion
uint8_t getChipVersion()
Gets the Chip Version.
Definition: SI470X.cpp:688
SI470X::setRdsMode
void setRdsMode(uint8_t rds_mode=0)
Sets the Rds Mode Standard or Verbose.
Definition: SI470X.cpp:741
SI470X::getRdsText0A
char * getRdsText0A(void)
Gets the station name and other messages.
Definition: SI470X.cpp:938
word16_to_bytes::raw
uint16_t raw
Definition: SI470X.h:436
SI470X::rds_buffer2A
char rds_buffer2A[65]
RDS Radio Text buffer - Program Information.
Definition: SI470X.h:475
REG09
#define REG09
Definition: SI470X.h:45
REG0C
#define REG0C
Definition: SI470X.h:48
SI470X::setSoftmuteAttenuation
void setSoftmuteAttenuation(uint8_t value)
Sets Softmute Attenuation..
Definition: SI470X.cpp:523
SI470X::resetPin
int resetPin
Definition: SI470X.h:481
si470x_reg08::raw
uint16_t raw
Definition: SI470X.h:251
SI470X::setFrequencyUp
void setFrequencyUp()
Increments the current frequency.
Definition: SI470X.cpp:278
SI470X::setVolume
void setVolume(uint8_t value)
Sets the audio volume level.
Definition: SI470X.cpp:582
SI470X::getRdsText2A
char * getRdsText2A(void)
Gets the Text processed for the 2A group.
Definition: SI470X.cpp:967
si470x_reg06::raw
uint16_t raw
Definition: SI470X.h:218
SI470X::currentFMBand
uint8_t currentFMBand
Definition: SI470X.h:483
si470x_reg05::raw
uint16_t raw
Definition: SI470X.h:186
REG03
#define REG03
Definition: SI470X.h:39
si470x_reg07::raw
uint16_t raw
Definition: SI470X.h:237
SI470X::getRssi
int getRssi()
Gets the Rssi.
Definition: SI470X.cpp:474
SI470X::setFrequencyDown
void setFrequencyDown()
Decrements the current frequency.
Definition: SI470X.cpp:293
SI470X::waitAndFinishTune
void waitAndFinishTune()
Wait STC (Seek/Tune Complete) status becomes 0.
Definition: SI470X.cpp:99
SI470X::getRealFrequency
uint16_t getRealFrequency()
Gets the frequency based on READCHAN register (0x0B)
Definition: SI470X.cpp:332
REG04
#define REG04
Definition: SI470X.h:40
SI470X::setAgc
void setAgc(bool value)
Sets the AGC enable or disable.
Definition: SI470X.cpp:534
SI470X::setDelayAfterCrystalOn
void setDelayAfterCrystalOn(uint8_t ms_value)
Set the Delay After Crystal On (default 500ms)
Definition: SI470X.h:502
SI470X::getFrequency
uint16_t getFrequency()
Gets the current frequency.
Definition: SI470X.cpp:308
SI470X::setBand
void setBand(uint8_t band=1)
Sets the FM Band
Definition: SI470X.cpp:445
SI470X::getVolume
uint8_t getVolume()
Gets the current audio volume level.
Definition: SI470X.cpp:596
SI470X::setVolumeDown
void setVolumeDown()
Decrements the audio volume.
Definition: SI470X.cpp:620
SI470X::setChannel
void setChannel(uint16_t channel)
Sets the channel.
Definition: SI470X.cpp:250
SI470X::setSeekThreshold
void setSeekThreshold(uint8_t value)
Sets RSSI Seek Threshold.
Definition: SI470X.cpp:425
SI470X::setShadownRegister
void setShadownRegister(uint8_t register_number, uint16_t value)
Sets a given value to the Shadown Register.
Definition: SI470X.h:527
si470x_reg0c
uint16_t si470x_reg0c
RDS Block A.
Definition: SI470X.h:330
SI470X::currentFMSpace
uint8_t currentFMSpace
Definition: SI470X.h:484
REG02
#define REG02
Definition: SI470X.h:38
SI470X::getRdsTime
char * getRdsTime()
Gets the RDS time and date when the Group type is 4.
Definition: SI470X.cpp:1020
REG0D
#define REG0D
Definition: SI470X.h:49
SI470X::seek
void seek(uint8_t seek_mode, uint8_t direction, void(*showFunc)())
Seek function.
Definition: SI470X.cpp:394
SI470X::currentFrequency
uint16_t currentFrequency
Definition: SI470X.h:482
si470x_reg09::raw
uint16_t raw
Definition: SI470X.h:265
si470x_rds_date_time::raw
uint8_t raw[6]
Definition: SI470X.h:423
SI470X::getRdsText
char * getRdsText(void)
Gets the RDS Text when the message is of the Group Type 2 version A.
Definition: SI470X.cpp:912
OSCILLATOR_TYPE_CRYSTAL
#define OSCILLATOR_TYPE_CRYSTAL
Definition: SI470X.h:21
SI470X::setup
void setup(int resetPin, int sdaPin, uint8_t oscillator_type)
Starts the device.
Definition: SI470X.cpp:240
SI470X::seekInterruptPin
int seekInterruptPin
Definition: SI470X.h:487
si470x_rds_blockb::blockB
si470x_reg0d blockB
Definition: SI470X.h:399
REG07
#define REG07
Definition: SI470X.h:43
REG08
#define REG08
Definition: SI470X.h:44
SI470X::getAllRegisters
void getAllRegisters()
Gets all current register content of the device.
Definition: SI470X.cpp:26
SI470X::isStereo
bool isStereo()
Checks stereo / mono status.
Definition: SI470X.cpp:570
SI470X::setFrequency
void setFrequency(uint16_t frequency)
Sets the FM frequency.
Definition: SI470X.cpp:265
MAX_DELAY_AFTER_OSCILLATOR
#define MAX_DELAY_AFTER_OSCILLATOR
Definition: SI470X.h:17
SI470X::getRdsText2B
char * getRdsText2B(void)
Gets the Text processed for the 2B group.
Definition: SI470X.cpp:995
SI470X::rds_buffer0A
char rds_buffer0A[9]
RDS Basic tuning and switching information (Type 0 groups)
Definition: SI470X.h:477
SI470X::reset
void reset()
Resets the device.
Definition: SI470X.cpp:120
si470x_reg0a::raw
uint16_t raw
Definition: SI470X.h:297
SI470X::getRdsGroupType
uint16_t getRdsGroupType()
Return the group type.
Definition: SI470X.cpp:796
SI470X::currentVolume
uint8_t currentVolume
Definition: SI470X.h:485
SI470X::setup
void setup(int resetPin, int sdaPin, int rdsInterruptPin=-1, int seekInterruptPin=-1, uint8_t oscillator_type=OSCILLATOR_TYPE_CRYSTAL)
Starts the device.
Definition: SI470X.cpp:209
si470x_reg0e
uint16_t si470x_reg0e
RDS Block C.
Definition: SI470X.h:344
REG06
#define REG06
Definition: SI470X.h:42
SI470X::setSpace
void setSpace(uint8_t space=0)
Sets the FM Space
Definition: SI470X.cpp:462
SI470X::getFirmwareVersion
uint8_t getFirmwareVersion()
Gets the Firmware Version.
Definition: SI470X.cpp:668
si470x_reg0f
uint16_t si470x_reg0f
RDS Block D.
Definition: SI470X.h:351
SI470X::setSoftmuteAttack
void setSoftmuteAttack(uint8_t value)
Sets Softmute Attack/Recover Rate.
Definition: SI470X.cpp:504
si470x_reg0b::raw
uint16_t raw
Definition: SI470X.h:322
SI470X::setExtendedVolumeRange
void setExtendedVolumeRange(bool value)
Sets Extended Volume Range.
Definition: SI470X.cpp:635
SI470X::setSoftmute
void setSoftmute(bool value)
Sets the Softmute true or false.
Definition: SI470X.cpp:485
SI470X::setVolumeUp
void setVolumeUp()
Increments the audio volume.
Definition: SI470X.cpp:606
SI470X::getRdsReady
bool getRdsReady()
Returns true if RDS Ready.
Definition: SI470X.cpp:769
SI470X::getRdsSync
bool getRdsSync()
Get the Rds Sync.
Definition: SI470X.cpp:1077
REG0E
#define REG0E
Definition: SI470X.h:50
si470x_reg03::raw
uint16_t raw
Definition: SI470X.h:131
SI470X::getRdsVersionCode
uint8_t getRdsVersionCode(void)
Gets the version code (extracted from the Block B)
Definition: SI470X.cpp:810
si470x_reg04::raw
uint16_t raw
Definition: SI470X.h:163
REG0A
#define REG0A
Definition: SI470X.h:46
SI470X::setMute
void setMute(bool value)
Sets the Mute true or false.
Definition: SI470X.cpp:546
si470x_reg00::raw
uint16_t raw
Definition: SI470X.h:74
SI470X::getRdsStatus
void getRdsStatus()
Gets the RDS registers information.
Definition: SI470X.cpp:718
SI470X::setRds
void setRds(bool value)
Sets the RDS operation.
Definition: SI470X.cpp:754
SI470X::getPartNumber
uint8_t getPartNumber()
Gets the Part Number.
Definition: SI470X.cpp:647
SI470X::getDeviceId
uint8_t getDeviceId()
Gets the Device identification.
Definition: SI470X.cpp:678
SI470X::oscillatorType
int oscillatorType
Definition: SI470X.h:488
SI470X::setFmDeemphasis
void setFmDeemphasis(uint8_t de)
Sets De-emphasis.
Definition: SI470X.cpp:700
SI470X::powerDown
void powerDown()
Powers the receiver off.
Definition: SI470X.cpp:186
REG0B
#define REG0B
Definition: SI470X.h:47
si470x_reg0d
uint16_t si470x_reg0d
RDS Block B.
Definition: SI470X.h:337