Solved I2C issue
Added uSDR.h containing the system wide definitions.
pull/13/head
ArjanteMarvelde 2022-08-13 16:08:08 +02:00
rodzic dff1711b96
commit a712c1c29b
12 zmienionych plików z 166 dodań i 158 usunięć

91
dsp.c
Wyświetl plik

@ -24,11 +24,11 @@
#include "hardware/timer.h"
#include "hardware/clocks.h"
#include "uSDR.h"
#include "dsp.h"
#include "hmi.h"
#include "fix_fft.h"
#define GP_PTT 15 // PTT pin 20 (GPIO 15)
volatile bool tx_enabled; // TX branch active
volatile uint32_t dsp_overrun; // Overrun counter
@ -354,14 +354,14 @@ bool __not_in_flash_func(dsp_callback)(repeating_timer_t *t)
if (tx_enabled)
{
A_buf[dsp_active][dsp_tick] = (int16_t)(tx_agc*adc_result[2]);
pwm_set_gpio_level(21, I_buf[dsp_active][dsp_tick] + DAC_BIAS); // Output I to DAC
pwm_set_gpio_level(20, Q_buf[dsp_active][dsp_tick] + DAC_BIAS); // Output Q to DAC
pwm_set_gpio_level(DAC_I, I_buf[dsp_active][dsp_tick] + DAC_BIAS); // Output I to DAC
pwm_set_gpio_level(DAC_Q, Q_buf[dsp_active][dsp_tick] + DAC_BIAS); // Output Q to DAC
}
else
{
I_buf[dsp_active][dsp_tick] = (int16_t)(rx_agc*adc_result[1]);
Q_buf[dsp_active][dsp_tick] = (int16_t)(rx_agc*adc_result[0]);
pwm_set_gpio_level(22, A_buf[dsp_active][dsp_tick] + DAC_BIAS); // Output A to DAC
pwm_set_gpio_level(DAC_A, A_buf[dsp_active][dsp_tick] + DAC_BIAS); // Output A to DAC
}
// When sample buffer is full, move pointer to next and signal the DSP loop
@ -378,12 +378,12 @@ bool __not_in_flash_func(dsp_callback)(repeating_timer_t *t)
if (tx_enabled)
{
a_sample = tx_agc * adc_result[2]; // Store A for DSP use
pwm_set_gpio_level(21, i_sample); // Output I to DAC
pwm_set_gpio_level(20, q_sample); // Output Q to DAC
pwm_set_gpio_level(DAC_I, i_sample); // Output I to DAC
pwm_set_gpio_level(DAC_Q, q_sample); // Output Q to DAC
}
else
{
pwm_set_gpio_level(22, a_sample); // Output Q to DAC
pwm_set_gpio_level(DAC_A, a_sample); // Output Q to DAC
q_sample = rx_agc * adc_result[0]; // Store Q for DSP use
i_sample = rx_agc * adc_result[1]; // Store I for DSP use
}
@ -413,15 +413,15 @@ void __not_in_flash_func(dsp_loop)()
* default mode is free running,
* A and B pins are output
*/
gpio_set_function(20, GPIO_FUNC_PWM); // GP20 is PWM for Q DAC (Slice 2, Channel A)
gpio_set_function(21, GPIO_FUNC_PWM); // GP21 is PWM for I DAC (Slice 2, Channel B)
dac_iq = pwm_gpio_to_slice_num(20); // Get PWM slice for GP20 (Same for GP21)
gpio_set_function(DAC_Q, GPIO_FUNC_PWM); // GP20 is PWM for Q DAC (Slice 2, Channel A)
gpio_set_function(DAC_I, GPIO_FUNC_PWM); // GP21 is PWM for I DAC (Slice 2, Channel B)
dac_iq = pwm_gpio_to_slice_num(DAC_Q); // Get PWM slice for GP20 (Same for GP21)
pwm_set_clkdiv_int_frac (dac_iq, 1, 0); // clock divide by 1: full system clock
pwm_set_wrap(dac_iq, DAC_RANGE-1); // Set cycle length; nr of counts until wrap, i.e. 125/DAC_RANGE MHz
pwm_set_enabled(dac_iq, true); // Set the PWM running
gpio_set_function(22, GPIO_FUNC_PWM); // GP22 is PWM for Audio DAC (Slice 3, Channel A)
dac_audio = pwm_gpio_to_slice_num(22); // Find PWM slice for GP22
gpio_set_function(DAC_A, GPIO_FUNC_PWM); // GP22 is PWM for Audio DAC (Slice 3, Channel A)
dac_audio = pwm_gpio_to_slice_num(DAC_A); // Find PWM slice for GP22
pwm_set_clkdiv_int_frac (dac_audio, 1, 0); // clock divide by 1: full system clock
pwm_set_wrap(dac_audio, DAC_RANGE-1); // Set cycle length; nr of counts until wrap, i.e. 125/DAC_RANGE MHz
pwm_set_enabled(dac_audio, true); // Set the PWM running
@ -431,9 +431,9 @@ void __not_in_flash_func(dsp_loop)()
* samples are stored in array through IRQ callback
*/
adc_init(); // Initialize ADC to known state
adc_gpio_init(26); // GP26 is ADC 0 for Q channel
adc_gpio_init(27); // GP27 is ADC 1 for I channel
adc_gpio_init(28); // GP28 is ADC 2 for Audio channel
adc_gpio_init(ADC_Q); // ADC GPIO for Q channel
adc_gpio_init(ADC_I); // ADC GPIO for I channel
adc_gpio_init(ADC_A); // ADC GPIO for Audio channel
adc_set_round_robin(0x01+0x02+0x04); // Sequence ADC 0-1-2 (GP 26, 27, 28) free running
adc_select_input(0); // Start with ADC0
adc_fifo_setup(true,true,3,false,false); // IRQ result, DMA req, fifo thr=3: xfer per 3 x 16 bits
@ -506,7 +506,7 @@ void __not_in_flash_func(dsp_loop)()
rx(); // Do RX signal processing
}
/////// This is a trap, ptt remains active after once asserted: to be checked!
/** !!! This is a trap, ptt remains active after once asserted: TO BE CHECKED! **/
tx_enabled = vox_active || ptt_active; // Check RX or TX
#if DSP_FFT == 1
@ -527,63 +527,4 @@ void dsp_init()
/* DMA EXAMPLE, should convert to chained DMA to reload after 3 words
// Init GPIO for analogue use: hi-Z, no pulls, disable digital input buffer.
adc_gpio_init(26 + CAPTURE_CHANNEL);
adc_init();
adc_select_input(CAPTURE_CHANNEL);
adc_fifo_setup(
true, // Write each completed conversion to the sample FIFO
true, // Enable DMA data request (DREQ)
1, // DREQ (and IRQ) asserted when at least 1 sample present
false, // We won't see the ERR bit because of 8 bit reads; disable.
true // Shift each sample to 8 bits when pushing to FIFO
);
// Divisor of 0 -> full speed. Free-running capture with the divider is
// equivalent to pressing the ADC_CS_START_ONCE button once per `div + 1`
// cycles (div not necessarily an integer). Each conversion takes 96
// cycles, so in general you want a divider of 0 (hold down the button
// continuously) or > 95 (take samples less frequently than 96 cycle
// intervals). This is all timed by the 48 MHz ADC clock.
adc_set_clkdiv(0);
printf("Arming DMA\n");
sleep_ms(1000);
// Set up the DMA to start transferring data as soon as it appears in FIFO
uint dma_chan = dma_claim_unused_channel(true);
dma_channel_config cfg = dma_channel_get_default_config(dma_chan);
// Reading from constant address, writing to incrementing byte addresses
channel_config_set_transfer_data_size(&cfg, DMA_SIZE_8);
channel_config_set_read_increment(&cfg, false);
channel_config_set_write_increment(&cfg, true);
// Pace transfers based on availability of ADC samples
channel_config_set_dreq(&cfg, DREQ_ADC);
dma_channel_configure(dma_chan, &cfg,
capture_buf, // dst
&adc_hw->fifo, // src
CAPTURE_DEPTH, // transfer count
true // start immediately
);
printf("Starting capture\n");
adc_run(true);
// Once DMA finishes, stop any new conversions from starting, and clean up
// the FIFO in case the ADC was still mid-conversion.
dma_channel_wait_for_finish_blocking(dma_chan);
printf("Capture finished\n");
adc_run(false);
adc_fifo_drain();
// Print samples to stdout so you can display them in pyplot, excel, matlab
for (int i = 0; i < CAPTURE_DEPTH; ++i) {
printf("%-3d, ", capture_buf[i]);
if (i % 10 == 9)
printf("\n");
}
*/

4
dsp.h
Wyświetl plik

@ -13,10 +13,6 @@
*
*/
#define DSP_FFT 1
/*
* Callback timeout is TIM_US, value in usec

Wyświetl plik

@ -53,7 +53,7 @@
*
*/
#include "uSDR.h"
/*
* FFT buffer allocation

Wyświetl plik

@ -28,6 +28,7 @@
*
*/
#include "uSDR.h"
/*
* Low pass FIR filters Fc=3, 7 and 15 kHz (see http://t-filter.engineerjs.com/)

13
hmi.c
Wyświetl plik

@ -29,10 +29,11 @@
#include <stdio.h>
#include <string.h>
#include "pico/stdlib.h"
#include "hardware/i2c.h"
#include "hardware/timer.h"
#include "hardware/clocks.h"
#include "hardware/gpio.h"
#include "uSDR.h"
#include "lcd.h"
#include "hmi.h"
#include "dsp.h"
@ -40,15 +41,8 @@
#include "relay.h"
/*
* GPIO assignments
* GPIO masks
*/
#define GP_ENC_A 2
#define GP_ENC_B 3
#define GP_AUX_0 6 // Enter, Confirm
#define GP_AUX_1 7 // Escape, Cancel
#define GP_AUX_2 8 // Left move
#define GP_AUX_3 9 // Right move
#define GP_PTT 15
#define GP_MASK_IN ((1<<GP_ENC_A)|(1<<GP_ENC_B)|(1<<GP_AUX_0)|(1<<GP_AUX_1)|(1<<GP_AUX_2)|(1<<GP_AUX_3)|(1<<GP_PTT))
#define GP_MASK_PTT (1<<GP_PTT)
@ -340,7 +334,6 @@ void hmi_evaluate(void)
dsp_setvox(hmi_sub[HMI_S_VOX]);
dsp_setagc(hmi_sub[HMI_S_AGC]);
relay_setband(hmi_bpf[hmi_sub[HMI_S_BPF]]);
sleep_ms(1); // I2C doesn't work without...
relay_setattn(hmi_pre[hmi_sub[HMI_S_PRE]]);
hmi_update = false;
}

2
hmi.h
Wyświetl plik

@ -9,8 +9,6 @@
* See hmi.c for more information
*/
#define CARRIER_OFFSET 3500
extern bool ptt_active;
void hmi_init(void);

49
lcd.c
Wyświetl plik

@ -4,11 +4,10 @@
* Created: Mar 2021
* Author: Arjan te Marvelde
*
* --> Set I2C address below!
* --> Select LCD_TYPE below!
*
* Driver for 16x2 HD44780 based LCD displays.
* There exist many different types, so you may need to adapt some of the code.
* => LCD Address and Type are chosen in uSDR.h!
*
* This file contains the driver for 16x2 HD44780 based LCD displays.
* Many different types exist, so you may need to adapt some of the code.
* Most notably the startup sequence and the way bytes are sent over the I2C interface.
* But also the register mappings as described below.
*
@ -46,19 +45,10 @@
#include "hardware/i2c.h"
#include "hardware/timer.h"
#include "hardware/clocks.h"
#include "uSDR.h"
#include "lcd.h"
/** User selectable definitions **/
// Set I2C address for your device
#define I2C_LCD 0x3E // Grove: 0x3E, 8574 backpack: 0x20..0x27
// Select LCD type to match your device,
// or define a new one when code changes are needed.
#define LCD_1804 0 // Seeed / Grove
#define LCD_8574_ADA 1 // Adafruit I2C backpack
#define LCD_8574_GEN 2 // Generic I2C backpack
#define LCD_TYPE LCD_1804
/** Generic HD44780 interface **/
// commands
@ -100,19 +90,20 @@
#define LCD_5x8DOTS 0x00
/** I2C interface specific mappings **/
// 1804-based specific bitmasks
// 1804-based specific bitmasks (Seeed/Grove)
#define LCD_COMMAND 0x80
#define LCD_DATA 0x40
#define LCD_INIT_1804 (LCD_FUNCTIONSET | LCD_8BITMODE | LCD_2LINE | LCD_5x8DOTS)
// 8574-based specific bitmasks
// 8574-based specific bitmasks (Adafruit)
#define LCD_COMMAND_ADA 0x00
#define LCD_DATA_ADA 0x02
#define LCD_BACKLIGHT_ADA 0x80
#define LCD_ENABLE_ADA 0x04
#define LCD_INIT_ADA (LCD_FUNCTIONSET | LCD_4BITMODE | LCD_2LINE | LCD_5x8DOTS)
// 8574-based specific bitmasks (Generic)
#define LCD_COMMAND_GEN 0x00
#define LCD_DATA_GEN 0x01
#define LCD_ENABLE_GEN 0x04
@ -131,9 +122,6 @@
#endif
/** Other definitions **/
#define LCD_DELAY 100 // Delay for regular write
/*
* User defined (CGRAM) characters
@ -164,8 +152,7 @@ void lcd_sendbyte(uint8_t command, uint8_t data)
// Write command/data flag and data byte
txdata[0] = (command?LCD_COMMAND:LCD_DATA);
txdata[1] = data;
i2c_write_blocking(i2c1, I2C_LCD, txdata, 2, false);
sleep_us(LCD_DELAY);
i2c_put_data(i2c1, I2C_LCD, txdata, 2, false);
#endif
#if LCD_TYPE == LCD_8574_ADA
@ -175,15 +162,15 @@ void lcd_sendbyte(uint8_t command, uint8_t data)
// Write high nibble
high |= LCD_ENABLE_ADA;
i2c_write_blocking(i2c1, I2C_LCD, &high, 1, false); sleep_us(LCD_DELAY);
i2c_put_data(i2c1, I2C_LCD, &high, 1, false);
high &= ~LCD_ENABLE_ADA;
i2c_write_blocking(i2c1, I2C_LCD, &high, 1, false); sleep_us(LCD_DELAY);
i2c_put_data(i2c1, I2C_LCD, &high, 1, false);
// Write low nibble
low |= LCD_ENABLE_ADA;
i2c_write_blocking(i2c1, I2C_LCD, &low, 1, false); sleep_us(LCD_DELAY);
i2c_put_data(i2c1, I2C_LCD, &low, 1, false);
low &= ~LCD_ENABLE_ADA;
i2c_write_blocking(i2c1, I2C_LCD, &low, 1, false); sleep_us(LCD_DELAY);
i2c_put_data(i2c1, I2C_LCD, &low, 1, false);
#endif
#if LCD_TYPE == LCD_8574_GEN
@ -193,15 +180,15 @@ void lcd_sendbyte(uint8_t command, uint8_t data)
// Write high nibble
high |= LCD_ENABLE_GEN;
i2c_write_blocking(i2c1, I2C_LCD, &high, 1, false); sleep_us(LCD_DELAY);
i2c_put_data(i2c1, I2C_LCD, &high, 1, false);
high &= ~LCD_ENABLE_GEN;
i2c_write_blocking(i2c1, I2C_LCD, &high, 1, false); sleep_us(LCD_DELAY);
i2c_put_data(i2c1, I2C_LCD, &high, 1, false);
// Write low nibble
low |= LCD_ENABLE_GEN;
i2c_write_blocking(i2c1, I2C_LCD, &low, 1, false); sleep_us(LCD_DELAY);
i2c_put_data(i2c1, I2C_LCD, &low, 1, false);
low &= ~LCD_ENABLE_GEN;
i2c_write_blocking(i2c1, I2C_LCD, &low, 1, false); sleep_us(LCD_DELAY);
i2c_put_data(i2c1, I2C_LCD, &low, 1, false);
#endif
}

Wyświetl plik

@ -14,6 +14,7 @@
#include <string.h>
#include "pico/stdlib.h"
#include "uSDR.h"
#include "lcd.h"
#include "si5351.h"
#include "dsp.h"
@ -21,12 +22,15 @@
#include "monitor.h"
// Some special character ASCII codes
#define CR 13
#define LF 10
#define SP 32
#define CMD_LEN 80
#define CMD_ARGS 16
char mon_cmd[CMD_LEN+1]; // Command string buffer
char *argv[CMD_ARGS]; // Argument pointers
int nargs; // Nr of arguments

17
relay.c
Wyświetl plik

@ -25,12 +25,11 @@
#include "pico/stdlib.h"
#include "hardware/i2c.h"
#include "uSDR.h"
#include "relay.h"
/* I2C address and pins */
#define I2C_RX 0x21
#define I2C_BPF 0x20
void relay_setband(int val)
@ -39,8 +38,8 @@ void relay_setband(int val)
int ret;
data[0] = ((uint8_t)val)&0x1f;
if (i2c_write_blocking(i2c1, I2C_BPF, data, 1, false) < 0)
i2c_write_blocking(i2c1, I2C_BPF, data, 1, false);
if (i2c_put_data(i2c1, I2C_BPF, data, 1, false) < 0)
i2c_put_data(i2c1, I2C_BPF, data, 1, false);
sleep_ms(1);
}
@ -49,7 +48,7 @@ int relay_getband(void)
uint8_t data[2];
int ret;
ret = i2c_read_blocking(i2c1, I2C_BPF, data, 1, false);
ret = i2c_get_data(i2c1, I2C_BPF, data, 1, false);
if (ret>=0)
ret=data[0];
return(ret);
@ -60,8 +59,8 @@ void relay_setattn(int val)
uint8_t data[2];
data[0] = ((uint8_t)val)&0x07;
if (i2c_write_blocking(i2c1, I2C_RX, data, 1, false) < 0)
i2c_write_blocking(i2c1, I2C_RX, data, 1, false);
if (i2c_put_data(i2c1, I2C_RX, data, 1, false) < 0)
i2c_put_data(i2c1, I2C_RX, data, 1, false);
sleep_ms(1);
}
@ -70,7 +69,7 @@ int relay_getattn(void)
uint8_t data[2];
int ret;
ret = i2c_read_blocking(i2c1, I2C_RX, data, 1, false);
ret = i2c_get_data(i2c1, I2C_RX, data, 1, false);
if (ret>=0)
ret=data[0];
return(ret);

Wyświetl plik

@ -149,9 +149,10 @@ Control Si5351 (see AN619):
#include "hardware/i2c.h"
#include "hardware/timer.h"
#include "hardware/clocks.h"
#include "uSDR.h"
#include "si5351.h"
#define I2C_VFO 0x60 // I2C address
// SI5351 register address definitions
#define SI_CLK_OE 3
@ -234,14 +235,14 @@ void si_enable(int i, bool en)
if ((i<0)||(i>1)) return; // Check VFO range
data[0] = SI_CLK_OE; // Read OE register
i2c_write_blocking(i2c0, I2C_VFO, &data[0], 1, true);
i2c_put_data(i2c0, I2C_VFO, &data[0], 1, true);
i2c_read_blocking(i2c0, I2C_VFO, &data[1], 1, false);
if (i==0)
data[1] = en ? data[1]&~SI_VFO0_DISABLE : data[1]|SI_VFO0_DISABLE; // clk0 and clk1
else
data[1] = en ? data[1]&~SI_VFO1_DISABLE : data[1]|SI_VFO1_DISABLE; // clk2
i2c_write_blocking(i2c0, I2C_VFO, &data[0], 2, false);
i2c_put_data(i2c0, I2C_VFO, &data[0], 2, false);
}
/*
@ -251,9 +252,9 @@ int si_getreg(uint8_t *data, uint8_t reg, uint8_t len)
{
int ret;
ret = i2c_write_blocking(i2c0, I2C_VFO, &reg, 1, true);
ret = i2c_put_data(i2c0, I2C_VFO, &reg, 1, true);
if (ret<0) printf ("I2C write error\n");
ret = i2c_read_blocking(i2c0, I2C_VFO, data, len, false);
ret = i2c_get_data(i2c0, I2C_VFO, data, len, false);
if (ret<0) printf ("I2C read error\n");
return(len);
}
@ -299,7 +300,7 @@ void si_setmsn(int i)
data[6] = ((SI_PLL_C & 0x000F0000) >> 12) | ((P2 & 0x000F0000) >> 16);
data[7] = (P2 & 0x0000FF00) >> 8;
data[8] = (P2 & 0x000000FF);
i2c_write_blocking(i2c0, I2C_VFO, data, 9, false);
i2c_put_data(i2c0, I2C_VFO, data, 9, false);
}
/*
@ -338,59 +339,56 @@ void si_setmsi(int i)
data[6] = 0x00;
data[7] = 0x00;
data[8] = 0x00;
i2c_write_blocking(i2c0, I2C_VFO, data, 9, false);
i2c_put_data(i2c0, I2C_VFO, data, 9, false);
// If vfo[0] also set clk 1 and phase offset, (integer mode(?) and high drive current for low phase noise).
if (i==0)
{
data[0] = SI_SYNTH_MS1; // Same data in synthesizer
i2c_write_blocking(i2c0, I2C_VFO, data, 9, false);
i2c_put_data(i2c0, I2C_VFO, data, 9, false);
if ((vfo[0].phase==PH090)||(vfo[0].phase==PH270)) // Phase is 90 or 270 deg?
{
data[0] = SI_CLK1_PHOFF;
data[1] = vfo[0].msi; // offset == MSi for 90deg
i2c_write_blocking(i2c0, I2C_VFO, data, 2, false);
i2c_put_data(i2c0, I2C_VFO, data, 2, false);
}
else // Phase is 0 or 180 deg
{
data[0] = SI_CLK1_PHOFF;
data[1] = 0; // offset == 0 for 0deg
i2c_write_blocking(i2c0, I2C_VFO, data, 2, false);
i2c_put_data(i2c0, I2C_VFO, data, 2, false);
}
sleep_us(500);
if ((vfo[0].phase==PH180)||(vfo[0].phase==PH270)) // Phase is 180 or 270 deg?
{
data[0] = SI_CLK0_CTL; // set the invert flag
data[1] = SI_VFO0CTL; // CLK0: nonINV
data[2] = SI_VFO0CTL | SI_CLK_INV; // CLK1: INV
i2c_write_blocking(i2c0, I2C_VFO, data, 3, false);
i2c_put_data(i2c0, I2C_VFO, data, 3, false);
}
else
{
data[0] = SI_CLK0_CTL; // set the invert flag
data[1] = SI_VFO0CTL; // CLK0: nonINV
data[2] = SI_VFO0CTL; // CLK1: nonINV
i2c_write_blocking(i2c0, I2C_VFO, data, 3, false);
i2c_put_data(i2c0, I2C_VFO, data, 3, false);
}
// Reset PLL A (use with care, this causes a click)
sleep_us(500);
data[0] = SI_PLL_RESET;
data[1] = SI_PLLA_RST|SI_PLLB_RST;
i2c_write_blocking(i2c0, I2C_VFO, data, 2, false);
i2c_put_data(i2c0, I2C_VFO, data, 2, false);
}
else
{
data[0] = SI_CLK2_CTL; // set the invert flag
data[1] = SI_VFO1CTL; // CLK2: nonINV
i2c_write_blocking(i2c0, I2C_VFO, data, 2, false);
i2c_put_data(i2c0, I2C_VFO, data, 2, false);
// Reset PLL B (use with care, this causes a click)
sleep_us(500);
data[0] = SI_PLL_RESET;
data[1] = SI_PLLA_RST|SI_PLLB_RST;
i2c_write_blocking(i2c0, I2C_VFO, data, 2, false);
i2c_put_data(i2c0, I2C_VFO, data, 2, false);
}
}
@ -457,14 +455,14 @@ void si_init(void)
// Disable spread spectrum (startup state is undefined)
data[0] = SI_SS_EN;
data[1] = 0x00;
i2c_write_blocking(i2c0, I2C_VFO, data, 2, false);
i2c_put_data(i2c0, I2C_VFO, data, 2, false);
// First time init of clock control registers
data[0] = SI_CLK0_CTL;
data[1] = SI_VFO0CTL;
data[2] = SI_VFO0CTL;
data[3] = SI_VFO1CTL;
i2c_write_blocking(i2c0, I2C_VFO, data, 4, false);
i2c_put_data(i2c0, I2C_VFO, data, 4, false);
// Initialize VFO values
vfo[0].freq = 7074000;

29
uSDR.c
Wyświetl plik

@ -22,6 +22,7 @@
#include "hardware/timer.h"
#include "hardware/clocks.h"
#include "uSDR.h"
#include "hmi.h"
#include "lcd.h"
#include "dsp.h"
@ -30,15 +31,30 @@
#include "relay.h"
#define I2C0_SDA 16
#define I2C0_SCL 17
#define I2C1_SDA 18
#define I2C1_SCL 19
/*
* Wrappers around i2c_write_blocking() and i2c_read_blocking()
* The SDK functions return too soon, potentially causing overlapping calls
*/
int i2c_put_data(i2c_inst_t *i2c, uint8_t addr, const uint8_t *src, size_t len, bool nostop)
{
int r = i2c_write_blocking(i2c, addr, src, len, nostop);
sleep_us(I2C_LINGER_US);
return(r);
}
int i2c_get_data(i2c_inst_t *i2c, uint8_t addr, uint8_t *dst, size_t len, bool nostop)
{
int r = i2c_read_blocking(i2c, addr, dst, len, nostop);
sleep_us(I2C_LINGER_US);
return(r);
}
/*
* LED TIMER definition and callback routine
*/
#define LED_MS 1000
struct repeating_timer led_timer;
bool led_callback(struct repeating_timer *t)
{
@ -49,11 +65,11 @@ bool led_callback(struct repeating_timer *t)
return true;
}
/*
* Scheduler callback function.
* This executes every LOOP_MS.
*/
#define LOOP_MS 100
semaphore_t loop_sem;
struct repeating_timer loop_timer;
bool loop_callback(struct repeating_timer *t)
@ -66,6 +82,7 @@ bool loop_callback(struct repeating_timer *t)
int main()
{
/*
* Main loop rnning on Core 0
* Optional: increase core voltage (normally 1.1V)
* Optional: overclock the CPU to 250MHz (normally 125MHz)
* Note that clk_peri (e.g. I2C) is derived from the SYS PLL

74
uSDR.h 100644
Wyświetl plik

@ -0,0 +1,74 @@
#ifndef __USDR_H__
#define __USDR_H__
/*
* uSDR.h
*
* Created: Aug 2022
* Author: Arjan te Marvelde
*
* This file contains the system-wide definitions and platform services.
*
*/
#include "hardware/i2c.h"
/* Set this to 1 when FFT engine must be used */
#define DSP_FFT 1
/* GPIO (pin) assignments */
#define GP_ENC_A 2 // Pin 4: Encoder channel A
#define GP_ENC_B 3 // Pin 5: Encoder channel B
#define GP_AUX_0 6 // Pin 9: Enter, Confirm
#define GP_AUX_1 7 // Pin 10: Escape, Cancel
#define GP_AUX_2 8 // Pin 11: Left move
#define GP_AUX_3 9 // Pin 12: Right move
#define GP_PTT 15 // Pin 20: PTT line (low is active)
#define I2C0_SDA 16 // Pin 21: I2C channel 0 - data
#define I2C0_SCL 17 // Pin 22: I2C channel 0 - clock
#define I2C1_SDA 18 // Pin 24: I2C channel 1 - data
#define I2C1_SCL 19 // Pin 25: I2C channel 1 - clock
#define DAC_Q 20 // Pin 26: PWM DAC Q channel
#define DAC_I 21 // Pin 27: PWM DAC I channel
#define DAC_A 22 // Pin 29: PWM DAC Audio channel
#define ADC_Q 26 // Pin 31: ADC 0
#define ADC_I 27 // Pin 32: ADC 1
#define ADC_A 28 // Pin 34: ADC 2
/* Timer values */
#define LED_MS 1000 // LED flashing, half cycle duration
#define LOOP_MS 100 // Core 0 main loop timer (see also uSDR.c)
/* I2C addresses */
#define I2C_RX 0x21 // Expander on Rx board
#define I2C_BPF 0x20 // Expander on Filter board
#define I2C_VFO 0x60 // Si5351A
#define I2C_LCD 0x3E // Grove: 0x3E, 8574 backpack range: 0x20..0x27
/* I2C wrapper functions (blocking write and read) */
#define I2C_LINGER_US 200 // Linger time added after i2c SDK functions
int i2c_put_data(i2c_inst_t *i2c, uint8_t addr, const uint8_t *src, size_t len, bool nostop);
int i2c_get_data(i2c_inst_t *i2c, uint8_t addr, uint8_t *dst, size_t len, bool nostop);
/* LCD type selection (see also lcd.c) */
#define LCD_1804 0 // Type 0: Seeed / Grove
#define LCD_8574_ADA 1 // Type 1: Adafruit I2C backpack
#define LCD_8574_GEN 2 // Type 2: Generic I2C backpack
#define LCD_TYPE LCD_1804 // Active selection
#endif