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 BEKEN - BK1086/88 - BROADCAST AM/FM/SW/LW RADIO RECEIVER manual.
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  word16_to_bytes result;
274  result.raw = this->readRegister(reg);
275  shadowRegisters[reg] = result.raw; // Syncs with the shadowRegisters
276  return result.raw; // 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  * @return bk_reg0a data type status register (Register 0Ah. Status2)
320  */
321 bk_reg0a BK108X::getStatus()
322 {
323  getRegister(REG0A); // update the reg0a shadow register
324 }
325 
326 /**
327  * @ingroup GA03
328  * @brief Wait STC (Seek/Tune Complete) status becomes 0
329  * @details Should be used before processing Tune or Seek.
330  * @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.
331  */
332 void BK108X::waitAndFinishTune()
333 {
334  while ( reg0a->refined.STC == 0) {
335  delay(10);
336  getRegister(REG0A);
337  }
338 
339  reg03->refined.TUNE = 0;
340  setRegister(REG03, reg03->raw);
341  delay(40);
342 }
343 
344 /**
345  * @ingroup GA03
346  * @brief Resets the device
347  */
348 void BK108X::reset()
349 {
350  reg02->refined.DISABLE = 1;
351  reg02->refined.ENABLE = 0;
352  setRegister(REG02, reg02->raw);
353  reg02->refined.DISABLE = 0;
354  reg02->refined.ENABLE = 1;
355  setRegister(REG02, reg02->raw);
356 }
357 
358 /**
359  * @ingroup GA03
360  * @brief Powers the receiver on
361  * @details Starts the receiver with some default configurations
362  */
363 void BK108X::powerUp()
364 {
365 
366  reg02->raw = 0; // Sets to 0 all attributes of the register 0x02 (Power Configuration)
367  reg02->refined.DSMUTE = 1; // Soft Mute disabled
368  reg02->refined.STEREO = 1; // Force stereo
369  reg02->refined.ENABLE = 1; // Power the receiver UP (DISABLE has to be 0)
370  setRegister(REG02,reg02->raw); // Stores the register 0x02
371 
372  setRegister(REG03, 0x00); // Sets to 0 all attributes of the register 0x03 (Channel)
373  setRegister(REG04, 0x00); // Sets to 0 all attributes of the register 0x04 (System Configuration1)
374 
375 
376  this->currentVolume = reg05->refined.VOLUME = 15;
377  setRegister(REG05, reg05->raw); // System Configuration2
378 
379  reg06->raw = 0;
380  reg06->refined.CLKSEL = 1;
381  reg06->refined.SKSNR = 0x06;
382  reg06->refined.SKCNT = 0x0F;
383  setRegister(REG06, reg06->raw);
384 
385  delay(100);
386 }
387 
388 /**
389  * @ingroup GA03
390  * @brief Powers the receiver off
391  */
392 void BK108X::powerDown()
393 {
394  reg02->refined.DISABLE = 1;
395  reg02->refined.ENABLE = 0;
396  setRegister(REG02, reg02->raw);
397  delay(100);
398 }
399 
400 /**
401  * @ingroup GA03
402  * @brief Starts the device
403  * @details sets the reset pin, interrupt pins and oscillator type you are using in your project.
404  * @details You have to inform at least two parameters: RESET pin and I2C SDA pin of your MCU
405  * @param rdsInterruptPin // optional. Sets the Interrupt Arduino pin used to RDS function control.
406  * @param seekInterruptPin // optional. Sets the Arduino pin used to Seek function control.
407  * @param oscillator_type // optional. Sets the Oscillator type used Crystal (default) or Ref. Clock.
408  */
409 void BK108X::setup(int sda_pin, int sclk_pin, int rdsInterruptPin, int seekInterruptPin, uint8_t oscillator_type)
410 {
411  // Configures BEKEN I2C bus
412  this->i2cInit(sda_pin, sclk_pin);
413 
414  if (rdsInterruptPin >= 0)
415  this->rdsInterruptPin = rdsInterruptPin;
416  if (seekInterruptPin >= 0)
417  this->seekInterruptPin = seekInterruptPin;
418 
419  this->oscillatorType = oscillator_type;
420 
421  powerUp();
422 
423 }
424 
425 /**
426  * @ingroup GA03
427  * @brief Sets the receiver to FM mode
428  * @details Configures the receiver on FM mode; Also sets the band limits, defaul frequency and step.
429  *
430  * @param minimum_frequency minimum frequency for the band
431  * @param maximum_frequency maximum frequency for the band
432  * @param default_frequency default freuency
433  * @param step increment and decrement frequency step
434  */
435 void BK108X::setFM(uint16_t minimum_frequency, uint16_t maximum_frequency, uint16_t default_frequency, uint16_t step)
436 {
437 
438  this->currentStep = step;
439  this->currentFrequency = default_frequency;
440  this->minimumFrequency = minimum_frequency;
441  this->maximumFrequency = maximum_frequency;
442  this->currentMode = MODE_FM;
443 
444 
445  reg07->refined.MODE = MODE_FM;
446  setRegister(REG07, reg07->raw);
447  // Sets BAND, SPACE and other parameters
448  this->currentFMBand = reg05->refined.BAND = 0;
449  this->currentFMSpace = reg05->refined.SPACE = 2;
450  setRegister(REG05, reg05->raw);
451 
452  setFrequency(default_frequency);
453 };
454 
455 /**
456  * @ingroup GA03
457  * @brief Sets the receiver to AM mode
458  * @details Configures the receiver on AM mode; Also sets the band limits, defaul frequency and step.
459  *
460  * @param minimum_frequency minimum frequency for the band
461  * @param maximum_frequency maximum frequency for the band
462  * @param default_frequency default freuency
463  * @param step increment and decrement frequency step
464  */
465 void BK108X::setAM(uint16_t minimum_frequency, uint16_t maximum_frequency, uint16_t default_frequency, uint16_t step, uint16_t am_space)
466 {
467  this->currentStep = step;
468  this->currentFrequency = default_frequency;
469  this->minimumFrequency = minimum_frequency;
470  this->maximumFrequency = maximum_frequency;
471 
472  this->currentMode = reg07->refined.MODE = MODE_AM;
473  setRegister(REG07, reg07->raw);
474  // Sets BAND, SPACE and other parameters
475 
476  if (minimum_frequency < 520 )
477  this->currentAMBand = reg05->refined.BAND = 0; // LW
478  else if (minimum_frequency < 1800)
479  this->currentAMBand = reg05->refined.BAND = 1; // MW
480  else
481  this->currentAMBand = reg05->refined.BAND = 2; // SW
482 
483  this->currentAMSpace = reg05->refined.SPACE = am_space; // Space default value 0 (0=1KHz; 1 = 5KHz; 2=9KHz; 3 = 10KHz)
484 
485  setRegister(REG05, reg05->raw);
486 
487  this->setFrequency(default_frequency);
488 }
489 
490 
491 
492 /**
493  * @ingroup GA03
494  * @brief Sets the channel
495  * @param channel
496  */
497 void BK108X::setChannel(uint16_t channel)
498 {
499  reg02->refined.SEEK = 0;
500  setRegister(REG02,reg02->raw);
501 
502  reg03->refined.TUNE = 1;
503  reg03->refined.CHAN = channel;
504 
505  setRegister(REG03,reg03->raw);
506  delay(50);
508 
509  this->currentChannel = channel;
510 }
511 
512 /**
513  * @ingroup GA03
514  * @brief Sets the FM frequency
515  * @details ....
516  * @param frequency
517  */
518 void BK108X::setFrequency(uint16_t frequency)
519 {
520  uint16_t channel;
521 
522  if (this->currentMode == MODE_FM) {
523  channel = (frequency - this->fmStartBand[this->currentFMBand]) / this->fmSpace[this->currentFMSpace];
524  }
525  else {
526  channel = (frequency - this->amStartBand[this->currentAMBand]) / this->amSpace[this->currentAMSpace];
527  }
528 
529  this->setChannel(channel);
530 }
531 
532 /**
533  * @ingroup GA03
534  * @brief Increments the current frequency
535  * @details The increment uses the band space as step. See array: uint16_t fmSpace[4] = {20, 10, 5, 1};
536  */
537 void BK108X::setFrequencyUp()
538 {
539  this->currentFrequency += this->currentStep;
540 
541  if (this->currentFrequency > this->maximumFrequency )
542  this->currentFrequency = this->minimumFrequency;
543 
544  setFrequency(this->currentFrequency);
545 }
546 
547 /**
548  * @ingroup GA03
549  * @brief Decrements the current frequency
550  * @details The drecrement uses the band space as step.
551  */
552 void BK108X::setFrequencyDown()
553 {
554  this->currentFrequency -= this->currentStep;
555 
556  if (this->currentFrequency < this->minimumFrequency)
557  this->currentFrequency = this->maximumFrequency;
558 
559  setFrequency(this->currentFrequency);
560 }
561 
562 /**
563  * @ingroup GA03
564  * @brief Gets the current frequency.
565  * @return uint16_t
566  */
568 {
569  return this->currentFrequency;
570 }
571 
572 /**
573  * @ingroup GA03
574  * @brief Gets the current channel.
575  * @return uint16_t
576  */
578 {
579  return this->currentChannel;
580 }
581 
582 /**
583  * @ingroup GA03
584  * @brief Gets the current channel stored in register 0x0B
585  * @details This method is useful to query the current channel during the seek operations.
586  * @return uint16_t
587  */
589 {
590 
591  return reg0b->refined.READCHAN;
592 }
593 
594 /**
595  * @ingroup GA03
596  * @brief Gets the frequency based on READCHAN register (0x0B)
597  * @details Unlike getFrequency method, this method queries the device.
598  *
599  * @return uint16_t
600  */
602 {
603  if (currentMode == MODE_AM) {
604  return getRealChannel() * this->amSpace[this->currentAMSpace] + this->amStartBand[this->currentAMBand];
605  } else {
606  return getRealChannel() * this->fmSpace[this->currentFMSpace] + this->fmStartBand[this->currentFMBand];
607  }
608 }
609 
610 /**
611  * @ingroup GA03
612  * @brief Seek function
613  * @details Seeks a station up or down.
614  * @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).
615  * @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.
616  * @details A seek operation may be aborted by setting SEEK = 0.
617  *
618  * @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.
619  * @param direction Seek Direction; 0 = Seek down (default); 1 = Seek up.
620  */
621 void BK108X::seek(uint8_t seek_mode, uint8_t direction)
622 {
623 
624 }
625 
626 /**
627  * @ingroup GA03
628  * @brief Seek function
629  * @details Seeks a station up or down.
630  * @details Seek up or down a station and call a function defined by the user to show the frequency during the seek process.
631  * @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).
632  * @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.
633  * @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.
634  * @details A seek operation may be aborted by setting SEEK = 0.
635  * @details It is important to say you have to implement a show frequency function. This function have to get the frequency via getFrequency function.
636  * @details Example:
637  * @code
638  *
639  * BK108X rx;
640  *
641  * void showFrequency() {
642  * uint16_t freq = rx.getFrequency();
643  * Serial.print(freq);
644  * Serial.println("MHz ");
645  * }
646  *
647  * void loop() {
648  * .
649  * .
650  * rx.seek(bk_SEEK_WRAP, bk_SEEK_UP, showFrequency); // Seek Up
651  * .
652  * .
653  * }
654  * @endcode
655  * @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.
656  * @param direction Seek Direction; 0 = Seek down (default); 1 = Seek up.
657  * @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.
658  */
659 void BK108X::seek(uint8_t seek_mode, uint8_t direction, void (*showFunc)())
660 {
661 
662 }
663 
664 /**
665  * @ingroup GA03
666  * @brief Sets RSSI Seek Threshold
667  * @param value between 0 and 127
668  */
669 void BK108X::setSeekThreshold(uint8_t value)
670 {
671 
672 }
673 
674 /**
675  * @ingroup GA03
676  * @brief Sets the FM Band
677 
678  *
679  * @param band
680  */
681 void BK108X::setBand(uint8_t band)
682 {
683 
684 }
685 
686 /**
687  * @ingroup GA03
688  * @brief Sets the FM Space
689  */
690 void BK108X::setSpace(uint8_t space)
691 {
692 
693 }
694 
695 /**
696  * @ingroup GA03
697  * @brief Gets the Rssi
698  *
699  * @return int
700  */
701 int BK108X::getRssi()
702 {
703 
704 }
705 
706 /**
707  * @ingroup GA03
708  * @brief Sets the Softmute true or false
709  * @param value TRUE or FALSE
710  */
711 void BK108X::setSoftmute(bool value)
712 {
713 
714 }
715 
716 /**
717  * @ingroup GA03
718  * @brief Sets Softmute Attack/Recover Rate.
719  *
720  * @param value
721  */
722 void BK108X::setSoftmuteAttack(uint8_t value)
723 {
724 
725 }
726 
727 /**
728  * @ingroup GA03
729  * @brief Sets Softmute Attenuation..
730  *
731  * @param value
732  */
733 void BK108X::setSoftmuteAttenuation(uint8_t value)
734 {
735 
736 }
737 
738 /**
739  * @ingroup GA03
740  * @brief Sets the AGC enable or disable
741  * @param value true = enable; fale = disable
742  */
743 void BK108X::setAgc(bool value)
744 {
745 
746 }
747 
748 /**
749  * @ingroup GA03
750  * @brief Sets the Mute true or false
751  *
752  * @param value TRUE or FALSE
753  */
754 void BK108X::setMute(bool value)
755 {
756 
757 }
758 
759 /**
760  * @ingroup GA03
761  * @brief Sets the Mono true or false (stereo)
762  *
763  * @param value TRUE or FALSE
764  */
765 void BK108X::setMono(bool value)
766 {
767 
768 }
769 
770 /**
771  * @ingroup GA03
772  * @brief Checks stereo / mono status
773  *
774  * @param value TRUE if stereo
775  */
776 bool BK108X::isStereo()
777 {
778 
779 }
780 
781 /**
782  * @ingroup GA03
783  * @brief Sets the audio volume level
784  *
785  * @param value 0 to 31 (if 0, mutes the audio)
786  */
787 void BK108X::setVolume(uint8_t value)
788 {
789  if ( value > 31) return;
790  this->currentVolume = value;
791  // reg05 is a shadow register and has the last value read or written from/to the internal device register
792  reg05->refined.VOLUME = value;
793 
794  setRegister(REG05,reg05->raw);
795 }
796 
797 /**
798  * @ingroup GA03
799  * @brief Gets the current audio volume level
800  *
801  * @return uint8_t 0 to 15
802  */
804 {
805  return this->currentVolume;
806 }
807 
808 /**
809  * @ingroup GA03
810  * @brief Increments the audio volume
811  *
812  */
813 void BK108X::setVolumeUp()
814 {
815  if (this->currentVolume < 31)
816  {
817  this->currentVolume++;
818  setVolume(this->currentVolume);
819  }
820 }
821 
822 /**
823  * @ingroup GA03
824  * @brief Decrements the audio volume
825  *
826  */
827 void BK108X::setVolumeDown()
828 {
829  if (this->currentVolume > 0)
830  {
831  this->currentVolume--;
832  setVolume(this->currentVolume);
833  }
834 }
835 
836 /**
837  * @ingroup GA03
838  * @brief Sets Extended Volume Range.
839  * @param value false = disabled (default); true = enabled.
840  */
841 void BK108X::setExtendedVolumeRange(bool value)
842 {
843 
844 }
845 
846 
847 
848 /**
849  * @ingroup GA03
850  * @brief Sets De-emphasis.
851  * @details 75 μs. Used in USA (default); 50 μs. Used in Europe, Australia, Japan.
852  *
853  * @param de 0 = 75 μs; 1 = 50 μs
854  */
855 void BK108X::setFmDeemphasis(uint8_t de)
856 {
857 
858 }
859 
860 /**
861  * @defgroup GA04 RDS Functions
862  * @section GA04 RDS/RBDS
863  */
864 
865 /**
866  * @ingroup GA04
867  * @brief Gets the RDS registers information
868  * @details Gets the value of the registers from 0x0A to 0x0F
869  * @details This function also updates the value of shadowRegisters[0];
870  * @return bk_reg0a
871  */
872 void BK108X::getRdsStatus()
873 {
874 
875 }
876 
877 /**
878  * @ingroup GA04
879  * @brief Sets the Rds Mode Standard or Verbose
880  *
881  * @param rds_mode 0 = Standard (default); 1 = Verbose
882  */
883 void BK108X::setRdsMode(uint8_t rds_mode)
884 {
885 
886 }
887 
888 /**
889  * @ingroup GA04
890  * @brief Sets the RDS operation
891  * @details Enable or Disable the RDS
892  *
893  * @param true = turns the RDS ON; false = turns the RDS OFF
894  */
895 void BK108X::setRds(bool value)
896 {
897 
898 }
899 
900 /**
901  * @ingroup GA04
902  * @brief Returns true if RDS Ready
903  * @details Read address 0Ah and check the bit RDSR.
904  * @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.
905  * @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.
906  * @return true
907  * @return false
908  */
909 bool BK108X::getRdsReady()
910 {
911 
912 };
913 
914 /**
915  * @ingroup GA04
916  *
917  * @brief Returns the current Text Flag A/B
918  *
919  * @return uint8_t current Text Flag A/B
920  */
921 uint8_t BK108X::getRdsFlagAB(void)
922 {
923 
924 }
925 
926 /**
927  * @ingroup GA04
928  * @brief Return the group type
929  *
930  * @return uint16_t
931  */
933 {
934 
935 }
936 
937 /**
938  * @ingroup GA04
939  *
940  * @brief Gets the version code (extracted from the Block B)
941  * @returns 0=A or 1=B
942  */
944 {
945 
946 }
947 
948 /**
949  * @ingroup GA04
950  * @brief Returns the Program Type (extracted from the Block B)
951  * @see https://en.wikipedia.org/wiki/Radio_Data_System
952  * @return program type (an integer betwenn 0 and 31)
953  */
955 {
956 
957 }
958 
959 /**
960  * @ingroup GA04
961  *
962  * @brief Process data received from group 2B
963  * @param c char array reference to the "group 2B" text
964  */
965 void BK108X::getNext2Block(char *c)
966 {
967 
968 }
969 
970 /**
971  * @ingroup GA04
972  *
973  * @brief Process data received from group 2A
974  *
975  * @param c char array reference to the "group 2A" text
976  */
977 void BK108X::getNext4Block(char *c)
978 {
979 
980 }
981 
982 /**
983  * @ingroup GA04
984  *
985  * @brief Gets the RDS Text when the message is of the Group Type 2 version A
986  * @return char* The string (char array) with the content (Text) received from group 2A
987  */
988 char *BK108X::getRdsText(void)
989 {
990  return NULL;
991 }
992 
993 /**
994  * @ingroup GA04
995  * @todo RDS Dynamic PS or Scrolling PS support
996  * @brief Gets the station name and other messages.
997  *
998  * @return char* should return a string with the station name.
999  * However, some stations send other kind of messages
1000  */
1001 char *BK108X::getRdsText0A(void)
1002 {
1003  return NULL;
1004 }
1005 
1006 /**
1007  * @ingroup @ingroup GA04
1008  *
1009  * @brief Gets the Text processed for the 2A group
1010  *
1011  * @return char* string with the Text of the group A2
1012  */
1013 char *BK108X::getRdsText2A(void)
1014 {
1015  return NULL;
1016 }
1017 
1018 /**
1019  * @ingroup GA04
1020  * @brief Gets the Text processed for the 2B group
1021  * @return char* string with the Text of the group AB
1022  */
1023 char *BK108X::getRdsText2B(void)
1024 {
1025  return NULL;
1026 }
1027 
1028 /**
1029  * @ingroup GA04
1030  * @brief Gets the RDS time and date when the Group type is 4
1031  * @return char* a string with hh:mm +/- offset
1032  */
1033 char *BK108X::getRdsTime()
1034 {
1035  return NULL;
1036 }
1037 
1038 /**
1039  * @ingroup GA04
1040  * @brief Get the Rds Sync
1041  * @details Returns true if RDS currently synchronized.
1042  * @return true or false
1043  */
1044 bool BK108X::getRdsSync()
1045 {
1046  return NULL;
1047 }
BK108X::getRdsText
char * getRdsText(void)
Gets the RDS Text when the message is of the Group Type 2 version A.
Definition: BK108X.cpp:988
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:435
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 FM Band
Definition: BK108X.cpp:681
BK108X::isStereo
bool isStereo()
Checks stereo / mono status.
Definition: BK108X.cpp:776
BK108X::getChannel
uint16_t getChannel()
Gets the current channel.
Definition: BK108X.cpp:577
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:1033
BK108X::getRdsText2A
char * getRdsText2A(void)
Gets the Text processed for the 2A group.
Definition: BK108X.cpp:1013
BK108X::i2cReceiveAck
uint8_t i2cReceiveAck()
Gets Acknowledge (ACK)
Definition: BK108X.cpp:136
BK108X::seek
void seek(uint8_t seek_mode, uint8_t direction)
Seek function.
Definition: BK108X.cpp:621
BK108X::i2cAck
void i2cAck()
Sends Acknowledge (ACK)
Definition: BK108X.cpp:102
REG03
#define REG03
Definition: BK108X.h:53
BK108X::setExtendedVolumeRange
void setExtendedVolumeRange(bool value)
Sets Extended Volume Range.
Definition: BK108X.cpp:841
BK108X::getDeviceId
uint16_t getDeviceId()
Returns the Device Indentifiction.
Definition: BK108X.cpp:302
BK108X::i2cBeginTransaction
void i2cBeginTransaction()
Starts the I2C bus transaction
Definition: BK108X.cpp:63
BK108X::powerDown
void powerDown()
Powers the receiver off.
Definition: BK108X.cpp:392
BK108X::getNext4Block
void getNext4Block(char *c)
Process data received from group 2A.
Definition: BK108X.cpp:977
REG04
#define REG04
Definition: BK108X.h:54
BK108X::getRealFrequency
uint16_t getRealFrequency()
Gets the frequency based on READCHAN register (0x0B)
Definition: BK108X.cpp:601
BK108X::rdsInterruptPin
int rdsInterruptPin
Definition: BK108X.h:798
BK108X::setFrequency
void setFrequency(uint16_t frequency)
Sets the FM frequency.
Definition: BK108X.cpp:518
BK108X::getRssi
int getRssi()
Gets the Rssi.
Definition: BK108X.cpp:701
BK108X::seek
void seek(uint8_t seek_mode, uint8_t direction, void(*showFunc)())
Seek function.
Definition: BK108X.cpp:659
BK108X::seekInterruptPin
int seekInterruptPin
Definition: BK108X.h:799
BK108X::setMute
void setMute(bool value)
Sets the Mute true or false.
Definition: BK108X.cpp:754
BK108X::getRdsVersionCode
uint8_t getRdsVersionCode(void)
Gets the version code (extracted from the Block B)
Definition: BK108X.cpp:943
BK108X::getRdsText0A
char * getRdsText0A(void)
Gets the station name and other messages.
Definition: BK108X.cpp:1001
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 FM Space
Definition: BK108X.cpp:690
BK108X::getRealChannel
uint16_t getRealChannel()
Gets the current channel stored in register 0x0B.
Definition: BK108X.cpp:588
BK108X::getRdsSync
bool getRdsSync()
Get the Rds Sync.
Definition: BK108X.cpp:1044
BK108X::setSoftmuteAttenuation
void setSoftmuteAttenuation(uint8_t value)
Sets Softmute Attenuation..
Definition: BK108X.cpp:733
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:497
BK108X::writeRegister
void writeRegister(uint8_t reg, uint16_t vakue)
Sends an array of values to a BK108X given register.
Definition: BK108X.cpp:207
BK108X::setVolumeDown
void setVolumeDown()
Decrements the audio volume.
Definition: BK108X.cpp:827
BK108X::waitAndFinishTune
void waitAndFinishTune()
Wait STC (Seek/Tune Complete) status becomes 0.
Definition: BK108X.cpp:332
BK108X::getNext2Block
void getNext2Block(char *c)
Process data received from group 2B.
Definition: BK108X.cpp:965
BK108X::setSoftmute
void setSoftmute(bool value)
Sets the Softmute true or false.
Definition: BK108X.cpp:711
BK108X::getRdsStatus
void getRdsStatus()
Gets the RDS registers information.
Definition: BK108X.cpp:872
BK108X::getFrequency
uint16_t getFrequency()
Gets the current frequency.
Definition: BK108X.cpp:567
BK108X::setFrequencyUp
void setFrequencyUp()
Increments the current frequency.
Definition: BK108X.cpp:537
BK108X::setSoftmuteAttack
void setSoftmuteAttack(uint8_t value)
Sets Softmute Attack/Recover Rate.
Definition: BK108X.cpp:722
BK108X::reset
void reset()
Resets the device.
Definition: BK108X.cpp:348
BK108X::getRdsProgramType
uint8_t getRdsProgramType(void)
Returns the Program Type (extracted from the Block B)
Definition: BK108X.cpp:954
BK108X::setVolume
void setVolume(uint8_t value)
Sets the audio volume level.
Definition: BK108X.cpp:787
REG01
#define REG01
Definition: BK108X.h:51
BK108X::getRdsFlagAB
uint8_t getRdsFlagAB(void)
Returns the current Text Flag A/B
Definition: BK108X.cpp:921
BK108X::setFmDeemphasis
void setFmDeemphasis(uint8_t de)
Sets De-emphasis.
Definition: BK108X.cpp:855
BK108X::powerUp
void powerUp()
Powers the receiver on.
Definition: BK108X.cpp:363
BK108X::getVolume
uint8_t getVolume()
Gets the current audio volume level.
Definition: BK108X.cpp:803
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:409
REG0A
#define REG0A
Definition: BK108X.h:60
MODE_FM
#define MODE_FM
Definition: BK108X.h:47
REG00
#define REG00
Definition: BK108X.h:50
BK108X::setFrequencyDown
void setFrequencyDown()
Decrements the current frequency.
Definition: BK108X.cpp:552
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:883
BK108X::getStatus
bk_reg0a getStatus()
Definition: BK108X.cpp:321
BK108X::getRdsGroupType
uint16_t getRdsGroupType()
Return the group type.
Definition: BK108X.cpp:932
REG05
#define REG05
Definition: BK108X.h:55
BK108X::getRdsText2B
char * getRdsText2B(void)
Gets the Text processed for the 2B group.
Definition: BK108X.cpp:1023
REG07
#define REG07
Definition: BK108X.h:57
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:465
BK108X::setMono
void setMono(bool value)
Sets the Mono true or false (stereo)
Definition: BK108X.cpp:765
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
BK108X::setSeekThreshold
void setSeekThreshold(uint8_t value)
Sets RSSI Seek Threshold.
Definition: BK108X.cpp:669
REG06
#define REG06
Definition: BK108X.h:56
BK108X::setRds
void setRds(bool value)
Sets the RDS operation.
Definition: BK108X.cpp:895
BK108X::setVolumeUp
void setVolumeUp()
Increments the audio volume.
Definition: BK108X.cpp:813
REG02
#define REG02
Definition: BK108X.h:52
BK108X::setAgc
void setAgc(bool value)
Sets the AGC enable or disable.
Definition: BK108X.cpp:743
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:909