updates lcd, monitor

pull/13/head
ArjanteMarvelde 2021-04-08 22:32:27 +02:00
rodzic 9984e43c16
commit fbe0e50663
5 zmienionych plików z 95 dodań i 77 usunięć

79
dsp.c
Wyświetl plik

@ -37,24 +37,6 @@
#include "dsp.h" #include "dsp.h"
/* Test sine waves 1, 2 and 4 kHz (@ 62.5kS/s rate) *
uint16_t wave1[64] =
{
500,549,597,645,691,735,777,817,853,886,915,940,961,978,990,997,999,997,990,978,961,940,915,886,853,817,777,735,691,645,597,549,
500,450,402,354,308,264,222,182,146,113,84,59,38,21,9,2,0,2,9,21,38,59,84,113,146,182,222,264,308,354,402,450
};
uint16_t wave2[64] =
{
500,597,691,777,853,915,961,990,999,990,961,915,853,777,691,597,500,402,308,222,146,84,38,9,0,9,38,84,146,222,308,402,
500,597,691,777,853,915,961,990,999,990,961,915,853,777,691,597,500,402,308,222,146,84,38,9,0,9,38,84,146,222,308,402
};
uint16_t wave4[64] =
{
500,691,853,961,999,961,853,691,500,308,146,38,0,38,146,308,500,691,853,961,999,961,853,691,500,308,146,38,0,38,146,308,
500,691,853,961,999,961,853,691,500,308,146,38,0,38,146,308,500,691,853,961,999,961,853,691,500,308,146,38,0,38,146,308
};
*/
/* /*
* DAC_RANGE defines PWM cycle, determining DAC resolution and PWM frequency. * DAC_RANGE defines PWM cycle, determining DAC resolution and PWM frequency.
* DAC resolution = Vcc / DAC_RANGE * DAC resolution = Vcc / DAC_RANGE
@ -63,12 +45,14 @@ uint16_t wave4[64] =
* ADC is 12 bit, so resolution is by definition 4096 * ADC is 12 bit, so resolution is by definition 4096
*/ */
#define DAC_RANGE 250 #define DAC_RANGE 250
#define DAC_BIAS DAC_RANGE/2
#define ADC_RANGE 4096 #define ADC_RANGE 4096
#define ADC_BIAS ADC_RANGE/2 #define ADC_BIAS ADC_RANGE/2
/* /*
* Callback timeout, determines frequency of TX and RX loops * Callback timeout and inter-core FIFO commands.
* Exact time is obtained by passing the value negative. * The timer value in usec determines frequency of TX and RX loops
* Exact time is obtained by passing the value as negative
* Here we use 16us (62.5 kHz == PWM freq/4 [or 8]) * Here we use 16us (62.5 kHz == PWM freq/4 [or 8])
*/ */
#define DSP_US 16 #define DSP_US 16
@ -78,7 +62,7 @@ uint16_t wave4[64] =
/* /*
* Low pass filters Fc=3, 7 and 15 kHz (see http://t-filter.engineerjs.com/) * Low pass filters Fc=3, 7 and 15 kHz (see http://t-filter.engineerjs.com/)
* for sample rates 62.500 , 31.250 or 15.625 kHz , stopband appr -40dB * for sample rates 62.500 , 31.250 or 15.625 kHz , stopband is appr -40dB
* 8 bit precision, so divide sum by 256 * 8 bit precision, so divide sum by 256
*/ */
int16_t lpf3_62[15] = { 3, 3, 5, 7, 9, 10, 11, 11, 11, 10, 9, 7, 5, 3, 3}; // Pass: 0-3000, Stop: 6000-31250 int16_t lpf3_62[15] = { 3, 3, 5, 7, 9, 10, 11, 11, 11, 10, 9, 7, 5, 3, 3}; // Pass: 0-3000, Stop: 6000-31250
@ -92,7 +76,10 @@ volatile uint16_t dac_iq, dac_audio;
volatile bool tx_enabled; volatile bool tx_enabled;
/* CORE1: RX branch */ /*
* CORE1:
* Execute RX branch signal processing
*/
volatile int16_t i_s[15], q_s[15], i_dc, q_dc, i_prev; volatile int16_t i_s[15], q_s[15], i_dc, q_dc, i_prev;
bool rx(void) bool rx(void)
{ {
@ -147,13 +134,6 @@ bool rx(void)
i_s[14] = (sample + i_prev)/2; // Correct for phase difference with Q samples i_s[14] = (sample + i_prev)/2; // Correct for phase difference with Q samples
i_prev = sample; // Remember last sample for next I-phase i_prev = sample; // Remember last sample for next I-phase
/*
* Hilbert transform: A0 = 2/128, A2 = 8/128, A4 = 21/128, A6 = 79/128
*/
// qh = (q_s[0]-q_s[14])/64 +
// (q_s[2]-q_s[12])/16 +
// (q_s[4]-q_s[10])/8 + (q_s[4]-q_s[10])*5/128 +
// (q_s[6]-q_s[ 8])/8 - (q_s[6]-q_s[8])/128 + (q_s[6]-q_s[8])/2;
/* /*
* Classic Hilbert transform 15 taps, 12 bits (see Iowa Hills): * Classic Hilbert transform 15 taps, 12 bits (see Iowa Hills):
*/ */
@ -166,7 +146,7 @@ bool rx(void)
* Add 250 offset and send to audio DAC output * Add 250 offset and send to audio DAC output
*/ */
sample = (i_s[7] - qh)/16; sample = (i_s[7] - qh)/16;
pwm_set_chan_level(dac_audio, PWM_CHAN_A, DAC_RANGE/2 + sample); pwm_set_chan_level(dac_audio, PWM_CHAN_A, DAC_BIAS + sample);
q_phase = true; // Next: Q branch q_phase = true; // Next: Q branch
} }
@ -175,7 +155,10 @@ bool rx(void)
} }
/* CORE1: TX branch */ /*
* CORE1:
* Execute TX branch signal processing
*/
volatile int16_t a_s_pre[15], a_s[15], a_dc; volatile int16_t a_s_pre[15], a_s[15], a_dc;
bool tx(void) bool tx(void)
{ {
@ -228,14 +211,17 @@ bool tx(void)
* Write I and Q to QSE DACs, phase is 7 back. * Write I and Q to QSE DACs, phase is 7 back.
* Need to multiply AC with DAC_RANGE/ADC_RANGE (appr 1/16, but compensate for losses) * Need to multiply AC with DAC_RANGE/ADC_RANGE (appr 1/16, but compensate for losses)
*/ */
pwm_set_chan_level(dac_iq, PWM_CHAN_A, DAC_RANGE/2 + (a_s[7]/8)); pwm_set_chan_level(dac_iq, PWM_CHAN_A, DAC_BIAS + (a_s[7]/8));
pwm_set_chan_level(dac_iq, PWM_CHAN_B, DAC_RANGE/2 + (qh/8)); pwm_set_chan_level(dac_iq, PWM_CHAN_B, DAC_BIAS + (qh/8));
return true; return true;
} }
/* CORE1: Timing loop, triggered through inter-core fifo */ /*
* CORE1:
* Timing loop, triggered through inter-core fifo
*/
void dsp_loop() void dsp_loop()
{ {
uint32_t cmd; uint32_t cmd;
@ -243,7 +229,7 @@ void dsp_loop()
while(1) while(1)
{ {
cmd = multicore_fifo_pop_blocking(); // Wait for fifo output cmd = multicore_fifo_pop_blocking(); // Wait for fifo output
if (cmd == DSP_TX) if (cmd == DSP_TX) // Change to switch(cmd) when more commands added
tx(); tx();
else else
rx(); rx();
@ -251,7 +237,11 @@ void dsp_loop()
} }
/* CORE0: Timer callback, triggers core1 through inter-core fifo */ /*
* CORE0:
* Timer callback, triggers core1 through inter-core fifo.
* Either TX or RX, but could do both when testing in loopback on I+Q channels.
*/
struct repeating_timer dsp_timer; struct repeating_timer dsp_timer;
bool dsp_callback(struct repeating_timer *t) bool dsp_callback(struct repeating_timer *t)
{ {
@ -264,18 +254,21 @@ bool dsp_callback(struct repeating_timer *t)
} }
/* CORE0: Initialize dsp context and spawn core1 process */ /*
* CORE0:
* Initialize dsp context and spawn core1 process
*/
void dsp_init() void dsp_init()
{ {
uint16_t slice_num; uint16_t slice_num;
/* Initialize DACs */ /* Initialize DACs */
// gpio_set_function(0, GPIO_FUNC_PWM); // GP0 is PWM for I DAC (Slice 0, Channel A) gpio_set_function(0, GPIO_FUNC_PWM); // GP0 is PWM for I DAC (Slice 0, Channel A)
// gpio_set_function(1, GPIO_FUNC_PWM); // GP1 is PWM for Q DAC (Slice 0, Channel B) gpio_set_function(1, GPIO_FUNC_PWM); // GP1 is PWM for Q DAC (Slice 0, Channel B)
// dac_iq = pwm_gpio_to_slice_num(0); // Get PWM slice for GP0 (Same for GP1) dac_iq = pwm_gpio_to_slice_num(0); // Get PWM slice for GP0 (Same for GP1)
// pwm_set_clkdiv_int_frac (dac_iq, 1, 0); // clock divide by 1 pwm_set_clkdiv_int_frac (dac_iq, 1, 0); // clock divide by 1
// pwm_set_wrap(dac_iq, DAC_RANGE); // Set cycle length pwm_set_wrap(dac_iq, DAC_RANGE); // Set cycle length
// pwm_set_enabled(dac_iq, true); // Set the PWM running pwm_set_enabled(dac_iq, true); // Set the PWM running
gpio_set_function(2, GPIO_FUNC_PWM); // GP2 is PWM for Audio DAC (Slice 1, Channel A) gpio_set_function(2, GPIO_FUNC_PWM); // GP2 is PWM for Audio DAC (Slice 1, Channel A)
dac_audio = pwm_gpio_to_slice_num(2); // Find PWM slice for GP2 dac_audio = pwm_gpio_to_slice_num(2); // Find PWM slice for GP2

57
lcd.c
Wyświetl plik

@ -10,6 +10,7 @@
* *
*/ */
#include <stdio.h> #include <stdio.h>
#include <string.h>
#include "pico/stdlib.h" #include "pico/stdlib.h"
#include "hardware/i2c.h" #include "hardware/i2c.h"
#include "hardware/timer.h" #include "hardware/timer.h"
@ -64,6 +65,8 @@
#define I2C0_SDA 8 #define I2C0_SDA 8
#define I2C0_SCL 9 #define I2C0_SCL 9
uint8_t lcd_buf[2][16]; // Buffer, y={0,1}, x={0..15}
uint8_t lcd_x, lcd_y;
void lcd_init(void) void lcd_init(void)
{ {
@ -93,11 +96,20 @@ void lcd_ctrl(uint8_t cmd, uint8_t x, uint8_t y)
switch(cmd) switch(cmd)
{ {
case LCD_CLEAR: case LCD_CLEAR:
for (lcd_x=0; lcd_x<16; lcd_x++)
{
lcd_buf[0][lcd_x] = ' ';
lcd_buf[1][lcd_x] = ' ';
}
lcd_y = 0x00;
lcd_x = 0x00;
txdata[1] = LCD_CLEARDISPLAY; txdata[1] = LCD_CLEARDISPLAY;
i2c_write_blocking(i2c0, I2C_LCD, txdata, 2, false); i2c_write_blocking(i2c0, I2C_LCD, txdata, 2, false);
sleep_us(1530); sleep_us(1530);
break; break;
case LCD_HOME: case LCD_HOME:
lcd_y = 0x00;
lcd_x = 0x00;
txdata[1] = LCD_RETURNHOME; txdata[1] = LCD_RETURNHOME;
i2c_write_blocking(i2c0, I2C_LCD, txdata, 2, false); i2c_write_blocking(i2c0, I2C_LCD, txdata, 2, false);
sleep_us(39); sleep_us(39);
@ -111,46 +123,63 @@ void lcd_ctrl(uint8_t cmd, uint8_t x, uint8_t y)
sleep_us(39); sleep_us(39);
break; break;
case LCD_GOTO: // 2-row is 0x00-0x27 per row, only 0x00-0x1F are visible case LCD_GOTO: // 2-row is 0x00-0x27 per row, only 0x00-0x1F are visible
lcd_y = y&0x01;
lcd_x = x&0x0f;
if (y==1) if (y==1)
txdata[1] = (x&0x0f) | 0xc0; txdata[1] = lcd_x | 0xc0;
else else
txdata[1] = (x&0x0f) | 0x80; txdata[1] = lcd_x | 0x80;
i2c_write_blocking(i2c0, I2C_LCD, txdata, 2, false); i2c_write_blocking(i2c0, I2C_LCD, txdata, 2, false);
sleep_us(39); sleep_us(39);
break; break;
} }
} }
void lcd_write(uint8_t *s, uint8_t len) void lcd_put(uint8_t c)
{ {
uint8_t i; uint8_t txdata[3];
uint8_t *p;
uint8_t txdata[8];
lcd_buf[lcd_y][lcd_x]=c;
lcd_x = (lcd_x<15)?(lcd_x + 1):lcd_x;
txdata[0] = 0x40; txdata[0] = 0x40;
p=s; txdata[1] = c;
for (i=0; i<len; i++)
{
txdata[1] = *p++;
i2c_write_blocking(i2c0, I2C_LCD, txdata, 2, false); i2c_write_blocking(i2c0, I2C_LCD, txdata, 2, false);
sleep_us(43); sleep_us(43);
}
} }
void lcd_write(uint8_t *s)
{
uint8_t i, len;
uint8_t txdata[18];
len = strlen(s);
len = (len>(16-lcd_x))?(16-lcd_x):len;
txdata[0] = 0x40;
for(i=0; i<len; i++)
{
lcd_buf[lcd_y][lcd_x++]=s[i];
txdata[i+1]=s[i];
}
i2c_write_blocking(i2c0, I2C_LCD, txdata, len+1, false);
sleep_us(43);
}
void lcd_test(void) void lcd_test(void)
{ {
uint8_t chr[16]; uint8_t chr[17];
int i, j; int i, j;
chr[16] = 0;
lcd_ctrl(LCD_CLEAR,0,0); lcd_ctrl(LCD_CLEAR,0,0);
for (i=0; i<16; i++) for (i=0; i<16; i++)
{ {
for(j=0; j<16; j++) chr[j] = (uint8_t)(16*i+j); for(j=0; j<16; j++) chr[j] = (uint8_t)(16*i+j);
lcd_ctrl(LCD_GOTO,0,0); lcd_ctrl(LCD_GOTO,0,0);
lcd_write(chr, 16); lcd_write(chr);
sleep_ms(800); sleep_ms(800);
lcd_ctrl(LCD_GOTO,0,1); lcd_ctrl(LCD_GOTO,0,1);
lcd_write(chr, 16); lcd_write(chr);
} }
lcd_ctrl(LCD_CLEAR,0,0); lcd_ctrl(LCD_CLEAR,0,0);
} }

3
lcd.h
Wyświetl plik

@ -20,7 +20,8 @@
void lcd_init(void); void lcd_init(void);
void lcd_ctrl(uint8_t cmd, uint8_t x, uint8_t y); void lcd_ctrl(uint8_t cmd, uint8_t x, uint8_t y);
void lcd_write(uint8_t *s, uint8_t len); void lcd_put(uint8_t c);
void lcd_write(uint8_t *s);
void lcd_test(void); void lcd_test(void);

Wyświetl plik

@ -71,7 +71,7 @@ void mon_init()
void mon_read(uint32_t timeout) void mon_read(uint32_t timeout)
{ {
int i = 0; static int i = 0;
int c = getchar_timeout_us(timeout); int c = getchar_timeout_us(timeout);
switch (c) switch (c)
{ {

25
uSDR.c
Wyświetl plik

@ -26,11 +26,11 @@
#include "monitor.h" #include "monitor.h"
uint8_t display1[16];
uint8_t display2[16];
/* LED TIMER definition and callback */ /*
* LED TIMER definition and callback routine
*/
struct repeating_timer led_timer; struct repeating_timer led_timer;
bool led_callback(struct repeating_timer *t) bool led_callback(struct repeating_timer *t)
{ {
@ -44,7 +44,6 @@ bool led_callback(struct repeating_timer *t)
int main() int main()
{ {
/* Initialize LED pin output */ /* Initialize LED pin output */
gpio_init(PICO_DEFAULT_LED_PIN); gpio_init(PICO_DEFAULT_LED_PIN);
gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT); gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT);
@ -55,27 +54,23 @@ int main()
si_init(); // VFO control unit si_init(); // VFO control unit
lcd_init(); // LCD output unit lcd_init(); // LCD output unit
dsp_init(); // Signal processing unit dsp_init(); // Signal processing unit
mon_init(); mon_init(); // Monitor shell on stdio
SI_SETFREQ(0, 2*7074000UL); // Set freq to 2*7074 kHz SI_SETFREQ(0, 2*7074000UL); // Set freq to 2*7074 kHz
SI_SETPHASE(0,2); // Set phase to 180deg SI_SETPHASE(0,2); // Set phase to 180deg
si_evaluate(); // Commit setting si_evaluate(); // Commit setting
lcd_test(); // Test LCD character set //lcd_test(); // Test LCD character set
lcd_ctrl(LCD_GOTO, 0, 0); lcd_ctrl(LCD_GOTO, 0, 0); // Go to (col, row)
sprintf(display1, " 7074.0 kHz"); lcd_write(" 7074.0 kHz USB"); // Max 16 char per line!
lcd_write(display1,11);
lcd_ctrl(LCD_GOTO, 1, 0); lcd_ctrl(LCD_GOTO, 1, 0);
lcd_ctrl(LCD_CURSOR, 1, 0); lcd_ctrl(LCD_CURSOR, 1, 0); // Switch cursor on
while (1) while (1)
{ {
/* Check for monitor input */ mon_read(100000L); // Check monitor input, wait max 100msec
mon_read(100000L); // Wait max 100msec si_evaluate(); // Check VFO settings
/* Check whether VFO settings have changed */
si_evaluate();
} }
return 0; return 0;