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 * @details he Strength Pilot refers to a specific technique used in digital broadcasting systems to provide an indication of the signal strength or quality.
941 * @details It is primarily used in FM (Frequency Modulation) broadcasting.
942 * @param value 0 ~ 3
943 */
944 inline void setTimeCallStrengthPilot(uint8_t value)
945 {
946 reg04->refined.TCPILOT = value;
947 setRegister(REG04, reg04->raw);
948 }
949
950 /**
951 * @ingroup GA03
952 * @brief Sets the Gpio2
953 * @details the General Purpose I/O 2. You can use this pin according to the table below.
954 *
955 * | value | description |
956 * | ----- | ----------- |
957 * | 0 | Low |
958 * | 1 | STC/RDS interrupt |
959 * | 2 | Low |
960 * | 3 | High |
961 *
962 * @param value See table above
963 */
964 inline void setGpio2( uint8_t value) {
965 reg04->refined.GPIO2 = value;
966 setRegister(REG04,reg04->raw);
967 }
968
969 /**
970 * @ingroup GA03
971 * @brief Sets the Gpio3
972 * @details the General Purpose I/O 3. You can use this pin according to the table below.
973 *
974 * | value | description |
975 * | ----- | ----------- |
976 * | 0 | Low |
977 * | 1 | Mono/Stereo Indicator |
978 * | 2 | Low |
979 * | 3 | High |
980 *
981 * @param value See table above
982 */
983 inline void setGpio3(uint8_t value)
984 {
985 reg04->refined.GPIO3 = value;
986 setRegister(REG04, reg04->raw);
987 }
988
989 /**
990 * @ingroup GA03
991 * @brief Enables or Disables AFC
992 * @details In DSP receivers, AFC stands for Automatic Frequency Control.
993 * @details It is a mechanism used to automatically adjust the frequency of the receiver's local oscillator to accurately track and lock onto the desired signal.
994 * @param value if True, it enables AFC
995 */
996 inline void setAfc(bool value)
997 {
998 reg08->refined.AFCEN = value;
999 setRegister(REG08, reg08->raw);
1000 }
1001
1002 /**
1003 * @ingroup GA03
1004 * @brief Sets AFC Rail
1005 * @details In the context of a DSP receiver, AFC (Automatic Frequency Control) rail refers to a control signal or voltage that is used to adjust the frequency of the receiver's local oscillator.
1006 * @details AFC rail helps maintain the receiver's frequency locked onto the desired signal by compensating for any variations or drifts in the received signal's frequency.
1007 * @details It is part of the automatic frequency control mechanism that ensures the receiver stays tuned accurately to the desired station or frequency.
1008 * @param value True or false. If true, it enables AFC Rail
1009 */
1010 inline void AfcRail(bool value) {
1011 reg0a->refined.AFCRL = value;
1012 setRegister(REG0A,reg0a->raw);
1013 }
1014
1015 /**
1016 * @ingroup GA03
1017 * @brief Sets AFC/RSSI/SNR Calculate Rate
1018 * @details 00 = fastest; 11 = slowest. 4X times each
1019 * @param value 0˜3
1020 */
1021 inline void setAfcRssiSnrCalculateRate(uint8_t value)
1022 {
1023 reg08->refined.TCSEL = value;
1024 setRegister(REG08, reg08->raw);
1025 }
1026
1027 /**
1028 * @ingroup GA03
1029 * @brief Sets AFCRL Threshold
1030 * @details 0 = Channel space/2; 1 = 25kHz
1031 * @param value 0=Channel space/2; 1 = 25kHz
1032 */
1033 inline void setAfcThreshold(uint8_t value)
1034 {
1035 reg08->refined.SEL25K = value;
1036 setRegister(REG08, reg08->raw);
1037 }
1038
1039 /**
1040 * @ingroup GA03
1041 * @brief Sets AFC Average
1042 * @details 0 = Use the instant AFC value; 1 = Use the average AFC value
1043 * @details AFC Average refers to the averaging of the Automatic Frequency Control (AFC) signal over a certain period of time.
1044 * @details AFC Average is used to mitigate short-term fluctuations or noise in the received signal's frequency.
1045 * @param value 0 or 1
1046 */
1047 inline void setAfcAve(uint8_t value)
1048 {
1049 reg08->refined.AVE = value;
1050 setRegister(REG08, reg08->raw);
1051 }
1052
1053 /**
1054 * @ingroup GA03
1055 * @brief Sets Variation Threshold for average AFC calculation
1056 * @details 0 = Disable; 1 = the most strict; 2= ?; 3 = the loosest
1057 * @param value 0, 1, 2 or 3
1058 */
1059 inline void setAfcVar(uint8_t value)
1060 {
1061 reg08->refined.VAR = value;
1062 setRegister(REG08, reg08->raw);
1063 }
1064
1065 /**
1066 * @brief Sets AFC range
1067 * @details 0 = he most strict; 3 = the loosest
1068 * @param value 0,1,2 or 3
1069 */
1070 inline void setAfcRange(uint8_t value)
1071 {
1072 reg08->refined.RANGE = value;
1073 setRegister(REG08, reg08->raw);
1074 }
1075
1076 /**
1077 * @ingroup GA03
1078 * @brief Sets RSSI Threshold for Instant AFC updating
1079 * @details default value is 16 (0x10)
1080 * @param value
1081 */
1082 inline void setAfcRssiThreshold(uint8_t value)
1083 {
1084 reg08->refined.AFCRSSIT = value;
1085 setRegister(REG08, reg08->raw);
1086 }
1087
1088
1089
1090 void setFrequency(uint16_t frequency);
1091 void setFrequencyUp();
1092 void setFrequencyDown();
1097 void setChannel(uint16_t channel);
1098 void seekHardware(uint8_t seek_mode, uint8_t direction, void (*showFunc)() = NULL);
1099 void seekSoftware(uint8_t seek_mode, uint8_t direction, void (*showFunc)() = NULL);
1100 // Alias to seekSoftware.
1101 inline void seek(uint8_t seek_mode, uint8_t direction, void (*showFunc)() = NULL)
1102 {
1103 this->seekHardware(seek_mode, direction, showFunc );
1104 };
1105 void setSeekThreshold(uint8_t rssiValue, uint8_t snrValue);
1106
1107 void setBand(uint8_t band = 1);
1108 void setSpace(uint8_t space = 0);
1109 int getRssi();
1110 int getSnr();
1111
1112 void setSoftMute(bool value);
1113 void setSoftMuteAttack(uint8_t value);
1114 void setSoftMuteAttenuation(uint8_t value);
1115 void setMuteThreshold(uint8_t rssi, uint8_t snr);
1116 void setSeekMute(bool value);
1117 void setAfcMute(bool value);
1118
1119 void setMono(bool value);
1120
1121 bool isStereo();
1122
1123 void setAudioMute(bool left, bool right);
1124 void setAudioMute(bool value);
1125 void setVolume(uint8_t value);
1127 void setVolumeUp();
1128 void setVolumeDown();
1129
1130 void setRdsMode(uint8_t rds_mode = 0);
1131 void setRds(bool value, bool interrupt_enable = false);
1132 inline void setRDS(bool value, bool interrupt_enable = false ) { setRds(value, interrupt_enable); };
1133 bool getRdsReady();
1134
1135 uint8_t getRdsFlagAB(void);
1139 void getNext2Block(char *c);
1140 void getNext4Block(char *c);
1141 char *getRdsText(void);
1142 char *getRdsText0A(void);
1143 char *getRdsText2A(void);
1144 char *getRdsText2B(void);
1145 bool getRdsAllData(char **stationName, char **stationInformation, char **programInformation, char **utcTime);
1146 char *getRdsTime();
1147 char *getRdsLocalTime();
1148 bool getRdsSync();
1149
1150 /**
1151 * @ingroup @ingroup GA04
1152 * @brief Gets the Program Information (RT - Radio Text)
1153 * @details Process the program information data. Same getRdsText2A(). It is a alias for getRdsText2A.
1154 * @details ATTENTION: You must call getRdsReady before calling this function.
1155 * @return char array with the program information (63 bytes)
1156 * @see getRdsText2A
1157 */
1158 inline char *getRdsProgramInformation(void) { return getRdsText2A(); };
1159
1160 /**
1161 * @ingroup GA04
1162 * @brief Gets the Station Information.
1163 * @details ATTENTION: You must call getRdsReady before calling this function.
1164 * @return char array with the Text of Station Information (33 bytes)
1165 * @see getRdsReady
1166 */
1167 inline char *getRdsStationInformation(void) { return getRdsText2B(); };
1168
1169 /**
1170 * @ingroup GA04
1171 * @brief Gets the Station Name
1172 * @details Alias for getRdsText0A
1173 * @details ATTENTION: You must call getRdsReady before calling this function.
1174 * @return char* should return a string with the station name. However, some stations send other kind of messages
1175 * @see getRdsText0A
1176 */
1177 inline char *getRdsStationName(void) { return getRdsText0A(); };
1178
1179
1180 void clearRdsBuffer();
1181
1182 int checkI2C(uint8_t *addressArray);
1183 void convertToChar(uint16_t value, char *strValue, uint8_t len, uint8_t dot, uint8_t separator, bool remove_leading_zeros = true);
1185
1186 /**
1187 * @ingroup GA05 Format the Frequency
1188 * @brief Convert a numeric frequency to a formated string (char *) frequency
1189 *
1190 * @param uint16_t value - A given frequency to be formated
1191 * @param char *strValue - Formated frequency (Exe: 103,90) - Array of char ( minimal 7 elements )
1192 * @param char decimalSeparator - the symbol that separates the decimal part (Exe: . or ,)
1193 * @return point of strValue
1194 */
1195 inline char *formatFrequency(uint16_t value, char *strValue, char decimalSeparator = ',', uint8_t decimalPosition = 3)
1196 {
1197 this->convertToChar(value, strValue, 5, decimalPosition, decimalSeparator, true);
1198 return strValue;
1199 };
1200 /**
1201 * @ingroup GA05 Format the Frequency
1202 * @brief Convert the current frequency to a formated string (char *) frequency
1203 * @details The current frequency is the latest setted frequency by setFrequency, seek, setFrequencyUp and setFrequencyDown.
1204 * @param char decimalSeparator - the symbol that separates the decimal part (Exe: . or ,)
1205 * @return point char string strFrequency (member variable)
1206 * @see setFrequency, seek, setFrequencyUp and setFrequencyDown
1207 */
1208 inline char *formatCurrentFrequency(char decimalSeparator = ',', uint8_t decimalPosition = 3)
1209 {
1210 this->convertToChar(this->currentFrequency, this->strFrequency, 5, decimalPosition, decimalSeparator, true);
1211 return this->strFrequency;
1212 };
1213
1214};
#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
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:1070
char rds_buffer2B[33]
RDS Radio Text buffer - Station Informaation.
Definition: BK108X.h:789
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
uint8_t raw[6]
Definition: BK108X.h:706
uint16_t chipId
Definition: BK108X.h:125
uint16_t raw
Definition: BK108X.h:150
uint16_t maxDelayAfterCrystalOn
Definition: BK108X.h:815
uint8_t rds_mode
Definition: BK108X.h:793
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
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:1132
void seek(uint8_t seek_mode, uint8_t direction, void(*showFunc)()=NULL)
Definition: BK108X.h:1101
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 setAfcAve(uint8_t value)
Sets AFC Average.
Definition: BK108X.h:1047
void reset()
Resets the device.
Definition: BK108X.cpp:371
uint16_t getChannel()
Gets the current channel.
Definition: BK108X.cpp:642
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:750
void setSpace(uint8_t space=0)
Sets the Space channel for AM or FM.
Definition: BK108X.cpp:846
void seekSoftware(uint8_t seek_mode, uint8_t direction, void(*showFunc)()=NULL)
Seeks a station via Software.
Definition: BK108X.cpp:712
uint16_t getRealChannel()
Gets the current channel stored in register 0x0B.
Definition: BK108X.cpp:653
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:908
void setSeekThreshold(uint8_t rssiValue, uint8_t snrValue)
Sets RSSI and SNR Seek Threshold.
Definition: BK108X.cpp:796
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:530
int getSnr()
Gets the current SNR.
Definition: BK108X.cpp:875
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:979
void AfcRail(bool value)
Sets AFC Rail.
Definition: BK108X.h:1010
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:581
void setBand(uint8_t band=1)
Sets the current band for AM or FM.
Definition: BK108X.cpp:821
void setAfcRssiThreshold(uint8_t value)
Sets RSSI Threshold for Instant AFC updating.
Definition: BK108X.h:1082
void setAfc(bool value)
Enables or Disables AFC.
Definition: BK108X.h:996
void setFrequencyDown()
Decrements the current frequency.
Definition: BK108X.cpp:617
void setAudioMute(bool value)
Sets the Mute true or false.
Definition: BK108X.cpp:992
void setSoftMute(bool value)
Sets the Softmute true or false.
Definition: BK108X.cpp:887
void setGpio2(uint8_t value)
Sets the Gpio2.
Definition: BK108X.h:964
void setAfcMute(bool value)
Disable or Enable soft mute when AFCRL is high.
Definition: BK108X.cpp:966
void setGpio3(uint8_t value)
Sets the Gpio3.
Definition: BK108X.h:983
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
void setAfcVar(uint8_t value)
Sets Variation Threshold for average AFC calculation.
Definition: BK108X.h:1059
bool isStereo()
Checks stereo / mono status.
Definition: BK108X.cpp:1017
void setAfcThreshold(uint8_t value)
Sets AFCRL Threshold.
Definition: BK108X.h:1033
void setVolumeUp()
Increments the audio volume.
Definition: BK108X.cpp:1056
uint16_t getFrequency()
Gets the current frequency.
Definition: BK108X.cpp:632
void setAfcRssiSnrCalculateRate(uint8_t value)
Sets AFC/RSSI/SNR Calculate Rate.
Definition: BK108X.h:1021
void setSoftMuteAttenuation(uint8_t value)
Sets Softmute Attenuation.
Definition: BK108X.cpp:927
void powerDown()
Powers the receiver off.
Definition: BK108X.cpp:460
void setChannel(uint16_t channel)
Sets the channel.
Definition: BK108X.cpp:560
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:500
void setVolume(uint8_t value)
Sets the audio volume level.
Definition: BK108X.cpp:1029
uint8_t getVolume()
Gets the current audio volume level.
Definition: BK108X.cpp:1046
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:1003
void setFmDeemphasis(uint8_t de)
Sets De-emphasis.
Definition: BK108X.h:931
void setFrequencyUp()
Increments the current frequency.
Definition: BK108X.cpp:602
uint16_t getRealFrequency()
Gets the frequency based on READCHAN register (0x0B)
Definition: BK108X.cpp:666
void setVolumeDown()
Decrements the audio volume.
Definition: BK108X.cpp:1070
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:480
void setTimeCallStrengthPilot(uint8_t value)
Sets the time used to call the strength of pilot.
Definition: BK108X.h:944
int getRssi()
Gets the current Rssi.
Definition: BK108X.cpp:863
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:941
void setSeekMute(bool value)
Disable or Enable soft mute when seeking.
Definition: BK108X.cpp:954
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:1241
bool getRdsReady()
Returns true if RDS Ready.
Definition: BK108X.cpp:1124
char * getRdsStationInformation(void)
Gets the Station Information.
Definition: BK108X.h:1167
char * getRdsText(void)
Gets the RDS Text when the message is of the Group Type 2 version A.
Definition: BK108X.cpp:1227
char * getRdsText2B(void)
Gets the Text processed for the 2B group.
Definition: BK108X.cpp:1296
void getNext4Block(char *c)
Processes data received from group 2A.
Definition: BK108X.cpp:1213
uint8_t getRdsVersionCode(void)
Gets the version code (extracted from the Block B)
Definition: BK108X.cpp:1170
char * getRdsStationName(void)
Gets the Station Name.
Definition: BK108X.h:1177
bool getRdsAllData(char **stationName, char **stationInformation, char **programInformation, char **utcTime)
Gets Station Name, Station Information, Program Information and utcTime.
Definition: BK108X.cpp:1340
char * getRdsTime()
Gets the RDS time and date when the Group type is 4.
Definition: BK108X.cpp:1358
uint16_t getRdsGroupType()
Return the group type - Gets the Group Type (extracted from the Block B)
Definition: BK108X.cpp:1156
uint8_t getRdsFlagAB(void)
Returns the current Text Flag A/B.
Definition: BK108X.cpp:1143
uint8_t getRdsProgramType(void)
Returns the Program Type (extracted from the Block B)
Definition: BK108X.cpp:1184
void getNext2Block(char *c)
Process data received from group 2B - Station Name.
Definition: BK108X.cpp:1200
char * getRdsText2A(void)
Gets the Text processed for the 2A group.
Definition: BK108X.cpp:1269
char * getRdsProgramInformation(void)
Gets the Program Information (RT - Radio Text)
Definition: BK108X.h:1158
void clearRdsBuffer()
Clear RDS Information (Station Name, Station Information, Program Information and Time)
Definition: BK108X.cpp:1497
bool getRdsSync()
Get the Rds Sync.
Definition: BK108X.cpp:1487
void setRdsMode(uint8_t rds_mode=0)
Sets the Rds Mode Standard or Verbose.
Definition: BK108X.cpp:1091
void setRds(bool value, bool interrupt_enable=false)
Sets the RDS operation.
Definition: BK108X.cpp:1105
char * getRdsLocalTime()
Gets the RDS time converted to local time.
Definition: BK108X.cpp:1424
char * formatCurrentFrequency(char decimalSeparator=',', uint8_t decimalPosition=3)
Convert the current frequency to a formated string (char *) frequency.
Definition: BK108X.h:1208
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:1567
uint16_t * getRegisterValues()
Returns the point of uint16_t array (size 32)
Definition: BK108X.cpp:1547
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:1195
int checkI2C(uint8_t *addressArray)
Check the I2C bus address.
Definition: BK108X.cpp:1519