From e4b64fbef2878e9390c8dd1b0e17dbeedfdc9645 Mon Sep 17 00:00:00 2001 From: Silvano Seva Date: Mon, 3 Jun 2024 22:05:35 +0200 Subject: [PATCH] Driver for AK2365A FM detector --- platform/drivers/baseband/AK2365A.c | 70 ++++++++++++++++++++++++++ platform/drivers/baseband/AK2365A.h | 76 +++++++++++++++++++++++++++++ 2 files changed, 146 insertions(+) create mode 100644 platform/drivers/baseband/AK2365A.c create mode 100644 platform/drivers/baseband/AK2365A.h diff --git a/platform/drivers/baseband/AK2365A.c b/platform/drivers/baseband/AK2365A.c new file mode 100644 index 00000000..a9ff7a66 --- /dev/null +++ b/platform/drivers/baseband/AK2365A.c @@ -0,0 +1,70 @@ +/*************************************************************************** + * Copyright (C) 2024 by Silvano Seva IU2KWO * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, see * + ***************************************************************************/ + +#include +#include "AK2365A.h" + + +static inline void writeReg(const struct ak2365a *dev, uint8_t reg, uint8_t value) +{ + uint8_t data[2]; + + data[0] = (reg & 0x3f) << 1; + data[1] = value; + + gpioPin_clear(&dev->cs); + spi_send(dev->spi, &data, 2); + gpioPin_set(&dev->cs); +} + + +void AK2365A_init(const struct ak2365a *dev) +{ + gpioPin_setMode(&dev->cs, OUTPUT); + gpioPin_setMode(&dev->res, OUTPUT); + + gpioPin_clear(&dev->res); + gpioPin_set(&dev->cs); + + delayUs(100); + gpioPin_set(&dev->res); + + writeReg(dev, 0x04, 0xAA); // Software reset + writeReg(dev, 0x01, 0xC1); // Operating mode 6, LO freq 50.4MHz + writeReg(dev, 0x02, 0x33); // Enable calibration + writeReg(dev, 0x03, 0x00); // IF buffer gain 5dB + writeReg(dev, 0x0B, 0x01); // AGC auto, AGC1 gain 21dB + writeReg(dev, 0x0C, 0x80); // AGC2 gain 12dB +} + +void AK2365A_terminate(const struct ak2365a *dev) +{ + gpioPin_clear(&dev->res); +} + +void AK2365A_setFilterBandwidth(const struct ak2365a *dev, const uint8_t bw) +{ + uint8_t reg = 0xE1 | (bw << 2); + + writeReg(dev, 0x01, reg); // Operating mode 7, LO freq. 50.4MHz + delayMs(1); + writeReg(dev, 0x01, reg); // Operating mode 7, LO freq. 50.4MHz + writeReg(dev, 0x02, 0x1E); // AGC time = 3, AGC step 2dB + writeReg(dev, 0x03, 0x00); // IF buffer gain 5dB + writeReg(dev, 0x0B, 0x01); // AGC auto, AGC1 gain 21dB + writeReg(dev, 0x0C, 0x80); // AGC2 gain 12dB +} diff --git a/platform/drivers/baseband/AK2365A.h b/platform/drivers/baseband/AK2365A.h new file mode 100644 index 00000000..3f39a375 --- /dev/null +++ b/platform/drivers/baseband/AK2365A.h @@ -0,0 +1,76 @@ +/*************************************************************************** + * Copyright (C) 2024 by Silvano Seva IU2KWO * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, see * + ***************************************************************************/ + +#ifndef AK2365A_H +#define AK2365A_H + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +enum AK2365A_BPF +{ + AK2365A_BPF_7p5 = 4, ///< BAND = 1, BPF_BW = 00 + AK2365A_BPF_6 = 0, ///< BAND = 0, BPF_BW = 00 + AK2365A_BPF_4p5 = 1, ///< BAND = 0, BPF_BW = 01 + AK2365A_BPF_3 = 2, ///< BAND = 0, BPF_BW = 10 + AK2365A_BPF_2 = 3, ///< BAND = 0, BPF_BW = 11 +}; + +/** + * AK2365A device data. + */ +struct ak2365a +{ + const struct spiDevice *spi; ///< SPI bus device driver + const struct gpioPin cs; ///< Chip select gpio + const struct gpioPin res; ///< Reset gpio +}; + + +/** + * Initialise the FM detector IC. + * + * @param dev: pointer to device data. + */ +void AK2365A_init(const struct ak2365a *dev); + +/** + * Terminate the driver and set the IC in reset state. + * + * @param dev: pointer to device data. + */ +void AK2365A_terminate(const struct ak2365a *dev); + +/** + * Set the bandwidth of the internal IF filter. + * + * @param dev: pointer to device data. + * @param bw: bandwidth. + */ +void AK2365A_setFilterBandwidth(const struct ak2365a *dev, const uint8_t bw); + +#ifdef __cplusplus +} +#endif + +#endif /* AK2365A_H */