PU2CLR BK108X Arduino Library 1.0.2
This is an Arduino Library to control the BK108X device
Loading...
Searching...
No Matches
BK108X.cpp
Go to the documentation of this file.
1/**
2 * @mainpage BK108X Arduino Library implementation
3 * @details BK108X Arduino Library implementation. This is an Arduino library for the BK108X, BROADCAST RECEIVER.
4 * @details This is an Arduino library for the BK1086 and BK1088 DSP BROADCAST RECEIVER.<br>
5 * @details It works with I2C protocol and can provide an easier interface for controlling the BK1086/88 devices.<br>
6 * @details This library is based on the Document: BEKEN - BK1086/88 - BROADCAST AM/FM/SW/LW RADIO RECEIVER Rev 1.3.
7 *
8 * __THIS LIBRARY IS UNDER CONSTRUCTION.....___
9 *
10 * This library can be freely distributed using the MIT Free Software model.
11 * Copyright (c) 2020-2003 Ricardo Lima Caratti.
12 * Contact: pu2clr@gmail.com
13 */
14
15#include <BK108X.h>
16#include <Wire.h> // This library is not used to communicate wwith BK108X family device. It is used to check I2C bus.
17
18
19/**
20 * @defgroup GA02 BEKEN I2C BUS
21 * @section GA02 I2C
22 *
23 * @brief About I2C Address on BK1086/88 and Arduino platform
24 *
25 * The BK1086/88 Datasheet says that the I2C buss address is 0x80. However, the Wire (I2C) Arduino library does not find
26 * the device on 0x80. Actually the Arduino finds the device on 0x40.
27 * This must be due to the internal conversion of the address from 8 bits to 7 bits. (0x80 = 0b10000000; 0x40 = 0b01000000)
28 * After a few unsuccessful attempts at using the Arduino I2C library, I decided to write the necessary I2C routines to deal
29 * with BK1086/88 device.
30 *
31 * @see setI2C, i2cInit, i2cStart, i2cEndTransaction(), i2cAck, i2cNack, i2cReceiveAck, i2cWriteByte, i2cReadByte, writeRegister, readRegister
32 *
33 * IMPORTANT:
34 * For stable communication, the rising edge time of SCLK should be less than 200ns.
35 */
36
37/**
38 * @ingroup GA02
39 * @brief Sets I2C bus address
40 * @details Useful if some release of BEKEN device is different of 0x80.
41 *
42 * @param i2c_addr
43 */
44void BK108X::setI2C(uint8_t i2c_addr) {
45 this->deviceAddress = i2c_addr;
46}
47
48/**
49 * @ingroup GA02
50 * @brief Sets the MCU pins connected to the I2C bus
51 * @details Configures the I2C bus for BK108X
52 *
53 * @param pin_sdio SDA/SDIO MCU/Arduino pin
54 * @param pin_sclk CLK/SCLK MCU/Arduino pin
55 */
56void BK108X::i2cInit(int pin_sdio, int pin_sclk){
57 this->pin_sdio = pin_sdio;
58 this->pin_sclk = pin_sclk;
59}
60
61/**
62 * @ingroup GA02
63 * @brief Starts the I2C bus transaction
64 */
66{
67 pinMode(this->pin_sdio, OUTPUT);
68 pinMode(this->pin_sclk, OUTPUT);
69 digitalWrite(this->pin_sdio, HIGH);
70 digitalWrite(this->pin_sclk, HIGH);
71 delayMicroseconds(1);
72
73 digitalWrite(this->pin_sdio, LOW);
74 delayMicroseconds(1);
75 digitalWrite(this->pin_sclk, LOW);
76 delayMicroseconds(1);
77 digitalWrite(this->pin_sdio, HIGH);
78}
79
80/**
81 * @ingroup GA02
82 * @brief Finish the I2C bus transaction
83 */
85{
86 pinMode(pin_sdio, OUTPUT);
87 digitalWrite(this->pin_sdio, LOW);
88 delayMicroseconds(1);
89
90 digitalWrite(this->pin_sclk, HIGH);
91 delayMicroseconds(1);
92
93 digitalWrite(this->pin_sdio, HIGH);
94 delayMicroseconds(1);
95}
96
97/**
98 * @ingroup GA02
99 * @brief Sends Acknowledge (ACK)
100 * @details Each byte of data (including the address byte) have to be followed by one ACK bit from the receiver.
101 * @details The ACK bit allows the receiver to communicate to the transmitter.
102 * @see https://www.ti.com/lit/an/slva704/slva704.pdf
103 */
105{
106 pinMode(pin_sdio, OUTPUT);
107 digitalWrite(this->pin_sclk, LOW);
108 digitalWrite(this->pin_sdio, LOW);
109 delayMicroseconds(1);
110 digitalWrite(this->pin_sclk, HIGH);
111 delayMicroseconds(1);
112 digitalWrite(this->pin_sclk, LOW);
113}
114
115/**
116 * @ingroup GA02
117 * @brief Sends Not Acknowledge (ACK)
118 * @see https://www.ti.com/lit/an/slva704/slva704.pdf
119 */
121{
122 pinMode(pin_sdio, OUTPUT);
123
124 digitalWrite(this->pin_sclk, LOW);
125 digitalWrite(this->pin_sdio, HIGH);
126 delayMicroseconds(1);
127 digitalWrite(this->pin_sclk, HIGH);
128 delayMicroseconds(1);
129 digitalWrite(this->pin_sclk, LOW);
130}
131
132/**
133 * @ingroup GA02
134 * @brief Gets Acknowledge (ACK)
135 * @see https://www.ti.com/lit/an/slva704/slva704.pdf
136 * @return ack value
137 */
139{
140 uint8_t ack;
141 pinMode(pin_sdio, INPUT);
142 delayMicroseconds(1);
143
144 digitalWrite(this->pin_sclk, HIGH);
145 delayMicroseconds(1);
146
147 ack = digitalRead(this->pin_sdio);
148
149 digitalWrite(this->pin_sclk, LOW);
150 delayMicroseconds(1);
151
152 return ack;
153}
154
155/**
156 * @ingroup GA02
157 * @brief Sends a Byte to the slave device
158 * @param data to be sent to the slave device
159 */
160void BK108X::i2cWriteByte( uint8_t data)
161{
162 pinMode(pin_sdio, OUTPUT);
163 delayMicroseconds(1);
164
165 for (int i = 0; i < 8; i++) {
166
167 digitalWrite(this->pin_sdio, (bool)(data & this->deviceAddress) );
168
169 delayMicroseconds(1);
170 digitalWrite(this->pin_sclk, HIGH);
171 delayMicroseconds(1);
172 digitalWrite(this->pin_sclk, LOW);
173 data = data << 1;
174 }
175}
176
177/**
178 * @ingroup GA02
179 * @brief Gets a Byte from the slave device
180 * @return value read from the device
181 */
183{
184 uint8_t value = 0;
185
186 pinMode(pin_sdio, INPUT);
187 delayMicroseconds(1);
188
189 for (int i = 0; i < 8; i++)
190 {
191 digitalWrite(this->pin_sclk, HIGH);
192 value = value << 1;
193 delayMicroseconds(1);
194 if ( digitalRead(this->pin_sdio) )
195 value = value | 1;
196 digitalWrite(this->pin_sclk, LOW);
197 delayMicroseconds(1);
198 }
199
200 return value;
201}
202
203/**
204 * @ingroup GA02
205 * @brief Sends an array of values to a BK108X given register
206 * @param reg register to be written
207 * @param value content to be stored into the register
208 */
209void BK108X::writeRegister(uint8_t reg, uint16_t value) {
210
211 word16_to_bytes data;
212 data.raw = value;
213
215 this->i2cWriteByte(this->deviceAddress);
216 this->i2cReceiveAck();
217
218 reg = reg << 1; // Converts address and sets to write operation
219
220 this->i2cWriteByte(reg);
221 this->i2cReceiveAck();
222
223 this->i2cWriteByte(data.refined.highByte);
224 this->i2cReceiveAck();
225 this->i2cWriteByte(data.refined.lowByte);
226 this->i2cReceiveAck();
227
229}
230
231/**
232 * @ingroup GA02
233 * @brief Gets an array of values from a BK108X given register
234 * @param reg register to be read
235 * @return register content
236 */
238
239 word16_to_bytes data;
240
242 this->i2cWriteByte(this->deviceAddress);
243 this->i2cReceiveAck();
244
245 reg = (reg << 1) | 1; // Converts address and sets to read operation
246
247 this->i2cWriteByte(reg);
248 this->i2cReceiveAck();
249
250 data.refined.highByte = this->i2cReadByte();
251 this->i2cAck();
252 data.refined.lowByte = this->i2cReadByte();
253 this->i2cNack();
254
256
257 return data.raw;
258}
259
260
261/**
262 * @defgroup GA03 Basic Functions
263 * @section GA03 Basic
264 */
265
266/**
267 * @ingroup GA03
268 * @brief Gets a givens current register content of the device
269 * @see shadowRegisters;
270 * @param device register address
271 * @return the register content (the shadowRegisters array has this content. So, you do not need to use it most of the cases)
272 */
274{
275 uint16_t reg_content;
276 reg_content = this->readRegister(reg);
277 shadowRegisters[reg] = reg_content; // Syncs with the shadowRegisters
278 return reg_content; // Optional
279}
280
281/**
282 * @ingroup GA03
283 * @brief Sets a given value to the device registers
284 * @details For write operations, the device acknowledge is followed by an eight bit data word latched internally on rising edges of SCLK. The device acknowledges each byte of data written by driving SDIO low after the next falling SCLK edge, for 1 cycle.
285 * @details An internal address counter automatically increments to allow continuous data byte writes, starting with the upper byte of register 02h, followed by the lower byte of register 02h, and onward until the lower byte of the last register is reached. The internal address counter then automatically wraps around to the upper byte of register 00h and proceeds from there until continuous writes end.
286 * @details The registers from 0x2 to 0x07 are used to setup the device. This method writes the array shadowRegisters, elements 8 to 14 (corresponding the registers 0x2 to 0x7 respectively) into the device. See Device registers map in BK108X.h file.
287 * @details To implement this, a register maping was created to deal with each register structure. For each type of register, there is a reference to the array element.
288 *
289 * @see shadowRegisters;
290 *
291 * @param device register address
292 */
293void BK108X::setRegister(uint8_t reg, uint16_t value)
294{
295 this->writeRegister(reg, value);
296 shadowRegisters[reg] = value; // Syncs with the shadowRegisters
297 delayMicroseconds(250);
298}
299
300/**
301 * @brief Returns the Device Indentifiction
302 * @return device id
303 */
305{
306 return getRegister(REG00);
307}
308
309/**
310 * @brief Returns the Chip Indentifiction
311 *
312 * @return IC id
313 */
315{
316 return getRegister(REG01);
317}
318
319/**
320 * @ingroup GA03
321 * @brief Gets the current status (register 0x0A) content
322 * @details You can use this function when you need to get more than one status attribute at once.
323 * @details See example code below.
324 * @code
325 * bk_reg0a status = getStatus();
326 *
327 * Serial.println(status.refined.ST); // Stereo Signal Received Indicator
328 * Serial.println(status.refined.RSSI); // Current RSSI value
329 * Serial.println(status.refined.RDSR); // RDS Ready Indicator
330 *
331 * @endcode
332 *
333 * @see getRSSI
334 * @see BK1086/88E - BROADCAST AM/FM/SW/LW RADIO RECEIVER Rev 1.3; page 17.
335 *
336 * @return bk_reg0a data type status register (Register 0Ah. Status2)
337 */
338bk_reg0a BK108X::getStatus()
339{
340 bk_reg0a tmp;
341 tmp.raw = getRegister(REG0A); // update the reg0a shadow register
342 return tmp;
343}
344
345
346/**
347 * @ingroup GA03
348 * @brief Wait STC (Seek/Tune Complete) status becomes 0
349 * @details Should be used before processing Tune or Seek.
350 * @details The STC bit being cleared indicates that the TUNE or SEEK bits may be set again to start another tune or seek operation. Do not set the TUNE or SEEK bits until the BK108X clears the STC bit.
351 */
353{
354 while ( reg0a->refined.STC == 0) {
355 delay(10);
356 getRegister(REG0A);
357 }
358
359 reg03->refined.TUNE = 0;
360 setRegister(REG03, reg03->raw);
361 // delay(40);
362}
363
364/**
365 * @ingroup GA03
366 * @brief Resets the device
367 */
369{
370 reg02->refined.DISABLE = 1;
371 reg02->refined.ENABLE = 0;
372 setRegister(REG02, reg02->raw);
373 reg02->refined.DISABLE = 0;
374 reg02->refined.ENABLE = 1;
375 setRegister(REG02, reg02->raw);
376}
377
378/**
379 * @ingroup GA03
380 * @brief Powers the receiver on
381 * @details Starts the receiver and set default configurations suggested by the BELEN
382 * @see BEKEN - BK1086/88 - BROADCAST AM/FM/SW/LW RADIO RECEIVER Rev 1.3; pages 12-21
383 * @see setup
384 */
386{
387 // Starts the mains register with default values suggested by BEKEN.
388
389 reg02->raw = 0x0280; // Sets to 0 all attributes of the register 0x02 (Power Configuration)
390 reg02->refined.DISABLE = 0; // Force stereo
391 reg02->refined.ENABLE = 1; // Power the receiver UP (DISABLE has to be 0)
392 setRegister(REG02,reg02->raw); // Stores the register 0x02
393
394 setRegister(REG03, 0x0000); // Sets to 0 all attributes of the register 0x03 (Channel)
395
396 setRegister(REG04, 0x60D4); // 0b0110000011010100
397 setRegister(REG05, 0x37CF); // 0b0011011111001111
398
399
400 reg06->raw = 0x086F; // Sets to the default value - 0b0000100001101111 -> CLKSEL = 1
401 reg06->refined.CLKSEL = this->oscillatorType; // Sets to the clock type selected by the user
402 setRegister(REG06, reg06->raw);
403
404 setRegister(REG07, 0x0101); // 0b0000000100000001
405 setRegister(REG08, 0xAC90); // 0b1010110010010000
406
407 setRegister(REG10, 0x7B11); // 0b0111101100010001
408 setRegister(REG11, 0x004A); // 0b0000000001001010
409 setRegister(REG12, 0x4000); // 0b0100000000000000
410 setRegister(REG13, 0x3E00); // 0b0011111000000000
411 setRegister(REG14, 0xC29A); // 0b1100001010011010
412 setRegister(REG15, 0x79F8); // 0b0111100111111000
413 setRegister(REG16, 0x4012); // 0b0100000000010010
414
415 // setRegister(REG17, 0x0040); // 0b0000000001000000
416 setRegister(REG17, 0x0800); // 0b0000100000000000
417 setRegister(REG18, 0x341C); // 0b0011010000011100
418 setRegister(REG19, 0x0080); // 0b0000000010000000
419 setRegister(REG1A, 0x0000); // 0
420 setRegister(REG1B, 0x4CA2); // 0b0100110010100010
421
422 // setRegister(REG1C, 0x8820); // 0b1000100000100000
423 setRegister(REG1C, 0); // 0b1000100000100000
424 setRegister(REG1D, 0x0200); // 0b0000001000000000 -> 512
425
426 delay(250);
427}
428
429/**
430 * @ingroup GA03
431 * @brief Powers the receiver off
432 */
434{
435 reg02->refined.DISABLE = 1;
436 reg02->refined.ENABLE = 0;
437 setRegister(REG02, reg02->raw);
438 delay(100);
439}
440
441/**
442 * @ingroup GA03
443 * @brief Starts the device
444 * @details sets the reset pin, interrupt pins and oscillator type you are using in your project.
445 * @details You have to inform at least two parameters: RESET pin and I2C SDA pin of your MCU
446 * @param rdsInterruptPin // optional. Sets the Interrupt Arduino pin used to RDS function control.
447 * @param seekInterruptPin // optional. Sets the Arduino pin used to Seek function control.
448 * @param oscillator_type // optional. Sets the Oscillator type used Crystal (default) or Ref. Clock.
449 */
450void BK108X::setup(int sda_pin, int sclk_pin, int rdsInterruptPin, int seekInterruptPin, uint8_t oscillator_type)
451{
452 // Configures BEKEN I2C bus
453 this->i2cInit(sda_pin, sclk_pin);
454
455 if (rdsInterruptPin >= 0)
456 this->rdsInterruptPin = rdsInterruptPin;
457 if (seekInterruptPin >= 0)
458 this->seekInterruptPin = seekInterruptPin;
459
460 this->oscillatorType = oscillator_type;
461
462 powerUp();
463
464}
465
466/**
467 * @ingroup GA03
468 * @brief Sets the receiver to FM mode
469 * @details Configures the receiver on FM mode; Also sets the band limits, defaul frequency and step.
470 *
471 * @param minimum_frequency minimum frequency for the band
472 * @param maximum_frequency maximum frequency for the band
473 * @param default_frequency default freuency
474 * @param step increment and decrement frequency step in KHz (default 10 * 10KHz)
475 */
476void BK108X::setFM(uint16_t minimum_frequency, uint16_t maximum_frequency, uint16_t default_frequency, uint16_t step)
477{
478 this->currentStep = step;
479 this->currentFrequency = default_frequency;
480 this->minimumFrequency = minimum_frequency;
481 this->maximumFrequency = maximum_frequency;
482 this->currentMode = BK_MODE_FM;
483
484 reg07->refined.MODE = BK_MODE_FM;
485 setRegister(REG07, reg07->raw);
486 delay(50);
487 // Sets BAND, SPACE and other parameters
488 this->currentFMBand = reg05->refined.BAND = 0;
489 this->currentFMSpace = reg05->refined.SPACE = 2;
490 setRegister(REG05, reg05->raw);
491 setFrequency(default_frequency);
492};
493
494/**
495 * @ingroup GA03
496 * @brief Sets the receiver to AM mode
497 * @details Configures the receiver on AM mode; Also sets the band limits, defaul frequency and step.
498 *
499 * @param minimum_frequency minimum frequency for the band
500 * @param maximum_frequency maximum frequency for the band
501 * @param default_frequency default freuency
502 * @param step increment and decrement frequency step
503 */
504void BK108X::setAM(uint16_t minimum_frequency, uint16_t maximum_frequency, uint16_t default_frequency, uint16_t step, uint16_t am_space)
505{
506 this->currentStep = step;
507 this->currentFrequency = default_frequency;
508 this->minimumFrequency = minimum_frequency;
509 this->maximumFrequency = maximum_frequency;
510
511 this->currentMode = reg07->refined.MODE = BK_MODE_AM;
512 setRegister(REG07, reg07->raw);
513 delay(50);
514 // Sets BAND, SPACE and other parameters
515
516 if (minimum_frequency < 520 )
517 this->currentAMBand = reg05->refined.BAND = 0; // LW
518 else if (minimum_frequency < 1800)
519 this->currentAMBand = reg05->refined.BAND = 1; // MW
520 else
521 this->currentAMBand = reg05->refined.BAND = 2; // SW
522
523 this->currentAMSpace = reg05->refined.SPACE = am_space; // Space default value 0 (0=1KHz; 1 = 5KHz; 2=9KHz; 3 = 10KHz)
524
525 setRegister(REG05, reg05->raw);
526 this->setFrequency(default_frequency);
527}
528
529
530/**
531 * @ingroup GA03
532 * @brief Sets the channel
533 * @param channel
534 */
535void BK108X::setChannel(uint16_t channel)
536{
537 reg02->refined.SEEK = 0;
538 setRegister(REG02,reg02->raw);
539
540 reg03->refined.TUNE = 1;
541 reg03->refined.CHAN = channel;
542
543 setRegister(REG03,reg03->raw);
544 // delay(50);
546
547 this->currentChannel = channel;
548}
549
550/**
551 * @ingroup GA03
552 * @brief Sets the FM frequency
553 * @details ....
554 * @param frequency
555 */
556void BK108X::setFrequency(uint16_t frequency)
557{
558 uint16_t channel;
559
560 if (this->currentMode == BK_MODE_FM) {
561 channel = (frequency - this->fmStartBand[this->currentFMBand]) / this->fmSpace[this->currentFMSpace];
562 }
563 else {
564 channel = (frequency - this->amStartBand[this->currentAMBand]) / this->amSpace[this->currentAMSpace];
565 }
566
567 this->setChannel(channel);
568}
569
570/**
571 * @ingroup GA03
572 * @brief Increments the current frequency
573 * @details The increment uses the band space as step.
574 */
576{
577 this->currentFrequency += this->currentStep;
578
579 if (this->currentFrequency > this->maximumFrequency )
580 this->currentFrequency = this->minimumFrequency;
581
582 setFrequency(this->currentFrequency);
583}
584
585/**
586 * @ingroup GA03
587 * @brief Decrements the current frequency
588 * @details The drecrement uses the band space as step.
589 */
591{
592 this->currentFrequency -= this->currentStep;
593
594 if (this->currentFrequency < this->minimumFrequency)
595 this->currentFrequency = this->maximumFrequency;
596
597 setFrequency(this->currentFrequency);
598}
599
600/**
601 * @ingroup GA03
602 * @brief Gets the current frequency.
603 * @return uint16_t
604 */
606{
607 return this->currentFrequency;
608}
609
610/**
611 * @ingroup GA03
612 * @brief Gets the current channel.
613 * @return uint16_t
614 */
616{
617 return this->currentChannel;
618}
619
620/**
621 * @ingroup GA03
622 * @brief Gets the current channel stored in register 0x0B
623 * @details This method is useful to query the current channel during the seek operations.
624 * @return uint16_t
625 */
627{
628 getRegister(REG0B);
629 return reg0b->refined.READCHAN;
630}
631
632/**
633 * @ingroup GA03
634 * @brief Gets the frequency based on READCHAN register (0x0B)
635 * @details Unlike getFrequency method, this method queries the device.
636 *
637 * @return uint16_t
638 */
640{
641 if (currentMode == BK_MODE_AM) {
642 return getRealChannel() * this->amSpace[this->currentAMSpace] + this->amStartBand[this->currentAMBand];
643 } else {
644 return getRealChannel() * this->fmSpace[this->currentFMSpace] + this->fmStartBand[this->currentFMBand];
645 }
646}
647
648
649
650/**
651 * @todo it is not working properly
652 * @ingroup GA03
653 * @brief Seeks a station via Software
654 * @details Seeks a station up or down.
655 * @details Seek up or down a station and call a function defined by the user to show the frequency during the seek process.
656 * @details Seek begins at the current channel, and goes in the direction specified with the SEEKUP bit. Seek operation stops when a channel is qualified as valid according to the seek parameters, the entire band has been searched (SKMODE = 0), or the upper or lower band limit has been reached (SKMODE = 1).
657 * @details The STC bit is set high when the seek operation completes and/or the SF/BL bit is set high if the seek operation was unable to find a channel qualified as valid according to the seek parameters. The STC and SF/BL bits must be set low by setting the SEEK bit low before the next seek or tune may begin.
658 * @details Seek performance for 50 kHz channel spacing varies according to RCLK tolerance. Silicon Laboratories recommends ±50 ppm RCLK crystal tolerance for 50 kHz seek performance.
659 * @details A seek operation may be aborted by setting SEEK = 0.
660 * @details It is important to say you have to implement a show frequency function. This function have to get the frequency via getFrequency function.
661 * @details Example:
662 * @code
663 *
664 * BK108X rx;
665 *
666 * void showFrequency() {
667 * uint16_t freq = rx.getFrequency();
668 * Serial.print(freq);
669 * Serial.println("MHz ");
670 * }
671 *
672 * void loop() {
673 * .
674 * .
675 * rx.seek(BK_SEEK_WRAP, BK_SEEK_UP, showFrequency); // Seek Up
676 * .
677 * .
678 * }
679 * @endcode
680 * @param seek_mode 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.
681 * @param direction Seek Direction; 0 = Seek down (default); 1 = Seek up.
682 * @param showFunc function that you have to implement to show the frequency during the seeking process. Set NULL if you do not want to show the progress.
683 */
684void BK108X::seekSoftware(uint8_t seek_mode, uint8_t direction, void (*showFunc)())
685{
686 long max_time = millis();
687
688 // reg06->refined.SKSNR = 9;
689 // setRegister(REG06,reg06->raw);
690
691 reg03->refined.TUNE = 0;
692 setRegister(REG03, reg03->raw);
693 delay(50);
694
695 do
696 {
697 reg02->refined.SKMODE = seek_mode;
698 reg02->refined.SEEKUP = direction;
699 reg02->refined.SEEK = 1;
700 setRegister(REG02, reg02->raw);
701 delay(50);
702 if (showFunc != NULL)
703 {
704 this->currentFrequency = getRealFrequency();
705 showFunc();
706 }
707 getRegister(REG0A);
708 } while ( (!reg0a->refined.STC && reg0a->refined.SF_BL) && (millis() - max_time) < MAX_SEEK_TIME);
709
710 reg02->refined.SEEK = 0;
711 reg03->refined.TUNE = 0;
712 setRegister(REG02, reg02->raw);
713 setRegister(REG03, reg03->raw);
714
715 this->currentFrequency = getRealFrequency();
716}
717
718/**
719 * @todo make it work.
720 * @ingroup GA03
721 * @brief Seeks a station via hardware functionality
722 *
723 * @param seek_mode 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.
724 * @param direction Seek Direction; 0 = Seek down (default); 1 = Seek up.
725 */
726void BK108X::seekHardware(uint8_t seek_mode, uint8_t direction) {
727
728 reg03->refined.TUNE = 0;
729 setRegister(REG03, reg03->raw);
730
731 reg02->refined.SKMODE = seek_mode;
732 reg02->refined.SEEKUP = direction;
733 reg02->refined.SKAFCRL = 1;
734
735
736 do {
737 reg02->refined.SEEK = 1;
738 setRegister(REG02, reg02->raw);
739 delay(40);
740 while (reg0a->refined.STC == 0 )
741 {
742 delay(10);
743 getRegister(REG0A);
744 }
745 } while ( reg0a->refined.SF_BL != 0 );
746
747 reg02->refined.SEEK = 0;
748 setRegister(REG02, reg02->raw);
749 delay(50);
750
751 this->setChannel(this->getRealChannel());
752 this->currentFrequency = getRealFrequency();
753}
754
755/**
756 * @todo make it work.
757 * @ingroup GA03
758 * @brief Sets RSSI and SNR Seek Threshold
759 * @param rssiValue between 0 and 127
760 * @param snrValue between 0 and 127
761 */
762void BK108X::setSeekThreshold(uint8_t rssiValue, uint8_t snrValue)
763{
764 reg05->refined.SEEKTH = rssiValue;
765 setRegister(REG05,reg05->raw);
766
767 reg06->refined.SKSNR = snrValue;
768 setRegister(REG06,reg06->raw);
769}
770
771/**
772 * @ingroup GA03
773 * @brief Sets the current band for AM or FM
774 * @details Configures the band by setting the Register 05h. System Configuration2
775 *
776 * | Band value | AM / KHz | FM / MHz |
777 * | ---------- | -------------- | ------------------- |
778 * | 0 | LW - 153~279 | FULL - 64~108 |
779 * | 1 | MW - 520~1710 | East Europe 64~76 |
780 * | 2 | SW - 2.3~21.85 | Japan 76~91 |
781 * | 3 | MW - 522~1710 | Europe 87~108 |
782 *
783 * @see BK1086/88E - BROADCAST AM/FM/SW/LW RADIO RECEIVER Rev 1.3; page 15
784 * @param band the valid values are 0, 1, 2 and 3. See table above.
785 */
786
787void BK108X::setBand(uint8_t band)
788{
789 if (this->currentMode == BK_MODE_AM )
790 this->currentAMBand = band;
791 else
792 this->currentFMBand = band;
793
794 reg05->refined.BAND = band;
795 setRegister(REG05,reg05->raw);
796}
797
798/**
799 * @ingroup GA03
800 * @brief Sets the Space channel for AM or FM
801 *
802 * | Band value | AM | FM |
803 * | ---------- | ---------| --------- |
804 * | 0 | 1 KHz | 10 KHz |
805 * | 1 | 5 KKz | 50 KHz |
806 * | 2 | 9 KHz | 100 KHz |
807 * | 3 | 10 KHz | 200 KHz |
808 *
809 * @see BK1086/88E - BROADCAST AM/FM/SW/LW RADIO RECEIVER Rev 1.3; page 15
810 * @param space valid values 0,1,2 and 3. See table above.
811 */
812void BK108X::setSpace(uint8_t space)
813{
814 if (this->currentMode == BK_MODE_AM )
815 this->currentAMSpace = space;
816 else
817 this->currentFMSpace = space;
818
819 reg05->refined.SPACE = space;
820 setRegister(REG05, reg05->raw);
821}
822
823/**
824 * @ingroup GA03
825 * @brief Gets the current Rssi
826 *
827 * @return int
828 */
830{
831 getRegister(REG0A);
832 return reg0a->refined.RSSI;
833}
834
835/**
836 * @ingroup GA03
837 * @brief Gets the current SNR
838 *
839 * @return int The SNR Value.( in dB)
840 */
842{
843 getRegister(REG09);
844 return reg09->refined.SNR;
845}
846
847/**
848 * @ingroup GA03
849 * @brief Sets the Softmute true or false
850 * @details Enable or Disable Soft Mute resource.
851 * @param value TRUE or FALSE
852 */
853void BK108X::setSoftMute(bool value)
854{
855 reg02->refined.DSMUTE = !value; // Soft mute TRUE/ENABLE means DSMUTE = 0.
856 setRegister(REG02,reg02->raw);
857}
858
859/**
860 * @ingroup GA03
861 * @brief Sets Softmute Attack/Recover Rate.
862 *
863 * Soft mute Attack/Recover
864 *
865 * | Value | Description |
866 * | ----- | ----------- |
867 * | 0 | fastest |
868 * | 1 | fast |
869 * | 2 | slow |
870 * | 3 | slowest |
871 *
872 * @param value See table above.
873 */
874void BK108X::setSoftMuteAttack(uint8_t value)
875{
876 reg06->refined.SMUTER = value;
877 setRegister(REG06,reg06->raw);
878}
879
880/**
881 * @ingroup GA03
882 * @brief Sets Softmute Attenuation.
883 *
884 * Soft mute Attenuation.
885 * | Value | Description |
886 * | ----- | ----------- |
887 * | 0 | fastest |
888 * | 1 | fast |
889 * | 2 | slow |
890 * | 3 | slowest |
891 * @param value See table above
892 */
893void BK108X::setSoftMuteAttenuation(uint8_t value)
894{
895 reg06->refined.SMUTEA = value;
896 setRegister(REG06, reg06->raw);
897}
898
899/**
900 * @ingroup GA03
901 * @brief Set the Mute Threshold based on RSSI and SNR
902 *
903 * @see BK1086/88 - BROADCAST AM/FM/SW/LW RADIO RECEIVER Rev 1.3; page 19; Register 0x14 (Boot Configuration5)
904 * @param rssi The Mute Threshold Based on RSSI (default 26)
905 * @param snr The Mute Threshold Based on SNR (default 5)
906 */
907void BK108X::setMuteThreshold(uint8_t rssi, uint8_t snr)
908{
909 reg14->refined.RSSIMTH = rssi;
910 reg14->refined.SNRMTH = snr;
911 setRegister(REG14,reg14->raw);
912}
913
914/**
915 * @ingroup GA03
916 * @brief Disable or Enable soft mute when seeking
917 *
918 * @param value If true, enable mute during the seek;
919 */
920void BK108X::setSeekMute(bool value){
921 reg14->refined.SKMUTE = value;
922 setRegister(REG14, reg14->raw);
923}
924
925/**
926 * @ingroup GA03
927 * @brief Disable or Enable soft mute when AFCRL is high
928 *
929 * @param value If true, enable soft mute when AFCRL is high
930 */
931void BK108X::setAfcMute(bool value) {
932 reg14->refined.AFCMUTE = value;
933 setRegister(REG14, reg14->raw);
934}
935
936
937
938/**
939 * @ingroup GA03
940 * @brief Sets the Mute true or false
941 *
942 * @param left left channel (TRUE = MUTE/ FALSE = UNMUTE)
943 * @param left right channel (TRUE = MUTE / FALSE = UMUTE)
944 */
945void BK108X::setAudioMute(bool left, bool right)
946{
947 reg02->refined.MUTEL = left;
948 reg02->refined.MUTER = right;
949 setRegister(REG02, reg02->raw);
950}
951
952/**
953 * @ingroup GA03
954 * @brief Sets the Mute true or false
955 *
956 * @param value left and right channels (TRUE = MUTE/ FALSE = UNMUTE)
957 */
958void BK108X::setAudioMute(bool value)
959{
960 this->setAudioMute(value,value);
961}
962
963/**
964 * @ingroup GA03
965 * @brief Sets the Mono true or false (stereo)
966 * @details if TRUE, force mono; else force stereo
967 * @param value TRUE or FALSE
968 */
969void BK108X::setMono(bool value)
970{
971 reg02->refined.MONO = value;
972 reg02->refined.STEREO = !value;
973 setRegister(REG02,reg02->raw);
974}
975
976/**
977 * @ingroup GA03
978 * @brief Checks stereo / mono status
979 *
980 * @see getStatus
981 * @param value TRUE if stereo
982 */
984{
985 getRegister(REG0A);
986 return reg0a->refined.STEN;
987}
988
989/**
990 * @ingroup GA03
991 * @brief Sets the audio volume level
992 *
993 * @param value 0 to 31 (if 0, mutes the audio)
994 */
995void BK108X::setVolume(uint8_t value)
996{
997 if ( value > 31) return;
998 this->currentVolume = value;
999 // reg05 is a shadow register and has the last value read or written from/to the internal device register
1000 reg05->refined.VOLUME = value;
1001
1002 setRegister(REG05,reg05->raw);
1003}
1004
1005/**
1006 * @ingroup GA03
1007 * @brief Gets the current audio volume level
1008 *
1009 * @return uint8_t 0 to 15
1010 */
1012{
1013 return this->currentVolume;
1014}
1015
1016/**
1017 * @ingroup GA03
1018 * @brief Increments the audio volume
1019 *
1020 */
1022{
1023 if (this->currentVolume < 31)
1024 {
1025 this->currentVolume++;
1026 setVolume(this->currentVolume);
1027 }
1028}
1029
1030/**
1031 * @ingroup GA03
1032 * @brief Decrements the audio volume
1033 *
1034 */
1036{
1037 if (this->currentVolume > 0)
1038 {
1039 this->currentVolume--;
1040 setVolume(this->currentVolume);
1041 }
1042}
1043
1044
1045
1046/**
1047 * @defgroup GA04 RDS Functions
1048 * @section GA04 RDS/RBDS
1049 */
1050
1051/**
1052 * @ingroup GA04
1053 * @brief Gets the RDS registers information
1054 * @details Gets the value of the registers from 0x0A to 0x0F
1055 * @details This function also updates the value of shadowRegisters[0];
1056 * @return bk_reg0a
1057 */
1059{
1060
1061}
1062
1063/**
1064 * @ingroup GA04
1065 * @brief Sets the Rds Mode Standard or Verbose
1066 *
1067 * @param rds_mode 0 = Standard (default); 1 = Verbose
1068 */
1069void BK108X::setRdsMode(uint8_t rds_mode)
1070{
1071 this->rds_mode = rds_mode;
1072}
1073
1074/**
1075 * @ingroup GA04
1076 * @brief Sets the RDS operation
1077 * @details Enable or Disable the RDS
1078 *
1079 * @param true = turns the RDS ON; false = turns the RDS OFF
1080 */
1081void BK108X::setRds(bool value)
1082{
1083 reg04->refined.RDSEN = value;
1084 setRegister(REG04,reg04->raw);
1085
1086}
1087
1088
1089/**
1090 * @ingroup GA04
1091 * @brief Returns true if RDS Ready
1092 * @details Read address 0Ah and check the bit RDSR.
1093 * @details If in verbose mode, the BLERA bits indicate how many errors were corrected in block A. If BLERA indicates 6 or more errors, the data in RDSA should be discarded.
1094 * @details When using the polling method, it is best not to poll continuously. The data will appear in intervals of ~88 ms and the RDSR indicator will be available for at least 40 ms, so a polling rate of 40 ms or less should be sufficient.
1095 * @return true
1096 * @return false
1097 */
1099{
1100 getRegister(REG0A);
1101 return reg0a->refined.RDSR;
1102};
1103
1104/**
1105 * @ingroup GA04
1106 *
1107 * @brief Returns the current Text Flag A/B
1108 *
1109 * @return uint8_t current Text Flag A/B
1110 */
1112{
1113 return 0;
1114}
1115
1116/**
1117 * @ingroup GA04
1118 * @brief Return the group type
1119 *
1120 * @return uint16_t
1121 */
1123{
1124 return 0;
1125}
1126
1127/**
1128 * @ingroup GA04
1129 *
1130 * @brief Gets the version code (extracted from the Block B)
1131 * @returns 0=A or 1=B
1132 */
1134{
1135 return 0;
1136}
1137
1138/**
1139 * @ingroup GA04
1140 * @brief Returns the Program Type (extracted from the Block B)
1141 * @see https://en.wikipedia.org/wiki/Radio_Data_System
1142 * @return program type (an integer betwenn 0 and 31)
1143 */
1145{
1146 return 0;
1147}
1148
1149/**
1150 * @todo to be implemented
1151 * @ingroup GA04
1152 *
1153 * @brief Process data received from group 2B
1154 * @param c char array reference to the "group 2B" text
1155 */
1156void BK108X::getNext2Block(char *c)
1157{
1158 this->rds_buffer2B[0] = *c;
1159 c = NULL;
1160}
1161
1162/**
1163 * @todo to be implemented
1164 * @ingroup GA04
1165 *
1166 * @brief Process data received from group 2A
1167 *
1168 * @param c char array reference to the "group 2A" text
1169 */
1170void BK108X::getNext4Block(char *c)
1171{
1172 this->rds_buffer2A[0] = *c;
1173 c = NULL;
1174}
1175
1176/**
1177 * @ingroup GA04
1178 *
1179 * @brief Gets the RDS Text when the message is of the Group Type 2 version A
1180 * @return char* The string (char array) with the content (Text) received from group 2A
1181 */
1182char *BK108X::getRdsText(void)
1183{
1184 return NULL;
1185}
1186
1187/**
1188 * @ingroup GA04
1189 * @todo RDS Dynamic PS or Scrolling PS support
1190 * @brief Gets the station name and other messages.
1191 *
1192 * @return char* should return a string with the station name.
1193 * However, some stations send other kind of messages
1194 */
1196{
1197 return NULL;
1198}
1199
1200/**
1201 * @ingroup @ingroup GA04
1202 *
1203 * @brief Gets the Text processed for the 2A group
1204 *
1205 * @return char* string with the Text of the group A2
1206 */
1208{
1209 return NULL;
1210}
1211
1212/**
1213 * @ingroup GA04
1214 * @brief Gets the Text processed for the 2B group
1215 * @return char* string with the Text of the group AB
1216 */
1218{
1219 return NULL;
1220}
1221
1222/**
1223 * @ingroup GA04
1224 * @brief Gets the RDS time and date when the Group type is 4
1225 * @return char* a string with hh:mm +/- offset
1226 */
1228{
1229 return NULL;
1230}
1231
1232/**
1233 * @ingroup GA04
1234 * @brief Get the Rds Sync
1235 * @details Returns true if RDS currently synchronized.
1236 * @return true or false
1237 */
1239{
1240 return NULL;
1241}
1242
1243
1244/**
1245 * @defgroup GA05 Tools
1246 * @section GA05 Tools / Helper
1247 */
1248
1249/**
1250 * @ingroup GA05 Check the I2C buss address
1251 * @brief Check the I2C bus address
1252 *
1253 * @param uint8_t address Array - this array will be populated with the I2C bus addresses found (minimum three elements)
1254 * @return 0 if no i2c device is found; -1 if error is found or n > 0, where n is the number of I2C bus address found
1255 */
1256int BK108X::checkI2C(uint8_t *addressArray)
1257{
1258 Wire.begin();
1259 int error, address;
1260 int idx = 0;
1261 for (address = 1; address < 127; address++)
1262 {
1263 Wire.beginTransmission(address);
1264 error = Wire.endTransmission();
1265 if (error == 0)
1266 {
1267 addressArray[idx] = address;
1268 idx++;
1269 }
1270 else if (error == 4)
1271 return -1;
1272 }
1273 Wire.end();
1274 return idx;
1275}
1276
1277
1278/**
1279 * @ingroup GA05 Covert numbers to char array
1280 * @brief Converts a number to a char array
1281 * @details It is useful to mitigate memory space used by functions like sprintf or othetr generic similar functions
1282 * @details You can use it to format frequency using decimal or tousand separator and also to convert smalm numbers.
1283 *
1284 * @param value value to be converted
1285 * @param strValue char array that will be receive the converted value
1286 * @param len final string size (in bytes)
1287 * @param dot the decimal or tousand separator position
1288 * @param separator symbol "." or ","
1289 * @param remove_leading_zeros if true removes up to two leading zeros (default is true)
1290 */
1291void BK108X::convertToChar(uint16_t value, char *strValue, uint8_t len, uint8_t dot, uint8_t separator, bool remove_leading_zeros)
1292{
1293 char d;
1294 for (int i = (len - 1); i >= 0; i--)
1295 {
1296 d = value % 10;
1297 value = value / 10;
1298 strValue[i] = d + 48;
1299 }
1300 strValue[len] = '\0';
1301 if (dot > 0)
1302 {
1303 for (int i = len; i >= dot; i--)
1304 {
1305 strValue[i + 1] = strValue[i];
1306 }
1307 strValue[dot] = separator;
1308 }
1309
1310 if (remove_leading_zeros)
1311 {
1312 if (strValue[0] == '0')
1313 {
1314 strValue[0] = ' ';
1315 if (strValue[1] == '0')
1316 strValue[1] = ' ';
1317 }
1318 }
1319}
#define REG12
Definition: BK108X.h:72
#define REG02
Definition: BK108X.h:56
#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 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 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 REG11
Definition: BK108X.h:71
#define REG08
Definition: BK108X.h:62
#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 REG14
Definition: BK108X.h:74
#define BK_MODE_FM
Definition: BK108X.h:47
#define REG01
Definition: BK108X.h:55
uint16_t getChipId()
Returns the Chip Indentifiction.
Definition: BK108X.cpp:314
char rds_buffer2A[65]
RDS Radio Text buffer - Program Information.
Definition: BK108X.h:780
char rds_buffer2B[33]
RDS Radio Text buffer - Station Informaation.
Definition: BK108X.h:781
uint16_t getDeviceId()
Returns the Device Indentifiction.
Definition: BK108X.cpp:304
int seekInterruptPin
Definition: BK108X.h:803
int deviceAddress
Definition: BK108X.h:787
int rdsInterruptPin
Definition: BK108X.h:802
KT0915 Class.
Definition: BK108X.h:725
uint8_t i2cReceiveAck()
Gets Acknowledge (ACK)
Definition: BK108X.cpp:138
uint8_t i2cReadByte()
Gets a Byte from the slave device.
Definition: BK108X.cpp:182
uint16_t readRegister(uint8_t reg)
Gets an array of values from a BK108X given register.
Definition: BK108X.cpp:237
void i2cBeginTransaction()
Starts the I2C bus transaction
Definition: BK108X.cpp:65
void i2cEndTransaction()
Finish the I2C bus transaction.
Definition: BK108X.cpp:84
void i2cWriteByte(uint8_t data)
Sends a Byte to the slave device.
Definition: BK108X.cpp:160
void writeRegister(uint8_t reg, uint16_t vakue)
Sends an array of values to a BK108X given register.
Definition: BK108X.cpp:209
void i2cNack()
Sends Not Acknowledge (ACK)
Definition: BK108X.cpp:120
void setI2C(uint8_t i2c_addr=I2C_DEVICE_ADDR)
Sets I2C bus address.
Definition: BK108X.cpp:44
void i2cAck()
Sends Acknowledge (ACK)
Definition: BK108X.cpp:104
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:368
uint16_t getChannel()
Gets the current channel.
Definition: BK108X.cpp:615
void setSpace(uint8_t space=0)
Sets the Space channel for AM or FM.
Definition: BK108X.cpp:812
void seekSoftware(uint8_t seek_mode, uint8_t direction, void(*showFunc)()=NULL)
Seeks a station via Software.
Definition: BK108X.cpp:684
uint16_t getRealChannel()
Gets the current channel stored in register 0x0B.
Definition: BK108X.cpp:626
void waitAndFinishTune()
Wait STC (Seek/Tune Complete) status becomes 0.
Definition: BK108X.cpp:352
void setSoftMuteAttack(uint8_t value)
Sets Softmute Attack/Recover Rate.
Definition: BK108X.cpp:874
void setSeekThreshold(uint8_t rssiValue, uint8_t snrValue)
Sets RSSI and SNR Seek Threshold.
Definition: BK108X.cpp:762
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:504
int getSnr()
Gets the current SNR.
Definition: BK108X.cpp:841
void setAudioMute(bool left, bool right)
Sets the Mute true or false.
Definition: BK108X.cpp:945
void setFrequency(uint16_t frequency)
Sets the FM frequency.
Definition: BK108X.cpp:556
void setBand(uint8_t band=1)
Sets the current band for AM or FM
Definition: BK108X.cpp:787
void setFrequencyDown()
Decrements the current frequency.
Definition: BK108X.cpp:590
void setAudioMute(bool value)
Sets the Mute true or false.
Definition: BK108X.cpp:958
void setSoftMute(bool value)
Sets the Softmute true or false.
Definition: BK108X.cpp:853
void setAfcMute(bool value)
Disable or Enable soft mute when AFCRL is high.
Definition: BK108X.cpp:931
bk_reg0a getStatus()
Gets the current status (register 0x0A) content.
Definition: BK108X.cpp:338
bool isStereo()
Checks stereo / mono status.
Definition: BK108X.cpp:983
void setVolumeUp()
Increments the audio volume.
Definition: BK108X.cpp:1021
void setup(int sda_pin, int sclk_pin, int rdsInterruptPin=-1, int seekInterruptPin=-1, uint8_t oscillator_type=OSCILLATOR_TYPE_CRYSTAL)
Starts the device.
Definition: BK108X.cpp:450
uint16_t getFrequency()
Gets the current frequency.
Definition: BK108X.cpp:605
void setSoftMuteAttenuation(uint8_t value)
Sets Softmute Attenuation.
Definition: BK108X.cpp:893
void powerDown()
Powers the receiver off.
Definition: BK108X.cpp:433
void setChannel(uint16_t channel)
Sets the channel.
Definition: BK108X.cpp:535
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:476
void setVolume(uint8_t value)
Sets the audio volume level.
Definition: BK108X.cpp:995
uint8_t getVolume()
Gets the current audio volume level.
Definition: BK108X.cpp:1011
void setMono(bool value)
Sets the Mono true or false (stereo)
Definition: BK108X.cpp:969
void setFrequencyUp()
Increments the current frequency.
Definition: BK108X.cpp:575
uint16_t getRealFrequency()
Gets the frequency based on READCHAN register (0x0B)
Definition: BK108X.cpp:639
void setVolumeDown()
Decrements the audio volume.
Definition: BK108X.cpp:1035
void powerUp()
Powers the receiver on.
Definition: BK108X.cpp:385
int getRssi()
Gets the current Rssi.
Definition: BK108X.cpp:829
void setRegister(uint8_t reg, uint16_t value)
Sets a given value to the device registers.
Definition: BK108X.cpp:293
void setMuteThreshold(uint8_t rssi, uint8_t snr)
Set the Mute Threshold based on RSSI and SNR.
Definition: BK108X.cpp:907
void seekHardware(uint8_t seek_mode, uint8_t direction)
Seeks a station via hardware functionality.
Definition: BK108X.cpp:726
void setSeekMute(bool value)
Disable or Enable soft mute when seeking.
Definition: BK108X.cpp:920
uint16_t getRegister(uint8_t reg)
Gets a givens current register content of the device.
Definition: BK108X.cpp:273
char * getRdsText0A(void)
Gets the station name and other messages.
Definition: BK108X.cpp:1195
bool getRdsReady()
Returns true if RDS Ready.
Definition: BK108X.cpp:1098
char * getRdsText(void)
Gets the RDS Text when the message is of the Group Type 2 version A.
Definition: BK108X.cpp:1182
char * getRdsText2B(void)
Gets the Text processed for the 2B group.
Definition: BK108X.cpp:1217
void getNext4Block(char *c)
Process data received from group 2A.
Definition: BK108X.cpp:1170
uint8_t getRdsVersionCode(void)
Gets the version code (extracted from the Block B)
Definition: BK108X.cpp:1133
char * getRdsTime()
Gets the RDS time and date when the Group type is 4.
Definition: BK108X.cpp:1227
uint16_t getRdsGroupType()
Return the group type.
Definition: BK108X.cpp:1122
uint8_t getRdsFlagAB(void)
Returns the current Text Flag A/B
Definition: BK108X.cpp:1111
uint8_t getRdsProgramType(void)
Returns the Program Type (extracted from the Block B)
Definition: BK108X.cpp:1144
void getNext2Block(char *c)
Process data received from group 2B.
Definition: BK108X.cpp:1156
char * getRdsText2A(void)
Gets the Text processed for the 2A group.
Definition: BK108X.cpp:1207
bool getRdsSync()
Get the Rds Sync.
Definition: BK108X.cpp:1238
void setRdsMode(uint8_t rds_mode=0)
Sets the Rds Mode Standard or Verbose.
Definition: BK108X.cpp:1069
void setRds(bool value)
Sets the RDS operation.
Definition: BK108X.cpp:1081
void getRdsStatus()
Gets the RDS registers information.
Definition: BK108X.cpp:1058
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:1291
int checkI2C(uint8_t *addressArray)
Check the I2C bus address.
Definition: BK108X.cpp:1256