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