Skip to content

Commit

Permalink
Mitigate si5351 PLL unlock issue by reference to https://github.com/q…
Browse files Browse the repository at this point in the history
  • Loading branch information
AA6KL committed Nov 16, 2019
1 parent 9ddd1ce commit 015b619
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 25 deletions.
20 changes: 14 additions & 6 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ int8_t sweep_once = FALSE;
int8_t cal_auto_interpolate = TRUE;
uint16_t redraw_request = 0; // contains REDRAW_XXX flags
int16_t vbat = 0;
bool pll_lock_failed;


static THD_WORKING_AREA(waThread1, 640);
Expand Down Expand Up @@ -90,6 +91,10 @@ static THD_FUNCTION(Thread1, arg)
draw_battery_status();
}

if (pll_lock_failed) {
draw_pll_lock_error();
}

/* calculate trace coordinates and plot only if scan completed */
if (completed) {
plot_into_index(measured);
Expand Down Expand Up @@ -664,6 +669,7 @@ ensure_edit_config(void)
// main loop for measurement
bool sweep(bool break_on_operation)
{
pll_lock_failed = false;
int i;

for (i = 0; i < sweep_points; i++) {
Expand Down Expand Up @@ -2044,10 +2050,16 @@ int main(void)
palClearPad(GPIOC, GPIOC_LED);
chMtxObjectInit(&mutex);

// SPI LCD Initialize
ili9341_init();
ili9341_fill(0, 0, 320, 240, 0x0000);

//palSetPadMode(GPIOB, 8, PAL_MODE_ALTERNATE(1) | PAL_STM32_OTYPE_OPENDRAIN);
//palSetPadMode(GPIOB, 9, PAL_MODE_ALTERNATE(1) | PAL_STM32_OTYPE_OPENDRAIN);
i2cStart(&I2CD1, &i2ccfg);
si5351_init();
while (!si5351_init()) {
ili9341_drawstring_size("error: si5351_init failed", 0, 0, RGBHEX(0xff0000), 0x0000, 2);
}

// MCO on PA8
//palSetPadMode(GPIOA, 8, PAL_MODE_ALTERNATE(0));
Expand All @@ -2067,11 +2079,6 @@ int main(void)
usbStart(serusbcfg.usbp, &usbcfg);
usbConnectBus(serusbcfg.usbp);

/*
* SPI LCD Initialize
*/
ili9341_init();

/*
* Initialize graph plotting
*/
Expand Down Expand Up @@ -2112,6 +2119,7 @@ int main(void)
*/
shellInit();

chThdSetPriority(HIGHPRIO);
chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO, Thread1, NULL);

while (1) {
Expand Down
5 changes: 5 additions & 0 deletions nanovna.h
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,7 @@ float get_trace_scale(int t);
float get_trace_refpos(int t);
const char *get_trace_typename(int t);
void draw_battery_status(void);
void draw_pll_lock_error(void);

void set_electrical_delay(float picoseconds);
float get_electrical_delay(void);
Expand Down Expand Up @@ -301,11 +302,15 @@ extern uint16_t redraw_request;
#define REDRAW_MARKER (1<<3)

extern int16_t vbat;
extern bool pll_lock_failed;


/*
* ili9341.c
*/
#define RGB565(b,r,g) ( (((b)<<8)&0xfc00) | (((r)<<2)&0x03e0) | (((g)>>3)&0x001f) )
#define RGB(r,g,b) ( (((g)&0x1c)<<11) | (((b)&0xf8)<<5) | ((r)&0xf8) | (((g)&0xe0)>>5) )
#define RGBHEX(hex) ( (((hex)&0x001c00)<<3) | (((hex)&0x0000f8)<<5) | (((hex)&0xf80000)>>16) | (((hex)&0x00e000)>>13) )

typedef struct {
uint16_t width;
Expand Down
17 changes: 15 additions & 2 deletions plot.c
Original file line number Diff line number Diff line change
Expand Up @@ -1748,8 +1748,21 @@ draw_battery_status(void)
ili9341_bulk(0, 1, w, h);
}

void
request_to_redraw_grid(void)
void draw_pll_lock_error(void)
{
int y = 1+7*2;
ili9341_fill(0, y, 10, 4*7, RGBHEX(0x000000));
y += 4;
ili9341_fill(1, y, 8, 3*7+4, RGBHEX(0xff0000));
y += 2;
ili9341_drawchar_5x7('P', 3, y, RGBHEX(0x000000), RGBHEX(0xff0000));
y+=7;
ili9341_drawchar_5x7('L', 3, y, RGBHEX(0x000000), RGBHEX(0xff0000));
y+=7;
ili9341_drawchar_5x7('L', 3, y, RGBHEX(0x000000), RGBHEX(0xff0000));
}

void request_to_redraw_grid(void)
{
force_set_markmap();
redraw_request |= REDRAW_CELLS;
Expand Down
82 changes: 66 additions & 16 deletions si5351.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,27 +23,36 @@

#define SI5351_I2C_ADDR (0x60<<1)

static void
si5351_write(uint8_t reg, uint8_t dat)
static bool si5351_bulk_read(uint8_t reg, uint8_t* buf, int len)
{
int addr = SI5351_I2C_ADDR>>1;
i2cAcquireBus(&I2CD1);
msg_t mr = i2cMasterTransmitTimeout(&I2CD1, addr, &reg, 1, buf, len, 1000);
i2cReleaseBus(&I2CD1);
return mr == MSG_OK;
}

static bool si5351_write(uint8_t reg, uint8_t dat)
{
int addr = SI5351_I2C_ADDR>>1;
uint8_t buf[] = { reg, dat };
i2cAcquireBus(&I2CD1);
(void)i2cMasterTransmitTimeout(&I2CD1, addr, buf, 2, NULL, 0, 1000);
msg_t mr = i2cMasterTransmitTimeout(&I2CD1, addr, buf, 2, NULL, 0, 1000);
i2cReleaseBus(&I2CD1);
return mr == MSG_OK;
}

static void
si5351_bulk_write(const uint8_t *buf, int len)
static bool si5351_bulk_write(const uint8_t *buf, int len)
{
int addr = SI5351_I2C_ADDR>>1;
i2cAcquireBus(&I2CD1);
(void)i2cMasterTransmitTimeout(&I2CD1, addr, buf, len, NULL, 0, 1000);
msg_t mr = i2cMasterTransmitTimeout(&I2CD1, addr, buf, len, NULL, 0, 1000);
i2cReleaseBus(&I2CD1);
return mr == MSG_OK;
}

// register addr, length, data, ...
const uint8_t si5351_configs[] = {
static const uint8_t si5351_configs[] = {
2, SI5351_REG_3_OUTPUT_ENABLE_CONTROL, 0xff,
4, SI5351_REG_16_CLK0_CONTROL, SI5351_CLK_POWERDOWN, SI5351_CLK_POWERDOWN, SI5351_CLK_POWERDOWN,
2, SI5351_REG_183_CRYSTAL_LOAD, SI5351_CRYSTAL_LOAD_8PF,
Expand All @@ -58,15 +67,53 @@ const uint8_t si5351_configs[] = {
0 // sentinel
};

void
si5351_init(void)
static bool si5351_wait_ready(void)
{
uint8_t status = 0xff;
systime_t start = chVTGetSystemTime();
systime_t end = start + MS2ST(1000); // 1000 ms timeout
while (chVTIsSystemTimeWithin(start, end))
{
if(!si5351_bulk_read(0, &status, 1))
status = 0xff; // comm timeout
if ((status & 0x80) == 0)
return true;
}
return false;
}

static void si5351_wait_pll_lock(void)
{
systime_t start = chVTGetSystemTime();
uint8_t status = 0xff;
if(!si5351_bulk_read(0, &status, 1))
status = 0xff; // comm timeout
if ((status & 0x60) == 0)
return;
systime_t end = start + MS2ST(100); // 100 ms timeout
while (chVTIsSystemTimeWithin(start, end))
{
if(!si5351_bulk_read(0, &status, 1))
status = 0xff; // comm timeout
if ((status & 0x60) == 0)
return;
chThdSleepMilliseconds(10);
}
pll_lock_failed = true;
}

bool si5351_init(void)
{
if (!si5351_wait_ready())
return false;
const uint8_t *p = si5351_configs;
while (*p) {
uint8_t len = *p++;
si5351_bulk_write(p, len);
if (!si5351_bulk_write(p, len))
return false;
p += len;
}
return true;
}

void si5351_disable_output(void)
Expand Down Expand Up @@ -291,14 +338,15 @@ si5351_set_frequency(int channel, int freq, uint8_t drive_strength)
} else {
si5351_set_frequency_fixeddiv(channel, SI5351_PLL_B, freq, 4, drive_strength);
}
si5351_wait_pll_lock();
}


int current_band = -1;
static int current_band = -1;

#define DELAY_NORMAL 3
#define DELAY_BANDCHANGE 2
#define DELAY_LOWBAND 1
#define DELAY_BANDCHANGE 10
#define DELAY_LOWBAND 2

/*
* configure output as follows:
Expand Down Expand Up @@ -390,13 +438,15 @@ si5351_set_frequency_with_offset(uint32_t freq, int offset, uint8_t drive_streng

if (current_band != band) {
si5351_reset_pll();
si5351_reset_pll();
si5351_wait_pll_lock();
#if 1
si5351_enable_output();
#endif
delay += DELAY_BANDCHANGE;
}
if (band == 0)
delay += DELAY_LOWBAND;
}
//if (band == 0)
// delay += DELAY_LOWBAND;

current_band = band;
return delay;
Expand Down
10 changes: 9 additions & 1 deletion si5351.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#ifndef __SI5351_H__
#define __SI5351_H__

#include <stdbool.h>
#include <stdint.h>

#define SI5351_PLL_A 0
#define SI5351_PLL_B 1

Expand Down Expand Up @@ -72,7 +78,7 @@

#define SI5351_CRYSTAL_FREQ_25MHZ 25000000

void si5351_init(void);
bool si5351_init(void);

void si5351_setupPLL(uint8_t pll, /* SI5351_PLL_A or SI5351_PLL_B */
uint8_t mult,
Expand All @@ -87,3 +93,5 @@ void si5351_setupMultisynth(uint8_t output,
uint8_t drive_strength);

void si5351_set_frequency(int channel, int freq, uint8_t drive_strength);

#endif //__SI5351_H__

0 comments on commit 015b619

Please sign in to comment.