parent
a3ebb0cca1
commit
4353721ec5
@ -1,131 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2014-2015, TAKAHASHI Tomohiro (TTRFTECH) edy555@gmail.com
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* This 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, or (at your option)
|
|
||||||
* any later version.
|
|
||||||
*
|
|
||||||
* The software 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 GNU Radio; see the file COPYING. If not, write to
|
|
||||||
* the Free Software Foundation, Inc., 51 Franklin Street,
|
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <arm_math.h>
|
|
||||||
#include "nanovna.h"
|
|
||||||
|
|
||||||
#ifdef ENABLED_DUMP
|
|
||||||
int16_t samp_buf[SAMPLE_LEN];
|
|
||||||
int16_t ref_buf[SAMPLE_LEN];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
const int16_t sincos_tbl[48][2] = {
|
|
||||||
{ 10533, 31029 }, { 27246, 18205 }, { 32698, -2143 }, { 24636, -21605 },
|
|
||||||
{ 6393, -32138 }, {-14493, -29389 }, {-29389, -14493 }, {-32138, 6393 },
|
|
||||||
{-21605, 24636 }, { -2143, 32698 }, { 18205, 27246 }, { 31029, 10533 },
|
|
||||||
{ 31029, -10533 }, { 18205, -27246 }, { -2143, -32698 }, {-21605, -24636 },
|
|
||||||
{-32138, -6393 }, {-29389, 14493 }, {-14493, 29389 }, { 6393, 32138 },
|
|
||||||
{ 24636, 21605 }, { 32698, 2143 }, { 27246, -18205 }, { 10533, -31029 },
|
|
||||||
{-10533, -31029 }, {-27246, -18205 }, {-32698, 2143 }, {-24636, 21605 },
|
|
||||||
{ -6393, 32138 }, { 14493, 29389 }, { 29389, 14493 }, { 32138, -6393 },
|
|
||||||
{ 21605, -24636 }, { 2143, -32698 }, {-18205, -27246 }, {-31029, -10533 },
|
|
||||||
{-31029, 10533 }, {-18205, 27246 }, { 2143, 32698 }, { 21605, 24636 },
|
|
||||||
{ 32138, 6393 }, { 29389, -14493 }, { 14493, -29389 }, { -6393, -32138 },
|
|
||||||
{-24636, -21605 }, {-32698, -2143 }, {-27246, 18205 }, {-10533, 31029 }
|
|
||||||
};
|
|
||||||
|
|
||||||
int32_t acc_samp_s;
|
|
||||||
int32_t acc_samp_c;
|
|
||||||
int32_t acc_ref_s;
|
|
||||||
int32_t acc_ref_c;
|
|
||||||
|
|
||||||
void
|
|
||||||
dsp_process(int16_t *capture, size_t length)
|
|
||||||
{
|
|
||||||
uint32_t *p = (uint32_t*)capture;
|
|
||||||
uint32_t len = length / 2;
|
|
||||||
uint32_t i;
|
|
||||||
int32_t samp_s = 0;
|
|
||||||
int32_t samp_c = 0;
|
|
||||||
int32_t ref_s = 0;
|
|
||||||
int32_t ref_c = 0;
|
|
||||||
|
|
||||||
for (i = 0; i < len; i++) {
|
|
||||||
uint32_t sr = *p++;
|
|
||||||
int16_t ref = sr & 0xffff;
|
|
||||||
int16_t smp = (sr>>16) & 0xffff;
|
|
||||||
#ifdef ENABLED_DUMP
|
|
||||||
ref_buf[i] = ref;
|
|
||||||
samp_buf[i] = smp;
|
|
||||||
#endif
|
|
||||||
int32_t s = sincos_tbl[i][0];
|
|
||||||
int32_t c = sincos_tbl[i][1];
|
|
||||||
samp_s += smp * s / 16;
|
|
||||||
samp_c += smp * c / 16;
|
|
||||||
ref_s += ref * s / 16;
|
|
||||||
ref_c += ref * c / 16;
|
|
||||||
#if 0
|
|
||||||
uint32_t sc = *(uint32_t)&sincos_tbl[i];
|
|
||||||
samp_s = __SMLABB(sr, sc, samp_s);
|
|
||||||
samp_c = __SMLABT(sr, sc, samp_c);
|
|
||||||
ref_s = __SMLATB(sr, sc, ref_s);
|
|
||||||
ref_c = __SMLATT(sr, sc, ref_c);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
acc_samp_s = samp_s;
|
|
||||||
acc_samp_c = samp_c;
|
|
||||||
acc_ref_s = ref_s;
|
|
||||||
acc_ref_c = ref_c;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
calculate_gamma(float gamma[2])
|
|
||||||
{
|
|
||||||
#if 1
|
|
||||||
// calculate reflection coeff. by samp divide by ref
|
|
||||||
float rs = acc_ref_s;
|
|
||||||
float rc = acc_ref_c;
|
|
||||||
float rr = rs * rs + rc * rc;
|
|
||||||
//rr = sqrtf(rr) * 1e8;
|
|
||||||
float ss = acc_samp_s;
|
|
||||||
float sc = acc_samp_c;
|
|
||||||
gamma[0] = (sc * rc + ss * rs) / rr;
|
|
||||||
gamma[1] = (ss * rc - sc * rs) / rr;
|
|
||||||
#elif 0
|
|
||||||
gamma[0] = acc_samp_s;
|
|
||||||
gamma[1] = acc_samp_c;
|
|
||||||
#else
|
|
||||||
gamma[0] = acc_ref_s;
|
|
||||||
gamma[1] = acc_ref_c;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
fetch_amplitude(float gamma[2])
|
|
||||||
{
|
|
||||||
gamma[0] = acc_samp_s * 1e-9;
|
|
||||||
gamma[1] = acc_samp_c * 1e-9;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
fetch_amplitude_ref(float gamma[2])
|
|
||||||
{
|
|
||||||
gamma[0] = acc_ref_s * 1e-9;
|
|
||||||
gamma[1] = acc_ref_c * 1e-9;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
reset_dsp_accumerator(void)
|
|
||||||
{
|
|
||||||
acc_ref_s = 0;
|
|
||||||
acc_ref_c = 0;
|
|
||||||
acc_samp_s = 0;
|
|
||||||
acc_samp_c = 0;
|
|
||||||
}
|
|
||||||
@ -1,193 +0,0 @@
|
|||||||
/* CHIBIOS FIX */
|
|
||||||
#include "ch.h"
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------/
|
|
||||||
/ FatFs - FAT file system module configuration file R0.09 (C)ChaN, 2011
|
|
||||||
/----------------------------------------------------------------------------/
|
|
||||||
/
|
|
||||||
/ CAUTION! Do not forget to make clean the project after any changes to
|
|
||||||
/ the configuration options.
|
|
||||||
/
|
|
||||||
/----------------------------------------------------------------------------*/
|
|
||||||
#ifndef _FFCONF
|
|
||||||
#define _FFCONF 6502 /* Revision ID */
|
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------/
|
|
||||||
/ Functions and Buffer Configurations
|
|
||||||
/----------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#define _FS_TINY 0 /* 0:Normal or 1:Tiny */
|
|
||||||
/* When _FS_TINY is set to 1, FatFs uses the sector buffer in the file system
|
|
||||||
/ object instead of the sector buffer in the individual file object for file
|
|
||||||
/ data transfer. This reduces memory consumption 512 bytes each file object. */
|
|
||||||
|
|
||||||
|
|
||||||
#define _FS_READONLY 0 /* 0:Read/Write or 1:Read only */
|
|
||||||
/* Setting _FS_READONLY to 1 defines read only configuration. This removes
|
|
||||||
/ writing functions, f_write, f_sync, f_unlink, f_mkdir, f_chmod, f_rename,
|
|
||||||
/ f_truncate and useless f_getfree. */
|
|
||||||
|
|
||||||
|
|
||||||
#define _FS_MINIMIZE 0 /* 0 to 3 */
|
|
||||||
/* The _FS_MINIMIZE option defines minimization level to remove some functions.
|
|
||||||
/
|
|
||||||
/ 0: Full function.
|
|
||||||
/ 1: f_stat, f_getfree, f_unlink, f_mkdir, f_chmod, f_truncate and f_rename
|
|
||||||
/ are removed.
|
|
||||||
/ 2: f_opendir and f_readdir are removed in addition to 1.
|
|
||||||
/ 3: f_lseek is removed in addition to 2. */
|
|
||||||
|
|
||||||
|
|
||||||
#define _USE_STRFUNC 0 /* 0:Disable or 1-2:Enable */
|
|
||||||
/* To enable string functions, set _USE_STRFUNC to 1 or 2. */
|
|
||||||
|
|
||||||
|
|
||||||
#define _USE_MKFS 1 /* 0:Disable or 1:Enable */
|
|
||||||
/* To enable f_mkfs function, set _USE_MKFS to 1 and set _FS_READONLY to 0 */
|
|
||||||
|
|
||||||
|
|
||||||
#define _USE_FORWARD 0 /* 0:Disable or 1:Enable */
|
|
||||||
/* To enable f_forward function, set _USE_FORWARD to 1 and set _FS_TINY to 1. */
|
|
||||||
|
|
||||||
|
|
||||||
#define _USE_FASTSEEK 0 /* 0:Disable or 1:Enable */
|
|
||||||
/* To enable fast seek feature, set _USE_FASTSEEK to 1. */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------/
|
|
||||||
/ Locale and Namespace Configurations
|
|
||||||
/----------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#define _CODE_PAGE 1251
|
|
||||||
/* The _CODE_PAGE specifies the OEM code page to be used on the target system.
|
|
||||||
/ Incorrect setting of the code page can cause a file open failure.
|
|
||||||
/
|
|
||||||
/ 932 - Japanese Shift-JIS (DBCS, OEM, Windows)
|
|
||||||
/ 936 - Simplified Chinese GBK (DBCS, OEM, Windows)
|
|
||||||
/ 949 - Korean (DBCS, OEM, Windows)
|
|
||||||
/ 950 - Traditional Chinese Big5 (DBCS, OEM, Windows)
|
|
||||||
/ 1250 - Central Europe (Windows)
|
|
||||||
/ 1251 - Cyrillic (Windows)
|
|
||||||
/ 1252 - Latin 1 (Windows)
|
|
||||||
/ 1253 - Greek (Windows)
|
|
||||||
/ 1254 - Turkish (Windows)
|
|
||||||
/ 1255 - Hebrew (Windows)
|
|
||||||
/ 1256 - Arabic (Windows)
|
|
||||||
/ 1257 - Baltic (Windows)
|
|
||||||
/ 1258 - Vietnam (OEM, Windows)
|
|
||||||
/ 437 - U.S. (OEM)
|
|
||||||
/ 720 - Arabic (OEM)
|
|
||||||
/ 737 - Greek (OEM)
|
|
||||||
/ 775 - Baltic (OEM)
|
|
||||||
/ 850 - Multilingual Latin 1 (OEM)
|
|
||||||
/ 858 - Multilingual Latin 1 + Euro (OEM)
|
|
||||||
/ 852 - Latin 2 (OEM)
|
|
||||||
/ 855 - Cyrillic (OEM)
|
|
||||||
/ 866 - Russian (OEM)
|
|
||||||
/ 857 - Turkish (OEM)
|
|
||||||
/ 862 - Hebrew (OEM)
|
|
||||||
/ 874 - Thai (OEM, Windows)
|
|
||||||
/ 1 - ASCII only (Valid for non LFN cfg.)
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#define _USE_LFN 1 /* 0 to 3 */
|
|
||||||
#define _MAX_LFN 255 /* Maximum LFN length to handle (12 to 255) */
|
|
||||||
/* The _USE_LFN option switches the LFN support.
|
|
||||||
/
|
|
||||||
/ 0: Disable LFN feature. _MAX_LFN and _LFN_UNICODE have no effect.
|
|
||||||
/ 1: Enable LFN with static working buffer on the BSS. Always NOT reentrant.
|
|
||||||
/ 2: Enable LFN with dynamic working buffer on the STACK.
|
|
||||||
/ 3: Enable LFN with dynamic working buffer on the HEAP.
|
|
||||||
/
|
|
||||||
/ The LFN working buffer occupies (_MAX_LFN + 1) * 2 bytes. To enable LFN,
|
|
||||||
/ Unicode handling functions ff_convert() and ff_wtoupper() must be added
|
|
||||||
/ to the project. When enable to use heap, memory control functions
|
|
||||||
/ ff_memalloc() and ff_memfree() must be added to the project. */
|
|
||||||
|
|
||||||
|
|
||||||
#define _LFN_UNICODE 0 /* 0:ANSI/OEM or 1:Unicode */
|
|
||||||
/* To switch the character code set on FatFs API to Unicode,
|
|
||||||
/ enable LFN feature and set _LFN_UNICODE to 1. */
|
|
||||||
|
|
||||||
|
|
||||||
#define _FS_RPATH 0 /* 0 to 2 */
|
|
||||||
/* The _FS_RPATH option configures relative path feature.
|
|
||||||
/
|
|
||||||
/ 0: Disable relative path feature and remove related functions.
|
|
||||||
/ 1: Enable relative path. f_chdrive() and f_chdir() are available.
|
|
||||||
/ 2: f_getcwd() is available in addition to 1.
|
|
||||||
/
|
|
||||||
/ Note that output of the f_readdir fnction is affected by this option. */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------/
|
|
||||||
/ Physical Drive Configurations
|
|
||||||
/----------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#define _VOLUMES 1
|
|
||||||
/* Number of volumes (logical drives) to be used. */
|
|
||||||
|
|
||||||
|
|
||||||
#define _MAX_SS 512 /* 512, 1024, 2048 or 4096 */
|
|
||||||
/* Maximum sector size to be handled.
|
|
||||||
/ Always set 512 for memory card and hard disk but a larger value may be
|
|
||||||
/ required for on-board flash memory, floppy disk and optical disk.
|
|
||||||
/ When _MAX_SS is larger than 512, it configures FatFs to variable sector size
|
|
||||||
/ and GET_SECTOR_SIZE command must be implememted to the disk_ioctl function. */
|
|
||||||
|
|
||||||
|
|
||||||
#define _MULTI_PARTITION 0 /* 0:Single partition, 1/2:Enable multiple partition */
|
|
||||||
/* When set to 0, each volume is bound to the same physical drive number and
|
|
||||||
/ it can mount only first primaly partition. When it is set to 1, each volume
|
|
||||||
/ is tied to the partitions listed in VolToPart[]. */
|
|
||||||
|
|
||||||
|
|
||||||
#define _USE_ERASE 1 /* 0:Disable or 1:Enable */
|
|
||||||
/* To enable sector erase feature, set _USE_ERASE to 1. CTRL_ERASE_SECTOR command
|
|
||||||
/ should be added to the disk_ioctl functio. */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------/
|
|
||||||
/ System Configurations
|
|
||||||
/----------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#define _WORD_ACCESS 1 /* 0 or 1 */
|
|
||||||
/* Set 0 first and it is always compatible with all platforms. The _WORD_ACCESS
|
|
||||||
/ option defines which access method is used to the word data on the FAT volume.
|
|
||||||
/
|
|
||||||
/ 0: Byte-by-byte access.
|
|
||||||
/ 1: Word access. Do not choose this unless following condition is met.
|
|
||||||
/
|
|
||||||
/ When the byte order on the memory is big-endian or address miss-aligned word
|
|
||||||
/ access results incorrect behavior, the _WORD_ACCESS must be set to 0.
|
|
||||||
/ If it is not the case, the value can also be set to 1 to improve the
|
|
||||||
/ performance and code size.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/* A header file that defines sync object types on the O/S, such as
|
|
||||||
/ windows.h, ucos_ii.h and semphr.h, must be included prior to ff.h. */
|
|
||||||
|
|
||||||
#define _FS_REENTRANT 0 /* 0:Disable or 1:Enable */
|
|
||||||
#define _FS_TIMEOUT 1000 /* Timeout period in unit of time ticks */
|
|
||||||
#define _SYNC_t Semaphore * /* O/S dependent type of sync object. e.g. HANDLE, OS_EVENT*, ID and etc.. */
|
|
||||||
|
|
||||||
/* The _FS_REENTRANT option switches the reentrancy (thread safe) of the FatFs module.
|
|
||||||
/
|
|
||||||
/ 0: Disable reentrancy. _SYNC_t and _FS_TIMEOUT have no effect.
|
|
||||||
/ 1: Enable reentrancy. Also user provided synchronization handlers,
|
|
||||||
/ ff_req_grant, ff_rel_grant, ff_del_syncobj and ff_cre_syncobj
|
|
||||||
/ function must be added to the project. */
|
|
||||||
|
|
||||||
|
|
||||||
#define _FS_SHARE 0 /* 0:Disable or >=1:Enable */
|
|
||||||
/* To enable file shareing feature, set _FS_SHARE to 1 or greater. The value
|
|
||||||
defines how many files can be opened simultaneously. */
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* _FFCONFIG */
|
|
||||||
@ -1,90 +0,0 @@
|
|||||||
/*
|
|
||||||
* fft.h is Based on
|
|
||||||
* Free FFT and convolution (C)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2019 Project Nayuki. (MIT License)
|
|
||||||
* https://www.nayuki.io/page/free-small-fft-in-multiple-languages
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
||||||
* this software and associated documentation files (the "Software"), to deal in
|
|
||||||
* the Software without restriction, including without limitation the rights to
|
|
||||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
||||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
|
||||||
* subject to the following conditions:
|
|
||||||
* - The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
* - The Software is provided "as is", without warranty of any kind, express or
|
|
||||||
* implied, including but not limited to the warranties of merchantability,
|
|
||||||
* fitness for a particular purpose and noninfringement. In no event shall the
|
|
||||||
* authors or copyright holders be liable for any claim, damages or other
|
|
||||||
* liability, whether in an action of contract, tort or otherwise, arising from,
|
|
||||||
* out of or in connection with the Software or the use or other dealings in the
|
|
||||||
* Software.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include <math.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
static uint16_t reverse_bits(uint16_t x, int n) {
|
|
||||||
uint16_t result = 0;
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < n; i++, x >>= 1)
|
|
||||||
result = (result << 1) | (x & 1U);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***
|
|
||||||
* dir = forward: 0, inverse: 1
|
|
||||||
* https://www.nayuki.io/res/free-small-fft-in-multiple-languages/fft.c
|
|
||||||
*/
|
|
||||||
static void fft256(float array[][2], const uint8_t dir) {
|
|
||||||
const uint16_t n = 256;
|
|
||||||
const uint8_t levels = 8; // log2(n)
|
|
||||||
|
|
||||||
const uint8_t real = dir & 1;
|
|
||||||
const uint8_t imag = ~real & 1;
|
|
||||||
uint16_t i;
|
|
||||||
uint16_t size;
|
|
||||||
|
|
||||||
for (i = 0; i < n; i++) {
|
|
||||||
uint16_t j = reverse_bits(i, levels);
|
|
||||||
if (j > i) {
|
|
||||||
float temp = array[i][real];
|
|
||||||
array[i][real] = array[j][real];
|
|
||||||
array[j][real] = temp;
|
|
||||||
temp = array[i][imag];
|
|
||||||
array[i][imag] = array[j][imag];
|
|
||||||
array[j][imag] = temp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cooley-Tukey decimation-in-time radix-2 FFT
|
|
||||||
for (size = 2; size <= n; size *= 2) {
|
|
||||||
uint16_t halfsize = size / 2;
|
|
||||||
uint16_t tablestep = n / size;
|
|
||||||
uint16_t i;
|
|
||||||
for (i = 0; i < n; i += size) {
|
|
||||||
uint16_t j, k;
|
|
||||||
for (j = i, k = 0; j < i + halfsize; j++, k += tablestep) {
|
|
||||||
uint16_t l = j + halfsize;
|
|
||||||
float tpre = array[l][real] * cos(2 * VNA_PI * k / 256) + array[l][imag] * sin(2 * VNA_PI * k / 256);
|
|
||||||
float tpim = -array[l][real] * sin(2 * VNA_PI * k / 256) + array[l][imag] * cos(2 * VNA_PI * k / 256);
|
|
||||||
array[l][real] = array[j][real] - tpre;
|
|
||||||
array[l][imag] = array[j][imag] - tpim;
|
|
||||||
array[j][real] += tpre;
|
|
||||||
array[j][imag] += tpim;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (size == n) // Prevent overflow in 'size *= 2'
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void fft256_forward(float array[][2]) {
|
|
||||||
fft256(array, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void fft256_inverse(float array[][2]) {
|
|
||||||
fft256(array, 1);
|
|
||||||
}
|
|
||||||
@ -0,0 +1,22 @@
|
|||||||
|
#ifndef __SI4432_H__
|
||||||
|
|
||||||
|
#define __SI4432_H__
|
||||||
|
|
||||||
|
#define byte uint8_t
|
||||||
|
extern volatile int SI4432_Sel; // currently selected SI4432
|
||||||
|
void SI4432_Write_Byte(byte ADR, byte DATA );
|
||||||
|
byte SI4432_Read_Byte( byte ADR );
|
||||||
|
|
||||||
|
void SI4432_Init(void);
|
||||||
|
float SI4432_RSSI(uint32_t i, int s);
|
||||||
|
#ifdef __SIMULATION__
|
||||||
|
float Simulated_SI4432_RSSI(uint32_t i, int s);
|
||||||
|
#endif
|
||||||
|
void SI4432_Set_Frequency ( long Freq );
|
||||||
|
void SI4432_Transmit(int d);
|
||||||
|
void SI4432_Receive(void);
|
||||||
|
float SI4432_SET_RBW(float WISH);
|
||||||
|
void PE4302_Write_Byte(unsigned char DATA );
|
||||||
|
void PE4302_init(void);
|
||||||
|
|
||||||
|
#endif //__SI4432_H__
|
||||||
@ -1,473 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2014-2015, TAKAHASHI Tomohiro (TTRFTECH) edy555@gmail.com
|
|
||||||
* Modified by DiSlord dislordlive@gmail.com
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* This 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, or (at your option)
|
|
||||||
* any later version.
|
|
||||||
*
|
|
||||||
* The software 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 GNU Radio; see the file COPYING. If not, write to
|
|
||||||
* the Free Software Foundation, Inc., 51 Franklin Street,
|
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
|
||||||
#include "hal.h"
|
|
||||||
#include "nanovna.h"
|
|
||||||
#include "si5351.h"
|
|
||||||
|
|
||||||
// Enable cache for SI5351 CLKX_CONTROL register, little speedup exchange
|
|
||||||
#define USE_CLK_CONTROL_CACHE TRUE
|
|
||||||
|
|
||||||
// XTAL frequency on si5351
|
|
||||||
#define XTALFREQ 26000000U
|
|
||||||
// MCLK (processor clock if set, audio codec) frequency clock
|
|
||||||
#define CLK2_FREQUENCY 8000000U
|
|
||||||
|
|
||||||
// Fixed PLL mode multiplier (used in band 1)
|
|
||||||
#define PLL_N 32
|
|
||||||
|
|
||||||
// I2C address on bus (only 0x60 for Si5351A in 10-Pin MSOP)
|
|
||||||
#define SI5351_I2C_ADDR 0x60
|
|
||||||
|
|
||||||
static uint8_t current_band = 0;
|
|
||||||
static uint32_t current_freq = 0;
|
|
||||||
static int32_t current_offset = FREQUENCY_OFFSET;
|
|
||||||
|
|
||||||
// Minimum value is 2, freq change apply at next dsp measure, and need skip it
|
|
||||||
#define DELAY_NORMAL 2
|
|
||||||
// Delay for bands (depend set band 1 more fast (can change before next dsp buffer ready, need wait additional interval)
|
|
||||||
#define DELAY_BAND_1 3
|
|
||||||
#define DELAY_BAND_2 2
|
|
||||||
// Band changes need set delay after reset PLL
|
|
||||||
#define DELAY_BANDCHANGE_1 3
|
|
||||||
#define DELAY_BANDCHANGE_2 3
|
|
||||||
// Delay after set new PLL values, and send reset (on band 1 unstable if less then 900, on 4000-5000 no amplitude spike on change)
|
|
||||||
#define DELAY_RESET_PLL 5000
|
|
||||||
|
|
||||||
uint32_t si5351_get_frequency(void)
|
|
||||||
{
|
|
||||||
return current_freq;
|
|
||||||
}
|
|
||||||
|
|
||||||
void si5351_set_frequency_offset(int32_t offset)
|
|
||||||
{
|
|
||||||
current_offset = offset;
|
|
||||||
current_freq = 0; // reset freq, for
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
si5351_bulk_write(const uint8_t *buf, int len)
|
|
||||||
{
|
|
||||||
i2cAcquireBus(&I2CD1);
|
|
||||||
(void)i2cMasterTransmitTimeout(&I2CD1, SI5351_I2C_ADDR, buf, len, NULL, 0, 1000);
|
|
||||||
i2cReleaseBus(&I2CD1);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
static bool si5351_bulk_read(uint8_t reg, uint8_t* buf, int len)
|
|
||||||
{
|
|
||||||
i2cAcquireBus(&I2CD1);
|
|
||||||
msg_t mr = i2cMasterTransmitTimeout(&I2CD1, SI5351_I2C_ADDR, ®, 1, buf, len, 1000);
|
|
||||||
i2cReleaseBus(&I2CD1);
|
|
||||||
return mr == MSG_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void si5351_wait_pll_lock(void)
|
|
||||||
{
|
|
||||||
uint8_t status;
|
|
||||||
int count = 100;
|
|
||||||
do{
|
|
||||||
status=0xFF;
|
|
||||||
si5351_bulk_read(0, &status, 1);
|
|
||||||
if ((status & 0x60) == 0) // PLLA and PLLB locked
|
|
||||||
return;
|
|
||||||
}while (--count);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
si5351_write(uint8_t reg, uint8_t dat)
|
|
||||||
{
|
|
||||||
uint8_t buf[] = { reg, dat };
|
|
||||||
si5351_bulk_write(buf, 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
// register addr, length, data, ...
|
|
||||||
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,
|
|
||||||
// All of this init code run late on sweep
|
|
||||||
#if 0
|
|
||||||
// setup PLL (26MHz * 32 = 832MHz, 32/2-2=14)
|
|
||||||
9, SI5351_REG_PLL_A, /*P3*/0, 1, /*P1*/0, 14, 0, /*P3/P2*/0, 0, 0,
|
|
||||||
9, SI5351_REG_PLL_B, /*P3*/0, 1, /*P1*/0, 14, 0, /*P3/P2*/0, 0, 0,
|
|
||||||
// RESET PLL
|
|
||||||
2, SI5351_REG_177_PLL_RESET, SI5351_PLL_RESET_A | SI5351_PLL_RESET_B | 0x0C, //
|
|
||||||
// setup multisynth (832MHz / 104 = 8MHz, 104/2-2=50)
|
|
||||||
9, SI5351_REG_58_MULTISYNTH2, /*P3*/0, 1, /*P1*/0, 50, 0, /*P2|P3*/0, 0, 0,
|
|
||||||
2, SI5351_REG_18_CLK2_CONTROL, SI5351_CLK_DRIVE_STRENGTH_2MA | SI5351_CLK_INPUT_MULTISYNTH_N | SI5351_CLK_INTEGER_MODE,
|
|
||||||
#endif
|
|
||||||
2, SI5351_REG_3_OUTPUT_ENABLE_CONTROL, ~(SI5351_CLK0_EN|SI5351_CLK1_EN|SI5351_CLK2_EN),
|
|
||||||
0 // sentinel
|
|
||||||
};
|
|
||||||
|
|
||||||
void
|
|
||||||
si5351_init(void)
|
|
||||||
{
|
|
||||||
const uint8_t *p = si5351_configs;
|
|
||||||
while (*p) {
|
|
||||||
uint8_t len = *p++;
|
|
||||||
si5351_bulk_write(p, len);
|
|
||||||
p += len;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static const uint8_t disable_output[] = {
|
|
||||||
SI5351_REG_16_CLK0_CONTROL,
|
|
||||||
SI5351_CLK_POWERDOWN, // CLK 0
|
|
||||||
SI5351_CLK_POWERDOWN, // CLK 1
|
|
||||||
SI5351_CLK_POWERDOWN // CLK 2
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Get the appropriate starting point for the PLL registers */
|
|
||||||
static const uint8_t msreg_base[] = {
|
|
||||||
SI5351_REG_42_MULTISYNTH0,
|
|
||||||
SI5351_REG_50_MULTISYNTH1,
|
|
||||||
SI5351_REG_58_MULTISYNTH2,
|
|
||||||
};
|
|
||||||
static const uint8_t clkctrl[] = {
|
|
||||||
SI5351_REG_16_CLK0_CONTROL,
|
|
||||||
SI5351_REG_17_CLK1_CONTROL,
|
|
||||||
SI5351_REG_18_CLK2_CONTROL
|
|
||||||
};
|
|
||||||
|
|
||||||
// Reset PLL need then band changes
|
|
||||||
static void si5351_reset_pll(uint8_t mask)
|
|
||||||
{
|
|
||||||
// Writing a 1<<5 will reset PLLA, 1<<7 reset PLLB, this is a self clearing bits.
|
|
||||||
// !!! Need delay before reset PLL for apply PLL freq changes before
|
|
||||||
chThdSleepMicroseconds(DELAY_RESET_PLL);
|
|
||||||
si5351_write(SI5351_REG_177_PLL_RESET, mask | 0x0C);
|
|
||||||
}
|
|
||||||
|
|
||||||
void si5351_disable_output(void)
|
|
||||||
{
|
|
||||||
si5351_write(SI5351_REG_3_OUTPUT_ENABLE_CONTROL, 0xFF);
|
|
||||||
si5351_bulk_write(disable_output, sizeof(disable_output));
|
|
||||||
current_band = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void si5351_enable_output(void)
|
|
||||||
{
|
|
||||||
si5351_write(SI5351_REG_3_OUTPUT_ENABLE_CONTROL, ~(SI5351_CLK0_EN|SI5351_CLK1_EN|SI5351_CLK2_EN));
|
|
||||||
//si5351_reset_pll(SI5351_PLL_RESET_A | SI5351_PLL_RESET_B);
|
|
||||||
current_freq = 0;
|
|
||||||
current_band = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set PLL freq = XTALFREQ * (mult + num/denom)
|
|
||||||
static void si5351_setupPLL(uint8_t pllSource, /* SI5351_REG_PLL_A or SI5351_REG_PLL_B */
|
|
||||||
uint32_t mult,
|
|
||||||
uint32_t num,
|
|
||||||
uint32_t denom)
|
|
||||||
{
|
|
||||||
/* Feedback Multisynth Divider Equation
|
|
||||||
* where: a = mult, b = num and c = denom
|
|
||||||
* P1 register is an 18-bit value using following formula:
|
|
||||||
* P1[17:0] = 128 * mult + int((128*num)/denom) - 512
|
|
||||||
* P2 register is a 20-bit value using the following formula:
|
|
||||||
* P2[19:0] = (128 * num) % denom
|
|
||||||
* P3 register is a 20-bit value using the following formula:
|
|
||||||
* P3[19:0] = denom
|
|
||||||
*/
|
|
||||||
/* Set the main PLL config registers */
|
|
||||||
mult <<= 7;
|
|
||||||
num <<= 7;
|
|
||||||
uint32_t P1 = mult - 512; // Integer mode
|
|
||||||
uint32_t P2 = 0;
|
|
||||||
uint32_t P3 = 1;
|
|
||||||
if (num) { // Fractional mode
|
|
||||||
P1+= num / denom;
|
|
||||||
P2 = num % denom;
|
|
||||||
P3 = denom;
|
|
||||||
}
|
|
||||||
// Pll MSN(A|B) registers Datasheet
|
|
||||||
uint8_t reg[9];
|
|
||||||
reg[0] = pllSource; // SI5351_REG_PLL_A or SI5351_REG_PLL_B
|
|
||||||
reg[1] = (P3 & 0x0FF00) >> 8; // MSN_P3[15: 8]
|
|
||||||
reg[2] = (P3 & 0x000FF); // MSN_P3[ 7: 0]
|
|
||||||
reg[3] = (P1 & 0x30000) >> 16; // MSN_P1[17:16]
|
|
||||||
reg[4] = (P1 & 0x0FF00) >> 8; // MSN_P1[15: 8]
|
|
||||||
reg[5] = (P1 & 0x000FF); // MSN_P1[ 7: 0]
|
|
||||||
reg[6] = ((P3 & 0xF0000) >> 12) | ((P2 & 0xF0000) >> 16); // MSN_P3[19:16] | MSN_P2[19:16]
|
|
||||||
reg[7] = (P2 & 0x0FF00) >> 8; // MSN_P2[15: 8]
|
|
||||||
reg[8] = (P2 & 0x000FF); // MSN_P2[ 7: 0]
|
|
||||||
si5351_bulk_write(reg, 9);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set Multisynth divider = (div + num/denom) * rdiv
|
|
||||||
static void
|
|
||||||
si5351_setupMultisynth(uint8_t channel,
|
|
||||||
uint32_t div, // 4,6,8, 8+ ~ 900
|
|
||||||
uint32_t num,
|
|
||||||
uint32_t denom,
|
|
||||||
uint32_t rdiv, // SI5351_R_DIV_1~128
|
|
||||||
uint8_t chctrl) // SI5351_REG_16_CLKX_CONTROL settings
|
|
||||||
{
|
|
||||||
/* Output Multisynth Divider Equations
|
|
||||||
* where: a = div, b = num and c = denom
|
|
||||||
* P1 register is an 18-bit value using following formula:
|
|
||||||
* P1[17:0] = 128 * a + int((128*b)/c) - 512
|
|
||||||
* P2 register is a 20-bit value using the following formula:
|
|
||||||
* P2[19:0] = (128 * b) % c
|
|
||||||
* P3 register is a 20-bit value using the following formula:
|
|
||||||
* P3[19:0] = c
|
|
||||||
*/
|
|
||||||
/* Set the main PLL config registers */
|
|
||||||
uint32_t P1 = 0;
|
|
||||||
uint32_t P2 = 0;
|
|
||||||
uint32_t P3 = 1;
|
|
||||||
if (div == 4)
|
|
||||||
rdiv|= SI5351_DIVBY4;
|
|
||||||
else {
|
|
||||||
num<<=7;
|
|
||||||
div<<=7;
|
|
||||||
P1 = div - 512; // Integer mode
|
|
||||||
if (num) { // Fractional mode
|
|
||||||
P1+= num / denom;
|
|
||||||
P2 = num % denom;
|
|
||||||
P3 = denom;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Set the MSx config registers */
|
|
||||||
uint8_t reg[9];
|
|
||||||
reg[0] = msreg_base[channel]; // SI5351_REG_42_MULTISYNTH0, SI5351_REG_50_MULTISYNTH1, SI5351_REG_58_MULTISYNTH2
|
|
||||||
reg[1] = (P3 & 0x0FF00)>>8; // MSx_P3[15: 8]
|
|
||||||
reg[2] = (P3 & 0x000FF); // MSx_P3[ 7: 0]
|
|
||||||
reg[3] = ((P1 & 0x30000)>>16)| rdiv; // Rx_DIV[2:0] | MSx_DIVBY4[1:0] | MSx_P1[17:16]
|
|
||||||
reg[4] = (P1 & 0x0FF00)>> 8; // MSx_P1[15: 8]
|
|
||||||
reg[5] = (P1 & 0x000FF); // MSx_P1[ 7: 0]
|
|
||||||
reg[6] = ((P3 & 0xF0000)>>12)|((P2 & 0xF0000)>>16); // MSx_P3[19:16] | MSx_P2[19:16]
|
|
||||||
reg[7] = (P2 & 0x0FF00)>>8; // MSx_P2[15: 8]
|
|
||||||
reg[8] = (P2 & 0x000FF); // MSx_P2[ 7: 0]
|
|
||||||
si5351_bulk_write(reg, 9);
|
|
||||||
|
|
||||||
/* Configure the clk control and enable the output */
|
|
||||||
uint8_t dat = chctrl | SI5351_CLK_INPUT_MULTISYNTH_N;
|
|
||||||
if (num == 0)
|
|
||||||
dat |= SI5351_CLK_INTEGER_MODE;
|
|
||||||
|
|
||||||
#if USE_CLK_CONTROL_CACHE == TRUE
|
|
||||||
// Use cache for this reg, not update if not change
|
|
||||||
static uint8_t clk_cache[3];
|
|
||||||
if (clk_cache[channel]!=dat) {
|
|
||||||
si5351_write(clkctrl[channel], dat);
|
|
||||||
clk_cache[channel]=dat;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
si5351_write(clkctrl[channel], dat);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find better approximate values for n/d
|
|
||||||
#define MAX_DENOMINATOR ((1 << 20) - 1)
|
|
||||||
static inline void approximate_fraction(uint32_t *n, uint32_t *d)
|
|
||||||
{
|
|
||||||
// cf. https://github.com/python/cpython/blob/master/Lib/fractions.py#L227
|
|
||||||
uint32_t denom = *d;
|
|
||||||
if (denom > MAX_DENOMINATOR) {
|
|
||||||
uint32_t num = *n;
|
|
||||||
uint32_t p0 = 0, q0 = 1, p1 = 1, q1 = 0;
|
|
||||||
while (denom != 0) {
|
|
||||||
uint32_t a = num / denom;
|
|
||||||
uint32_t b = num % denom;
|
|
||||||
uint32_t q2 = q0 + a*q1;
|
|
||||||
if (q2 > MAX_DENOMINATOR)
|
|
||||||
break;
|
|
||||||
uint32_t p2 = p0 + a*p1;
|
|
||||||
p0 = p1; q0 = q1; p1 = p2; q1 = q2;
|
|
||||||
num = denom; denom = b;
|
|
||||||
}
|
|
||||||
*n = p1;
|
|
||||||
*d = q1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Setup Multisynth divider for get correct output freq if fixed PLL = pllfreq
|
|
||||||
static void
|
|
||||||
si5351_set_frequency_fixedpll(uint8_t channel, uint64_t pllfreq, uint32_t freq, uint32_t rdiv, uint8_t chctrl)
|
|
||||||
{
|
|
||||||
uint32_t denom = freq;
|
|
||||||
uint32_t div = pllfreq / denom; // range: 8 ~ 1800
|
|
||||||
uint32_t num = pllfreq % denom;
|
|
||||||
approximate_fraction(&num, &denom);
|
|
||||||
si5351_setupMultisynth(channel, div, num, denom, rdiv, chctrl);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Setup PLL freq if Multisynth divider fixed = div (need get output = freq/mul)
|
|
||||||
static void
|
|
||||||
si5351_setupPLL_freq(uint32_t pllSource, uint32_t freq, uint32_t div, uint32_t mul)
|
|
||||||
{
|
|
||||||
uint32_t denom = XTALFREQ * mul;
|
|
||||||
uint64_t pllfreq = (uint64_t)freq * div;
|
|
||||||
uint32_t multi = pllfreq / denom;
|
|
||||||
uint32_t num = pllfreq % denom;
|
|
||||||
approximate_fraction(&num, &denom);
|
|
||||||
si5351_setupPLL(pllSource, multi, num, denom);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
static void
|
|
||||||
si5351_set_frequency_fixeddiv(uint8_t channel, uint32_t pll, uint32_t freq, uint32_t div,
|
|
||||||
uint8_t chctrl, uint32_t mul)
|
|
||||||
{
|
|
||||||
si5351_setupPLL_freq(pll, freq, div, mul);
|
|
||||||
si5351_setupMultisynth(channel, div, 0, 1, SI5351_R_DIV_1, chctrl);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
si5351_set_frequency(int channel, uint32_t freq, uint8_t drive_strength)
|
|
||||||
{
|
|
||||||
if (freq <= 100000000) {
|
|
||||||
si5351_setupPLL(SI5351_PLL_B, 32, 0, 1);
|
|
||||||
si5351_set_frequency_fixedpll(channel, SI5351_PLL_B, PLLFREQ, freq, SI5351_R_DIV_1, drive_strength, 1);
|
|
||||||
} else if (freq < 150000000) {
|
|
||||||
si5351_set_frequency_fixeddiv(channel, SI5351_PLL_B, freq, 6, drive_strength, 1);
|
|
||||||
} else {
|
|
||||||
si5351_set_frequency_fixeddiv(channel, SI5351_PLL_B, freq, 4, drive_strength, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Frequency generation divide on 3 band
|
|
||||||
* Band 1
|
|
||||||
* 1~100MHz fixed PLL = XTALFREQ * PLL_N, fractional divider
|
|
||||||
* Band 2
|
|
||||||
* 100~150MHz fractional PLL = 600- 900MHz, fixed divider 'fdiv = 6'
|
|
||||||
* Band 3
|
|
||||||
* 150~300MHz fractional PLL = 600-1200MHz, fixed divider 'fdiv = 4'
|
|
||||||
*
|
|
||||||
* For FREQ_HARMONICS = 300MHz - band range is:
|
|
||||||
* +-----------------------------------------------------------------------------------------------------------------------+
|
|
||||||
* | Band 1 | Band 2 | Band 3 | Band 2 | Band 3 |
|
|
||||||
* +-----------------------------------------------------------------------------------------------------------------------+
|
|
||||||
* | Direct mode x1 : x1 | x3 : x5 | x5-x7 | x7-x9 | x9-x11 |
|
|
||||||
* +-----------------------------------------------------------------------------------------------------------------------+
|
|
||||||
* | 50kHz - 100MHz | 100 - 150MHz | 150 - 300MHz | 300-450MHz | 450-900MHz | 900-1500MHz | 1500-2100MHz | 2100-2700MHz |
|
|
||||||
* +-----------------------------------------------------------------------------------------------------------------------+
|
|
||||||
* | f = 50kHz-300MHz | f=100-150 | f=150-300 | f=150-300 | f=214-300 | f=233-300 |
|
|
||||||
* | of = 50kHz-300MHz |of= 60- 90 |of= 90-180 |of=128-215 |of=166-234 |of=190-246 |
|
|
||||||
* +-----------------------------------------------------------------------------------------------------------------------+
|
|
||||||
*/
|
|
||||||
static inline uint8_t
|
|
||||||
si5351_get_band(uint32_t freq)
|
|
||||||
{
|
|
||||||
if (freq < 100000000U) return 1;
|
|
||||||
if (freq < 150000000U) return 2;
|
|
||||||
return 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Maximum supported frequency = FREQ_HARMONICS * 9U
|
|
||||||
* configure output as follows:
|
|
||||||
* CLK0: frequency + offset
|
|
||||||
* CLK1: frequency
|
|
||||||
* CLK2: fixed 8MHz
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
si5351_set_frequency(uint32_t freq, uint8_t drive_strength)
|
|
||||||
{
|
|
||||||
uint8_t band;
|
|
||||||
int delay = DELAY_NORMAL;
|
|
||||||
if (freq == current_freq)
|
|
||||||
return delay;
|
|
||||||
else if (current_freq > freq) // Reset band on sweep begin (if set range 150-600, fix error then 600 MHz band 2 or 3 go back)
|
|
||||||
current_band = 0;
|
|
||||||
current_freq = freq;
|
|
||||||
uint32_t ofreq = freq + current_offset;
|
|
||||||
uint32_t mul = 1, omul = 1;
|
|
||||||
uint32_t rdiv = SI5351_R_DIV_1;
|
|
||||||
uint32_t fdiv;
|
|
||||||
// Fix possible incorrect input
|
|
||||||
drive_strength&=SI5351_CLK_DRIVE_STRENGTH_MASK;
|
|
||||||
|
|
||||||
if (freq >= config.harmonic_freq_threshold * 7U) {
|
|
||||||
mul = 9;
|
|
||||||
omul = 11;
|
|
||||||
} else if (freq >= config.harmonic_freq_threshold * 5U) {
|
|
||||||
mul = 7;
|
|
||||||
omul = 9;
|
|
||||||
} else if (freq >= config.harmonic_freq_threshold * 3U) {
|
|
||||||
mul = 5;
|
|
||||||
omul = 7;
|
|
||||||
} else if (freq >= config.harmonic_freq_threshold) {
|
|
||||||
mul = 3;
|
|
||||||
omul = 5;
|
|
||||||
} else if (freq <= 500000U) {
|
|
||||||
rdiv = SI5351_R_DIV_64;
|
|
||||||
freq<<= 6;
|
|
||||||
ofreq<<= 6;
|
|
||||||
} else if (freq <= 4000000U) {
|
|
||||||
rdiv = SI5351_R_DIV_8;
|
|
||||||
freq<<= 3;
|
|
||||||
ofreq<<= 3;
|
|
||||||
}
|
|
||||||
band = si5351_get_band(freq / mul);
|
|
||||||
switch (band) {
|
|
||||||
case 1:
|
|
||||||
// Setup CH0 and CH1 constant PLLA freq at band change, and set CH2 freq =
|
|
||||||
// CLK2_FREQUENCY
|
|
||||||
if (current_band != 1) {
|
|
||||||
si5351_setupPLL(SI5351_REG_PLL_A, PLL_N, 0, 1);
|
|
||||||
si5351_set_frequency_fixedpll(
|
|
||||||
2, XTALFREQ * PLL_N, CLK2_FREQUENCY, SI5351_R_DIV_1,
|
|
||||||
SI5351_CLK_DRIVE_STRENGTH_2MA | SI5351_CLK_PLL_SELECT_A);
|
|
||||||
delay = DELAY_BANDCHANGE_1;
|
|
||||||
} else {
|
|
||||||
delay = DELAY_BAND_1;
|
|
||||||
}
|
|
||||||
// Calculate and set CH0 and CH1 divider
|
|
||||||
si5351_set_frequency_fixedpll(0, (uint64_t)omul * XTALFREQ * PLL_N, ofreq, rdiv,
|
|
||||||
drive_strength | SI5351_CLK_PLL_SELECT_A);
|
|
||||||
si5351_set_frequency_fixedpll(1, (uint64_t)mul * XTALFREQ * PLL_N, freq, rdiv,
|
|
||||||
drive_strength | SI5351_CLK_PLL_SELECT_A);
|
|
||||||
break;
|
|
||||||
case 2: // fdiv = 6
|
|
||||||
case 3: // fdiv = 4;
|
|
||||||
fdiv = (band == 2) ? 6 : 4;
|
|
||||||
// Setup CH0 and CH1 constant fdiv divider at change
|
|
||||||
if (current_band != band) {
|
|
||||||
si5351_setupMultisynth(0, fdiv, 0, 1, SI5351_R_DIV_1,
|
|
||||||
drive_strength | SI5351_CLK_PLL_SELECT_A);
|
|
||||||
si5351_setupMultisynth(1, fdiv, 0, 1, SI5351_R_DIV_1,
|
|
||||||
drive_strength | SI5351_CLK_PLL_SELECT_B);
|
|
||||||
delay = DELAY_BANDCHANGE_2;
|
|
||||||
} else {
|
|
||||||
delay = DELAY_BAND_2;
|
|
||||||
}
|
|
||||||
// Calculate and set CH0 and CH1 PLL freq
|
|
||||||
si5351_setupPLL_freq(SI5351_REG_PLL_A, ofreq, fdiv,
|
|
||||||
omul); // set PLLA freq = (ofreq/omul)*fdiv
|
|
||||||
si5351_setupPLL_freq(SI5351_REG_PLL_B, freq, fdiv,
|
|
||||||
mul); // set PLLB freq = ( freq/ mul)*fdiv
|
|
||||||
// Calculate CH2 freq = CLK2_FREQUENCY, depend from calculated before CH1 PLLB = (freq/mul)*fdiv
|
|
||||||
si5351_set_frequency_fixedpll(
|
|
||||||
2, (uint64_t)freq * fdiv, CLK2_FREQUENCY * mul, SI5351_R_DIV_1,
|
|
||||||
SI5351_CLK_DRIVE_STRENGTH_2MA | SI5351_CLK_PLL_SELECT_B);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (current_band != band) {
|
|
||||||
si5351_reset_pll(SI5351_PLL_RESET_A|SI5351_PLL_RESET_B);
|
|
||||||
current_band = band;
|
|
||||||
}
|
|
||||||
return delay;
|
|
||||||
}
|
|
||||||
@ -1,77 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2014-2015, TAKAHASHI Tomohiro (TTRFTECH) edy555@gmail.com
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* This 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, or (at your option)
|
|
||||||
* any later version.
|
|
||||||
*
|
|
||||||
* The software 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 GNU Radio; see the file COPYING. If not, write to
|
|
||||||
* the Free Software Foundation, Inc., 51 Franklin Street,
|
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define SI5351_REG_3_OUTPUT_ENABLE_CONTROL 3
|
|
||||||
#define SI5351_CLK0_EN (1<<0)
|
|
||||||
#define SI5351_CLK1_EN (1<<1)
|
|
||||||
#define SI5351_CLK2_EN (1<<2)
|
|
||||||
|
|
||||||
// Reg 16-18 CLKX_CONTROL
|
|
||||||
#define SI5351_REG_16_CLK0_CONTROL 16
|
|
||||||
#define SI5351_REG_17_CLK1_CONTROL 17
|
|
||||||
#define SI5351_REG_18_CLK2_CONTROL 18
|
|
||||||
#define SI5351_CLK_POWERDOWN (1<<7)
|
|
||||||
#define SI5351_CLK_INTEGER_MODE (1<<6)
|
|
||||||
#define SI5351_CLK_PLL_SELECT_A (0<<5)
|
|
||||||
#define SI5351_CLK_PLL_SELECT_B (1<<5)
|
|
||||||
#define SI5351_CLK_INVERT (1<<4)
|
|
||||||
#define SI5351_CLK_INPUT_MASK (3<<2)
|
|
||||||
#define SI5351_CLK_INPUT_XTAL (0<<2)
|
|
||||||
#define SI5351_CLK_INPUT_CLKIN (1<<2)
|
|
||||||
#define SI5351_CLK_INPUT_MULTISYNTH_0_4 (2<<2)
|
|
||||||
#define SI5351_CLK_INPUT_MULTISYNTH_N (3<<2)
|
|
||||||
#define SI5351_CLK_DRIVE_STRENGTH_MASK (3<<0)
|
|
||||||
#define SI5351_CLK_DRIVE_STRENGTH_2MA (0<<0)
|
|
||||||
#define SI5351_CLK_DRIVE_STRENGTH_4MA (1<<0)
|
|
||||||
#define SI5351_CLK_DRIVE_STRENGTH_6MA (2<<0)
|
|
||||||
#define SI5351_CLK_DRIVE_STRENGTH_8MA (3<<0)
|
|
||||||
|
|
||||||
#define SI5351_REG_PLL_A 26
|
|
||||||
#define SI5351_REG_PLL_B 34
|
|
||||||
|
|
||||||
#define SI5351_REG_42_MULTISYNTH0 42
|
|
||||||
#define SI5351_REG_50_MULTISYNTH1 50
|
|
||||||
#define SI5351_REG_58_MULTISYNTH2 58
|
|
||||||
#define SI5351_DIVBY4 (3<<2)
|
|
||||||
#define SI5351_R_DIV_1 (0<<4)
|
|
||||||
#define SI5351_R_DIV_2 (1<<4)
|
|
||||||
#define SI5351_R_DIV_4 (2<<4)
|
|
||||||
#define SI5351_R_DIV_8 (3<<4)
|
|
||||||
#define SI5351_R_DIV_16 (4<<4)
|
|
||||||
#define SI5351_R_DIV_32 (5<<4)
|
|
||||||
#define SI5351_R_DIV_64 (6<<4)
|
|
||||||
#define SI5351_R_DIV_128 (7<<4)
|
|
||||||
|
|
||||||
#define SI5351_REG_177_PLL_RESET 177
|
|
||||||
#define SI5351_PLL_RESET_B (1<<7)
|
|
||||||
#define SI5351_PLL_RESET_A (1<<5)
|
|
||||||
|
|
||||||
#define SI5351_REG_183_CRYSTAL_LOAD 183
|
|
||||||
#define SI5351_CRYSTAL_LOAD_6PF (1<<6)
|
|
||||||
#define SI5351_CRYSTAL_LOAD_8PF (2<<6)
|
|
||||||
#define SI5351_CRYSTAL_LOAD_10PF (3<<6)
|
|
||||||
|
|
||||||
void si5351_init(void);
|
|
||||||
void si5351_disable_output(void);
|
|
||||||
void si5351_enable_output(void);
|
|
||||||
|
|
||||||
void si5351_set_frequency_offset(int32_t offset);
|
|
||||||
int si5351_set_frequency(uint32_t freq, uint8_t drive_strength);
|
|
||||||
uint32_t si5351_get_frequency(void);
|
|
||||||
@ -1,144 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2014-2015, TAKAHASHI Tomohiro (TTRFTECH) edy555@gmail.com
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* This 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, or (at your option)
|
|
||||||
* any later version.
|
|
||||||
*
|
|
||||||
* The software 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 GNU Radio; see the file COPYING. If not, write to
|
|
||||||
* the Free Software Foundation, Inc., 51 Franklin Street,
|
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
|
||||||
#include "hal.h"
|
|
||||||
#include "nanovna.h"
|
|
||||||
|
|
||||||
#define REFCLK_8000KHZ
|
|
||||||
#define AIC3204_ADDR 0x18
|
|
||||||
|
|
||||||
#define wait_ms(ms) chThdSleepMilliseconds(ms)
|
|
||||||
|
|
||||||
static const uint8_t conf_data[] = {
|
|
||||||
// reg, data,
|
|
||||||
// PLL clock config
|
|
||||||
0x00, 0x00, /* Initialize to Page 0 */
|
|
||||||
0x01, 0x01, /* Initialize the device through software reset */
|
|
||||||
0x04, 0x43, /* PLL Clock High, MCLK, PLL */
|
|
||||||
#ifdef REFCLK_8000KHZ
|
|
||||||
/* 8.000MHz*10.7520 = 86.016MHz, 86.016MHz/(2*7*128) = 48kHz */
|
|
||||||
0x05, 0x91, /* Power up PLL, P=1,R=1 */
|
|
||||||
0x06, 0x0a, /* J=10 */
|
|
||||||
0x07, 29, /* D=7520 = (29<<8) + 96 */
|
|
||||||
0x08, 96,
|
|
||||||
#endif
|
|
||||||
// Clock config, default fs=48kHz
|
|
||||||
0x0b, 0x82, /* Power up the NDAC divider with value 2 */
|
|
||||||
0x0c, 0x87, /* Power up the MDAC divider with value 7 */
|
|
||||||
0x0d, 0x00, /* Program the OSR of DAC to 128 */
|
|
||||||
0x0e, 0x80,
|
|
||||||
0x3c, 0x08, /* Set the DAC Mode to PRB_P8 */
|
|
||||||
//0x3c, 25, /* Set the DAC Mode to PRB_P25 */
|
|
||||||
0x1b, 0x0c, /* Set the BCLK,WCLK as output */
|
|
||||||
0x1e, 0x80 + 28, /* Enable the BCLKN divider with value 28 */
|
|
||||||
0x25, 0xee, /* DAC power up */
|
|
||||||
|
|
||||||
0x12, 0x82, /* Power up the NADC divider with value 2 */
|
|
||||||
0x13, 0x87, /* Power up the MADC divider with value 7 */
|
|
||||||
0x14, 0x80, /* Program the OSR of ADC to 128 */
|
|
||||||
0x3d, 0x01, /* Select ADC PRB_R1 */
|
|
||||||
// Data routing
|
|
||||||
0x00, 0x01, /* Select Page 1 */
|
|
||||||
0x01, 0x08, /* Disable Internal Crude AVdd in presence of external AVdd supply or before powering up internal AVdd LDO*/
|
|
||||||
0x02, 0x01, /* Enable Master Analog Power Control */
|
|
||||||
0x7b, 0x01, /* Set the REF charging time to 40ms */
|
|
||||||
0x14, 0x25, /* HP soft stepping settings for optimal pop performance at power up Rpop used is 6k with N = 6 and soft step = 20usec. This should work with 47uF coupling capacitor. Can try N=5,6 or 7 time constants as well. Trade-off delay vs “pop” sound. */
|
|
||||||
0x0a, 0x33, /* Set the Input Common Mode to 0.9V and Output Common Mode for Headphone to 1.65V */
|
|
||||||
|
|
||||||
0x3d, 0x00, /* Select ADC PTM_R4 */
|
|
||||||
0x47, 0x32, /* Set MicPGA startup delay to 3.1ms */
|
|
||||||
0x7b, 0x01, /* Set the REF charging time to 40ms */
|
|
||||||
0x34, 0x10, /* Route IN2L to LEFT_P with 10K */
|
|
||||||
0x36, 0x10, /* Route IN2R to LEFT_N with 10K */
|
|
||||||
//0x37, 0x04, /* Route IN3R to RIGHT_P with 10K */
|
|
||||||
//0x39, 0x04, /* Route IN3L to RIGHT_N with 10K */
|
|
||||||
//0x3b, 0x00, /* Unmute Left MICPGA, Gain selection of 32dB to make channel gain 0dB */
|
|
||||||
//0x3c, 0x00, /* Unmute Right MICPGA, Gain selection of 32dB to make channel gain 0dB */
|
|
||||||
};
|
|
||||||
|
|
||||||
static const uint8_t conf_data_unmute[] = {
|
|
||||||
// reg, data,
|
|
||||||
0x00, 0x00, /* Select Page 0 */
|
|
||||||
0x51, 0xc0, /* Power up Left and Right ADC Channels */
|
|
||||||
0x52, 0x00, /* Unmute Left and Right ADC Digital Volume Control */
|
|
||||||
};
|
|
||||||
|
|
||||||
static const uint8_t conf_data_ch3_select[] = {
|
|
||||||
// reg, data,
|
|
||||||
0x00, 0x01, /* Select Page 1 */
|
|
||||||
0x37, 0x04, /* Route IN3R to RIGHT_P with input impedance of 10K */
|
|
||||||
0x39, 0x04, /* Route IN3L to RIGHT_N with input impedance of 10K */
|
|
||||||
};
|
|
||||||
|
|
||||||
static const uint8_t conf_data_ch1_select[] = {
|
|
||||||
// reg, data,
|
|
||||||
0x00, 0x01, /* Select Page 1 */
|
|
||||||
0x37, 0x40, /* Route IN1R to RIGHT_P with input impedance of 10K */
|
|
||||||
0x39, 0x10, /* Route IN1L to RIGHT_N with input impedance of 10K */
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
tlv320aic3204_bulk_write(const uint8_t *buf, int len)
|
|
||||||
{
|
|
||||||
(void)i2cMasterTransmitTimeout(&I2CD1, AIC3204_ADDR, buf, len, NULL, 0, 1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
static int
|
|
||||||
tlv320aic3204_read(uint8_t d0)
|
|
||||||
{
|
|
||||||
int addr = AIC3204_ADDR;
|
|
||||||
uint8_t buf[] = { d0 };
|
|
||||||
i2cAcquireBus(&I2CD1);
|
|
||||||
i2cMasterTransmitTimeout(&I2CD1, addr, buf, 1, buf, 1, 1000);
|
|
||||||
i2cReleaseBus(&I2CD1);
|
|
||||||
return buf[0];
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void
|
|
||||||
tlv320aic3204_config(const uint8_t *data, int len)
|
|
||||||
{
|
|
||||||
i2cAcquireBus(&I2CD1);
|
|
||||||
for (; len--; data += 2)
|
|
||||||
tlv320aic3204_bulk_write(data, 2);
|
|
||||||
i2cReleaseBus(&I2CD1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void tlv320aic3204_init(void)
|
|
||||||
{
|
|
||||||
tlv320aic3204_config(conf_data, sizeof(conf_data)/2);
|
|
||||||
wait_ms(40);
|
|
||||||
tlv320aic3204_config(conf_data_unmute, sizeof(conf_data_unmute)/2);
|
|
||||||
}
|
|
||||||
|
|
||||||
void tlv320aic3204_select(int channel)
|
|
||||||
{
|
|
||||||
tlv320aic3204_config(channel ? conf_data_ch1_select : conf_data_ch3_select, sizeof(conf_data_ch3_select)/2);
|
|
||||||
}
|
|
||||||
|
|
||||||
void tlv320aic3204_set_gain(int lgain, int rgain)
|
|
||||||
{
|
|
||||||
uint8_t data[] = {
|
|
||||||
0x00, 0x01, /* Select Page 1 */
|
|
||||||
0x3b, lgain, /* Unmute Left MICPGA, set gain */
|
|
||||||
0x3c, rgain, /* Unmute Right MICPGA, set gain */
|
|
||||||
};
|
|
||||||
tlv320aic3204_config(data, sizeof(data)/2);
|
|
||||||
}
|
|
||||||
@ -0,0 +1,826 @@
|
|||||||
|
|
||||||
|
void markmap_all_markers(void);
|
||||||
|
static void menu_marker_type_cb(int item, uint8_t data);
|
||||||
|
|
||||||
|
void set_sweep_frequency(int type, uint32_t frequency);
|
||||||
|
uint32_t get_sweep_frequency(int type);
|
||||||
|
void clearDisplay(void);
|
||||||
|
//void ui_process_touch(void);
|
||||||
|
void SetPowerGrid(int);
|
||||||
|
void SetRefLevel(int);
|
||||||
|
void set_refer_output(int);
|
||||||
|
int get_refer_output(void);
|
||||||
|
void SetAttenuation(int);
|
||||||
|
void SetPowerLevel(int);
|
||||||
|
void SetGenerate(int);
|
||||||
|
void SetRBW(int);
|
||||||
|
void SetSpur(int);
|
||||||
|
int GetSpur(void);
|
||||||
|
void SetAverage(int);
|
||||||
|
int GetAverage(void);
|
||||||
|
void SetStorage(void);
|
||||||
|
void SetClearStorage(void);
|
||||||
|
void SetSubtractStorage(void);
|
||||||
|
void toggle_waterfall(void);
|
||||||
|
void SetMode(int);
|
||||||
|
int GetMode(void);
|
||||||
|
void AllDirty(void);
|
||||||
|
void MenuDirty(void);
|
||||||
|
void redrawHisto(void);
|
||||||
|
void self_test(void);
|
||||||
|
extern int32_t frequencyExtra;
|
||||||
|
extern int extraVFO;
|
||||||
|
extern int settingDrive;
|
||||||
|
extern int settingLNA;
|
||||||
|
extern int settingAGC;
|
||||||
|
extern int settingSpeed;
|
||||||
|
extern int stepDelay;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
KM_START, KM_STOP, KM_CENTER, KM_SPAN, KM_CW, KM_REFPOS, KM_SCALE, KM_ATTENUATION, KM_ACTUALPOWER, KM_IF, KM_SAMPLETIME, KM_DRIVE
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#define KP_X(x) (48*(x) + 2 + (320-BUTTON_WIDTH-192))
|
||||||
|
#define KP_Y(y) (48*(y) + 2)
|
||||||
|
|
||||||
|
|
||||||
|
#define KP_PERIOD 10
|
||||||
|
#define KP_MINUS 11
|
||||||
|
#define KP_X1 12
|
||||||
|
#define KP_K 13
|
||||||
|
#define KP_M 14
|
||||||
|
#define KP_G 15
|
||||||
|
#define KP_BS 16
|
||||||
|
#define KP_INF 17
|
||||||
|
#define KP_DB 18
|
||||||
|
#define KP_PLUSMINUS 19
|
||||||
|
#define KP_KEYPAD 20
|
||||||
|
#define KP_N 21
|
||||||
|
#define KP_P 22
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t x:4;
|
||||||
|
uint8_t y:4;
|
||||||
|
int8_t c;
|
||||||
|
} keypads_t;
|
||||||
|
|
||||||
|
static const keypads_t *keypads;
|
||||||
|
|
||||||
|
static uint8_t keypads_last_index;
|
||||||
|
|
||||||
|
|
||||||
|
static const keypads_t keypads_freq[] = {
|
||||||
|
{ 1, 3, KP_PERIOD },
|
||||||
|
{ 0, 3, 0 },
|
||||||
|
{ 0, 2, 1 },
|
||||||
|
{ 1, 2, 2 },
|
||||||
|
{ 2, 2, 3 },
|
||||||
|
{ 0, 1, 4 },
|
||||||
|
{ 1, 1, 5 },
|
||||||
|
{ 2, 1, 6 },
|
||||||
|
{ 0, 0, 7 },
|
||||||
|
{ 1, 0, 8 },
|
||||||
|
{ 2, 0, 9 },
|
||||||
|
{ 3, 0, KP_G },
|
||||||
|
{ 3, 1, KP_M },
|
||||||
|
{ 3, 2, KP_K },
|
||||||
|
{ 3, 3, KP_X1 },
|
||||||
|
{ 2, 3, KP_BS },
|
||||||
|
{ 0, 0, -1 }
|
||||||
|
};
|
||||||
|
|
||||||
|
static const keypads_t keypads_scale[] = {
|
||||||
|
{ 1, 3, KP_PERIOD },
|
||||||
|
{ 0, 3, 0 },
|
||||||
|
{ 0, 2, 1 },
|
||||||
|
{ 1, 2, 2 },
|
||||||
|
{ 2, 2, 3 },
|
||||||
|
{ 0, 1, 4 },
|
||||||
|
{ 1, 1, 5 },
|
||||||
|
{ 2, 1, 6 },
|
||||||
|
{ 0, 0, 7 },
|
||||||
|
{ 1, 0, 8 },
|
||||||
|
{ 2, 0, 9 },
|
||||||
|
{ 3, 3, KP_X1 },
|
||||||
|
{ 2, 3, KP_BS },
|
||||||
|
{ 0, 0, -1 }
|
||||||
|
};
|
||||||
|
|
||||||
|
static const keypads_t keypads_level[] = {
|
||||||
|
{ 1, 3, KP_PERIOD },
|
||||||
|
{ 0, 3, 0 },
|
||||||
|
{ 0, 2, 1 },
|
||||||
|
{ 1, 2, 2 },
|
||||||
|
{ 2, 2, 3 },
|
||||||
|
{ 0, 1, 4 },
|
||||||
|
{ 1, 1, 5 },
|
||||||
|
{ 2, 1, 6 },
|
||||||
|
{ 0, 0, 7 },
|
||||||
|
{ 1, 0, 8 },
|
||||||
|
{ 2, 0, 9 },
|
||||||
|
{ 3, 2, KP_MINUS },
|
||||||
|
{ 3, 3, KP_X1 },
|
||||||
|
{ 2, 3, KP_BS },
|
||||||
|
{ 0, 0, -1 }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static const keypads_t * const keypads_mode_tbl[] = {
|
||||||
|
keypads_freq, // start
|
||||||
|
keypads_freq, // stop
|
||||||
|
keypads_freq, // center
|
||||||
|
keypads_freq, // span
|
||||||
|
keypads_freq, // cw freq
|
||||||
|
keypads_level, // refpos
|
||||||
|
keypads_scale, // scale
|
||||||
|
keypads_scale, // attenuation
|
||||||
|
keypads_level, // actual power
|
||||||
|
keypads_freq, // IF
|
||||||
|
keypads_level, // sample time
|
||||||
|
keypads_scale, // drive
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef __VNA__
|
||||||
|
static const char * const keypad_mode_label[] = {
|
||||||
|
"START", "STOP", "CENTER", "SPAN", "CW FREQ", "SCALE", "REFPOS", "EDELAY", "VELOCITY%", "DELAY"
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
#ifdef __SA__
|
||||||
|
static const char * const keypad_mode_label[] = {
|
||||||
|
"START", "STOP", "CENTER", "SPAN", "CW FREQ", "REFPOS", "SCALE", "ATTENUATION", "ACTUALPOWER", "IF", "SAMPLE TIME", "DRIVE"
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// ===[MENU CALLBACKS]=========================================================
|
||||||
|
|
||||||
|
|
||||||
|
int generator_enabled = false;
|
||||||
|
|
||||||
|
static void menu_mode_cb(int item, uint8_t data)
|
||||||
|
{
|
||||||
|
(void)data;
|
||||||
|
switch (item) {
|
||||||
|
case 4: // Change reference output
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
SetMode(item);
|
||||||
|
menu_move_back();
|
||||||
|
ui_mode_normal();
|
||||||
|
draw_cal_status();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
extern int dirty;
|
||||||
|
void menu_autosettings_cb(int item, uint8_t data)
|
||||||
|
{
|
||||||
|
(void)item;
|
||||||
|
(void)data;
|
||||||
|
SetMode(M_LOW);
|
||||||
|
// set_sweep_frequency(ST_START, (int32_t) 0);
|
||||||
|
// set_sweep_frequency(ST_STOP, (int32_t) 300000000);
|
||||||
|
|
||||||
|
int value = 10; // 10dB/
|
||||||
|
set_trace_scale(0, value);
|
||||||
|
set_trace_scale(1, value);
|
||||||
|
set_trace_scale(2, value);
|
||||||
|
|
||||||
|
value = -10; // Top at -10dB
|
||||||
|
set_trace_refpos(0, - value / get_trace_scale(0) + NGRIDY);
|
||||||
|
set_trace_refpos(1, - value / get_trace_scale(0) + NGRIDY);
|
||||||
|
set_trace_refpos(2, - value / get_trace_scale(0) + NGRIDY);
|
||||||
|
|
||||||
|
active_marker = 0;
|
||||||
|
menu_marker_type_cb(M_REFERENCE,M_REFERENCE);
|
||||||
|
|
||||||
|
set_refer_output(1);
|
||||||
|
SetAttenuation(0);
|
||||||
|
SetPowerLevel(100); // Reset
|
||||||
|
SetRBW(0);
|
||||||
|
dirty = true;
|
||||||
|
menu_move_back();
|
||||||
|
ui_mode_normal();
|
||||||
|
draw_cal_status();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void menu_config_cb(int item, uint8_t data)
|
||||||
|
{
|
||||||
|
(void)data;
|
||||||
|
switch (item) {
|
||||||
|
case 0:
|
||||||
|
touch_cal_exec();
|
||||||
|
redraw_frame();
|
||||||
|
request_to_redraw_grid();
|
||||||
|
draw_menu();
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
touch_draw_test();
|
||||||
|
redraw_frame();
|
||||||
|
request_to_redraw_grid();
|
||||||
|
draw_menu();
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
menu_move_back();
|
||||||
|
ui_mode_normal();
|
||||||
|
self_test();
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
show_version();
|
||||||
|
redraw_frame();
|
||||||
|
request_to_redraw_grid();
|
||||||
|
draw_menu();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void menu_dfu_cb(int item, uint8_t data)
|
||||||
|
{
|
||||||
|
(void)data;
|
||||||
|
switch (item) {
|
||||||
|
case 0:
|
||||||
|
enter_dfu();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int menu_refer_value[]={-1,0,1,2,3,4,5,6};
|
||||||
|
static void menu_refer_cb(int item, uint8_t data)
|
||||||
|
{
|
||||||
|
(void)data;
|
||||||
|
//Serial.println(item);
|
||||||
|
set_refer_output(menu_refer_value[item]);
|
||||||
|
menu_move_back();
|
||||||
|
ui_mode_normal();
|
||||||
|
draw_cal_status();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void menu_refer_cb2(int item, uint8_t data)
|
||||||
|
{
|
||||||
|
(void)data;
|
||||||
|
//Serial.println(item);
|
||||||
|
set_refer_output(menu_refer_value[item+5]);
|
||||||
|
menu_move_back();
|
||||||
|
ui_mode_normal();
|
||||||
|
draw_cal_status();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void menu_spur_cb(int item, uint8_t data)
|
||||||
|
{
|
||||||
|
(void)data;
|
||||||
|
(void)item;
|
||||||
|
if (GetSpur())
|
||||||
|
SetSpur(0);
|
||||||
|
else
|
||||||
|
SetSpur(1); // must be 0 or 1 !!!!
|
||||||
|
menu_move_back();
|
||||||
|
ui_mode_normal();
|
||||||
|
draw_cal_status();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void menu_storage_cb(int item, uint8_t data)
|
||||||
|
{
|
||||||
|
(void)data;
|
||||||
|
switch(item) {
|
||||||
|
case 0:
|
||||||
|
SetStorage();
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
SetClearStorage();
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
SetSubtractStorage();
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
toggle_waterfall();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
menu_move_back();
|
||||||
|
ui_mode_normal();
|
||||||
|
draw_cal_status();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void menu_average_cb(int item, uint8_t data)
|
||||||
|
{
|
||||||
|
(void)data;
|
||||||
|
SetAverage(item);
|
||||||
|
menu_move_back();
|
||||||
|
ui_mode_normal();
|
||||||
|
draw_cal_status();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void menu_marker_type_cb(int item, uint8_t data)
|
||||||
|
{
|
||||||
|
(void)data;
|
||||||
|
if (markers[active_marker].enabled)
|
||||||
|
{
|
||||||
|
if (item == M_REFERENCE) {
|
||||||
|
for (int i = 0; i<MARKER_COUNT; i++ ) {
|
||||||
|
if (markers[i].mtype ==M_REFERENCE)
|
||||||
|
markers[i].mtype = M_NORMAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
markers[active_marker].mtype = item;
|
||||||
|
}
|
||||||
|
markmap_all_markers();
|
||||||
|
// redraw_marker(active_marker, TRUE);
|
||||||
|
menu_move_back();
|
||||||
|
draw_menu();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int rbwsel[]={0,3,10,30,100,300};
|
||||||
|
|
||||||
|
static void menu_rbw_cb(int item, uint8_t data)
|
||||||
|
{
|
||||||
|
(void)data;
|
||||||
|
SetRBW(rbwsel[item]);
|
||||||
|
menu_move_back();
|
||||||
|
ui_mode_normal();
|
||||||
|
draw_cal_status();
|
||||||
|
}
|
||||||
|
|
||||||
|
int menu_dBper_value[]={1,2,5,10,20};
|
||||||
|
|
||||||
|
static void menu_dBper_cb(int item, uint8_t data)
|
||||||
|
{
|
||||||
|
(void)data;
|
||||||
|
set_trace_scale(0, menu_dBper_value[item]);
|
||||||
|
set_trace_scale(1, menu_dBper_value[item]);
|
||||||
|
set_trace_scale(2, menu_dBper_value[item]);
|
||||||
|
menu_move_back();
|
||||||
|
ui_mode_normal();
|
||||||
|
draw_cal_status();
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
static void choose_active_trace(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
if (trace[uistat.current_trace].enabled)
|
||||||
|
// do nothing
|
||||||
|
return;
|
||||||
|
for (i = 0; i < TRACE_COUNT ; i++)
|
||||||
|
if (trace[i].enabled) {
|
||||||
|
uistat.current_trace = i;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
static void choose_active_marker(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < MARKER_COUNT; i++)
|
||||||
|
if (markers[i].enabled) {
|
||||||
|
active_marker = i;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
active_marker = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void menu_scale_cb(int item, uint8_t data)
|
||||||
|
{
|
||||||
|
(void)data;
|
||||||
|
int status;
|
||||||
|
int km = KM_REFPOS + item;
|
||||||
|
// if (km == KM_SCALE && trace[uistat.current_trace].type == TRC_DELAY) {
|
||||||
|
// km = KM_SCALEDELAY;
|
||||||
|
// }
|
||||||
|
status = btn_wait_release();
|
||||||
|
if (status & EVT_BUTTON_DOWN_LONG) {
|
||||||
|
ui_mode_numeric(km);
|
||||||
|
// ui_process_numeric();
|
||||||
|
} else {
|
||||||
|
ui_mode_keypad(km);
|
||||||
|
ui_process_keypad();
|
||||||
|
}
|
||||||
|
draw_cal_status();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void menu_settings_cb(int item, uint8_t data)
|
||||||
|
{
|
||||||
|
(void)data;
|
||||||
|
int status;
|
||||||
|
int km = KM_ACTUALPOWER+item;
|
||||||
|
status = btn_wait_release();
|
||||||
|
if (status & EVT_BUTTON_DOWN_LONG) {
|
||||||
|
ui_mode_numeric(km);
|
||||||
|
// ui_process_numeric();
|
||||||
|
} else {
|
||||||
|
ui_mode_keypad(km);
|
||||||
|
ui_process_keypad();
|
||||||
|
}
|
||||||
|
draw_cal_status();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void menu_settings2_cb(int item, uint8_t data)
|
||||||
|
{
|
||||||
|
(void)data;
|
||||||
|
switch(item) {
|
||||||
|
case 0:
|
||||||
|
settingAGC = !settingAGC;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
settingLNA = !settingLNA;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
extraVFO = !extraVFO;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
draw_cal_status();
|
||||||
|
draw_menu();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void menu_stimulus_cb(int item, uint8_t data)
|
||||||
|
{
|
||||||
|
(void) data;
|
||||||
|
int status;
|
||||||
|
switch (item) {
|
||||||
|
case 0: /* START */
|
||||||
|
case 1: /* STOP */
|
||||||
|
case 2: /* CENTER */
|
||||||
|
case 3: /* SPAN */
|
||||||
|
case 4: /* CW */
|
||||||
|
status = btn_wait_release();
|
||||||
|
if (status & EVT_BUTTON_DOWN_LONG) {
|
||||||
|
ui_mode_numeric(item);
|
||||||
|
// ui_process_numeric();
|
||||||
|
} else {
|
||||||
|
ui_mode_keypad(item);
|
||||||
|
ui_process_keypad();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 5: /* PAUSE */
|
||||||
|
toggle_sweep();
|
||||||
|
menu_move_back();
|
||||||
|
ui_mode_normal();
|
||||||
|
draw_menu();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
draw_cal_status();
|
||||||
|
}
|
||||||
|
|
||||||
|
//static void menu_marker_sel_cb(int);
|
||||||
|
//static void menu_marker_op_cb(int);
|
||||||
|
|
||||||
|
// ===[MENU DEFINITION]=========================================================
|
||||||
|
|
||||||
|
static const menuitem_t menu_average[] = {
|
||||||
|
{ MT_CALLBACK, 0, "OFF", menu_average_cb},
|
||||||
|
{ MT_CALLBACK, 0, "MIN", menu_average_cb},
|
||||||
|
{ MT_CALLBACK, 0, "MAX", menu_average_cb},
|
||||||
|
{ MT_CALLBACK, 0, " 2 ", menu_average_cb},
|
||||||
|
{ MT_CALLBACK, 0, " 4 ", menu_average_cb},
|
||||||
|
{ MT_CALLBACK, 0, " 8 ", menu_average_cb},
|
||||||
|
{ MT_CANCEL, 0, S_LARROW" BACK", NULL },
|
||||||
|
{ MT_NONE, 0, NULL, NULL } // sentinel
|
||||||
|
};
|
||||||
|
|
||||||
|
static const menuitem_t menu_storage[] = {
|
||||||
|
{ MT_CALLBACK, 0, "STORE", menu_storage_cb},
|
||||||
|
{ MT_CALLBACK, 0, "CLEAR", menu_storage_cb},
|
||||||
|
{ MT_CALLBACK, 0, "SUBTRACT", menu_storage_cb},
|
||||||
|
{ MT_CALLBACK, 0, "WATERFALL",menu_storage_cb},
|
||||||
|
{ MT_CANCEL, 0, S_LARROW" BACK", NULL },
|
||||||
|
{ MT_NONE, 0, NULL, NULL } // sentinel
|
||||||
|
};
|
||||||
|
|
||||||
|
static const menuitem_t menu_rbw[] = {
|
||||||
|
{ MT_CALLBACK, 0, " AUTO", menu_rbw_cb},
|
||||||
|
{ MT_CALLBACK, 0, " 3kHz", menu_rbw_cb},
|
||||||
|
{ MT_CALLBACK, 0, " 10kHz", menu_rbw_cb},
|
||||||
|
{ MT_CALLBACK, 0, " 30kHz", menu_rbw_cb},
|
||||||
|
{ MT_CALLBACK, 0, "100kHz", menu_rbw_cb},
|
||||||
|
{ MT_CALLBACK, 0, "300kHz", menu_rbw_cb},
|
||||||
|
{ MT_CANCEL, 0, S_LARROW" BACK", NULL },
|
||||||
|
{ MT_NONE, 0, NULL, NULL } // sentinel
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static const menuitem_t menu_dBper[] = {
|
||||||
|
{ MT_CALLBACK, 0, " 1dB/", menu_dBper_cb},
|
||||||
|
{ MT_CALLBACK, 0, " 2dB/", menu_dBper_cb},
|
||||||
|
{ MT_CALLBACK, 0, " 5dB/", menu_dBper_cb},
|
||||||
|
{ MT_CALLBACK, 0, " 10dB/", menu_dBper_cb},
|
||||||
|
{ MT_CALLBACK, 0, " 20dB/", menu_dBper_cb},
|
||||||
|
{ MT_CANCEL, 0, S_LARROW" BACK", NULL },
|
||||||
|
{ MT_NONE, 0, NULL, NULL } // sentinel
|
||||||
|
};
|
||||||
|
|
||||||
|
static const menuitem_t menu_refer2[] = {
|
||||||
|
{ MT_CALLBACK, 0, "3MHz" , menu_refer_cb2},
|
||||||
|
{ MT_CALLBACK, 0, "2MHz" , menu_refer_cb2},
|
||||||
|
{ MT_CALLBACK, 0, "1MHz" , menu_refer_cb2},
|
||||||
|
{ MT_CANCEL, 0, S_LARROW" BACK", NULL },
|
||||||
|
{ MT_NONE, 0, NULL, NULL } // sentinel
|
||||||
|
};
|
||||||
|
|
||||||
|
static const menuitem_t menu_refer[] = {
|
||||||
|
{ MT_CALLBACK, 0, "OFF" , menu_refer_cb},
|
||||||
|
{ MT_CALLBACK, 0, "30MHz", menu_refer_cb},
|
||||||
|
{ MT_CALLBACK, 0, "15MHz", menu_refer_cb},
|
||||||
|
{ MT_CALLBACK, 0, "10MHz", menu_refer_cb},
|
||||||
|
{ MT_CALLBACK, 0, "4MHz" , menu_refer_cb},
|
||||||
|
{ MT_SUBMENU, 0, S_RARROW" MORE", menu_refer2},
|
||||||
|
{ MT_CANCEL, 0, S_LARROW" BACK", NULL },
|
||||||
|
{ MT_NONE, 0, NULL, NULL } // sentinel
|
||||||
|
};
|
||||||
|
|
||||||
|
static const menuitem_t menu_scale[] = {
|
||||||
|
{ MT_CALLBACK, 0, "\2REF\0LEVEL", menu_scale_cb},
|
||||||
|
{ MT_SUBMENU, 0, "\2SCALE/\0DIV", menu_dBper},
|
||||||
|
{ MT_CALLBACK, 0, "ATTEN", menu_scale_cb},
|
||||||
|
{ MT_SUBMENU, 0, "AVERAGE", menu_average},
|
||||||
|
{ MT_CALLBACK, 0, "\2SPUR\0REDUCT.",menu_spur_cb},
|
||||||
|
{ MT_SUBMENU, 0, "RBW", menu_rbw},
|
||||||
|
{ MT_CANCEL, 0, S_LARROW" BACK", NULL },
|
||||||
|
{ MT_NONE, 0, NULL, NULL } // sentinel
|
||||||
|
};
|
||||||
|
|
||||||
|
static const menuitem_t menu_stimulus[] = {
|
||||||
|
{ MT_CALLBACK, 0, "START", menu_stimulus_cb},
|
||||||
|
{ MT_CALLBACK, 0, "STOP", menu_stimulus_cb},
|
||||||
|
{ MT_CALLBACK, 0, "CENTER", menu_stimulus_cb},
|
||||||
|
{ MT_CALLBACK, 0, "SPAN", menu_stimulus_cb},
|
||||||
|
{ MT_CALLBACK, 0, "CW FREQ", menu_stimulus_cb},
|
||||||
|
// { MT_SUBMENU, 0, "RBW", menu_rbw},
|
||||||
|
{ MT_CALLBACK, 0, "\2PAUSE\0SWEEP", menu_stimulus_cb},
|
||||||
|
{ MT_CANCEL, 0, S_LARROW" BACK", NULL },
|
||||||
|
{ MT_NONE, 0, NULL, NULL } // sentinel
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static const menuitem_t menu_marker_type[] = {
|
||||||
|
{ MT_CALLBACK, 0, "REFERENCE", menu_marker_type_cb},
|
||||||
|
{ MT_CALLBACK, 0, "NORMAL", menu_marker_type_cb},
|
||||||
|
{ MT_CALLBACK, 0, "DELTA", menu_marker_type_cb},
|
||||||
|
{ MT_CANCEL, 0, S_LARROW" BACK", NULL },
|
||||||
|
{ MT_NONE, 0, NULL, NULL } // sentinel
|
||||||
|
};
|
||||||
|
|
||||||
|
static const menuitem_t menu_marker_sel[] = {
|
||||||
|
{ MT_CALLBACK, 0, "MARKER 1", menu_marker_sel_cb},
|
||||||
|
{ MT_CALLBACK, 0, "MARKER 2", menu_marker_sel_cb},
|
||||||
|
{ MT_CALLBACK, 0, "MARKER 3", menu_marker_sel_cb},
|
||||||
|
{ MT_CALLBACK, 0, "MARKER 4", menu_marker_sel_cb},
|
||||||
|
{ MT_CALLBACK, 0, "ALL OFF", menu_marker_sel_cb},
|
||||||
|
{ MT_CANCEL, 0, S_LARROW" BACK", NULL },
|
||||||
|
{ MT_NONE, 0, NULL, NULL } // sentinel
|
||||||
|
};
|
||||||
|
|
||||||
|
static const menuitem_t menu_marker[] = {
|
||||||
|
{ MT_SUBMENU, 0, "\2SELECT\0MARKER", menu_marker_sel},
|
||||||
|
{ MT_SUBMENU, 0, "\2MARKER\0TYPE", menu_marker_type},
|
||||||
|
{ MT_CALLBACK, 0, S_RARROW"START", menu_marker_op_cb},
|
||||||
|
{ MT_CALLBACK, 0, S_RARROW"STOP", menu_marker_op_cb},
|
||||||
|
{ MT_CALLBACK, 0, S_RARROW"CENTER", menu_marker_op_cb},
|
||||||
|
{ MT_CALLBACK, 0, S_RARROW"SPAN", menu_marker_op_cb},
|
||||||
|
{ MT_CANCEL, 0, S_LARROW" BACK", NULL },
|
||||||
|
{ MT_NONE, 0, NULL, NULL } // sentinel
|
||||||
|
};
|
||||||
|
|
||||||
|
static const menuitem_t menu_dfu[] = {
|
||||||
|
{ MT_CALLBACK, 0, "ENTER DFU", menu_dfu_cb},
|
||||||
|
{ MT_CANCEL, 0, S_LARROW" BACK", NULL },
|
||||||
|
{ MT_NONE, 0, NULL, NULL } // sentinel
|
||||||
|
};
|
||||||
|
|
||||||
|
static const menuitem_t menu_mode[] = {
|
||||||
|
{ MT_CALLBACK, 0, "\2LOW\0INPUT", menu_mode_cb},
|
||||||
|
{ MT_CALLBACK, 0, "\2HIGH\0INPUT",menu_mode_cb},
|
||||||
|
{ MT_CALLBACK, 0, "\2LOW\0OUTPUT", menu_mode_cb},
|
||||||
|
{ MT_CALLBACK, 0, "\2HIGH\0OUTPUT",menu_mode_cb},
|
||||||
|
{ MT_SUBMENU, 0, "\2REFER\0OUTPUT",menu_refer},
|
||||||
|
{ MT_CANCEL, 0, S_LARROW" BACK", NULL },
|
||||||
|
{ MT_NONE, 0, NULL, NULL } // sentinel
|
||||||
|
};
|
||||||
|
|
||||||
|
static const menuitem_t menu_settings2[] =
|
||||||
|
{
|
||||||
|
// { MT_CALLBACK, 0, "TRACK", menu_settings2_cb},
|
||||||
|
{ MT_CALLBACK, 0, "AGC", menu_settings2_cb},
|
||||||
|
{ MT_CALLBACK, 0, "LNA", menu_settings2_cb},
|
||||||
|
{ MT_CALLBACK, 0, "BPF", menu_settings2_cb},
|
||||||
|
{ MT_CANCEL, 0, S_LARROW" BACK", NULL },
|
||||||
|
{ MT_NONE, 0, NULL, NULL } // sentinel
|
||||||
|
};
|
||||||
|
|
||||||
|
static const menuitem_t menu_settings[] =
|
||||||
|
{
|
||||||
|
{ MT_CALLBACK, 0, "\2ACTUAL\0POWER", menu_settings_cb},
|
||||||
|
{ MT_CALLBACK, 0, "\2IF\0FREQ", menu_settings_cb},
|
||||||
|
{ MT_CALLBACK, 0, "\2SAMPLE\0TIME", menu_settings_cb},
|
||||||
|
{ MT_CALLBACK, 0, "\2LO\0DRIVE", menu_settings_cb},
|
||||||
|
{ MT_SUBMENU, 0, S_RARROW" MORE", menu_settings2},
|
||||||
|
|
||||||
|
// { MT_SUBMENU, 0, "RBW", menu_rbw},
|
||||||
|
{ MT_CANCEL, 0, S_LARROW" BACK", NULL },
|
||||||
|
{ MT_NONE, 0, NULL, NULL } // sentinel
|
||||||
|
};
|
||||||
|
|
||||||
|
static const menuitem_t menu_config[] = {
|
||||||
|
{ MT_CALLBACK, 0, "\2TOUCH\0CAL", menu_config_cb},
|
||||||
|
{ MT_CALLBACK, 0, "\2TOUCH\0TEST", menu_config_cb},
|
||||||
|
{ MT_CALLBACK, 0, "\2SELF\0TEST", menu_config_cb},
|
||||||
|
{ MT_CALLBACK, 0, "VERSION", menu_config_cb},
|
||||||
|
{ MT_SUBMENU, 0, "SETTINGS", menu_settings},
|
||||||
|
// { MT_SUBMENU, 0, "RBW", menu_rbw},
|
||||||
|
{ MT_SUBMENU, 0, S_RARROW"DFU", menu_dfu},
|
||||||
|
{ MT_CANCEL, 0, S_LARROW" BACK", NULL },
|
||||||
|
{ MT_NONE, 0, NULL, NULL } // sentinel
|
||||||
|
};
|
||||||
|
|
||||||
|
static const menuitem_t menu_top[] = {
|
||||||
|
{ MT_CALLBACK, 0, "AUTO", menu_autosettings_cb},
|
||||||
|
{ MT_SUBMENU, 0, "SCAN", menu_stimulus},
|
||||||
|
{ MT_SUBMENU, 0, "MARKER", menu_marker},
|
||||||
|
{ MT_SUBMENU, 0, "DISPLAY", menu_scale},
|
||||||
|
{ MT_SUBMENU, 0, "STORAGE", menu_storage},
|
||||||
|
{ MT_SUBMENU, 0, "MODE", menu_mode},
|
||||||
|
{ MT_SUBMENU, 0, "CONFIG", menu_config},
|
||||||
|
{ MT_NONE, 0, NULL, NULL } // sentinel,
|
||||||
|
// MENUITEM_CLOSE,
|
||||||
|
};
|
||||||
|
|
||||||
|
// ===[MENU DEFINITION END]======================================================
|
||||||
|
|
||||||
|
#undef BOARD_NAME
|
||||||
|
#define BOARD_NAME "tinySA"
|
||||||
|
|
||||||
|
#define ACTIVE_COLOR RGBHEX(0x007FFF)
|
||||||
|
|
||||||
|
static void menu_item_modify_attribute(
|
||||||
|
const menuitem_t *menu, int item, uint16_t *fg, uint16_t *bg)
|
||||||
|
{
|
||||||
|
if (menu == menu_mode) {
|
||||||
|
if (item == GetMode()){
|
||||||
|
*bg = DEFAULT_MENU_TEXT_COLOR;
|
||||||
|
*fg = config.menu_normal_color;
|
||||||
|
}
|
||||||
|
} else if (menu == menu_refer) {
|
||||||
|
if (item < 5 && item == get_refer_output() + 1){
|
||||||
|
*bg = DEFAULT_MENU_TEXT_COLOR;
|
||||||
|
*fg = config.menu_normal_color;
|
||||||
|
}
|
||||||
|
} else if (menu == menu_refer2) {
|
||||||
|
if (item == get_refer_output() - 4){
|
||||||
|
*bg = DEFAULT_MENU_TEXT_COLOR;
|
||||||
|
*fg = config.menu_normal_color;
|
||||||
|
}
|
||||||
|
} else if (menu == menu_stimulus) {
|
||||||
|
if (item == 5 /* PAUSE */ && !(sweep_mode&SWEEP_ENABLE)) {
|
||||||
|
*bg = DEFAULT_MENU_TEXT_COLOR;
|
||||||
|
*fg = config.menu_normal_color;
|
||||||
|
}
|
||||||
|
} else if (menu == menu_scale) {
|
||||||
|
if (item == 4 /* Spur reduction */ && GetSpur()) {
|
||||||
|
*bg = DEFAULT_MENU_TEXT_COLOR;
|
||||||
|
*fg = config.menu_normal_color;
|
||||||
|
}
|
||||||
|
} else if (menu == menu_average) {
|
||||||
|
if (item == GetAverage()){
|
||||||
|
*bg = DEFAULT_MENU_TEXT_COLOR;
|
||||||
|
*fg = config.menu_normal_color;
|
||||||
|
}
|
||||||
|
} else if (menu == menu_dBper) {
|
||||||
|
if (menu_dBper_value[item] == get_trace_scale(1)){
|
||||||
|
*bg = DEFAULT_MENU_TEXT_COLOR;
|
||||||
|
*fg = config.menu_normal_color;
|
||||||
|
}
|
||||||
|
} else if (menu == menu_rbw) {
|
||||||
|
if (rbwsel[item] == GetRBW()){
|
||||||
|
*bg = DEFAULT_MENU_TEXT_COLOR;
|
||||||
|
*fg = config.menu_normal_color;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (menu == menu_storage) {
|
||||||
|
if (item ==0 && GetStorage()){
|
||||||
|
*bg = DEFAULT_MENU_TEXT_COLOR;
|
||||||
|
*fg = config.menu_normal_color;
|
||||||
|
}
|
||||||
|
if (item == 2 && GetSubtractStorage()){
|
||||||
|
*bg = DEFAULT_MENU_TEXT_COLOR;
|
||||||
|
*fg = config.menu_normal_color;
|
||||||
|
}
|
||||||
|
if (item == 3 && get_waterfall()){
|
||||||
|
*bg = DEFAULT_MENU_TEXT_COLOR;
|
||||||
|
*fg = config.menu_normal_color;
|
||||||
|
}
|
||||||
|
} else if (menu == menu_settings2) {
|
||||||
|
if (item ==0 && settingAGC){
|
||||||
|
*bg = DEFAULT_MENU_TEXT_COLOR;
|
||||||
|
*fg = config.menu_normal_color;
|
||||||
|
}
|
||||||
|
if (item == 1 && settingLNA){
|
||||||
|
*bg = DEFAULT_MENU_TEXT_COLOR;
|
||||||
|
*fg = config.menu_normal_color;
|
||||||
|
}
|
||||||
|
if (item == 2 && extraVFO){
|
||||||
|
*bg = DEFAULT_MENU_TEXT_COLOR;
|
||||||
|
*fg = config.menu_normal_color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fetch_numeric_target(void)
|
||||||
|
{
|
||||||
|
switch (keypad_mode) {
|
||||||
|
case KM_START:
|
||||||
|
uistat.value = get_sweep_frequency(ST_START);
|
||||||
|
break;
|
||||||
|
case KM_STOP:
|
||||||
|
uistat.value = get_sweep_frequency(ST_STOP);
|
||||||
|
break;
|
||||||
|
case KM_CENTER:
|
||||||
|
uistat.value = get_sweep_frequency(ST_CENTER);
|
||||||
|
break;
|
||||||
|
case KM_SPAN:
|
||||||
|
uistat.value = get_sweep_frequency(ST_SPAN);
|
||||||
|
break;
|
||||||
|
case KM_CW:
|
||||||
|
uistat.value = get_sweep_frequency(ST_CW);
|
||||||
|
break;
|
||||||
|
case KM_SCALE:
|
||||||
|
uistat.value = get_trace_scale(uistat.current_trace) * 1000;
|
||||||
|
break;
|
||||||
|
case KM_REFPOS:
|
||||||
|
uistat.value = get_trace_refpos(uistat.current_trace) * 1000;
|
||||||
|
break;
|
||||||
|
case KM_ATTENUATION:
|
||||||
|
uistat.value = settingAttenuate;
|
||||||
|
break;
|
||||||
|
case KM_ACTUALPOWER:
|
||||||
|
uistat.value = settingLevelOffset;
|
||||||
|
break;
|
||||||
|
case KM_IF:
|
||||||
|
uistat.value = frequency_IF;
|
||||||
|
break;
|
||||||
|
case KM_SAMPLETIME:
|
||||||
|
uistat.value = settingSpeed;
|
||||||
|
break;
|
||||||
|
case KM_DRIVE:
|
||||||
|
uistat.value = settingDrive;
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
uint32_t x = uistat.value;
|
||||||
|
int n = 0;
|
||||||
|
for (; x >= 10 && n < 9; n++)
|
||||||
|
x /= 10;
|
||||||
|
uistat.digit = n;
|
||||||
|
}
|
||||||
|
// uistat.previous_value = uistat.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
set_numeric_value(void)
|
||||||
|
{
|
||||||
|
switch (keypad_mode) {
|
||||||
|
case KM_START:
|
||||||
|
set_sweep_frequency(ST_START, uistat.value);
|
||||||
|
break;
|
||||||
|
case KM_STOP:
|
||||||
|
set_sweep_frequency(ST_STOP, uistat.value);
|
||||||
|
break;
|
||||||
|
case KM_CENTER:
|
||||||
|
set_sweep_frequency(ST_CENTER, uistat.value);
|
||||||
|
break;
|
||||||
|
case KM_SPAN:
|
||||||
|
set_sweep_frequency(ST_SPAN, uistat.value);
|
||||||
|
break;
|
||||||
|
case KM_CW:
|
||||||
|
set_sweep_frequency(ST_CW, uistat.value);
|
||||||
|
break;
|
||||||
|
case KM_SCALE:
|
||||||
|
set_trace_scale(0, uistat.value / 1000.0);
|
||||||
|
set_trace_scale(1, uistat.value / 1000.0);
|
||||||
|
set_trace_scale(2, uistat.value / 1000.0);
|
||||||
|
break;
|
||||||
|
case KM_REFPOS:
|
||||||
|
set_trace_refpos(0, NGRIDY - uistat.value / get_trace_scale(0));
|
||||||
|
set_trace_refpos(1, NGRIDY - uistat.value / get_trace_scale(0));
|
||||||
|
set_trace_refpos(2, NGRIDY - uistat.value / get_trace_scale(0));
|
||||||
|
break;
|
||||||
|
case KM_ATTENUATION:
|
||||||
|
SetAttenuation(uistat.value);
|
||||||
|
break;
|
||||||
|
case KM_ACTUALPOWER:
|
||||||
|
SetPowerLevel(uistat.value);
|
||||||
|
config_save();
|
||||||
|
break;
|
||||||
|
case KM_IF:
|
||||||
|
frequency_IF = uistat.value;
|
||||||
|
config_save();
|
||||||
|
break;
|
||||||
|
case KM_SAMPLETIME:
|
||||||
|
settingSpeed = uistat.value;
|
||||||
|
break;
|
||||||
|
case KM_DRIVE:
|
||||||
|
settingDrive = uistat.value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in new issue