uv-k5-firmware-chinese-lts/driver/bk1080.c

214 lines
6.6 KiB
C
Raw Normal View History

2023-12-07 03:39:09 +00:00
/* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "bsp/dp32g030/gpio.h"
#include "bk1080.h"
#include "driver/gpio.h"
#include "driver/i2c.h"
#include "driver/system.h"
2023-12-23 14:22:37 +00:00
#include "frequencies.h"
2023-12-07 03:39:09 +00:00
#include "misc.h"
2023-12-23 14:22:37 +00:00
//#define CHAN_SPACING 0u // 200kHz
//#define CHAN_SPACING 1u // 100kHz
#define CHAN_SPACING 2u // 50kHz
2023-12-07 03:39:09 +00:00
2023-12-23 14:22:37 +00:00
#define VOLUME 15u
#define SEEK_THRESHOLD 10u
const freq_band_table_t FM_RADIO_FREQ_BAND_TABLE[] =
2023-12-07 03:39:09 +00:00
{
2023-12-23 14:22:37 +00:00
{875, 1080}, // 87.5 ~ 108 MHz
{760, 1080}, // 76 ~ 108 MHz
{760, 900}, // 76 ~ 90 MHz
{640, 760} // 64 ~ 76 MHz
2023-12-07 03:39:09 +00:00
};
2023-12-23 14:22:37 +00:00
static const uint16_t BK1080_RegisterTable[] =
{
0x0008, // 0x00
0x1080, // 0x01 chip ID
(1u << 9) | (1u << 0), // 0x02 0x0201 0000001000000001
0x0000, // 0x03
0x40C0, // 0x04 0100000011000000
(SEEK_THRESHOLD << 8) | (0u << 6) | (CHAN_SPACING << 4) | (VOLUME << 0), // 0x0A1F, // 0x05 00001010 00 01 1111
0x002E, // 0x06 0000000000101110
0x02FF, // 0x07 0000001011111111
0x5B11, // 0x08 0101101100010001
0x0000, // 0x09
0x411E, // 0x0A 0100000100011110
0x0000, // 0x0B
0xCE00, // 0x0C 1100111000000000
0x0000, // 0x0D
0x0000, // 0x0E
0x1000, // 0x0F 1000000000000000
0x3197, // 0x10 0011000110010111
0x0000, // 0x11
0x13FF, // 0x12 0001001111111111
0x9852, // 0x13 1001100001010010
0x0000, // 0x14
0x0000, // 0x15
0x0008, // 0x16
0x0000, // 0x17
0x51E1, // 0x18 0101000111100001
0xA8BC, // 0x19 1010100010111100
0x2645, // 0x1A 0010011001000101
0x00E4, // 0x1B 0000000011100100
0x1CD8, // 0x1C 0001110011011000
0x3A50, // 0x1D 0011101001010000
0xEAE0, // 0x1E 1110101011100000
0x3000, // 0x1F 0011000000000000
0x0200, // 0x20 0010000000000000
0x0000 // 0x21
};
2023-12-07 03:39:09 +00:00
uint16_t BK1080_BaseFrequency;
uint16_t BK1080_FrequencyDeviation;
2023-12-23 14:22:37 +00:00
bool is_init;
uint16_t BK1080_freq_lower;
uint16_t BK1080_freq_upper;
uint16_t BK1080_freq_base;
int16_t BK1080_freq_offset;
void BK1080_Init(const uint16_t frequency, const bool initialise)
2023-12-07 03:39:09 +00:00
{
unsigned int i;
2023-12-23 14:22:37 +00:00
// determine the lower and upper frequency limits when multiple bands are used
if (!is_init)
2023-12-07 03:39:09 +00:00
{
2023-12-23 14:22:37 +00:00
BK1080_freq_base = 0;
BK1080_freq_offset = 0;
BK1080_freq_lower = 0xffff;
BK1080_freq_upper = 0;
for (i = 0; i < ARRAY_SIZE(FM_RADIO_FREQ_BAND_TABLE); i++)
{
const uint16_t lower = FM_RADIO_FREQ_BAND_TABLE[i].lower;
const uint16_t upper = FM_RADIO_FREQ_BAND_TABLE[i].upper;
if (BK1080_freq_lower > lower)
BK1080_freq_lower = lower;
if (BK1080_freq_upper < upper)
BK1080_freq_upper = upper;
}
}
if (initialise)
{ // init and enable the chip
2023-12-07 03:39:09 +00:00
GPIO_ClearBit(&GPIOB->DATA, GPIOB_PIN_BK1080);
2023-12-23 14:22:37 +00:00
if (!is_init)
2023-12-07 03:39:09 +00:00
{
for (i = 0; i < ARRAY_SIZE(BK1080_RegisterTable); i++)
BK1080_WriteRegister(i, BK1080_RegisterTable[i]);
SYSTEM_DelayMs(250);
2023-12-23 14:22:37 +00:00
BK1080_WriteRegister(BK1080_REG_25_INTERNAL, 0xA83C); // 1010 1000 0011 1100
BK1080_WriteRegister(BK1080_REG_25_INTERNAL, 0xA8BC); // 1010 1000 1011 1100
2023-12-07 03:39:09 +00:00
SYSTEM_DelayMs(60);
2023-12-23 14:22:37 +00:00
is_init = true;
2023-12-07 03:39:09 +00:00
}
else
{
2023-12-23 14:22:37 +00:00
BK1080_WriteRegister(BK1080_REG_02_POWER_CONFIGURATION, (1u << 9) | (1u << 0));
2023-12-07 03:39:09 +00:00
}
2023-12-23 14:22:37 +00:00
BK1080_WriteRegister(BK1080_REG_05_SYSTEM_CONFIGURATION2, 0x0A5F); // 0000 1010 0101 1111
2023-12-07 03:39:09 +00:00
2023-12-23 14:22:37 +00:00
BK1080_SetFrequency(frequency);
2023-12-07 03:39:09 +00:00
}
else
2023-12-23 14:22:37 +00:00
{ // disable the chip
BK1080_WriteRegister(BK1080_REG_02_POWER_CONFIGURATION, (1u << 9) | (1u << 6) | (1u << 0)); // 0x0241); // 0000 0010 0100 0001
2023-12-07 03:39:09 +00:00
GPIO_SetBit(&GPIOB->DATA, GPIOB_PIN_BK1080);
}
}
uint16_t BK1080_ReadRegister(BK1080_Register_t Register)
{
uint8_t Value[2];
I2C_Start();
I2C_Write(0x80);
I2C_Write((Register << 1) | I2C_READ);
I2C_ReadBuffer(Value, sizeof(Value));
I2C_Stop();
return (Value[0] << 8) | Value[1];
}
void BK1080_WriteRegister(BK1080_Register_t Register, uint16_t Value)
{
I2C_Start();
I2C_Write(0x80);
I2C_Write((Register << 1) | I2C_WRITE);
Value = ((Value >> 8) & 0xFF) | ((Value & 0xFF) << 8);
I2C_WriteBuffer(&Value, sizeof(Value));
I2C_Stop();
}
2023-12-23 14:22:37 +00:00
void BK1080_Mute(const bool Mute)
2023-12-07 03:39:09 +00:00
{
2023-12-23 14:22:37 +00:00
BK1080_WriteRegister(BK1080_REG_02_POWER_CONFIGURATION, (1u << 9) | (1u << 0) | (Mute ? 1u << 14 : 0u));
2023-12-07 03:39:09 +00:00
}
void BK1080_SetFrequency(uint16_t Frequency)
{
2023-12-23 14:22:37 +00:00
int channel;
uint16_t band = 0;
// determine which band to use
for (band = 0; band < ARRAY_SIZE(FM_RADIO_FREQ_BAND_TABLE); band++)
if (Frequency >= FM_RADIO_FREQ_BAND_TABLE[band].lower && Frequency < FM_RADIO_FREQ_BAND_TABLE[band].upper)
break;
if (band >= ARRAY_SIZE(FM_RADIO_FREQ_BAND_TABLE))
{
Frequency = BK1080_freq_lower;
}
// channel = (int)Frequency - FM_RADIO_FREQ_BAND_TABLE[band].lower; // 100kHz channel spacing
channel = ((int)Frequency - FM_RADIO_FREQ_BAND_TABLE[band].lower) * 2; // 50kHz channel spacing
channel = (channel < 0) ? 0 : (channel > 1023) ? 1023 : channel;
BK1080_WriteRegister(BK1080_REG_05_SYSTEM_CONFIGURATION2, (SEEK_THRESHOLD << 8) | (band << 6) | (CHAN_SPACING << 4) | (VOLUME << 0));
BK1080_WriteRegister(BK1080_REG_03_CHANNEL, (uint16_t)channel);
// SYSTEM_DelayMs(1);
BK1080_WriteRegister(BK1080_REG_03_CHANNEL, (uint16_t)channel | (1u << 15));
}
int16_t BK1080_get_freq_offset(const uint16_t Frequency)
{
BK1080_freq_base = Frequency;
BK1080_freq_offset = (int16_t)BK1080_ReadRegister(BK1080_REG_07) / 16;
return BK1080_freq_offset;
2023-12-07 03:39:09 +00:00
}
void BK1080_GetFrequencyDeviation(uint16_t Frequency)
{
BK1080_BaseFrequency = Frequency;
BK1080_FrequencyDeviation = BK1080_ReadRegister(BK1080_REG_07) / 16;
2023-12-23 14:22:37 +00:00
}