From 9802bc4e75363cf500e4c84b3093649c0d59c72b Mon Sep 17 00:00:00 2001 From: Silvano Seva Date: Sun, 17 Jan 2021 10:18:10 +0100 Subject: [PATCH] Started implementation of baseband drivers for GDx platforms --- meson.build | 5 +- platform/drivers/baseband/interfaces.h | 60 ++++++++++ platform/drivers/baseband/interfaces_GDx.c | 125 +++++++++++++++++++++ platform/targets/DM-1801/hwconfig.h | 18 +++ platform/targets/DM-1801/platform.c | 10 ++ 5 files changed, 217 insertions(+), 1 deletion(-) create mode 100644 platform/drivers/baseband/interfaces.h create mode 100644 platform/drivers/baseband/interfaces_GDx.c diff --git a/meson.build b/meson.build index 90c81f78..76da2a56 100644 --- a/meson.build +++ b/meson.build @@ -263,7 +263,10 @@ dm1801_src = src + mk22fn512_src + ['platform/targets/DM-1801/platform.c', 'platform/drivers/NVM/spiFlash_GDx.c', 'platform/drivers/NVM/nvmem_GDx.c', 'platform/drivers/ADC/ADC0_GDx.c', - 'platform/drivers/baseband/rtx_GDx.c'] + 'platform/drivers/baseband/rtx_GDx.c', + 'platform/drivers/baseband/AT1846S.c', + 'platform/drivers/baseband/HR-C6000.c', + 'platform/drivers/baseband/interfaces_GDx.c'] dm1801_inc = inc + mk22fn512_inc + ['platform/targets/DM-1801'] dm1801_def = def + mk22fn512_def + {'PLATFORM_DM1801': ''} diff --git a/platform/drivers/baseband/interfaces.h b/platform/drivers/baseband/interfaces.h new file mode 100644 index 00000000..ccdf1240 --- /dev/null +++ b/platform/drivers/baseband/interfaces.h @@ -0,0 +1,60 @@ +/*************************************************************************** + * Copyright (C) 2020 by Federico Amedeo Izzo IU2NUO, * + * Niccolò Izzo IU2KIN * + * Frederik Saraci IU2NRO * + * 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 INTERFACES_H +#define INTERFACES_H + +#include + +/* + * This file provides a standard interface for low-level data exchange with the + * baseband chipset (HR_C6000, AT1846S, ...). + * Its aim is to provide a decoupling layer between the chipset drivers, written + * to be platform-agnostic, and the platform-specific communication busses. + */ + + +/** + * Initialise I2C subsystem. + */ +void i2c_init(); + +/** + * AT1846S specific: write a device register. + */ +void i2c_writeReg16(uint8_t reg, uint16_t value); + +/** + * AT1846S specific: read a device register. + */ +uint16_t i2c_readReg16(uint8_t reg); + +/** + * HR_C5000 and HR_C6000: initialise "user" SPI interface, the one for chip + * configuration. + */ +void uSpi_init(); + +/** + * HR_C5000 and HR_C6000: transfer one byte over the "user" SPI interface. + */ +uint8_t uSpi_sendRecv(uint8_t val); + +#endif /* INTERFACES_H */ diff --git a/platform/drivers/baseband/interfaces_GDx.c b/platform/drivers/baseband/interfaces_GDx.c new file mode 100644 index 00000000..17b73b16 --- /dev/null +++ b/platform/drivers/baseband/interfaces_GDx.c @@ -0,0 +1,125 @@ +/*************************************************************************** + * Copyright (C) 2020 by Federico Amedeo Izzo IU2NUO, * + * Niccolò Izzo IU2KIN * + * Frederik Saraci IU2NRO * + * 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 +#include +#include +#include +#include +#include +#include "interfaces.h" + +/* + * Implementation of AT1846S I2C interface. + * + * NOTE: on GDx devices the I2C bus is shared between the EEPROM and the AT1846S, + * so we have to acquire exclusive ownership before exchanging data + */ + +static const uint8_t devAddr = 0xE2; + +void i2c_init() +{ + /* I2C already init'd by platform support package */ +} + +void i2c_writeReg16(uint8_t reg, uint16_t value) +{ + /* + * Beware of endianness! + * When writing an AT1846S register, bits 15:8 must be sent first, followed + * by bits 7:0. + */ + uint8_t buf[3]; + buf[0] = reg; + buf[1] = (value >> 8) & 0xFF; + buf[2] = value & 0xFF; + + i2c0_lockDeviceBlocking(); + i2c0_write(devAddr, buf, 3, true); + i2c0_releaseDevice(); +} + +uint16_t i2c_readReg16(uint8_t reg) +{ + uint16_t value = 0; + + i2c0_lockDeviceBlocking(); + i2c0_write(devAddr, ®, 1, false); + i2c0_read(devAddr, &value, 2); + i2c0_releaseDevice(); + + /* Correction for AT1846S sending register data in big endian format */ + return __builtin_bswap16(value); +} + +/* + * Implementation of HR_C6000 "user" SPI interface. + */ + +void uSpi_init() +{ + gpio_setMode(DMR_CLK, OUTPUT); + gpio_setMode(DMR_MOSI, OUTPUT); + gpio_setMode(DMR_MISO, INPUT); + + gpio_setAlternateFunction(DMR_CLK, 0); + gpio_setAlternateFunction(DMR_MOSI, 0); + gpio_setAlternateFunction(DMR_MISO, 0); + + SIM->SCGC6 |= SIM_SCGC6_SPI0_MASK; + + SPI0->MCR &= ~SPI_MCR_MDIS_MASK; /* Enable the SPI0 module */ + SPI0->MCR |= SPI_MCR_MSTR_MASK /* Master mode */ + | SPI_MCR_PCSIS_MASK /* CS high when inactive */ + | SPI_MCR_DIS_RXF_MASK /* Disable RX FIFO */ + | SPI_MCR_DIS_TXF_MASK /* Disable TX FIFO */ + | SPI_MCR_HALT_MASK; /* Stop transfers */ + + SPI0->CTAR[0] = SPI_CTAR_FMSZ(7) /* 8bit frame size */ + | SPI_CTAR_CPHA_MASK /* CPHA = 1 */ + | SPI_CTAR_PBR(2) /* CLK prescaler divide by 5 */ + | SPI_CTAR_BR(3) /* CLK scaler divide by 8 */ + | SPI_CTAR_PCSSCK(1) + | SPI_CTAR_PASC(1) + | SPI_CTAR_CSSCK(4) + | SPI_CTAR_ASC(4); +} + +uint8_t uSpi_sendRecv(uint8_t val) +{ + SPI0->MCR &= ~SPI_MCR_HALT_MASK; /* Start transfer */ + + SPI0->MCR |= SPI_MCR_CLR_TXF_MASK | SPI_MCR_CLR_RXF_MASK; + + while((SPI0->SR & SPI_SR_TFFF_MASK) == 0) ; + + SPI0->PUSHR = SPI_PUSHR_EOQ_MASK | val; + + SPI0->SR |= SPI_SR_TFFF_MASK; + + while((SPI0->SR & SPI_SR_RFDF_MASK) == 0) ; + SPI0->SR |= SPI_SR_RFDF_MASK; + + SPI0->MCR |= SPI_MCR_HALT_MASK; /* Start transfer */ + + return SPI0->POPR; +} diff --git a/platform/targets/DM-1801/hwconfig.h b/platform/targets/DM-1801/hwconfig.h index 24700816..12c64033 100644 --- a/platform/targets/DM-1801/hwconfig.h +++ b/platform/targets/DM-1801/hwconfig.h @@ -82,4 +82,22 @@ #define I2C_SDA GPIOE,25 #define I2C_SCL GPIOE,24 +/* RTX stage control */ +#define VHF_LNA_EN GPIOC,13 +#define UHF_LNA_EN GPIOC,15 +#define VHF_PA_EN GPIOE,0 +#define UHF_PA_EN GPIOE,1 + +/* Audio control */ +#define AUDIO_AMP_EN GPIOB,0 +#define RX_AUDIO_MUX GPIOC,5 +#define TX_AUDIO_MUX GPIOC,6 + +#define DMR_RESET GPIOE,2 +#define DMR_SLEEP GPIOE,3 +#define DMR_CS GPIOD,0 +#define DMR_CLK GPIOD,1 +#define DMR_MOSI GPIOD,2 +#define DMR_MISO GPIOD,3 + #endif diff --git a/platform/targets/DM-1801/platform.c b/platform/targets/DM-1801/platform.c index 2b4274d2..0cf0d3b7 100644 --- a/platform/targets/DM-1801/platform.c +++ b/platform/targets/DM-1801/platform.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include "hwconfig.h" @@ -60,6 +61,15 @@ void platform_init() */ adc0_init(); OSMutexCreate(&adc_mutex, "", &e); + + /* + * Initialise I2C driver, once for all the modules + */ + gpio_setMode(I2C_SDA, OPEN_DRAIN); + gpio_setMode(I2C_SCL, OPEN_DRAIN); + gpio_setAlternateFunction(I2C_SDA, 3); + gpio_setAlternateFunction(I2C_SCL, 3); + i2c0_init(); } void platform_terminate()