From 729f2a2c3ebfb2612d873caf453a1d7ca02180d9 Mon Sep 17 00:00:00 2001 From: dmlunar Date: Wed, 22 Jan 2025 16:47:21 +0200 Subject: varpa: initial public commit --- firmware/src/driver/f1956.c | 61 +++++++++++++ firmware/src/driver/mcp3202.c | 129 +++++++++++++++++++++++++++ firmware/src/driver/mcp4725.c | 101 +++++++++++++++++++++ firmware/src/driver/si4468.c | 201 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 492 insertions(+) create mode 100644 firmware/src/driver/f1956.c create mode 100644 firmware/src/driver/mcp3202.c create mode 100644 firmware/src/driver/mcp4725.c create mode 100644 firmware/src/driver/si4468.c (limited to 'firmware/src/driver') diff --git a/firmware/src/driver/f1956.c b/firmware/src/driver/f1956.c new file mode 100644 index 0000000..3af5fba --- /dev/null +++ b/firmware/src/driver/f1956.c @@ -0,0 +1,61 @@ +/** + * + * Author: Dylan Muller + * Copyright (c) 2025 + * All rights reserved. + * + * - Commercial/IP use prohibited. + * - Attribution required. + * See License.txt + * + */ + +#include "setup.h" + +#include "peripheral/spi.h" +#include "driver/f1956.h" + +#include +#include +#include + +void att_init(uint8_t init_value) +{ + F1956_DEV_0_DDR |= (1 << F1956_DEV_0_SS); + F1956_DEV_0_PORT |= (1 << F1956_DEV_0_SS); + + att_set(F1956_ID_INPUT_ATT, init_value); + _delay_ms(10); +} + +void att_set( + uint8_t id, + uint8_t value +) +{ + uint8_t dev_id = 0x0; + uint8_t dev_ss = 0x0; + uint8_t* dev_port = 0x0; + uint8_t cmd_buf[2] = {0x0, 0x0}; + + switch (id) + { + case F1956_ID_INPUT_ATT: + dev_id = F1956_DEV_INPUT_ATT; + break; + } + + switch (dev_id) + { + case F1956_DEV_INPUT_ATT: + dev_ss = F1956_DEV_0_SS; + dev_port = (uint8_t*)&F1956_DEV_0_PORT; + break; + } + + cmd_buf[0] = value & 0x7F; + cmd_buf[1] = F1956_DEV_INPUT_ATT_ADDR; + + spi_start(cmd_buf, cmd_buf, sizeof(cmd_buf), dev_port, dev_ss); + spi_flush(); +} diff --git a/firmware/src/driver/mcp3202.c b/firmware/src/driver/mcp3202.c new file mode 100644 index 0000000..07f84db --- /dev/null +++ b/firmware/src/driver/mcp3202.c @@ -0,0 +1,129 @@ +/** + * + * Author: Dylan Muller + * Copyright (c) 2025 + * All rights reserved. + * + * - Commercial/IP use prohibited. + * - Attribution required. + * See License.txt + * + */ + +#include "setup.h" + +#include "peripheral/spi.h" +#include "driver/mcp3202.h" + +#include +#include +#include + +void adc_init(void) +{ + MCP3202_DEV_0_DDR |= (1 << MCP3202_DEV_0_SS); + MCP3202_DEV_1_DDR |= (1 << MCP3202_DEV_1_SS); + + MCP3202_DEV_0_PORT &= ~(1 << MCP3202_DEV_0_SS); + MCP3202_DEV_1_PORT &= ~(1 << MCP3202_DEV_1_SS); + + _delay_ms(TRANSACT_DELAY_MS); + + MCP3202_DEV_0_PORT |= (1 << MCP3202_DEV_0_SS); + MCP3202_DEV_1_PORT |= (1 << MCP3202_DEV_1_SS); + + _delay_ms(TRANSACT_DELAY_MS); +} + +uint16_t adc_read( + uint8_t id, + uint8_t conv_bypass +) +{ + uint8_t dev_id = 0x0; + uint8_t dev_ch = 0x0; + uint8_t dev_ss = 0x0; + uint8_t* dev_port = 0x0; + uint8_t cmd_buf[3] = {0x0, 0x0, 0x0}; + uint16_t adc_daq = 0x0; + + switch(id) + { + case MCP3202_ID_FW_POWER: + dev_id = MCP3202_DEV_FW_POWER; + dev_ch = MCP3202_CHN_FW_POWER; + break; + + case MCP3202_ID_REV_POWER: + dev_id = MCP3202_DEV_REV_POWER; + dev_ch = MCP3202_CHN_REV_POWER; + break; + + case MCP3202_ID_DRAIN_VOLT: + dev_id = MCP3202_DEV_DRAIN_VOLT; + dev_ch = MCP3202_CHN_DRAIN_VOLT; + break; + + case MCP3202_ID_DRAIN_AMP: + dev_id = MCP3202_DEV_DRAIN_AMP; + dev_ch = MCP3202_CHN_DRAIN_AMP; + break; + } + + switch(dev_id) + { + case MCP3202_DEV_0: + dev_port = (uint8_t*)&MCP3202_DEV_0_PORT; + dev_ss = MCP3202_DEV_0_SS; + break; + + case MCP3202_DEV_1: + dev_port = (uint8_t*)&MCP3202_DEV_1_PORT; + dev_ss = MCP3202_DEV_1_SS; + break; + } + + cmd_buf[0] = MCP3202_REQ_START; + cmd_buf[1] = (dev_ch == MCP3202_CHN_0) ? MCP3202_REQ_CH0 : MCP3202_REQ_CH1; + cmd_buf[2] = MCP3202_REQ_PAD; + + spi_start(cmd_buf, cmd_buf, sizeof(cmd_buf), dev_port, dev_ss); + spi_flush(); + + adc_daq = (uint16_t)(cmd_buf[MCP3202_DAQ_MSB]); + adc_daq |= ((uint16_t)(cmd_buf[MCP3202_DAQ_LSB] & 0xF) << 8); + adc_daq = adc_daq & 0xFFF; + + if (conv_bypass == 0) + { + switch(id) + { + case MCP3202_ID_DRAIN_VOLT: + adc_daq = (uint32_t)(((uint32_t)adc_daq * MCP3202_DRAIN_VOLT_GAIN)/10); + break; + case MCP3202_ID_DRAIN_AMP: + adc_daq = (uint32_t)(((uint32_t)adc_daq * 10)/MCP3202_DRAIN_AMP_GAIN); + break; + } + } + + return (uint16_t)adc_daq; +} + +uint16_t adc_read_n( + uint8_t id, + uint8_t n +) +{ + uint32_t x = 0; + uint8_t i = 0; + + for (i = 0; i < n; i++) + { + x += adc_read(id, 0); + } + + x /= n; + + return (uint16_t)x; +} diff --git a/firmware/src/driver/mcp4725.c b/firmware/src/driver/mcp4725.c new file mode 100644 index 0000000..4cb9bd6 --- /dev/null +++ b/firmware/src/driver/mcp4725.c @@ -0,0 +1,101 @@ +/** + * + * Author: Dylan Muller + * Copyright (c) 2025 + * All rights reserved. + * + * - Commercial/IP use prohibited. + * - Attribution required. + * See License.txt + * + */ + +#include "setup.h" + +#include "peripheral/twi.h" +#include "driver/mcp4725.h" + +#include +#include +#include + +void dac_init(uint16_t init_value) +{ + dac_write(MCP4725_ID_GATE_VOLT, init_value, 0); + dac_write(MCP4725_ID_DRAIN_VOLT, init_value, 0); + + _delay_ms(TRANSACT_DELAY_MS); +} + +void dac_write( + uint8_t id, + uint16_t value, + uint8_t conv_bypass +) +{ + uint8_t dev_addr = 0x0; + uint8_t cmd_buf[2] = {0x0, 0x0}; + uint8_t drain_mode = 0x0; + + switch(id) + { + case MCP4725_ID_GATE_VOLT: + dev_addr = TWI_ADDRESS_W(MCP4725_DEV_GATE_VOLT_ADDR); + break; + case MCP4725_ID_DRAIN_VOLT: + dev_addr = TWI_ADDRESS_W(MCP4725_DEV_DRAIN_VOLT_ADDR); + drain_mode = 1; + break; + } + + if (conv_bypass == 0) + { + if (drain_mode == 1) + { + value = (uint16_t)(((uint32_t)value * 10)/MCP4725_DRAIN_GAIN); + } + } + + cmd_buf[0] = ((value >> 8) & 0xF) | MCP4725_BIT_PD0(0) | MCP4725_BIT_PD1(0); + cmd_buf[1] = value & 0xFF; + + twi_start(dev_addr, cmd_buf, sizeof(cmd_buf)); + twi_flush(); +} + +uint16_t dac_read( + uint8_t id, + uint8_t conv_bypass +) +{ + uint8_t dev_addr = 0x0; + uint8_t cmd_buf[3] = {0x0, 0x0, 0x0}; + uint16_t value = 0x0; + uint8_t drain_mode = 0x0; + + switch(id) + { + case MCP4725_ID_GATE_VOLT: + dev_addr = TWI_ADDRESS_R(MCP4725_DEV_GATE_VOLT_ADDR); + break; + case MCP4725_ID_DRAIN_VOLT: + dev_addr = TWI_ADDRESS_R(MCP4725_DEV_DRAIN_VOLT_ADDR); + drain_mode = 1; + break; + } + + twi_start(dev_addr, cmd_buf, sizeof(cmd_buf)); + twi_flush(); + + value = (((uint16_t)cmd_buf[1]) << 4) | (cmd_buf[2] >> 4); + + if (conv_bypass == 0) + { + if (drain_mode) + { + value = (uint16_t)(((uint32_t)value * MCP4725_DRAIN_GAIN)/10); + } + } + + return (value & 0xFFF); +} diff --git a/firmware/src/driver/si4468.c b/firmware/src/driver/si4468.c new file mode 100644 index 0000000..17dd77d --- /dev/null +++ b/firmware/src/driver/si4468.c @@ -0,0 +1,201 @@ +/** + * + * Author: Dylan Muller + * Copyright (c) 2025 + * All rights reserved. + * + * - Commercial/IP use prohibited. + * - Attribution required. + * See License.txt + * + */ + +#include "setup.h" + +#include "peripheral/spi.h" + +#include "driver/si4468.h" +#include "driver/radio_config.h" +#include "driver/device.h" + +#include +#include +#include + +#include +#include +#include +#include +#include + + +static const uint8_t config[] PROGMEM = RADIO_CONFIGURATION_DATA_ARRAY; + +void si4468_init(void) +{ + SI4468_DEV_0_DDR |= (1 << SI4468_DEV_0_SS); + SI4468_DEV_0_PORT |= (1 << SI4468_DEV_0_SS); +} + +void si44468_get_device( + int id, + t_dev* device +) +{ + uint8_t dev_id = 0x0; + uint8_t dev_ss = 0x0; + uint8_t* dev_port = 0x0; + + device->dev_id = 0; + device->dev_ss = 0; + device->dev_port = 0; + + switch (id) + { + case SI4468_ID_RADIO: + dev_id = SI4468_DEV_RADIO; + break; + } + + switch (dev_id) + { + case SI4468_DEV_RADIO: + dev_ss = SI4468_DEV_0_SS; + dev_port = (uint8_t*)&SI4468_DEV_0_PORT; + break; + } + + device->dev_id = dev_id; + device->dev_ss = dev_ss; + device->dev_port = dev_port; +} + +static uint8_t si4468_get_response( + void* buf, + uint8_t len +) +{ + t_dev device; + uint8_t cts = 0x0; + uint8_t* cmd_buf = 0x0; + uint16_t cmd_size = 0x0; + uint8_t i = 0; + + si44468_get_device(SI4468_ID_RADIO, &device); + + cmd_size = len + SI4468_GET_RESP_LEN; + cmd_buf = (uint8_t*)malloc((cmd_size)); + + cmd_buf[0] = SI4468_CMD_READ_CMD_BUFF; + cmd_buf[1] = SI4468_CTS; + + spi_start(cmd_buf, cmd_buf, SI4468_GET_RESP_LEN, device.dev_port, device.dev_ss); + spi_flush(); + + cts = (cmd_buf[0] == SI4468_CTS); + + if(cts) + { + if (len > 0) + { + for(i = 0x0; i < cmd_size; i++) + { + cmd_buf[i] = SI4468_CTS; + } + + cmd_buf[0] = SI4468_CMD_READ_CMD_BUFF; + + spi_start(cmd_buf, cmd_buf, cmd_size, (uint8_t*)&SI4468_DEV_0_PORT, SI4468_DEV_0_SS); + spi_flush(); + + for(i = SI4468_GET_RESP_LEN; i < cmd_size; i++) + { + ((uint8_t*)buf)[i - SI4468_GET_RESP_LEN] = cmd_buf[i]; + } + + } + } + + free(cmd_buf); + + return cts; +} + +static uint8_t si4468_wait_for_response( + void* buf, + uint8_t buf_len +) +{ + while(!si4468_get_response(buf, buf_len)) + { + _delay_ms(10); + } + + return 1; +} + +static void si4468_exec_api( + void* in, + size_t in_len, + void* out, + uint8_t out_len +) +{ + t_dev device; + si44468_get_device(SI4468_ID_RADIO, &device); + + if (si4468_wait_for_response(0, 0)) + { + spi_start(in, 0, in_len, device.dev_port, device.dev_ss); + spi_flush(); + + if (out != 0) + { + si4468_wait_for_response(out, out_len); + } + } +} + +void si4468_apply_startup_config(void) +{ + uint16_t i = 0; + uint8_t buf[100]; + + for(i = 0; i < sizeof(config); i++) + { + memcpy_P(buf, &config[i], sizeof(buf)); + uint8_t tmp = buf[0]; + si4468_exec_api(&buf[1], tmp, 0, 0); + i += tmp; + } +} + +void si4468_get_info( + si4468_info_t* info +) +{ + uint8_t data[8] = { + SI4468_CMD_PART_INFO + }; + + si4468_exec_api(data, 1, data, 8); + + info->chipRev = data[0]; + info->part = (data[1]<<8) | data[2]; + info->partBuild = data[3]; + info->id = (data[4]<<8) | data[5]; + info->customer = data[6]; + info->romId = data[7]; +} + +void si4468_tx_mode(void) +{ + uint8_t packet[] = {SI4468_CMD_START_TX, 0,0,0, 0,0,0 }; + si4468_exec_api(packet, sizeof(packet), 0, 0); +} + +void si4468_rx_mode(void) +{ + uint8_t packet[] = {SI4468_CMD_CHANGE_STATE, 0x3}; + si4468_exec_api(packet, sizeof(packet), 0, 0); +} -- cgit v1.2.3-70-g09d2