/** * @mainpage PU2CLR rda Arduino Library * @brief PU2CLR rda Arduino Library implementation.
* @details This library works with I2C protocol and can provide an easier interface for controlling the RDA5807M devices.
* @details This is an Arduino library was implemented based on RDA5807M - SINGLE-CHIP BROADCAST FMRADIO TUNER document from RDA microeletronics. * * @details IMPORTANT: * @details The RDA5807M can be accessed by using two I2C bus address. * @details If you need to access a specific register, use the 0x11 buss adress. * @details If you need to access a set o register, use the 0x10 buss adress. * * @see RDA5807M - SINGLE-CHIP BROADCAST FMRADIO TUNER; page 5. * @see the methods setRegister, getRegister and getStatusRegisters * * This library can be freely distributed using the MIT Free Software model. * Copyright(c) 2020 Ricardo Lima Caratti. * Contact : pu2clr @gmail.com * */ #include #include #define MAX_DELAY_AFTER_OSCILLATOR 500 // Max delay after the crystal oscilator becomes active #define I2C_ADDR_DIRECT_ACCESS 0x11 //!< Can be used to access a given register at a time. #define I2C_ADDR_FULL_ACCESS 0x10 //!< Can be used to access a set of register at a time. #define OSCILLATOR_TYPE_CRYSTAL 0 //!< Crystal #define OSCILLATOR_TYPE_REFCLK 1 //!< Reference clock #define CLOCK_32K 0 //!< 32.768kHz #define CLOCK_12M 1 //!< 12Mhz #define CLOCK_13M 2 //!< 13Mhz #define CLOCK_19_2M 3 //!< 19.2Mhz #define CLOCK_24M 5 //!< 24Mhz #define CLOCK_26M 6 //!< 26Mhz #define CLOCK_38_4M 7 //!< 38.4Mhz #define RDS_STANDARD 0 //!< RDS Mode. #define RDS_VERBOSE 1 //!< RDS Mode. #define RDA_FM_BAND_USA_EU 0 //!< 87.5–108 MHz (US / Europe, Default) #define RDA_FM_BAND_JAPAN_WIDE 1 //!< 76–91 MHz (Japan wide band) #define RDA_FM_BAND_WORLD 2 //!< 76–108 MHz (world wide) #define RDA_FM_BAND_SPECIAL 3 //!< 65 –76 MHz(East Europe) or 50 - 65MHz(see bit 9 of gegister 0x06) #define RDA_SEEK_WRAP 0 //!< Wrap at the upper or lower band limit and continue seeking #define RDA_SEEK_STOP 1 //!< Stop seeking at the upper or lower band limit #define RDA_SEEK_DOWN 0 //!< Seek Up #define RDA_SEEK_UP 1 //!< Seek Down #define REG00 0x00 #define REG02 0x02 #define REG03 0x03 #define REG04 0x04 #define REG05 0x05 #define REG06 0x06 #define REG07 0x07 #define REG0A 0x0A #define REG0B 0x0B #define REG0C 0x0C #define REG0D 0x0D #define REG0E 0x0E #define REG0F 0x0F #define SH_REG0A 0 // Shadow array position for register 0x0A #define SH_REG0B 1 // Shadow array position for register 0x0B #define SH_REG0C 2 // Shadow array position for register 0x0C - RDS Block A #define SH_REG0D 3 // Shadow array position for register 0x0D - RDS Block B #define SH_REG0E 4 // Shadow array position for register 0x0E - RDS Block C #define SH_REG0F 5 // Shadow array position for register 0x0F - RDS Block D /** * @defgroup GA01 Union, Structure and Defined Data Types * @brief rda Defined Data Types * @details Defined Data Types is a way to represent the rda registers information * @details The information shown here was extracted from Datasheet: * @details rda stereo FM digital tuning radio documentation. */ /** * @ingroup GA01 * @brief Register 0x00 * */ typedef union { struct { uint8_t CHIPID: 8; //!< Chip ifdef uint8_t DUMMY: 8; } refined; uint16_t raw; } rda_reg00; /** * @ingroup GA01 * @brief Register 0x01 - Dummy * @details It is not documented by the RDA. */ typedef union { struct { uint8_t lowByte; uint8_t highByte; } refined; uint16_t raw; } rda_reg01; /** * @ingroup GA01 * @brief Register 0x02 - Basic setup: RESET configuration; * @details Clock type configuration; seek operation; Sterio/Mono; Bass; and Audio configuration * @details The RDA5807M is RESET itself when power up. You also can use soft reset by triggering SOFT_RESET bit to 1. * @details Seek begins in the direction specified by SEEKUP and ends when a channel is found, or the entire band has been searched. * @details The SEEK bit is set low and the STC bit is set high when the seek operation completes. * @details RCLK NON-CALIBRATE MODE. if 0=RCLK clock is always supply; if 1=RCLK clock is not always supply when FM work ( when 1, RDA5807M can’t directly support -20 °C ~70 °C temperature. * @details Only suppory ±20°C temperature swing from tune point). * * Clock CLK_MODE table * * | Value | Clock | * | ----- | --------- | * | 000 | 32.768kHz | * | 001 | 12Mhz | * | 101 | 24Mhz | * | 010 | 13Mhz | * | 110 | 26Mhz | * | 011 | 19.2Mhz | * | 111 | 38.4Mhz | */ typedef union { struct { uint8_t ENABLE : 1; //!< Power Up Enable; 0 = Disabled; 1 = Enabled uint8_t SOFT_RESET : 1; //!< Soft reset; If 0, not reset; If 1, reset. uint8_t NEW_METHOD : 1; //!< New Demodulate Method Enable, can improve 0 the receive sensitivity about 1dB. uint8_t RDS_EN : 1; //!< RDS/RBDS enable; If 1, rds/rbds enable uint8_t CLK_MODE : 3; //!< See table above uint8_t SKMODE : 1; //!< Seek Mode; 0 = wrap at the upper or lower band limit and continue seeking; 1 = stop seeking at the upper or lower band limit uint8_t SEEK : 1; //!< Seek; 0 = Disable stop seek; 1 = Enable; uint8_t SEEKUP : 1; //!< Seek Up; 0 = Seek down; 1 = Seek up uint8_t RCLK_DIRECT_IN : 1; //!< RCLK clock use the directly input mode. 1 = enable uint8_t NON_CALIBRATE : 1; //!< 0=RCLK clock is always supply; 1=RCLK clock is not always supply when FM work uint8_t BASS : 1; //!< Bass Boost; 0 = Disabled; 1 = Bass boost enabled uint8_t MONO : 1; //!< Mono Select; 0 = Stereo; 1 = Force mono uint8_t DMUTE : 1; //!< Mute Disable; 0 = Mute; 1 = Normal operation uint8_t DHIZ : 1; //!< Audio Output High-Z Disable; 0 = High impedance; 1 = Normal operation } refined; uint16_t raw; } rda_reg02; /** * @ingroup GA01 * @brief Register 0x03 * @details Receiver configuratio * @details The tune operation begins when the TUNE bit is set high. The STC bit is set high when the tune operation completes. * @details The tune bit is reset to low automatically when the tune operation completes * * Channel space table * * | Value | Description | * | ----- | ----------- | * | 00 | 100KHz | * | 01 | 200KHz | * | 10 | 50KHz | * | 11 | 25KHz | * * * FM band table * * | Value | Description | * | ----- | --------------------------- | * | 00 | 87–108 MHz (US/Europe) | * | 01 | 76–91 MHz (Japan) | * | 10 | 76–108 MHz (world wide) | * | 11 | 65 –76 MHz (East Europe) or 50-65MHz (see bit 9 of gegister 0x06) | * * Channel select table * * | BAND | Description | * | ------ | -------------------------------------------------- | * | 0 | Frequency = Channel Spacing (kHz) x CHAN+ 87.0 MHz | * | 1 or 2 | Frequency = Channel Spacing (kHz) x CHAN + 76.0 MHz | * | 3 | Frequency = Channel Spacing (kHz) x CHAN + 65.0 MHz | * IMPORTANT: CHAN is updated after a seek operation. * */ typedef union { struct { uint16_t SPACE: 2; //!< See Channel space table above uint16_t BAND: 2; //!< Seet band table above uint16_t TUNE : 1; //!< Tune; 0 = Disable; 1 = Enable uint16_t DIRECT_MODE : 1; //!< Directly Control Mode, Only used when test uint16_t CHAN : 10; //!< Channel Select. } refined; uint16_t raw; } rda_reg03; /** * @ingroup GA01 * @brief Register 0x04 * @details Receiver properties * @details Volume scale is logarithmic When 0000, output mute and output impedance is very large * @details Setting STCIEN = 1 will generate a low pulse on GPIO2 when the interrupt occurs. */ typedef union { struct { uint8_t GPIO1 : 2; //!< General Purpose I/O 1. when gpio_sel=01; 00 = High impedance; 01 = Reserved; 10 = Low; 11 = High uint8_t GPIO2 : 2; //!< General Purpose I/O 2. when gpio_sel=01; 00 = High impedance; 01 = Reserved; 10 = Low; 11 = High uint8_t GPIO3 : 2; //!< General Purpose I/O 1. when gpio_sel=01; 00 = High impedance; 01 = Mono/Stereo indicator (ST); 10 = Low; 11 = High uint8_t I2S_ENABLE : 1; //!< I2S enable; 0 = disabled; 1 = enabled. uint8_t RSVD1 : 1; uint8_t AFCD : 1; //!< AFC disable; If 0, afc work; If 1, afc disabled. uint8_t SOFTMUTE_EN : 1; //!< If 1, softmute enable. uint8_t RDS_FIFO_CLR : 1; //!< 1 = clear RDS fifo uint8_t DE : 1; //!< De-emphasis; 0 = 75 μs; 1 = 50 μs uint8_t RDS_FIFO_EN : 1; //!< 1 = RDS fifo mode enable. uint8_t RBDS : 1; //!< 1 = RBDS mode enable; 0 = RDS mode only uint8_t STCIEN : 1; //!< Seek/Tune Complete Interrupt Enable; 0 = Disable Interrupt; 1 = Enable Interrupt; uint8_t RSVD2 : 1; } refined; uint16_t raw; } rda_reg04; /** * @ingroup GA01 * @brief Register 0x05 */ typedef union { struct { uint8_t VOLUME : 4; //!< DAC Gain Control Bits (Volume); 0000 = min volume; 1111 = max volume. uint8_t LNA_ICSEL_BIT : 2; //!< Lna working current bit: 00=1.8mA; 01=2.1mA; 10=2.5mA; 11=3.0mA. uint8_t LNA_PORT_SEL : 2; //!< LNA input port selection bit: 00: no input; 01: LNAN; 10: LNAP; 11: dual port input uint8_t SEEKTH : 4; //!< Seek SNR Threshold value uint8_t RSVD2 : 1; uint8_t SEEK_MODE : 2; //!< Default value is 00; When = 10, will add the RSSI seek mode uint8_t INT_MODE : 1; //!< If 0, generate 5ms interrupt; If 1, interrupt last until read reg0CH action occurs. } refined; uint16_t raw; } rda_reg05; /** * @ingroup GA01 * @brief Register 0x06 * * I2S_SW_CNT values table * * | Value | Description | * | ------- | ------------------ | * | 0b1000 | WS_STEP_48 | * | 0b0111 | WS_STEP=44.1kbps | * | 0b0110 | WS_STEP=32kbps | * | 0b0101 | WS_STEP=24kbps | * | 0b0100 | WS_STEP=22.05kbps | * | 0b0011 | WS_STEP=16kbps | * | 0b0010 | WS_STEP=12kbps | * | 0b0001 | WS_STEP=11.025kbps | * | 0b0000 | WS_STEP=8kbps | */ typedef union { struct { uint8_t R_DELY : 1; //!< If 1, R channel data delay 1T. uint8_t L_DELY : 1; //!< If 1, L channel data delay 1T. uint8_t SCLK_O_EDGE : 1; //!< If 1, invert sclk output when as master. uint8_t SW_O_EDGE : 1; //!< If 1, invert ws output when as master. uint8_t I2S_SW_CNT : 4; //!< Only valid in master mode. See table above uint8_t WS_I_EDGE : 1; //!< If 0, use normal ws internally; If 1, inverte ws internally. uint8_t DATA_SIGNED : 1; //!< If 0, I2S output unsigned 16-bit audio data. If 1, I2S output signed 16-bit audio data. uint8_t SCLK_I_EDGE : 1; //!< If 0, use normal sclk internally;If 1, inverte sclk internally. uint8_t WS_LR : 1; //!< Ws relation to l/r channel; If 0, ws=0 ->r, ws=1 ->l; If 1, ws=0 ->l, ws=1 ->r. uint8_t SLAVE_MASTER : 1; //!< I2S slave or master; 1 = slave; 0 = master. uint8_t OPEN_MODE : 2; //!< Open reserved register mode; 11=open behind registers writing function others: only open behind registers reading function. uint8_t RSVD : 1; } refined; uint16_t raw; } rda_reg06; /** * @ingroup GA01 * @brief Register 0x07 */ typedef union { struct { uint8_t FREQ_MODE : 1; //!< If 1, then freq setting changed. Freq = 76000(or 87000) kHz + freq_direct (08H) kHz. uint8_t SOFTBLEND_EN : 1; //!< If 1, Softblend enable uint8_t SEEK_TH_OLD : 6; //!< Seek threshold for old seek mode, Valid when Seek_Mode=001 uint8_t RSVD1 : 1; uint8_t MODE_50_60 : 1; //!< 1 = 65~76 MHz; 0 = 50~76MHz uint8_t TH_SOFRBLEND : 5; //!< Threshold for noise soft blend setting, unit 2dB (default 0b10000). uint8_t RSVD2 : 1; } refined; uint16_t raw; } rda_reg07; /** * @ingroup GA01 * @brief Register 0x08 - Direct Frequency * @details Valid when freq_mode = 1 * @details Freq = 7600(or 8700) kHz + freq_direct (08H) kHz. * @details Value to be stores is frequency - 7600 or 8700 */ typedef union { struct { uint8_t lowByte; uint8_t highByte; } refined; uint16_t raw; } rda_reg08; /** * @ingroup GA01 * @brief Register 0x0A - Device current status * @details The seek fail flag (SF) is set when the seek operation fails to find a channel with an RSSI level greater than SEEKTH[5:0]. * @details The seek/tune complete (STC) flag is set when the seek or tune operation completes. * * * Channel table * * | BAND | Description | * | ------ | -------------------------------------------------- | * | 0 | Frequency = Channel Spacing (kHz) x CHAN+ 87.0 MHz | * | 1 or 2 | Frequency = Channel Spacing (kHz) x CHAN + 76.0 MHz | * | 3 | Frequency = Channel Spacing (kHz) x CHAN + 65.0 MHz | * */ typedef union { struct { uint16_t READCHAN : 10; //!< See Channel table . See table above uint16_t ST : 1; //!< Stereo Indicator; 0 = Mono; 1 = Stereo uint16_t BLK_E : 1; //!< When RDS enable: 1 = Block E has been found; 0 = no Block E has been found uint16_t RDSS : 1; //!< RDS Synchronization; 0 = RDS decoder not synchronized(default); 1 = RDS decoder synchronized; Available only in RDS Verbose mode uint16_t SF : 1; //!< Seek Fail. 0 = Seek successful; 1 = Seek failure; uint16_t STC : 1; //!< Seek/Tune Complete. 0 = Not complete; 1 = Complete; uint16_t RDSR : 1; //!< RDS ready; 0 = No RDS/RBDS group ready(default); 1 = New RDS/RBDS group ready. } refined; uint16_t raw; } rda_reg0a; /** * @ingroup GA01 * @brief Register 0x0B * @details Current RDS and device status * * Errors Level table (Block Errors Level of RDS_DATA_0 and RDS_DATA_1. * Always read as Errors Level of RDS BLOCKs A and B (in RDS mode ) or E (in RBDS mode when ABCD_E flag is 1). * * | Value | Description | * | ----- | ----------- | * | 00 | 0 errors requiring correction | * | 01 | 1~2 errors requiring correction | * | 10 | 3~5 errors requiring correction | * | 10 | 6+ errors or error in checkword, correction not possible | * */ typedef union { struct { uint8_t BLERB : 2; //!< Block Errors Level of RDS_DATA_1 uint8_t BLERA : 2; //!< Block Errors Level of RDS_DATA_0 uint8_t ABCD_E : 1; //!< 1 = the block id of register 0cH,0dH,0eH,0fH is E; 0 = the block id of register 0cH, 0dH, 0eH,0fH is A, B, C, D uint8_t RSVD1 : 2; uint8_t FM_READY : 1; //!< 1=ready; 0=not ready. uint8_t FM_TRUE : 1; //!< 1 = the current channel is a station; 0 = the current channel is not a station. uint8_t RSSI : 7; //!< RSSI; 000000 = min; 111111 = max; RSSI scale is logarithmic. } refined; uint16_t raw; } rda_reg0b; /** * @ingroup GA01 * @brief Register 0x0C * @details BLOCK A ( in RDS mode) or BLOCK E (in RBDS mode when ABCD_E flag is 1) * */ typedef union { struct { uint8_t lowByte; uint8_t highByte; } refined; uint16_t RDSA; //!< BLOCK A ( in RDS mode) or BLOCK E (in RBDS mode when ABCD_E flag is 1) } rda_reg0c; /** * @ingroup GA01 * @brief Register 0x0D * @details BLOCK B ( in RDS mode) or BLOCK E (in RBDS mode when ABCD_E flag is 1) * */ typedef union { struct { uint8_t lowByte; uint8_t highByte; } refined; uint16_t RDSB; } rda_reg0d; /** * @ingroup GA01 * @brief Register 0x0E * @details BLOCK C ( in RDS mode) or BLOCK E (in RBDS mode when ABCD_E flag is 1) * */ typedef union { struct { uint8_t lowByte; uint8_t highByte; } refined; uint16_t RDSC; } rda_reg0e; /** * @ingroup GA01 * @brief Register 0x0F * @details BLOCK D ( in RDS mode) or BLOCK E (in RBDS mode when ABCD_E flag is 1) * */ typedef union { struct { uint8_t lowByte; uint8_t highByte; } refined; uint16_t RDSD; } rda_reg0f; /** * @ingroup GA01 * @brief RDS Block B data type * * @details For GCC on System-V ABI on 386-compatible (32-bit processors), the following stands: * * 1) Bit-fields are allocated from right to left (least to most significant). * 2) A bit-field must entirely reside in a storage unit appropriate for its declared type. * Thus a bit-field never crosses its unit boundary. * 3) Bit-fields may share a storage unit with other struct/union members, including members that are not bit-fields. * Of course, struct members occupy different parts of the storage unit. * 4) Unnamed bit-fields' types do not affect the alignment of a structure or union, although individual * bit-fields' member offsets obey the alignment constraints. * * @see also https://en.wikipedia.org/wiki/Radio_Data_System */ typedef union { struct { uint8_t address : 2; // Depends on Group Type and Version codes. If 0A or 0B it is the Text Segment Address. uint8_t DI : 1; // Decoder Controll bit uint8_t MS : 1; // Music/Speech uint8_t TA : 1; // Traffic Announcement uint8_t programType : 5; // PTY (Program Type) code uint8_t trafficProgramCode : 1; // (TP) => 0 = No Traffic Alerts; 1 = Station gives Traffic Alerts uint8_t versionCode : 1; // (B0) => 0=A; 1=B uint8_t groupType : 4; // Group Type code. } group0; struct { uint8_t address : 4; // Depends on Group Type and Version codes. If 2A or 2B it is the Text Segment Address. uint8_t textABFlag : 1; // Do something if it chanhes from binary "0" to binary "1" or vice-versa uint8_t programType : 5; // PTY (Program Type) code uint8_t trafficProgramCode : 1; // (TP) => 0 = No Traffic Alerts; 1 = Station gives Traffic Alerts uint8_t versionCode : 1; // (B0) => 0=A; 1=B uint8_t groupType : 4; // Group Type code. } group2; struct { uint8_t content : 4; // Depends on Group Type and Version codes. uint8_t textABFlag : 1; // Do something if it chanhes from binary "0" to binary "1" or vice-versa uint8_t programType : 5; // PTY (Program Type) code uint8_t trafficProgramCode : 1; // (TP) => 0 = No Traffic Alerts; 1 = Station gives Traffic Alerts uint8_t versionCode : 1; // (B0) => 0=A; 1=B uint8_t groupType : 4; // Group Type code. } refined; uint16_t blockB; } rds_blockb; /** * @ingroup GA01 * Group RDS type 4A ( RDS Date and Time) * When group type 4A is used by the station, it shall be transmitted every minute according to EN 50067. * This Structure uses blocks 2,3 and 5 (B,C,D) * * ATTENTION: * To make it compatible with 8, 16 and 32 bits platforms and avoid Crosses boundary, it was necessary to * split minute and hour representation. */ typedef union { struct { uint8_t offset : 5; // Local Time Offset uint8_t offset_sense : 1; // Local Offset Sign ( 0 = + , 1 = - ) uint8_t minute1 : 2; // UTC Minutes - 2 bits less significant (void “Crosses boundary”). uint8_t minute2 : 4; // UTC Minutes - 4 bits more significant (void “Crosses boundary”) uint8_t hour1 : 4; // UTC Hours - 4 bits less significant (void “Crosses boundary”) uint8_t hour2 : 1; // UTC Hours - 4 bits more significant (void “Crosses boundary”) uint32_t mjd : 17; // Modified Julian Day Code } refined; uint8_t raw[6]; } rds_date_time; /** * @ingroup GA01 * @brief Converts 16 bits word to two bytes */ typedef union { struct { uint8_t lowByte; uint8_t highByte; } refined; uint16_t raw; } word16_to_bytes; /** * @ingroup GA01 * @brief KT0915 Class * @details This class implements all functions that will help you to control the KT0915 devices. * * @author PU2CLR - Ricardo Lima Caratti */ class RDA5807 { private: uint16_t shadowStatusRegisters[6]; //!< shadow status registers uint16_t shadowRegisters[9]; //!< shadow configuration registers // Shadow device configuration register references (writable registers) rda_reg00 *reg00 = (rda_reg00 *)&shadowRegisters[0]; // REG01; rda_reg01 *reg01 = (rda_reg01 *)&shadowRegisters[1]; // REG01; rda_reg02 *reg02 = (rda_reg02 *)&shadowRegisters[2]; // REG02; rda_reg03 *reg03 = (rda_reg03 *)&shadowRegisters[3]; // REG03; rda_reg04 *reg04 = (rda_reg04 *)&shadowRegisters[4]; // REG04; rda_reg05 *reg05 = (rda_reg05 *)&shadowRegisters[5]; // REG05; rda_reg06 *reg06 = (rda_reg06 *)&shadowRegisters[6]; // REG06; rda_reg07 *reg07 = (rda_reg07 *)&shadowRegisters[7]; // REG07; rda_reg08 *reg08 = (rda_reg08 *)&shadowRegisters[8]; // REG08; // Shadow device status register references (read only registers) rda_reg0a *reg0a = (rda_reg0a *)&shadowStatusRegisters[0]; // SH_REG0A; rda_reg0b *reg0b = (rda_reg0b *)&shadowStatusRegisters[1]; // SH_REG0B; rda_reg0c *reg0c = (rda_reg0c *)&shadowStatusRegisters[2]; // SH_REG0C; rda_reg0d *reg0d = (rda_reg0d *)&shadowStatusRegisters[3]; // SH_REG0D; rda_reg0e *reg0e = (rda_reg0e *)&shadowStatusRegisters[4]; // SH_REG0E; rda_reg0f *reg0f = (rda_reg0f *)&shadowStatusRegisters[5]; // SH_REG0F; uint16_t startBand[4] = {8700, 7600, 7600, 6500}; uint16_t endBand[4] = {10800, 9100, 10800, 7600}; //!< End FM band limit uint16_t fmSpace[4] = {100, 200, 50, 25}; char rds_buffer2A[65]; //!< RDS Radio Text buffer - Program Information char rds_buffer2B[33]; //!< RDS Radio Text buffer - Station Informaation char rds_buffer0A[9]; //!< RDS Basic tuning and switching information (Type 0 groups) char rds_time[20]; //!< RDS date time received information protected: int deviceAddressDirectAccess = I2C_ADDR_DIRECT_ACCESS; int deviceAddressFullAccess = I2C_ADDR_FULL_ACCESS; int resetPin; uint16_t currentFrequency; uint8_t currentFMBand = 0; uint8_t currentFMSpace = 0; uint8_t currentVolume = 0; int gpio1Control = -1; //!< Can be used to add control to the system via GPIO1 pin int gpio2Control = -1; //!< Can be used to add control to the system via GPIO2 pin int gpio3Control = -1; //!< Can be used to add control to the system via GPIO3 pin uint8_t clockType = CLOCK_32K; uint8_t oscillatorType = OSCILLATOR_TYPE_CRYSTAL; uint16_t maxDelayAftarCrystalOn = MAX_DELAY_AFTER_OSCILLATOR; public : /** * @brief Set the Delay After Crystal On (default 500ms) * * @param ms_value Value in milliseconds */ inline void setDelayAfterCrystalOn(uint8_t ms_value) { maxDelayAftarCrystalOn = ms_value; }; /** * @ingroup GA03 * @brief Sets alternatives I2C bus address * @details You do not need use this function on RDA5807M * @param directAccess * @param fullAccess */ inline void setI2CBusAddrs(int directAccess, int fullAccess) { this->deviceAddressDirectAccess = directAccess; this->deviceAddressFullAccess = fullAccess; } void getStatusRegisters(); void *getStatus(uint8_t reg); void setRegister(uint8_t reg, uint16_t value); void setGpio(uint8_t gpioPin, uint8_t gpioSetup = 0, int mcuPin = -1); void waitAndFinishTune(); void softReset(); void powerUp(); void powerDown(); void setup(uint8_t clock_type = CLOCK_32K, uint8_t oscillator_type = OSCILLATOR_TYPE_CRYSTAL); void setFrequency(uint16_t frequency); uint16_t getFrequency(); void setFrequencyUp(); void setFrequencyDown(); uint16_t getRealFrequency(); uint16_t getRealChannel(); void setChannel(uint16_t channel); void seek(uint8_t seek_mode, uint8_t direction); void seek(uint8_t seek_mode, uint8_t direction, void (*showFunc)()); void setSeekThreshold(uint8_t value); void setBand(uint8_t band = 1); void setSpace(uint8_t space = 0); int getRssi(); void setSoftmute(bool value); void setMono(bool value); void setBass(bool value); bool isStereo(); uint8_t getDeviceId(); void setMute(bool value); void setVolume(uint8_t value); uint8_t getVolume(); void setVolumeUp(); void setVolumeDown(); void setFmDeemphasis(uint8_t de); //******** RDS methods void setRDS(bool value); void setRBDS(bool value); void setRdsFifo(bool value); void clearRdsFifo(); bool getRdsReady(); uint8_t getRdsFlagAB(void); uint8_t getRdsVersionCode(void); uint16_t getRdsGroupType(); uint8_t getRdsProgramType(void); void getNext2Block(char *c); void getNext4Block(char *c); char *getRdsText(void); char *getRdsText0A(void); char *getRdsText2A(void); char *getRdsText2B(void); char *getRdsTime(); bool getRdsSync(); uint8_t getBlockId(); uint8_t getErrorBlockB(); bool hasRdsInfo(); uint32_t rdsTest(); };