PU2CLR BK108X Arduino Library 1.0.2
This is an Arduino Library to control the BK108X device
Loading...
Searching...
No Matches
BK108X.h
Go to the documentation of this file.
1
2/**
3 * @mainpage PU2CLR BK108X Arduino Library
4 * @brief PU2CLR BK108X Arduino Library implementation. <br>
5 * @details This is an Arduino library for the BK1086 and BK1088 DSP BROADCAST RECEIVER.<br>
6 * @details It works with I2C protocol and can provide an easier interface for controlling the BK1086/88 devices.<br>
7 * @details This library is based on BEKEN - BK1086/88 - BROADCAST AM/FM/SW/LW RADIO RECEIVER manual.
8 *
9 * @see https://github.com/pu2clr/BK108X
10 *
11 * __THIS LIBRARY IS UNDER CONSTRUCTION.....___
12 *
13 *
14 * This library can be freely distributed using the MIT Free Software model.
15 * Copyright (c) 2020 Ricardo Lima Caratti.
16 * Contact: pu2clr@gmail.com
17 */
18
19#include <Arduino.h>
20
21#define MAX_DELAY_AFTER_OSCILLATOR 500 // Max delay after the crystal oscilator becomes active
22
23#define I2C_DEVICE_ADDR 0x80
24
25#define MAX_SEEK_TIME 5000 // Maximum time have to be a seeking process (in ms).
26
27#define OSCILLATOR_TYPE_CRYSTAL 1 // Crystal
28#define OSCILLATOR_TYPE_REFCLK 0 // Reference clock
29
30#define RDS_STANDARD 0 //!< RDS Mode.
31#define RDS_VERBOSE 1 //!< RDS Mode.
32#define BK_SEEK_DOWN 0 //!< Seek Down Direction
33#define BK_SEEK_UP 1 //!< Seek Up Direction
34#define BK_SEEK_WRAP 0 //
35#define BK_SEEK_STOP 1
36
37#define FM_FULL 0 //!< 64~108MHz
38#define FM_BAND_JAPAN_WIDE 1 //!< 76–108 MHz (Japan wide band)
39#define FM_BAND_JAPAN 2 //!< 76–90 MHz (Japan)
40#define FM_BAND_USA_EU 3 //!< 87–108 MHz (US / Europe, Default)
41
42#define AM_LW 0 //!< 153~279KHz
43#define AM_MW1 1 //!< 520~1710Khz
44#define AM_SW 2 //!< 2.3~21.85KHz
45#define AM_M22 3 //!< 522~1710
46
47#define BK_MODE_FM 0
48#define BK_MODE_AM 1
49
50#define DE_EMPHASIS_75 0
51#define DE_EMPHASIS_50 1
52
53
54#define REG00 0x00
55#define REG01 0x01
56#define REG02 0x02
57#define REG03 0x03
58#define REG04 0x04
59#define REG05 0x05
60#define REG06 0x06
61#define REG07 0x07
62#define REG08 0x08
63#define REG09 0x09
64#define REG0A 0x0A
65#define REG0B 0x0B
66#define REG0C 0x0C
67#define REG0D 0x0D
68#define REG0E 0x0E
69#define REG0F 0x0F
70#define REG10 0x10
71#define REG11 0x11
72#define REG12 0x12
73#define REG13 0x13
74#define REG14 0x14
75#define REG15 0x15
76#define REG16 0x16
77#define REG17 0x17
78#define REG18 0x18
79#define REG19 0x19
80#define REG1A 0x1A
81#define REG1B 0x1B
82#define REG1C 0x1C
83#define REG1D 0x1D
84#define REG1E 0x1E
85#define REG1F 0x1F
86
87/**
88 * @defgroup GA01 Union, Structure and Defined Data Types
89 * @brief BK108X Defined Data Types
90 * @details Defined Data Types is a way to represent the BK108X registers information
91 * @details Some information appears to be inaccurate due to translation problems from Chinese to English.
92 * @details The information shown here was extracted from Datasheet:
93 * @details BK108X stereo FM digital tuning radio documentation.
94 * @details Other information seems incomplete even in the original Chinese Datasheet.
95 * @details For example: Reg 10 (0x0A). There is no information about it. The Reg11 and 12 seem wrong
96 */
97
98/**
99 * @ingroup GA01
100 * @brief Device ID
101 *
102 */
103typedef union
104{
105 struct
106 {
107 uint8_t lowByte;
108 uint8_t highByte;
109 } refined;
111} bk_reg00;
112
113/**
114 * @ingroup GA01
115 * @brief Chip ID
116 *
117 */
118typedef union
119{
120 struct
121 {
122 uint8_t lowByte;
123 uint8_t highByte;
124 } refined;
126} bk_reg01;
127
128/**
129 * @ingroup GA01
130 * @brief Power Configuratio
131 * @see BEKEN - BK1086/88 - BROADCAST AM/FM/SW/LW RADIO RECEIVER; pages 13 and 14
132 */
133typedef union
134{
135 struct
136 {
137 uint8_t ENABLE : 1; //!< Powerup Enable;
138 uint8_t SNR_REF : 5; //!< Output SNR adjustment. Read SNR = SNR (calculated)
139 uint8_t DISABLE : 1; //!< Powerup Disable;
140 uint8_t SKAFCRL : 1; //!< Seek with AFC Rail; 0 = During seeking, the channel is valid no matter whether AFCRL is high or low; 1 = During seeking, the channel is invalid if AFCRL is high.
141 uint8_t SEEK : 1; //!< 0 = Disable (default); 1 = Enable;
142 uint8_t SEEKUP : 1; //!< Seek Direction; 0 = Seek down (default); 1 = Seek up.
143 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.
144 uint8_t STEREO : 1; //!< Stereo; 0 = Normal operation; 1 = Force stereo; MONO and STEREO cannot be set to 1 simultaneously.
145 uint8_t MONO : 1; //!< Mono; 0 = Normal operation; 1 = Force mono.
146 uint8_t MUTER : 1; //!< Mute R channel; 0 = R channel normal operation; 1 = R channel mute.
147 uint8_t MUTEL : 1; //!< Mute L channel; 0 = L channel normal operation; 1 = L channel mute.
148 uint8_t DSMUTE : 1; //!< Softmute Disable; 0 = Softmute enable (default); 1 = Softmute disable.
149 } refined;
151} bk_reg02;
152
153/**
154 * @ingroup GA01
155 * @brief Channe
156 * @details The tuned Frequency = Band + CHAN * SPACE
157 * @see BEKEN - BK1086/88 - BROADCAST AM/FM/SW/LW RADIO RECEIVER; page 14
158 */
159typedef union
160{
161 struct
162 {
163 uint16_t CHAN : 15; //!< Channel Select; The tuned Frequency = Band + CHAN * SPACE.
164 uint16_t TUNE : 1; //!< Tune. 0 = Disable (default); 1 = Enable.
165 } refined;
167} bk_reg03;
168
169/**
170 * @ingroup GA01
171 * @brief Register 04h. System Configuration1 (0x1180)
172 * @details When register GPIO2[1:0]=2’b01 and seek or tune finish, a 5ms low pulse will appear at GPIO2 .Both RDSIEN and STCIEN can be high;
173 * @details When register GPIO2[1:0]=2’b01 and new RDS come, a 5ms low pulse will appear at GPIO2.
174 *
175 */
176typedef union
177{
178 struct
179 {
180 uint16_t DUMMY : 2; //!< Not used / RESERVED General Purpose I/O 1; 00 = High impedance (default); 01 = CLK38MHz; 10 = Low; 11 = High.
181 uint16_t GPIO2 : 2; //!< General Purpose I/O 2. 00 = High impedance (default); 01 = STC/RDS interrupt; 10 = Low; 11 = High.
182 uint16_t GPIO3 : 2; //!< General Purpose I/O 2. 00 = High impedance (default); 01 = Mono/Stereo indicator (ST); 10 = Low; 11 = High.
183 uint16_t PILOTS : 3; //!< Stereo/Mono Blend Level Adjustment. Sets the RSSI range for stereo/mono blend. See table above.
184 uint16_t TCPILOT : 2; //!< The Time Used to Cal The Strength of Pilot
185 uint16_t DE : 1; //!< De-emphasis; 0 = 75 μs. Used in USA (default); 1 = 50 μs. Used in Europe, Australia, Japan.
186 uint16_t RDSEN : 1; //!< RDS Enable; 0 = Disable (default); 1 = Enable.
187 uint16_t AFCINV : 1; //!< AFC Invert; 0 = Normal AFC into mixer; 1 = Reverse AFC into mixer.
188 uint16_t STCIEN : 1; //!< Seek/Tune Complete Interrupt Enable; 0 = Disable Interrupt (default); 1 = Enable Interrupt. See details above.
189 uint16_t RDSIEN : 1; //!< RDS Interrupt Enable; 0 = Disable Interrupt (default); 1 = Enable Interrupt. See details above.
190 } refined;
192} bk_reg04;
193
194/**
195 * @ingroup GA01
196 * @brief Register 05h. System Configuration2 (0x3ddf)
197 * @details LW and SW Band are only defined at BK1088
198 *
199 * AM and Fm Band table ()
200 * | BAND value | AM band KHz | FM band MHz |
201 * | ---------- | ----------------| ----------------- |
202 * | 0 | 00: LW 153~279 | FULL 64~108 |
203 * | 1 | 10: MW 520~1710 | East Europe 64~76 |
204 * | 2 | 10: SW 2.3~21.85| Japan 76~91 |
205 * | 3 | 11: MW 522~1710 | Europe 87~108 |
206 *
207 *
208 * AM and FM Channel Space
209 * | BAND value | AM Space KHz | FM Space KHz |
210 * | ---------- | ------------- | ------------- |
211 * | 0 | 1 | 10 |
212 * | 1 | 5 | 50 |
213 * | 2 | 9 | 100 |
214 * | 3 | 10 | 200 |
215 *
216 * @see bk_reg07
217 */
218typedef union
219{
220 struct
221 {
222 uint16_t VOLUME : 5; //!< 0x00 is the lowest and 0x1F is highest (0dBFS). 2dB each
223 uint16_t SPACE : 2; //!< Channel Spacing; See AM and FM Channel Space table above.
224 uint16_t BAND : 2; //!< Band Select. See AM and Fm Band table above.
225 uint16_t SEEKTH : 7; //!< RSSI Seek Threshold. 0x00 = min RSSI (default); 0x7F = max RSSI.
226 } refined;
228} bk_reg05;
229
230/**
231 * @ingroup GA01
232 * @brief Register 06h. System Configuration3 (0x01ef)
233 * @details SKCNT - Seek Impulse Detection Threshold Allowable number of impulse for a valid seek channel while setting all zeros means not use Impulse number to judge the channel’s validity.
234 *
235 *
236 * SMUTEA table
237 *
238 * | Softmute Attenuation | Description |
239 * | ---------------------- | --------------- |
240 * | 0 | 16 dB (default) |
241 * | 1 | 14 dB |
242 * | 2 | 12 dB |
243 * | 3 | 10 dB |
244 *
245 * SMUTER table
246 *
247 * | Softmute Attack/Recover Rate | Description |
248 * | ------------------------------ | ----------------- |
249 * | 0 | fastest (default) |
250 * | 1 | fast |
251 * | 2 | slow |
252 * | 3 | slowest |
253 *
254 */
255typedef union
256{
257 struct
258 {
259 uint16_t SKCNT : 4; //!< See details above.
260 uint16_t SKSNR : 7; //!< Seek SNR Threshold. Required channel SNR for a valid seek channel
261 uint16_t CLKSEL : 1; //!< Clock Select. 0 = External clock input; 1= Internal oscillator input.
262 uint16_t SMUTEA : 2; //!< Softmute Attenuation; See table above.
263 uint16_t SMUTER : 2; //!< Softmute Attack/Recover Rate; See table above
264 } refined;
266} bk_reg06;
267
268/**
269 * @ingroup GA01
270 * @brief Register 07h. Test1 (0x0900)
271 */
272typedef union
273{
274 struct
275 {
276 uint16_t FMGAIN : 3; //!< The gain of Frequency demodulated; 000 = 0dB ... 011= +18dB; 100= 0dB ... 111= -18dB
277 uint16_t RESERVED :3;
278 uint16_t STHYS_SEL : 1; //!< ST/MONO Transition Hysterisis Select. 0 = 6dB; 1=2dB
279 uint16_t DACCK_SEL : 1; //!< DAC Clock Select
280 uint16_t IMPTH : 2; //!< Threshold of Impulse Detect. 00 = toughest; 11 = loosest
281 uint16_t BPDE : 1; //!< De-emphasis Bypass; 0 = Normal operation; 1 = Bypass de-emphasis.
282 uint16_t IMPEN : 1; //!< Impulse Remove Enable; 0 = Disable; 1 = Enable.
283 uint16_t SIQ : 1; //!< IF I/Q Signal switch; 0 = Normal operation; 1 = Reversed I/Q signal.
284 uint16_t MODE : 1; //!< 0 = FM receiver; 1 = AM receiver
285 uint16_t LINEIN_EN : 1; //!< Audio Line in Enable; 0 = Disable (Receiver Mode)
286 uint16_t LINEIN_SEL : 1; //!< Audio Line in Channel Select; 0 = Channel 1; 1=Channel 2 ((QFN24 only support one line in channel))
287 } refined;
289} bk_reg07;
290
291/**
292 * @ingroup GA01
293 * @brief Test 2
294 * @details RSSI Threshold for Instant AFC updating; AFC Average Range; Variation Threshold for average AFC calculation;
295 * @details AFC Average; AFCRL Threshold; AFC/RSSI/SNR Calculate Rate; AFC Enable
296 *
297 */
298typedef union
299{
300 struct
301 {
302 uint16_t AFCRSSIT : 7; //!< RSSI Threshold for Instant AFC updating
303 uint16_t RANGE : 2; //!< AFC Average Range; 00 = the toughest; 11 = the loosest
304 uint16_t VAR : 2; //!< Variation Threshold for average AFC calculation; 00 = Disable; 01 = the toughest; 11 = the loosest
305 uint16_t AVE : 1; //!< AFC Average
306 uint16_t SEL25K : 1; //!< AFCRL Threshold; 0 = Channel space/2; 1 = 25kHz
307 uint16_t TCSEL : 2; //!< AFC/RSSI/SNR Calculate Rate; 00 = fastest; 11 = slowest. 4X times each
308 uint16_t AFCEN : 1; //!< AFC Enable; 0 = Disable; 1 = Enable.
309 } refined;
311} bk_reg08;
312
313/**
314 * @ingroup GA01
315 * @brief Register 09h. Status1 (0x0000)
316 */
317typedef union
318{
319 struct
320 {
321 uint16_t SNR:7; //!< The AFC value.
322 uint16_t AFC:9; //!< unit AM 0.15k Hz, FM 0.6k Hz
323 } refined;
325} bk_reg09;
326
327/**
328 * @ingroup GA01
329 * @brief Register 0Ah. Status2 (0x0000)
330 */
331typedef union
332{
333 struct
334 {
335 uint16_t RSSI : 7; //!< RSSI (Received Signal Strength Indicator).
336 uint16_t ST : 1; //!< Stereo Indicator; 0 = Mono; 1 = Stereo.
337 uint16_t STEN : 1; //!< Impulse Number
338 uint16_t DUMMY: 3;
339 uint16_t AFCRL : 1; //!< AFC Rail; 0 = AFC not railed; 1 = AFC railed.
340 uint16_t SF_BL : 1; //!< Seek Fail/Band Limit; 0 = Seek successful; 1 = Seek failure/Band limit reached.
341 uint16_t STC : 1; //!< Seek/Tune Complete; 0 = Not complete (default); 1 = Complete.
342 uint16_t RDSR : 1; //!< RDS Ready; 0 = No RDS group ready (default); 1 = New RDS group ready. Keep high for 40ms after new RDS is received
343 } refined;
345} bk_reg0a;
346
347/**
348 * @ingroup GA01
349 * @brief Register 0Bh. Read Channel (0x0000)
350 */
351typedef union
352{
353 struct
354 {
355 uint16_t READCHAN : 14; //!< Read Channel. Provides the current working channel
356 uint16_t RESERVED : 2;
357 } refined;
359} bk_reg0b;
360
361/**
362 * @ingroup GA01
363 * @brief Register 0Ch. RDS1 (0x0000)
364 * @details RDS Block A - The First Register of RDS Received
365 */
366typedef union
367{
368 struct
369 {
370 uint16_t BLERB : 2; //!< Block Errors Level of RDS_DATA_1
371 uint16_t BLERA : 2; //!< Block Errors Level of RDS_DATA_0
372 uint16_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
373 uint16_t DUMMY : 2;
374 uint16_t FM_READY : 1; //!< 1=ready; 0=not ready.
375 uint16_t FM_TRUE : 1; //!< 1 = the current channel is a station; 0 = the current channel is not a station.
376 uint16_t RSSI : 7; //!< RSSI; 000000 = min; 111111 = max; RSSI scale is logarithmic.
377 } rds_status;
378 struct
379 {
380 uint8_t lowByte;
381 uint8_t highByte;
382 } refined;
384} bk_reg0c;
385
386/**
387 * @ingroup GA01
388 * @brief Register 0Dh. RDS2 (0x0000)
389 * @details RDS Block B - The second register of RDS received
390 */
391typedef union
392{
393 struct
394 {
395 uint8_t lowByte;
396 uint8_t highByte;
397 } refined;
399} bk_reg0d;
400
401/**
402 * @ingroup GA01
403 * @brief Register 0Eh. RDS2 (0x0000)
404 * @details RDS Block C - The third register of RDS received
405 */
406typedef union
407{
408 struct
409 {
410 uint8_t lowByte;
411 uint8_t highByte;
412 } refined;
414} bk_reg0e;
415
416/**
417 * @ingroup GA01
418 * @brief Register 0Fh. RDS4 (0x0000)
419 * @details RDS Block D - The fourth register of RDS received when read
420 */
421typedef union
422{
423 struct
424 {
425 uint8_t lowByte;
426 uint8_t highByte;
427 } refined;
429} bk_reg0f;
430
431/**
432 * @ingroup GA01
433 * @brief Register 10h. Boot Configuration1 (0x7b11)
434 */
435typedef union
436{
437 struct
438 {
439 uint8_t lowByte;
440 uint8_t highByte;
441 } refined;
443} bk_reg10;
444
445/**
446 * @ingroup GA01
447 * @brief Register 11h. Boot Configuration2 (0x0080)
448 */
449typedef union
450{
451 struct
452 {
453 uint8_t lowByte;
454 uint8_t highByte;
455 } refined;
457} bk_reg11;
458
459/**
460 * @ingroup GA01
461 * @brief Register 12h. Boot Configuration3 (0x4000)
462 */
463typedef union
464{
465 struct
466 {
467 uint8_t lowByte;
468 uint8_t highByte;
469 } refined;
471} bk_reg12;
472
473/**
474 * @ingroup GA01
475 * @brief Register 13h. Boot Configuration4 (0x3e00)
476 */
477typedef union
478{
479 struct
480 {
481 uint8_t lowByte;
482 uint8_t highByte;
483 } refined;
485} bk_reg13;
486
487/**
488 * @ingroup GA01
489 * @brief Register 14h. Boot Configuration5 (0x0000)
490 */
491typedef union
492{
493 struct
494 {
495 uint16_t RSSIMTH : 7; //!< The Mute Threshold Based on RSSI
496 uint16_t SNRMTH : 7; //!< The Mute Threshold Based on SNR
497 uint16_t AFCMUTE : 1; //!< 0: disable soft mute when AFCRL is high; 1: enable soft mute when AFCRL is high
498 uint16_t SKMUTE : 1; //!< 0: disable soft mute when seeking; 1: enable soft mute when seeking
499 } refined;
501} bk_reg14;
502
503/**
504 * @ingroup GA01
505 * @brief 15h. Boot Configuration6 (0x0000)
506 */
507typedef union
508{
509 struct
510 {
511 uint8_t lowByte;
512 uint8_t highByte;
513 } refined;
515} bk_reg15;
516
517/**
518 * @ingroup GA01
519 * @brief Register 16h. Boot Configuration7 (0x0400)
520 */
521typedef union
522{
523 struct
524 {
525 uint8_t lowByte;
526 uint8_t highByte;
527 } refined;
529} bk_reg16;
530
531/**
532 * @ingroup GA01
533 * @brief Register 17h. Boot Configuration8 (0x0001)
534 */
535typedef union
536{
537 struct
538 {
539 uint8_t lowByte;
540 uint8_t highByte;
541 } refined;
543} bk_reg17;
544
545/**
546 * @ingroup GA01
547 * @brief Register 18h. Boot Configuration9 (0x143c)
548 */
549typedef union
550{
551 struct
552 {
553 uint8_t lowByte;
554 uint8_t highByte;
555 } refined;
557} bk_reg18;
558
559/**
560 * @ingroup GA01
561 * @brief Register 19h. Boot Configuration10 (0x4351)
562 */
563typedef union
564{
565 struct
566 {
567 uint8_t lowByte;
568 uint8_t highByte;
569 } refined;
571} bk_reg19;
572
573/**
574 * @ingroup GA01
575 * @brief Register 1Ah. Boot Configuration11 (0x0000)
576 */
577typedef union
578{
579 struct
580 {
581 uint16_t RESERVED1 : 3;
582 uint16_t ANT_SEL : 5; //!< Antenna varactor tune
583 uint16_t RESERVED2 : 4;
584 } refined;
586} bk_reg1A;
587
588/**
589 * @ingroup GA01
590 * @brief Register 1Bh. Analog Configuration1 (0x0000)
591 */
592typedef union
593{
594 struct {
595 uint16_t RESERVED;
596 } refined;
598} bk_reg1B;
599
600/**
601 * @ingroup GA01
602 * @brief Register 1Ch. Analog Configuration2 (0x0000)
603 */
604typedef union
605{
606 struct
607 {
608 uint16_t RESERVED : 14;
609 uint16_t FREQ_SEL : 2; //!< Reference clock divider control ,Refer to Reg1D Default 0 for 32.768kHz reference input.
610 } refined;
612} bk_reg1C;
613
614/**
615 * @ingroup GA01
616 * @brief Register 1Dh. Analog Configuration2 (0x0000)
617 */
618typedef union
619{
620 struct {
621 uint16_t FREQ_SEL;
622 } refined;
623 uint16_t raw; //!< //!< Reference clock divider control , FREQ_SEL[17:0] = HEX | Ref Frequency/512+0.5 | Default 16 for 32.768kHz reference.
624} bk_reg1D;
625
626/**
627 * @brief The user does not have access to registsres 0x1E, 0x1F and 0x20.
628 * @details They are Internal test registers and can be provided separately by BEKEN.
629 * @details The author of this library did not have access to these register.
630 */
631typedef uint16_t bk_reg1E; // Internal register
632typedef uint16_t bk_reg1F; // Internal Register
633typedef uint16_t bk_reg20; // Internal Register
634
635
636/**
637 * @ingroup GA01
638 * @brief RDS Block B data type
639 *
640 * @details For GCC on System-V ABI on 386-compatible (32-bit processors), the following stands:
641 *
642 * 1) Bit-fields are allocated from right to left (least to most significant).
643 * 2) A bit-field must entirely reside in a storage unit appropriate for its declared type.
644 * Thus a bit-field never crosses its unit boundary.
645 * 3) Bit-fields may share a storage unit with other struct/union members, including members that are not bit-fields.
646 * Of course, struct members occupy different parts of the storage unit.
647 * 4) Unnamed bit-fields' types do not affect the alignment of a structure or union, although individual
648 * bit-fields' member offsets obey the alignment constraints.
649 *
650 * @see also https://en.wikipedia.org/wiki/Radio_Data_System
651 */
652typedef union
653{
654 struct
655 {
656 uint16_t address : 2; // Depends on Group Type and Version codes. If 0A or 0B it is the Text Segment Address.
657 uint16_t DI : 1; // Decoder Controll bit
658 uint16_t MS : 1; // Music/Speech
659 uint16_t TA : 1; // Traffic Announcement
660 uint16_t programType : 5; // PTY (Program Type) code
661 uint16_t trafficProgramCode : 1; // (TP) => 0 = No Traffic Alerts; 1 = Station gives Traffic Alerts
662 uint16_t versionCode : 1; // (B0) => 0=A; 1=B
663 uint16_t groupType : 4; // Group Type code.
664 } group0;
665 struct
666 {
667 uint16_t address : 4; // Depends on Group Type and Version codes. If 2A or 2B it is the Text Segment Address.
668 uint16_t textABFlag : 1; // Do something if it chanhes from binary "0" to binary "1" or vice-versa
669 uint16_t programType : 5; // PTY (Program Type) code
670 uint16_t trafficProgramCode : 1; // (TP) => 0 = No Traffic Alerts; 1 = Station gives Traffic Alerts
671 uint16_t versionCode : 1; // (B0) => 0=A; 1=B
672 uint16_t groupType : 4; // Group Type code.
673 } group2;
674 struct
675 {
676 uint16_t content : 4; // Depends on Group Type and Version codes.
677 uint16_t textABFlag : 1; // Do something if it chanhes from binary "0" to binary "1" or vice-versa
678 uint16_t programType : 5; // PTY (Program Type) code
679 uint16_t trafficProgramCode : 1; // (TP) => 0 = No Traffic Alerts; 1 = Station gives Traffic Alerts
680 uint16_t versionCode : 1; // (B0) => 0=A; 1=B
681 uint16_t groupType : 4; // Group Type code.
682 } refined;
684} bk_rds_blockb;
685
686/**
687 * @ingroup GA01
688 * Group RDS type 4A ( RDS Date and Time)
689 * When group type 4A is used by the station, it shall be transmitted every minute according to EN 50067.
690 * This Structure uses blocks 2,3 and 5 (B,C,D)
691 *
692 * ATTENTION:
693 * To make it compatible with 8, 16 and 32 bits platforms and avoid Crosses boundary, it was necessary to
694 * split minute and hour representation.
695 */
696typedef union
697{
698 struct
699 {
700 uint32_t offset : 5; // Local Time Offset
701 uint32_t offset_sense : 1; // Local Offset Sign ( 0 = + , 1 = - )
702 uint32_t minute : 6; // UTC Minutes - 2 bits less significant (void “Crosses boundary”).
703 uint32_t hour : 5; // UTC Hours - 4 bits less significant (void “Crosses boundary”)
704 uint32_t mjd : 17; // Modified Julian Day Code
705 } refined;
707} bk_rds_date_time;
708
709/**
710 * @ingroup GA01
711 * @brief Converts 16 bits word to two bytes
712 */
713typedef union
714{
715 struct
716 {
717 uint8_t lowByte;
718 uint8_t highByte;
719 } refined;
721} word16_to_bytes;
722
723
724
725/**
726 * @ingroup GA01
727 * @brief KT0915 Class
728 * @details This class implements all functions that will help you to control the KT0915 devices.
729 *
730 * @author PU2CLR - Ricardo Lima Caratti
731 */
733{
734
735private:
736
737 // uint8_t i2cBuffer[32];
738
739 uint16_t shadowRegisters[32]; //!< shadow registers 0x00 to 0x1F (0 - 31)
740
741 // Device registers map - References to the shadow registers
742 bk_reg00 *reg00 = (bk_reg00 *)&shadowRegisters[REG00]; // 0
743 bk_reg01 *reg01 = (bk_reg01 *)&shadowRegisters[REG01]; // 1
744 bk_reg02 *reg02 = (bk_reg02 *)&shadowRegisters[REG02]; // 2
745 bk_reg03 *reg03 = (bk_reg03 *)&shadowRegisters[REG03]; // 3
746 bk_reg04 *reg04 = (bk_reg04 *)&shadowRegisters[REG04]; // 4
747 bk_reg05 *reg05 = (bk_reg05 *)&shadowRegisters[REG05]; // 5
748 bk_reg06 *reg06 = (bk_reg06 *)&shadowRegisters[REG06]; // 6
749 bk_reg07 *reg07 = (bk_reg07 *)&shadowRegisters[REG07]; // 7
750 bk_reg08 *reg08 = (bk_reg08 *)&shadowRegisters[REG08]; // 8
751 bk_reg09 *reg09 = (bk_reg09 *)&shadowRegisters[REG09]; // 9
752 bk_reg0a *reg0a = (bk_reg0a *)&shadowRegisters[REG0A]; // 10
753 bk_reg0b *reg0b = (bk_reg0b *)&shadowRegisters[REG0B]; // 11
754 bk_reg0c *reg0c = (bk_reg0c *)&shadowRegisters[REG0C]; // 12
755 bk_reg0d *reg0d = (bk_reg0d *)&shadowRegisters[REG0D]; // 13
756 bk_reg0e *reg0e = (bk_reg0e *)&shadowRegisters[REG0E]; // 14
757 bk_reg0f *reg0f = (bk_reg0f *)&shadowRegisters[REG0F]; // 15
758 bk_reg10 *reg10 = (bk_reg10 *)&shadowRegisters[REG10]; // 16
759 bk_reg11 *reg11 = (bk_reg11 *)&shadowRegisters[REG11]; // 17
760 bk_reg12 *reg12 = (bk_reg12 *)&shadowRegisters[REG12]; // 18
761 bk_reg13 *reg13 = (bk_reg13 *)&shadowRegisters[REG13]; // 19
762 bk_reg14 *reg14 = (bk_reg14 *)&shadowRegisters[REG14]; // 20
763 bk_reg15 *reg15 = (bk_reg15 *)&shadowRegisters[REG15]; // 21
764 bk_reg16 *reg16 = (bk_reg16 *)&shadowRegisters[REG16]; // 22
765 bk_reg17 *reg17 = (bk_reg17 *)&shadowRegisters[REG17]; // 23
766 bk_reg18 *reg18 = (bk_reg18 *)&shadowRegisters[REG18]; // 24
767 bk_reg19 *reg19 = (bk_reg19 *)&shadowRegisters[REG19]; // 25
768 bk_reg1A *reg1A = (bk_reg1A *)&shadowRegisters[REG1A]; // 26
769 bk_reg1B *reg1b = (bk_reg1B *)&shadowRegisters[REG1B]; // 27
770 bk_reg1C *reg1c = (bk_reg1C *)&shadowRegisters[REG1C]; // 28
771 bk_reg1D *reg1d = (bk_reg1D *)&shadowRegisters[REG1D]; // 29
772 bk_reg1E *reg1e = (bk_reg1E *)&shadowRegisters[REG1E]; // 30
773 bk_reg1F *reg1f = (bk_reg1F *)&shadowRegisters[REG1F]; // 31
774
775 uint16_t fmStartBand[4] = {6400, 7400, 7600, 8700}; //!< Start FM band limit
776 uint16_t fmEndBand[4] = {10800, 7600, 9100, 10800}; //!< End FM band limit
777 uint16_t fmSpace[4] = {1, 5, 10, 20}; //!< FM channel space
778
779 uint16_t amStartBand[4] = {153, 520, 2300, 522}; //!< Start FM band limit
780 uint16_t amEndBand[4] = {279, 1710, 21850, 1710}; //!< End FM band limit
781 uint16_t amSpace[4] = {1, 5, 9, 10}; //!< AM channel space
782
783 char strFrequency[9];
784
785 int pin_sdio, pin_sclk;
786
787protected:
788 char rds_buffer2A[65]; //!< RDS Radio Text buffer - Program Information
789 char rds_buffer2B[33]; //!< RDS Radio Text buffer - Station Informaation
790 char rds_buffer0A[9]; //!< RDS Basic tuning and switching information (Type 0 groups)
791 char rds_time[20]; //!< RDS date time received information
792
794
796
800
808
814
816
817
818public:
819 void setI2C(uint8_t i2c_addr = I2C_DEVICE_ADDR);
820 void i2cInit(int pin_sdio, int pin_sclk);
821 void i2cBeginTransaction();
822 void i2cEndTransaction();
823 void i2cAck();
824 void i2cNack();
826 void i2cWriteByte(uint8_t data);
828 void writeRegister(uint8_t reg,uint16_t vakue);
830
831 void reset();
832 void powerUp();
833 void powerDown();
834 void waitAndFinishTune();
835
836
837
838 /**
839 * @ingroup GA03
840 * @brief Sets the I2C bus address
841 * @details This function must to be called before setup function if your device are not using 0x10 (default)
842 * @param bus_addr I2C buss address
843 */
844 inline void setI2CAddress(int bus_addr) { this->deviceAddress = bus_addr; };
845
846 /**
847 * @ingroup GA03
848 * @brief Set the Delay After Crystal On (default 500ms)
849 *
850 * @param ms_value Value in milliseconds
851 */
852 inline void setDelayAfterCrystalOn(uint8_t ms_value) { maxDelayAfterCrystalOn = ms_value; };
853
855 void setRegister(uint8_t reg, uint16_t value);
856 bk_reg0a getStatus();
857
858 /**
859 * @ingroup GA03
860 * @brief Get the Shadown Register object
861 * @details if you want to get the current value of the device register, call getAllRegisters() before calling this function.
862 * @details if you are dealing with the status register (0x0A), you can call getStatus() instead getAllRegisters().
863 * @see setAllRegisters, getAllRegisters, getShadownRegister, getStatus
864 * @param register_number
865 * @return 16 bits word with the Shadown registert
866 */
867 inline uint16_t getShadownRegister(uint8_t register_number) { return shadowRegisters[register_number]; };
868
869 /**
870 * @ingroup GA03
871 * @brief Sets a given value to the Shadown Register
872 * @details You have to call setAllRegisters() after setting the Shadow Registers to store the value into the device.
873 * @see setAllRegisters, getAllRegisters, getShadownRegister, getStatus
874 * @param register_number register index (from 0x00 to 0x0F)
875 * @param value 16 bits word with the content of the register
876 */
877 void setShadownRegister(uint8_t register_number, uint16_t value)
878 {
879 if (register_number > 0x0F)
880 return;
881 shadowRegisters[register_number] = value;
882 };
883
886
887 void setup(int sda_pin, int sclk_pin, uint8_t oscillator_type = OSCILLATOR_TYPE_CRYSTAL, uint32_t oscillator_frequency = 32768);
888 // void setup(int sda_pin, int sclk_pin, int rdsInterruptPin = -1, int seekInterruptPin = -1, uint8_t oscillator_type = OSCILLATOR_TYPE_CRYSTAL, uint16_t maxDelayAfterCrystalOn = MAX_DELAY_AFTER_OSCILLATOR);
889
890 void setFM(uint16_t minimum_frequency, uint16_t maximum_frequency, uint16_t default_frequency, uint16_t step);
891 void setAM(uint16_t minimum_frequency, uint16_t maximum_frequency, uint16_t default_frequency, uint16_t step, uint16_t am_space = 0);
892
893 /**
894 * @ingroup GA03
895 * @brief set the FM gain.
896 * @param if 0, +18db. If 7, - 18db
897 *
898 * @param value
899 */
900 void inline setFMGain(uint8_t value = 0) {
901 reg07->refined.FMGAIN = value;
902 setRegister(REG07,reg07->raw);
903 }
904
905 /**
906 * @ingroup GA03
907 * @brief Get the Current Mode (AM or FM)
908 *
909 * @return uint8_t 0 = FM; 1 = AM
910 */
911 inline uint8_t getCurrentMode() { return this->currentMode; };
912
913 /**
914 * @ingroup GA03
915 * @brief Sets the Stereo Threshold of Pilotto Strength
916 *
917 * @param value 0 ~ 7
918 */
919 inline void setStereoThresholdPilotStrength(uint8_t value) {
920 reg04->refined.PILOTS = value;
921 setRegister(REG04,reg04->raw);
922 }
923
924 /**
925 * @ingroup GA03
926 * @brief Sets De-emphasis.
927 * @details 75 μs. Used in USA (default); 50 μs. Used in Europe, Australia, Japan.
928 *
929 * @param de 0 = 75 μs; 1 = 50 μs
930 */
931 inline void setFmDeemphasis(uint8_t de)
932 {
933 reg04->refined.DE = de;
934 setRegister(REG04, reg04->raw);
935 }
936
937 /**
938 * @ingroup GA03
939 * @brief Sets the time used to call the strength of pilot
940 *
941 * @param value 0 ~ 3
942 */
943 inline void setTimeCallStrengthPilot(uint8_t value)
944 {
945 reg04->refined.TCPILOT = value;
946 setRegister(REG04, reg04->raw);
947 }
948
949 /**
950 * @brief Sets the Gpio2
951 * @details the General Purpose I/O 2. You can use this pin according to the table below.
952 *
953 * | value | description |
954 * | ----- | ----------- |
955 * | 0 | Low |
956 * | 1 | STC/RDS interrupt |
957 * | 2 | Low |
958 * | 3 | High |
959 *
960 * @param value See table above
961 */
962 inline void setGpio2( uint8_t value) {
963 reg04->refined.GPIO2 = value;
964 setRegister(REG04,reg04->raw);
965 }
966
967 /**
968 * @brief Sets the Gpio3
969 * @details the General Purpose I/O 3. You can use this pin according to the table below.
970 *
971 * | value | description |
972 * | ----- | ----------- |
973 * | 0 | Low |
974 * | 1 | Mono/Stereo Indicator |
975 * | 2 | Low |
976 * | 3 | High |
977 *
978 * @param value See table above
979 */
980 inline void setGpio3(uint8_t value)
981 {
982 reg04->refined.GPIO3 = value;
983 setRegister(REG04, reg04->raw);
984 }
985
986 /**
987 * @brief Enables or Disables AFC
988 *
989 * @param value if True, it enables AFC
990 */
991 inline void setAfc(bool value)
992 {
993 reg08->refined.AFCEN = value;
994 setRegister(REG08, reg08->raw);
995 }
996
997 /**
998 * @brief Sets AFC/RSSI/SNR Calculate Rate
999 * @details 00 = fastest; 11 = slowest. 4X times each
1000 * @param value 0˜3
1001 */
1002 inline void setAfcRssiSnrCalculateRate(uint8_t value)
1003 {
1004 reg08->refined.TCSEL = value;
1005 setRegister(REG08, reg08->raw);
1006 }
1007
1008 /**
1009 * @brief Sets AFCRL Threshold
1010 * @details 0 = Channel space/2; 1 = 25kHz
1011 * @param value 0=Channel space/2; 1 = 25kHz
1012 */
1013 inline void setAfcThreshold(uint8_t value)
1014 {
1015 reg08->refined.SEL25K = value;
1016 setRegister(REG08, reg08->raw);
1017 }
1018
1019 /**
1020 * @brief Sets AFC Average
1021 * @details 0 = Use the instant AFC value; 1 = Use the average AFC value
1022 * @param value 0 or 1
1023 */
1024 inline void setAfcAve(uint8_t value)
1025 {
1026 reg08->refined.AVE = value;
1027 setRegister(REG08, reg08->raw);
1028 }
1029
1030 /**
1031 * @brief Sets Variation Threshold for average AFC calculation
1032 * @details 0 = Disable; 1 = the most strict; 2= ?; 3 = the loosest
1033 * @param value 0, 1, 2 or 3
1034 */
1035 inline void setAfcVar(uint8_t value)
1036 {
1037 reg08->refined.VAR = value;
1038 setRegister(REG08, reg08->raw);
1039 }
1040
1041 /**
1042 * @brief Sets AFC range
1043 * @details 0 = he most strict; 3 = the loosest
1044 * @param value 0,1,2 or 3
1045 */
1046 inline void setAfcRange(uint8_t value)
1047 {
1048 reg08->refined.RANGE = value;
1049 setRegister(REG08, reg08->raw);
1050 }
1051
1052 /**
1053 * @brief Sets RSSI Threshold for Instant AFC updating
1054 * @details default value is 16 (0x10)
1055 * @param value
1056 */
1057 inline void setAfcRssiThreshold(uint8_t value)
1058 {
1059 reg08->refined.AFCRSSIT = value;
1060 setRegister(REG08, reg08->raw);
1061 }
1062
1063
1064
1065 void setFrequency(uint16_t frequency);
1066 void setFrequencyUp();
1067 void setFrequencyDown();
1072 void setChannel(uint16_t channel);
1073 void seekHardware(uint8_t seek_mode, uint8_t direction, void (*showFunc)() = NULL);
1074 void seekSoftware(uint8_t seek_mode, uint8_t direction, void (*showFunc)() = NULL);
1075 // Alias to seekSoftware.
1076 inline void seek(uint8_t seek_mode, uint8_t direction, void (*showFunc)() = NULL)
1077 {
1078 this->seekHardware(seek_mode, direction, showFunc );
1079 };
1080 void setSeekThreshold(uint8_t rssiValue, uint8_t snrValue);
1081
1082 void setBand(uint8_t band = 1);
1083 void setSpace(uint8_t space = 0);
1084 int getRssi();
1085 int getSnr();
1086
1087 void setSoftMute(bool value);
1088 void setSoftMuteAttack(uint8_t value);
1089 void setSoftMuteAttenuation(uint8_t value);
1090 void setMuteThreshold(uint8_t rssi, uint8_t snr);
1091 void setSeekMute(bool value);
1092 void setAfcMute(bool value);
1093
1094 void setMono(bool value);
1095
1096 bool isStereo();
1097
1098 void setAudioMute(bool left, bool right);
1099 void setAudioMute(bool value);
1100 void setVolume(uint8_t value);
1102 void setVolumeUp();
1103 void setVolumeDown();
1104
1105 void getRdsStatus();
1106 void setRdsMode(uint8_t rds_mode = 0);
1107 void setRds(bool value, bool interrupt_enable = false);
1108 inline void setRDS(bool value, bool interrupt_enable = false ) { setRds(value, interrupt_enable); };
1109 bool getRdsReady();
1110
1111 uint8_t getRdsFlagAB(void);
1115 void getNext2Block(char *c);
1116 void getNext4Block(char *c);
1117 char *getRdsText(void);
1118 char *getRdsText0A(void);
1119 char *getRdsText2A(void);
1120 char *getRdsText2B(void);
1121 bool getRdsAllData(char **stationName, char **stationInformation, char **programInformation, char **utcTime);
1122 char *getRdsTime();
1123 char *getRdsLocalTime();
1124 bool getRdsSync();
1125
1126 /**
1127 * @ingroup @ingroup GA04
1128 * @brief Gets the Program Information (RT - Radio Text)
1129 * @details Process the program information data. Same getRdsText2A(). It is a alias for getRdsText2A.
1130 * @details ATTENTION: You must call getRdsReady before calling this function.
1131 * @return char array with the program information (63 bytes)
1132 * @see getRdsText2A
1133 */
1134 inline char *getRdsProgramInformation(void) { return getRdsText2A(); };
1135
1136 /**
1137 * @ingroup GA04
1138 * @brief Gets the Station Information.
1139 * @details ATTENTION: You must call getRdsReady before calling this function.
1140 * @return char array with the Text of Station Information (33 bytes)
1141 * @see getRdsReady
1142 */
1143 inline char *getRdsStationInformation(void) { return getRdsText2B(); };
1144
1145 /**
1146 * @ingroup GA04
1147 * @brief Gets the Station Name
1148 * @details Alias for getRdsText0A
1149 * @details ATTENTION: You must call getRdsReady before calling this function.
1150 * @return char* should return a string with the station name. However, some stations send other kind of messages
1151 * @see getRdsText0A
1152 */
1153 inline char *getRdsStationName(void) { return getRdsText0A(); };
1154
1155
1156 void clearRdsBuffer();
1157
1158 int checkI2C(uint8_t *addressArray);
1159 void convertToChar(uint16_t value, char *strValue, uint8_t len, uint8_t dot, uint8_t separator, bool remove_leading_zeros = true);
1161
1162 /**
1163 * @ingroup GA05 Format the Frequency
1164 * @brief Convert a numeric frequency to a formated string (char *) frequency
1165 *
1166 * @param uint16_t value - A given frequency to be formated
1167 * @param char *strValue - Formated frequency (Exe: 103,90) - Array of char ( minimal 7 elements )
1168 * @param char decimalSeparator - the symbol that separates the decimal part (Exe: . or ,)
1169 * @return point of strValue
1170 */
1171 inline char *formatFrequency(uint16_t value, char *strValue, char decimalSeparator = ',', uint8_t decimalPosition = 3)
1172 {
1173 this->convertToChar(value, strValue, 5, decimalPosition, decimalSeparator, true);
1174 return strValue;
1175 };
1176 /**
1177 * @ingroup GA05 Format the Frequency
1178 * @brief Convert the current frequency to a formated string (char *) frequency
1179 * @details The current frequency is the latest setted frequency by setFrequency, seek, setFrequencyUp and setFrequencyDown.
1180 * @param char decimalSeparator - the symbol that separates the decimal part (Exe: . or ,)
1181 * @return point char string strFrequency (member variable)
1182 * @see setFrequency, seek, setFrequencyUp and setFrequencyDown
1183 */
1184 inline char *formatCurrentFrequency(char decimalSeparator = ',', uint8_t decimalPosition = 3)
1185 {
1186 this->convertToChar(this->currentFrequency, this->strFrequency, 5, decimalPosition, decimalSeparator, true);
1187 return this->strFrequency;
1188 };
1189
1190};
#define REG12
Definition: BK108X.h:72
#define REG02
Definition: BK108X.h:56
#define REG0C
Definition: BK108X.h:66
uint16_t bk_reg1E
The user does not have access to registsres 0x1E, 0x1F and 0x20.
Definition: BK108X.h:631
#define REG0E
Definition: BK108X.h:68
#define REG07
Definition: BK108X.h:61
#define REG13
Definition: BK108X.h:73
#define REG17
Definition: BK108X.h:77
#define BK_MODE_AM
Definition: BK108X.h:48
#define REG15
Definition: BK108X.h:75
#define REG0D
Definition: BK108X.h:67
#define REG09
Definition: BK108X.h:63
#define REG10
Definition: BK108X.h:70
#define REG19
Definition: BK108X.h:79
#define REG0A
Definition: BK108X.h:64
#define REG1A
Definition: BK108X.h:80
#define REG1C
Definition: BK108X.h:82
#define REG1F
Definition: BK108X.h:85
#define REG00
Definition: BK108X.h:54
#define REG0B
Definition: BK108X.h:65
#define REG16
Definition: BK108X.h:76
#define REG05
Definition: BK108X.h:59
#define REG04
Definition: BK108X.h:58
#define REG1B
Definition: BK108X.h:81
#define REG1D
Definition: BK108X.h:83
#define REG0F
Definition: BK108X.h:69
#define REG11
Definition: BK108X.h:71
#define REG08
Definition: BK108X.h:62
uint16_t bk_reg20
Definition: BK108X.h:633
uint16_t bk_reg1F
Definition: BK108X.h:632
#define REG03
Definition: BK108X.h:57
#define REG06
Definition: BK108X.h:60
#define REG18
Definition: BK108X.h:78
#define MAX_SEEK_TIME
Definition: BK108X.h:25
#define OSCILLATOR_TYPE_CRYSTAL
Definition: BK108X.h:27
#define REG14
Definition: BK108X.h:74
#define I2C_DEVICE_ADDR
Definition: BK108X.h:23
#define BK_MODE_FM
Definition: BK108X.h:47
#define REG1E
Definition: BK108X.h:84
#define MAX_DELAY_AFTER_OSCILLATOR
Definition: BK108X.h:21
#define REG01
Definition: BK108X.h:55
uint16_t raw
Definition: BK108X.h:597
uint8_t currentAMBand
Definition: BK108X.h:804
void setAfcAve(uint8_t value)
Sets AFC Average.
Definition: BK108X.h:1024
uint16_t raw
Definition: BK108X.h:344
uint16_t raw
Definition: BK108X.h:456
uint16_t getChipId()
Returns the Chip Indentifiction.
Definition: BK108X.cpp:317
uint16_t raw
Definition: BK108X.h:556
uint32_t maximumFrequency
Definition: BK108X.h:799
uint16_t raw
Definition: BK108X.h:500
uint16_t raw
//!< Reference clock divider control , FREQ_SEL[17:0] = HEX | Ref Frequency/512+0....
Definition: BK108X.h:623
uint8_t currentFMBand
Definition: BK108X.h:803
uint8_t currentFMSpace
Definition: BK108X.h:805
uint16_t raw
Definition: BK108X.h:383
uint16_t raw
Definition: BK108X.h:585
uint16_t raw
Definition: BK108X.h:514
char rds_buffer2A[65]
RDS Radio Text buffer - Program Information.
Definition: BK108X.h:788
uint16_t raw
Definition: BK108X.h:470
uint16_t blockB
Definition: BK108X.h:683
int oscillatorType
Definition: BK108X.h:812
void setAfcRange(uint8_t value)
Sets AFC range.
Definition: BK108X.h:1046
char rds_buffer2B[33]
RDS Radio Text buffer - Station Informaation.
Definition: BK108X.h:789
void setAfcRssiThreshold(uint8_t value)
Sets RSSI Threshold for Instant AFC updating.
Definition: BK108X.h:1057
void setAfc(bool value)
Enables or Disables AFC.
Definition: BK108X.h:991
uint16_t raw
Definition: BK108X.h:358
uint16_t deviceId
Definition: BK108X.h:110
uint16_t getDeviceId()
Returns the Device Indentifiction.
Definition: BK108X.cpp:307
uint16_t raw
Definition: BK108X.h:442
uint8_t currentVolume
Definition: BK108X.h:809
int seekInterruptPin
Definition: BK108X.h:811
void setGpio2(uint8_t value)
Sets the Gpio2.
Definition: BK108X.h:962
void setGpio3(uint8_t value)
Sets the Gpio3.
Definition: BK108X.h:980
uint8_t raw[6]
Definition: BK108X.h:706
uint16_t chipId
Definition: BK108X.h:125
uint16_t raw
Definition: BK108X.h:150
void setAfcVar(uint8_t value)
Sets Variation Threshold for average AFC calculation.
Definition: BK108X.h:1035
uint16_t maxDelayAfterCrystalOn
Definition: BK108X.h:815
uint8_t rds_mode
Definition: BK108X.h:793
void setAfcThreshold(uint8_t value)
Sets AFCRL Threshold.
Definition: BK108X.h:1013
char rds_buffer0A[9]
RDS Basic tuning and switching information (Type 0 groups)
Definition: BK108X.h:790
uint16_t raw
Definition: BK108X.h:227
int deviceAddress
Definition: BK108X.h:795
void setAfcRssiSnrCalculateRate(uint8_t value)
Sets AFC/RSSI/SNR Calculate Rate.
Definition: BK108X.h:1002
char rds_time[20]
RDS date time received information.
Definition: BK108X.h:791
uint16_t raw
Definition: BK108X.h:324
uint32_t currentFrequency
Definition: BK108X.h:797
int rdsInterruptPin
Definition: BK108X.h:810
uint16_t raw
Definition: BK108X.h:428
uint8_t currentMode
Definition: BK108X.h:807
uint8_t currentAMSpace
Definition: BK108X.h:806
uint16_t raw
Definition: BK108X.h:542
uint16_t raw
Definition: BK108X.h:720
uint16_t raw
Definition: BK108X.h:611
uint16_t raw
Definition: BK108X.h:484
uint16_t raw
Definition: BK108X.h:570
uint16_t raw
Definition: BK108X.h:191
uint32_t minimumFrequency
Definition: BK108X.h:798
uint32_t oscillatorFrequency
Definition: BK108X.h:813
uint16_t currentChannel
Definition: BK108X.h:801
uint16_t raw
Definition: BK108X.h:528
uint16_t raw
Definition: BK108X.h:310
uint16_t raw
Definition: BK108X.h:265
uint16_t raw
Definition: BK108X.h:413
void setRDS(bool value, bool interrupt_enable=false)
Definition: BK108X.h:1108
void seek(uint8_t seek_mode, uint8_t direction, void(*showFunc)()=NULL)
Definition: BK108X.h:1076
uint16_t raw
Definition: BK108X.h:288
uint16_t currentStep
Definition: BK108X.h:802
uint16_t raw
Definition: BK108X.h:166
uint16_t raw
Definition: BK108X.h:398
KT0915 Class.
Definition: BK108X.h:733
uint8_t i2cReceiveAck()
Gets Acknowledge (ACK)
Definition: BK108X.cpp:139
uint8_t i2cReadByte()
Gets a Byte from the slave device.
Definition: BK108X.cpp:184
uint16_t readRegister(uint8_t reg)
Gets an array of values from a BK108X given register.
Definition: BK108X.cpp:240
void i2cBeginTransaction()
Starts the I2C bus transaction.
Definition: BK108X.cpp:66
void i2cEndTransaction()
Finish the I2C bus transaction.
Definition: BK108X.cpp:85
void i2cWriteByte(uint8_t data)
Sends a Byte to the slave device.
Definition: BK108X.cpp:161
void writeRegister(uint8_t reg, uint16_t vakue)
Sends an array of values to a BK108X given register.
Definition: BK108X.cpp:211
void i2cNack()
Sends Not Acknowledge (ACK)
Definition: BK108X.cpp:121
void setI2C(uint8_t i2c_addr=I2C_DEVICE_ADDR)
Sets I2C bus address.
Definition: BK108X.cpp:43
void i2cAck()
Sends Acknowledge (ACK)
Definition: BK108X.cpp:105
void i2cInit(int pin_sdio, int pin_sclk)
Sets the MCU pins connected to the I2C bus.
Definition: BK108X.cpp:56
void reset()
Resets the device.
Definition: BK108X.cpp:371
uint16_t getChannel()
Gets the current channel.
Definition: BK108X.cpp:638
void setShadownRegister(uint8_t register_number, uint16_t value)
Sets a given value to the Shadown Register.
Definition: BK108X.h:877
void seekHardware(uint8_t seek_mode, uint8_t direction, void(*showFunc)()=NULL)
Seeks a station via hardware functionality.
Definition: BK108X.cpp:746
void setSpace(uint8_t space=0)
Sets the Space channel for AM or FM.
Definition: BK108X.cpp:842
void seekSoftware(uint8_t seek_mode, uint8_t direction, void(*showFunc)()=NULL)
Seeks a station via Software.
Definition: BK108X.cpp:708
uint16_t getRealChannel()
Gets the current channel stored in register 0x0B.
Definition: BK108X.cpp:649
void waitAndFinishTune()
Wait STC (Seek/Tune Complete) status becomes 0.
Definition: BK108X.cpp:354
void setSoftMuteAttack(uint8_t value)
Sets Softmute Attack/Recover Rate.
Definition: BK108X.cpp:904
void setSeekThreshold(uint8_t rssiValue, uint8_t snrValue)
Sets RSSI and SNR Seek Threshold.
Definition: BK108X.cpp:792
void setAM(uint16_t minimum_frequency, uint16_t maximum_frequency, uint16_t default_frequency, uint16_t step, uint16_t am_space=0)
Sets the receiver to AM mode.
Definition: BK108X.cpp:526
int getSnr()
Gets the current SNR.
Definition: BK108X.cpp:871
void setDelayAfterCrystalOn(uint8_t ms_value)
Set the Delay After Crystal On (default 500ms)
Definition: BK108X.h:852
void setAudioMute(bool left, bool right)
Sets the Mute true or false.
Definition: BK108X.cpp:975
void setI2CAddress(int bus_addr)
Sets the I2C bus address.
Definition: BK108X.h:844
void setFrequency(uint16_t frequency)
Sets the FM frequency.
Definition: BK108X.cpp:577
void setBand(uint8_t band=1)
Sets the current band for AM or FM.
Definition: BK108X.cpp:817
void setFrequencyDown()
Decrements the current frequency.
Definition: BK108X.cpp:613
void setAudioMute(bool value)
Sets the Mute true or false.
Definition: BK108X.cpp:988
void setSoftMute(bool value)
Sets the Softmute true or false.
Definition: BK108X.cpp:883
void setAfcMute(bool value)
Disable or Enable soft mute when AFCRL is high.
Definition: BK108X.cpp:962
bk_reg0a getStatus()
Gets the current status (register 0x0A) content.
Definition: BK108X.cpp:341
uint8_t getCurrentMode()
Get the Current Mode (AM or FM)
Definition: BK108X.h:911
void setStereoThresholdPilotStrength(uint8_t value)
Sets the Stereo Threshold of Pilotto Strength.
Definition: BK108X.h:919
bool isStereo()
Checks stereo / mono status.
Definition: BK108X.cpp:1013
void setVolumeUp()
Increments the audio volume.
Definition: BK108X.cpp:1052
uint16_t getFrequency()
Gets the current frequency.
Definition: BK108X.cpp:628
void setSoftMuteAttenuation(uint8_t value)
Sets Softmute Attenuation.
Definition: BK108X.cpp:923
void powerDown()
Powers the receiver off.
Definition: BK108X.cpp:457
void setChannel(uint16_t channel)
Sets the channel.
Definition: BK108X.cpp:556
void setFM(uint16_t minimum_frequency, uint16_t maximum_frequency, uint16_t default_frequency, uint16_t step)
Sets the receiver to FM mode.
Definition: BK108X.cpp:496
void setVolume(uint8_t value)
Sets the audio volume level.
Definition: BK108X.cpp:1025
uint8_t getVolume()
Gets the current audio volume level.
Definition: BK108X.cpp:1042
uint16_t getShadownRegister(uint8_t register_number)
Get the Shadown Register object.
Definition: BK108X.h:867
void setMono(bool value)
Sets the Mono true or false (stereo)
Definition: BK108X.cpp:999
void setFmDeemphasis(uint8_t de)
Sets De-emphasis.
Definition: BK108X.h:931
void setFrequencyUp()
Increments the current frequency.
Definition: BK108X.cpp:598
uint16_t getRealFrequency()
Gets the frequency based on READCHAN register (0x0B)
Definition: BK108X.cpp:662
void setVolumeDown()
Decrements the audio volume.
Definition: BK108X.cpp:1066
void powerUp()
Powers the receiver on.
Definition: BK108X.cpp:388
void setup(int sda_pin, int sclk_pin, uint8_t oscillator_type=OSCILLATOR_TYPE_CRYSTAL, uint32_t oscillator_frequency=32768)
Starts the device.
Definition: BK108X.cpp:477
void setTimeCallStrengthPilot(uint8_t value)
Sets the time used to call the strength of pilot.
Definition: BK108X.h:943
int getRssi()
Gets the current Rssi.
Definition: BK108X.cpp:859
void setRegister(uint8_t reg, uint16_t value)
Sets a given value to the device registers.
Definition: BK108X.cpp:296
void setFMGain(uint8_t value=0)
set the FM gain.
Definition: BK108X.h:900
void setMuteThreshold(uint8_t rssi, uint8_t snr)
Set the Mute Threshold based on RSSI and SNR.
Definition: BK108X.cpp:937
void setSeekMute(bool value)
Disable or Enable soft mute when seeking.
Definition: BK108X.cpp:950
uint16_t getRegister(uint8_t reg)
Gets a givens current register content of the device.
Definition: BK108X.cpp:276
char * getRdsText0A(void)
Gets the Station Name and other messages.
Definition: BK108X.cpp:1244
bool getRdsReady()
Returns true if RDS Ready.
Definition: BK108X.cpp:1130
char * getRdsStationInformation(void)
Gets the Station Information.
Definition: BK108X.h:1143
char * getRdsText(void)
Gets the RDS Text when the message is of the Group Type 2 version A.
Definition: BK108X.cpp:1230
char * getRdsText2B(void)
Gets the Text processed for the 2B group.
Definition: BK108X.cpp:1300
void getNext4Block(char *c)
Processes data received from group 2A.
Definition: BK108X.cpp:1216
uint8_t getRdsVersionCode(void)
Gets the version code (extracted from the Block B)
Definition: BK108X.cpp:1176
char * getRdsStationName(void)
Gets the Station Name.
Definition: BK108X.h:1153
bool getRdsAllData(char **stationName, char **stationInformation, char **programInformation, char **utcTime)
Gets Station Name, Station Information, Program Information and utcTime.
Definition: BK108X.cpp:1344
char * getRdsTime()
Gets the RDS time and date when the Group type is 4.
Definition: BK108X.cpp:1362
uint16_t getRdsGroupType()
Return the group type - Gets the Group Type (extracted from the Block B)
Definition: BK108X.cpp:1162
uint8_t getRdsFlagAB(void)
Returns the current Text Flag A/B.
Definition: BK108X.cpp:1149
uint8_t getRdsProgramType(void)
Returns the Program Type (extracted from the Block B)
Definition: BK108X.cpp:1190
void getNext2Block(char *c)
Process data received from group 2B.
Definition: BK108X.cpp:1203
char * getRdsText2A(void)
Gets the Text processed for the 2A group.
Definition: BK108X.cpp:1273
char * getRdsProgramInformation(void)
Gets the Program Information (RT - Radio Text)
Definition: BK108X.h:1134
void clearRdsBuffer()
Clear RDS Information (Station Name, Station Information, Program Information and Time)
Definition: BK108X.cpp:1501
bool getRdsSync()
Get the Rds Sync.
Definition: BK108X.cpp:1491
void setRdsMode(uint8_t rds_mode=0)
Sets the Rds Mode Standard or Verbose.
Definition: BK108X.cpp:1097
void getRdsStatus()
Gets the RDS registers information.
Definition: BK108X.cpp:1087
void setRds(bool value, bool interrupt_enable=false)
Sets the RDS operation.
Definition: BK108X.cpp:1111
char * getRdsLocalTime()
Gets the RDS time converted to local time.
Definition: BK108X.cpp:1428
char * formatCurrentFrequency(char decimalSeparator=',', uint8_t decimalPosition=3)
Convert the current frequency to a formated string (char *) frequency.
Definition: BK108X.h:1184
void convertToChar(uint16_t value, char *strValue, uint8_t len, uint8_t dot, uint8_t separator, bool remove_leading_zeros=true)
Converts a number to a char array.
Definition: BK108X.cpp:1571
uint16_t * getRegisterValues()
Returns the point of uint16_t array (size 32)
Definition: BK108X.cpp:1551
char * formatFrequency(uint16_t value, char *strValue, char decimalSeparator=',', uint8_t decimalPosition=3)
Convert a numeric frequency to a formated string (char *) frequency.
Definition: BK108X.h:1171
int checkI2C(uint8_t *addressArray)
Check the I2C bus address.
Definition: BK108X.cpp:1523