PU2CLR SI4844 Arduino Library  1.0.9
Arduino Library for Si4844 Devices - By Ricardo Lima Caratti
SI4844.h
Go to the documentation of this file.
1 /**
2  * @brief SI4844 ARDUINO LIBRARY
3  *
4  * @details This is an Arduino library for the SI4844, BROADCAST AM/FM/SW RADIO RECEIVER IC family from Silicon Labs.
5  * @details This library is intended to provide an easier interface for controlling the SI47XX by using Arduino platform.
6  * @details The communication used by this library is I2C.
7  * @details This file contains: const (#define), Defined Data type and Methods declarations
8  * @details You can see a complete documentation on <https://github.com/pu2clr/SI4844>
9  *
10  * @see https://pu2clr.github.io/SI4844/
11  *
12  * @author PU2CLR - Ricardo Lima Caratti
13  * @date 2019-2020
14  */
15 
16 #include <Arduino.h>
17 #include <Wire.h>
18 
19 #define SI4844_ADDRESS 0x11
20 
21 // English...: Si4844 Commands
22 // Portuguese: Comando usado no Si4844
23 // Reference.: Si48XX ATDD PROGRAMMING GUIDE, page 12
24 #define ATDD_POWER_DOWN 0x11
25 #define ATDD_POWER_UP 0xE1
26 #define ATDD_AUDIO_MODE 0xE2
27 #define GET_REV 0x10
28 #define ATDD_XOSCEN 0x80
29 #define ATDD_XOWAIT 0x40
30 #define ATDD_GET_STATUS 0xE0
31 
32 #define SET_PROPERTY 0x12
33 #define GET_PROPERTY 0x13
34 #define RX_VOLUME 0x4000
35 #define RX_HARD_MUTE 0x4001
36 #define RX_BASS_TREBLE 0x4002
37 #define RX_ACTUAL_VOLUME 0x4003
38 
39 #define FM_SOFT_MUTE_MAX_ATTENUATION 0x1302
40 #define AM_SOFT_MUTE_MAX_ATTENUATION 0x3302
41 #define FM_DEEMPHASIS 0x1100
42 
43 /** @defgroup GA1 Union and Structures
44  * @section GA1
45  *
46  * @brief SI4844 data representation
47  *
48  * @details The goal of this approach is separating data from code.
49  * The SI4844 works with many internal data that can be represented by data structure
50  * or defined data type in C/C++.
51  */
52 
53 /**
54  * @ingroup GA1
55  * @brief Status
56  * @details Represents searching for a valid frequency data type.
57  */
58 typedef union {
59  struct
60  {
61  uint8_t D0 : 1;
62  uint8_t D1 : 1;
63  uint8_t D2 : 1;
64  uint8_t D3 : 1;
65  uint8_t D4 : 1;
66  uint8_t ERR : 1; //!< 1 = Error.
67  uint8_t CTS : 1; //!< 0 = Wait before sending next command; 1 = Clear to send next command.
68  } refined;
70 } si4844_status;
71 
72 /**
73  * @ingroup GA1
74  * @brief Device Status
75  * @details The structure below represents the four bytes response got by command ATDD_GET_STATUS
76  * @see PROGRAMMING GUIDE, pages 14 and 15
77  */
78 typedef struct
79 {
80  uint8_t BCFG0 : 1; // Bit 0
81  uint8_t BCFG1 : 1; // bit 1
82  uint8_t STEREO : 1; // bit 2
83  uint8_t STATION : 1; // bit 3
84  uint8_t INFORDY : 1; // bit 4
85  uint8_t HOSTPWRUP : 1; // bit 5
86  uint8_t HOSTRST : 1; // bit 6
87  uint8_t CTS : 1; // bit 7
88  uint8_t BANDIDX : 6; // Form bit 0 to 5
89  uint8_t BANDMODE : 2; // From bit 6 to 7
90  uint8_t d2 : 4; // Frequency digit 2
91  uint8_t d1 : 4; // Frequency digit 1
92  uint8_t d4 : 4; // Frequency digit 4
93  uint8_t d3 : 4; // frequency digit 3
94 } si4844_get_status;
95 
96 /**
97  * @ingroup GA1
98  * @brief Status response
99  * @see See Si48XX ATDD PROGRAMMING GUIDE, pages 14 and 15
100 */
101 typedef union {
102  si4844_get_status refined;
104 } si4844_status_response;
105 
106 /**
107  * @ingroup GA1
108  * @brief Firmware Information
109  * @see Si48XX ATDD PROGRAMMING GUIDE, page 22.
110  */
111 typedef struct
112 {
113  uint8_t RESERVED : 6; // Bit 0 to 5
114  uint8_t ERR : 1; // bit 6
115  uint8_t CTS : 1; // bit 2
116  uint8_t PN; // Final 2 digits of Part Number (HEX).
117  uint8_t FWMAJOR; // Firmware Major Revision (ASCII).
118  uint8_t FWMINOR; // Firmware Minor Revision (ASCII).
119  uint8_t CMPMAJOR; // Component Major Revision (ASCII).
120  uint8_t CMPMINOR; // Component Minor Revision (ASCII).
121  uint8_t CHIPREV; // Chip Revision (ASCII).
122 } si4844_firmware_info;
123 
124 /**
125  * @brief Firmware Response
126  *
127  */
128 typedef union {
129  si4844_firmware_info refined;
131 } si4844_firmware_response;
132 
133 /**
134  * @ingroup GA1
135  * @brief Audio Mode
136  */
137 typedef union {
138  struct
139  {
140  uint8_t AUDIOMODE : 2;
141  uint8_t FM_MONO : 1;
142  uint8_t ADJPT_ATTN : 1;
143  uint8_t ADJPT_STEO : 1;
144  uint8_t Reserved : 2;
145  uint8_t OPCODE : 1;
146  } arg1;
148 } si4844_audiomode;
149 
150 /**
151  * @ingroup GA1
152  * @brief Audio Status Response
153  */
154 typedef union {
155  struct {
156  uint8_t AUDIOMODE:2;
157  uint8_t FM_MONO:1;
158  uint8_t ADJPT_ATTN:1;
159  uint8_t ADJPT_STEO:1;
160  uint8_t Reserved:1;
161  uint8_t ERR:1;
162  uint8_t CTS:1;
163  } status;
165 } si4844_audiomode_status_response;
166 
167 /**
168  * @brief Data type to deal with SET_PROPERTY command
169  *
170  * @details Property Data type (help to deal with SET_PROPERTY command on si473X)
171  */
172 typedef union {
173  struct
174  {
175  uint8_t byteLow;
176  uint8_t byteHigh;
177  } raw;
179 } si4844_property;
180 
181 /**
182  * @brief Interrupt status
183  * @details This variable must be true every time an interruption occurs and then must return to the false every time an action resulting from the interruption is performed.
184  * @details The variable below indicates a change of the ATDD status. When it occurs, it means the system needs to process some action (for example show on LCD this change).
185  */
186 volatile static bool data_from_device;
187 
188 /**
189  * @brief Library handle interrupt
190  * @details Handling interruptions.
191  * @details Whenever the status of the ATDD changes, a hardware interrupt is triggered. For example, when you move the tuner
192  * @details potenciometer, the ATDD sends a signal to the Arduino pin (INTERRUPT_PIN). The same is true when the ATDD is capturing
193  * @details mono FM signal and has switched to stereo.
194  * @details You can control the interrupt process via your sketch intead of this library.
195  * @see setStatusInterruptFromDevice, getStatusInterruptFromDevice, setup
196  */
197 static void interrupt_hundler()
198 {
199  data_from_device = true;
200 }
201 
202 
203 /**
204  * @brief SI4844 Class
205  *
206  * @details This class implements all functions to help you to control the Si4844 devices.
207  */
208 
209 class SI4844
210 {
211 
212 private:
213 
214  si4844_status_response status_response;
215  si4844_firmware_response firmware_response;
216  uint16_t resetPin;
217  uint16_t interruptPin;
218  uint8_t currentBand;
219 
220  inline void setClockLow(void) { Wire.setClock(10000); };
221  inline void setClockHigh(void) { Wire.setClock(50000); };
222  inline void waitInterrupt(void);
223  inline bool isClearToSend(void);
224  inline void waitToSend(void);
225 
226  // SI4844 band description (FM = 0; AM = 1; SW = 2)
227  const char *bandmode_table[3] = {"FM", "AM", "SW"};
228  const char *stereo_indicator_table[2] = {"Off","On "};
229 
230  uint8_t volume = 48;
231  uint8_t bassTreble = 4;
232 
233 public :
234  /**
235  * @ingroup GB
236  * @brief Set the Data Status From Device
237  * @details It is a flag that means the device triggered an interrupt.
238  * @details You can use this function to back the flag status to false. This way you can check when the device triggers the next interrupt.
239  * @details It is very useful when the user wants to control the interrupt instead of give this control to the library.
240  * @param value true or false
241  */
242  inline void setStatusInterruptFromDevice( bool value ) { data_from_device = value; };
243  /**
244  * @ingroup GB
245  * @brief Get the Data Status From Device
246  * @details It returns true when the device has triggered an interrupt.
247  * @return true or false
248  */
249  inline bool getDataStatusInterruptFromDevice() { return data_from_device; };
250 
251 
252  void setProperty(uint16_t propertyNumber, uint16_t parameter);
254  void sendCommand(uint8_t cmd, int parameter_size, const uint8_t *parameter);
255  void getCommandResponse(int response_size, uint8_t *response);
256 
257  void setup(uint16_t resetPin, int interruptPin, byte defaultBand);
258  void debugDevice(uint16_t resetPin, uint16_t interruptPin, uint8_t defaultBand, void (*showFunc)(char *msg));
259  void reset(void );
260  void setBand(byte);
261 
262  void changeVolume(char); // deprecated
263  void volumeUp(void);
264  void volumeDown(void);
265  void setVolume(byte);
266  void setBassTreble(uint8_t bass_treble);
267  void bassTrebleUp();
268  void bassTrebleDown();
269  void audioMute(uint8_t value);
270  void setAudioMute(bool on);
271 
272  void setAmSoftMuteMaxAttenuation(uint8_t value);
273  void setFmSoftMuteMaxAttenuation(uint8_t value);
274  void setFmDeemphasis(uint8_t value);
275 
276 
277  si4844_audiomode_status_response
278  setAudioMode(uint8_t audiomode, uint8_t fm_mono, uint8_t adjpt_attn, uint8_t adjpt_steo, uint8_t opcode);
279 
280  si4844_status_response *getStatus(void);
281  si4844_firmware_response *getFirmware(void);
282  // customize the frequency range of a band
283  void setCustomBand(byte, uint16_t , uint16_t , byte);
284 
285  void powerDown(void);
286  void powerUp(void);
287 
288  float getFrequency(void);
289  bool hasStatusChanged(void);
290  void resetStatus(void);
291 
292  /**
293  * @ingroup GB
294  * @brief Gets the current audio volume level
295  *
296  * @return Volume level
297  */
298  inline uint8_t getVolume() {return volume; };
300 
301  /**
302  * @ingroup GB
303  * @brief Get the Band Mode
304  * @return char* "FM", "AM" or "SW"
305  */
306  inline char * getBandMode(){ return (char *) bandmode_table[status_response.refined.BANDMODE]; };
307 
308  /**
309  * @ingroup GB
310  * @brief Get the Stereo Indicator
311  * @return char* "ON" or "OFF"
312  */
313  inline char * getStereoIndicator(){ return (char *) stereo_indicator_table[status_response.refined.STATION]; };
314 
315 
316  inline uint16_t getStatusBCFG0() { return status_response.refined.BCFG0; };
317  inline uint16_t getStatusBCFG1() { return status_response.refined.BCFG1; };
318  inline uint16_t getStatusStereo() { return status_response.refined.STEREO; };
319  inline uint16_t getStatusStationIndicator() { return status_response.refined.STATION; };
320  inline uint16_t getStatusInformationReady() { return status_response.refined.INFORDY; };
321  inline uint16_t getStatusHostPowerUp() { return status_response.refined.HOSTPWRUP; };
322  inline uint16_t getStatusHostReset() { return status_response.refined.HOSTRST; };
323  inline uint16_t getStatusBandMode() { return status_response.refined.BANDMODE; };
324  inline uint16_t getStatusBandIndex() { return status_response.refined.BANDIDX; };
325  inline uint16_t getStatusCTS() { return status_response.refined.CTS; };
326 
327 
328  inline uint16_t getFirmwareReserved() { return firmware_response.refined.RESERVED; };
329  inline uint16_t getFirmwareErr() { return firmware_response.refined.ERR; };
330  inline uint16_t getFirmwareCTS() { return firmware_response.refined.CTS; };
331  inline uint16_t getFirmwarePartNumber() { return firmware_response.refined.PN; };
332  inline uint16_t getFirmwareMajorRevision() { return firmware_response.refined.FWMAJOR; };
333  inline uint16_t getFirmwareMinorRevision() { return firmware_response.refined.FWMINOR; };
334  inline uint16_t getFirmwareComponentMajorRevision() { return firmware_response.refined.CMPMAJOR; };
335  inline uint16_t getFirmwareComponentMinorRevision() { return firmware_response.refined.CMPMINOR; };
336  inline uint16_t getFirmwareChipRevision() { return firmware_response.refined.CHIPREV; };
337 };
si4844_get_status::HOSTRST
uint8_t HOSTRST
Definition: SI4844.h:86
si4844_get_status::CTS
uint8_t CTS
Definition: SI4844.h:87
SI4844::getFirmwareComponentMajorRevision
uint16_t getFirmwareComponentMajorRevision()
Definition: SI4844.h:334
SI4844::getStatusStereo
uint16_t getStatusStereo()
Definition: SI4844.h:318
SI4844::getStereoIndicator
char * getStereoIndicator()
Get the Stereo Indicator.
Definition: SI4844.h:313
SI4844::getFirmwareErr
uint16_t getFirmwareErr()
Definition: SI4844.h:329
SI4844::getFirmwarePartNumber
uint16_t getFirmwarePartNumber()
Definition: SI4844.h:331
SI4844::getStatusBandMode
uint16_t getStatusBandMode()
Definition: SI4844.h:323
RX_ACTUAL_VOLUME
#define RX_ACTUAL_VOLUME
Definition: SI4844.h:37
SI4844::powerUp
void powerUp(void)
Power the device up.
Definition: SI4844.cpp:269
SI4844::getStatusInformationReady
uint16_t getStatusInformationReady()
Definition: SI4844.h:320
GET_PROPERTY
#define GET_PROPERTY
Definition: SI4844.h:33
SI4844::volumeDown
void volumeDown(void)
Decreases the volume level.
Definition: SI4844.cpp:387
SI4844::setup
void setup(uint16_t resetPin, int interruptPin, byte defaultBand)
Initiates the SI4844 instance and connect the device (SI4844) to Arduino.
Definition: SI4844.cpp:150
si4844_firmware_info::FWMAJOR
uint8_t FWMAJOR
Definition: SI4844.h:117
GET_REV
#define GET_REV
Definition: SI4844.h:27
si4844_firmware_info::CMPMAJOR
uint8_t CMPMAJOR
Definition: SI4844.h:119
si4844_firmware_info::RESERVED
uint8_t RESERVED
Definition: SI4844.h:113
SI4844::setBassTreble
void setBassTreble(uint8_t bass_treble)
Set the sound volume level, bass and treble.
Definition: SI4844.cpp:442
SET_PROPERTY
#define SET_PROPERTY
Definition: SI4844.h:32
SI4844::getFrequency
float getFrequency(void)
Get the current frequency of the radio in KHz.
Definition: SI4844.cpp:618
si4844_property::value
uint16_t value
Definition: SI4844.h:178
si4844_firmware_response::refined
si4844_firmware_info refined
Definition: SI4844.h:129
ATDD_GET_STATUS
#define ATDD_GET_STATUS
Definition: SI4844.h:30
SI4844::getFirmwareComponentMinorRevision
uint16_t getFirmwareComponentMinorRevision()
Definition: SI4844.h:335
si4844_get_status::BANDMODE
uint8_t BANDMODE
Definition: SI4844.h:89
si4844_firmware_info::ERR
uint8_t ERR
Definition: SI4844.h:114
si4844_status_response::refined
si4844_get_status refined
Definition: SI4844.h:102
SI4844_ADDRESS
#define SI4844_ADDRESS
SI4844 ARDUINO LIBRARY
Definition: SI4844.h:19
si4844_get_status::d4
uint8_t d4
Definition: SI4844.h:92
SI4844::setVolume
void setVolume(byte)
Sets the volume level.
Definition: SI4844.cpp:401
SI4844::setBand
void setBand(byte)
Sets a new band to the device.
Definition: SI4844.cpp:284
SI4844::debugDevice
void debugDevice(uint16_t resetPin, uint16_t interruptPin, uint8_t defaultBand, void(*showFunc)(char *msg))
Used to debug
Definition: SI4844.cpp:188
SI4844::getStatus
si4844_status_response * getStatus(void)
Get tune freq, band, and others information, status of the device.
Definition: SI4844.cpp:557
SI4844::setCustomBand
void setCustomBand(byte, uint16_t, uint16_t, byte)
This method allows you to customize the frequency range of a band.
Definition: SI4844.cpp:693
si4844_get_status::HOSTPWRUP
uint8_t HOSTPWRUP
Definition: SI4844.h:85
si4844_firmware_info::PN
uint8_t PN
Definition: SI4844.h:116
SI4844::getBandMode
char * getBandMode()
Get the Band Mode.
Definition: SI4844.h:306
SI4844::hasStatusChanged
bool hasStatusChanged(void)
Checks whether the SI4844 has its status changed.
Definition: SI4844.cpp:664
FM_SOFT_MUTE_MAX_ATTENUATION
#define FM_SOFT_MUTE_MAX_ATTENUATION
Definition: SI4844.h:39
AM_SOFT_MUTE_MAX_ATTENUATION
#define AM_SOFT_MUTE_MAX_ATTENUATION
Definition: SI4844.h:40
si4844_get_status::INFORDY
uint8_t INFORDY
Definition: SI4844.h:84
SI4844::setProperty
void setProperty(uint16_t propertyNumber, uint16_t parameter)
Sends (sets) property to the SI48XX.
Definition: SI4844.cpp:25
SI4844::setFmDeemphasis
void setFmDeemphasis(uint8_t value)
Sets de-emphasis time constant.
Definition: SI4844.cpp:773
si4844_audiomode_status_response::raw
uint8_t raw
Definition: SI4844.h:164
SI4844::setAudioMute
void setAudioMute(bool on)
Mutes the audio output.
Definition: SI4844.cpp:541
si4844_get_status::BANDIDX
uint8_t BANDIDX
Definition: SI4844.h:88
RX_VOLUME
#define RX_VOLUME
Definition: SI4844.h:34
SI4844::getFirmwareChipRevision
uint16_t getFirmwareChipRevision()
Definition: SI4844.h:336
SI4844::powerDown
void powerDown(void)
Power the device down.
Definition: SI4844.cpp:252
SI4844::getStatusBandIndex
uint16_t getStatusBandIndex()
Definition: SI4844.h:324
si4844_status::raw
uint8_t raw
Definition: SI4844.h:69
SI4844::getFirmwareReserved
uint16_t getFirmwareReserved()
Definition: SI4844.h:328
SI4844::getStatusBCFG1
uint16_t getStatusBCFG1()
Definition: SI4844.h:317
RX_BASS_TREBLE
#define RX_BASS_TREBLE
Definition: SI4844.h:36
SI4844::getDataStatusInterruptFromDevice
bool getDataStatusInterruptFromDevice()
Get the Data Status From Device.
Definition: SI4844.h:249
si4844_get_status::BCFG0
uint8_t BCFG0
Definition: SI4844.h:80
si4844_firmware_info::FWMINOR
uint8_t FWMINOR
Definition: SI4844.h:118
SI4844::getFirmwareMinorRevision
uint16_t getFirmwareMinorRevision()
Definition: SI4844.h:333
si4844_get_status::d3
uint8_t d3
Definition: SI4844.h:93
SI4844::bassTrebleUp
void bassTrebleUp()
More treble, less bass.
Definition: SI4844.cpp:461
SI4844::getVolume
uint8_t getVolume()
Gets the current audio volume level.
Definition: SI4844.h:298
SI4844::volumeUp
void volumeUp(void)
Increases the volume level.
Definition: SI4844.cpp:376
SI4844::getCommandResponse
void getCommandResponse(int response_size, uint8_t *response)
Returns with the command response.
Definition: SI4844.cpp:118
si4844_firmware_info::CMPMINOR
uint8_t CMPMINOR
Definition: SI4844.h:120
ATDD_POWER_UP
#define ATDD_POWER_UP
Definition: SI4844.h:25
si4844_get_status::d2
uint8_t d2
Definition: SI4844.h:90
si4844_status_response::raw
uint8_t raw[4]
Definition: SI4844.h:103
SI4844::getStatusBCFG0
uint16_t getStatusBCFG0()
Definition: SI4844.h:316
SI4844::changeVolume
void changeVolume(char)
Up or down the sound volume level.
Definition: SI4844.cpp:351
SI4844::bassTrebleDown
void bassTrebleDown()
Less treble, more bass.
Definition: SI4844.cpp:450
SI4844::audioMute
void audioMute(uint8_t value)
Mutes the audio output.
Definition: SI4844.cpp:530
SI4844
SI4844 Class.
Definition: SI4844.h:209
SI4844::resetStatus
void resetStatus(void)
set the interrupr status to false. It will turn true after next interrupr
Definition: SI4844.cpp:673
ATDD_POWER_DOWN
#define ATDD_POWER_DOWN
Definition: SI4844.h:24
SI4844::getStatusHostPowerUp
uint16_t getStatusHostPowerUp()
Definition: SI4844.h:321
si4844_firmware_response::raw
uint8_t raw[9]
Definition: SI4844.h:130
SI4844::getStatusCTS
uint16_t getStatusCTS()
Definition: SI4844.h:325
si4844_audiomode::raw
uint8_t raw
Definition: SI4844.h:147
SI4844::getFirmwareMajorRevision
uint16_t getFirmwareMajorRevision()
Definition: SI4844.h:332
SI4844::setAudioMode
si4844_audiomode_status_response setAudioMode(uint8_t audiomode, uint8_t fm_mono, uint8_t adjpt_attn, uint8_t adjpt_steo, uint8_t opcode)
Set audio mode.
Definition: SI4844.cpp:493
SI4844::getProperty
uint16_t getProperty(uint16_t propertyNumber)
Gets a given property from the SI4844.
Definition: SI4844.cpp:54
si4844_firmware_info::CTS
uint8_t CTS
Definition: SI4844.h:115
si4844_get_status::STEREO
uint8_t STEREO
Definition: SI4844.h:82
ATDD_AUDIO_MODE
#define ATDD_AUDIO_MODE
Definition: SI4844.h:26
si4844_get_status::d1
uint8_t d1
Definition: SI4844.h:91
SI4844::setStatusInterruptFromDevice
void setStatusInterruptFromDevice(bool value)
Set the Data Status From Device.
Definition: SI4844.h:242
SI4844::getFirmware
si4844_firmware_response * getFirmware(void)
Get part number, chip revision, firmware, patch, and component revision numbers.
Definition: SI4844.cpp:590
si4844_firmware_info::CHIPREV
uint8_t CHIPREV
Definition: SI4844.h:121
SI4844::getStatusStationIndicator
uint16_t getStatusStationIndicator()
Definition: SI4844.h:319
FM_DEEMPHASIS
#define FM_DEEMPHASIS
Definition: SI4844.h:41
SI4844::getVolumeProperty
uint8_t getVolumeProperty()
Gets the current volume value stored in SI4844 device.
Definition: SI4844.cpp:418
SI4844::sendCommand
void sendCommand(uint8_t cmd, int parameter_size, const uint8_t *parameter)
Sends a given command to the SI4844 device.
Definition: SI4844.cpp:96
SI4844::getFirmwareCTS
uint16_t getFirmwareCTS()
Definition: SI4844.h:330
si4844_get_status::STATION
uint8_t STATION
Definition: SI4844.h:83
RX_HARD_MUTE
#define RX_HARD_MUTE
Definition: SI4844.h:35
si4844_get_status::BCFG1
uint8_t BCFG1
Definition: SI4844.h:81
SI4844::setFmSoftMuteMaxAttenuation
void setFmSoftMuteMaxAttenuation(uint8_t value)
FM Soft Mute Maximum Attenuation.
Definition: SI4844.cpp:761
SI4844::getStatusHostReset
uint16_t getStatusHostReset()
Definition: SI4844.h:322
SI4844::setAmSoftMuteMaxAttenuation
void setAmSoftMuteMaxAttenuation(uint8_t value)
Sets AM Soft Mute Max Attenuation..
Definition: SI4844.cpp:750
SI4844::reset
void reset(void)
Resets the SI4844 device.
Definition: SI4844.cpp:231