├── .cproject ├── .project ├── ChibiOS.7z ├── FatFs ├── diskio.c ├── diskio.h ├── ff.c ├── ff.h ├── ffconf_072.h ├── ffconf_303.h ├── ffsystem.c ├── ffunicode.c └── integer.h ├── Makefile ├── NANOVNA_STM32_F072 ├── STM32F072xB.ld ├── adc_v1.c ├── board.c ├── board.h ├── board.mk ├── board │ ├── stm32f0discovery.cfg │ └── stm32f3discovery.cfg ├── dac_v1.c ├── debug │ └── STM32F3xx-ADC (OpenOCD, Flash and Run).launch ├── dma_v1.c ├── exti_v1.c ├── flash.c ├── gpio_v2.c ├── i2c_v2.c ├── i2s.c ├── interface │ └── stlink.cfg ├── mcuconf.h ├── rtc_v2.c ├── run_openocd └── target │ ├── stm32f0x.cfg │ ├── stm32f3x.cfg │ └── swj-dp.tcl ├── NANOVNA_STM32_F303 ├── STM32F303xC.ld ├── adc_v3.c ├── board.c ├── board.h ├── board.mk ├── board │ └── stm32f3discovery.cfg ├── dac_v1.c ├── debug │ └── STM32F3xx-ADC (OpenOCD, Flash and Run).launch ├── dma_v1.c ├── exti_v1.c ├── flash.c ├── gpio_v2.c ├── i2c_v2.c ├── i2s.c ├── interface │ └── stlink.cfg ├── mcuconf.h ├── rtc_v2.c ├── run_openocd └── target │ ├── stm32f3x.cfg │ └── swj-dp.tcl ├── NanoVNA_DAP.cfg ├── README.md ├── chconf.h ├── chprintf.c ├── common.c ├── data_storage.c ├── doc ├── NanoVNA User Guide_20190711.pdf ├── NanoVNA-H-2.jpg ├── NanoVNASharp.zip ├── NanoVNA_Rev3.4_PCB.jpg ├── Schematic_NanoVNA-H4_REV4_3.pdf ├── Schematic_NanoVNA-H4_REV4_4.pdf ├── Schematic_nanovna-H_REV3_4_1.png ├── Schematic_nanovna-H_REV3_4_2.pdf ├── Schematic_nanovna-H_Sheet-1_20190902.png ├── Schematic_nanovna_H_REV3_5_1.pdf ├── Schematic_nanovna_H_REV3_6.pdf ├── Schematic_nanovna_H_REV3_6_1.pdf ├── Schematic_nanovna_H_REV3_7.pdf ├── ZEETK_NE602A.pdf └── clone.jpg ├── dsp.c ├── dsp.h ├── fonts ├── Font11x14.c ├── Font5x7.c ├── Font6x10.c ├── Font7x11b.c └── numfont16x22.c ├── halconf.h ├── hardware.c ├── hardware.h ├── icons_marker.c ├── icons_menu.c ├── lcd.c ├── main.c ├── mcuconf.h ├── measure.c ├── nanovna.h ├── numfont16x22.c ├── numfont20x22.c ├── numfont20x24.c ├── plot.c ├── prog.sh ├── si5351.c ├── si5351.h ├── spi.h ├── tlv320aic3204.c ├── ui.c ├── usbcfg.c ├── usbcfg.h ├── vna_math.c ├── vna_math.h └── vna_modules └── vna_browser.c /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | NanoVNA-H 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.cdt.managedbuilder.core.genmakebuilder 10 | clean,full,incremental, 11 | 12 | 13 | 14 | 15 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder 16 | full,incremental, 17 | 18 | 19 | 20 | 21 | 22 | org.eclipse.cdt.core.cnature 23 | org.eclipse.cdt.core.ccnature 24 | org.eclipse.cdt.managedbuilder.core.managedBuildNature 25 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature 26 | 27 | 28 | -------------------------------------------------------------------------------- /ChibiOS.7z: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hugen79/NanoVNA-H/8e280e879dd56d30cf8412d807365011b9a8030f/ChibiOS.7z -------------------------------------------------------------------------------- /FatFs/diskio.c: -------------------------------------------------------------------------------- 1 | /*-----------------------------------------------------------------------*/ 2 | /* Low level disk I/O module SKELETON for FatFs (C)ChaN, 2019 */ 3 | /*-----------------------------------------------------------------------*/ 4 | /* If a working storage control module is available, it should be */ 5 | /* attached to the FatFs via a glue function rather than modifying it. */ 6 | /* This is an example of glue functions to attach various exsisting */ 7 | /* storage control modules to the FatFs module with a defined API. */ 8 | /*-----------------------------------------------------------------------*/ 9 | 10 | #include "ff.h" /* Obtains integer types */ 11 | #include "diskio.h" /* Declarations of disk functions */ 12 | 13 | /* Definitions of physical drive number for each drive */ 14 | #define DEV_RAM 0 /* Example: Map Ramdisk to physical drive 0 */ 15 | #define DEV_MMC 1 /* Example: Map MMC/SD card to physical drive 1 */ 16 | #define DEV_USB 2 /* Example: Map USB MSD to physical drive 2 */ 17 | 18 | 19 | /*-----------------------------------------------------------------------*/ 20 | /* Get Drive Status */ 21 | /*-----------------------------------------------------------------------*/ 22 | 23 | DSTATUS disk_status ( 24 | BYTE pdrv /* Physical drive nmuber to identify the drive */ 25 | ) 26 | { 27 | DSTATUS stat; 28 | int result; 29 | 30 | switch (pdrv) { 31 | case DEV_RAM : 32 | result = RAM_disk_status(); 33 | 34 | // translate the reslut code here 35 | 36 | return stat; 37 | 38 | case DEV_MMC : 39 | result = MMC_disk_status(); 40 | 41 | // translate the reslut code here 42 | 43 | return stat; 44 | 45 | case DEV_USB : 46 | result = USB_disk_status(); 47 | 48 | // translate the reslut code here 49 | 50 | return stat; 51 | } 52 | return STA_NOINIT; 53 | } 54 | 55 | 56 | 57 | /*-----------------------------------------------------------------------*/ 58 | /* Inidialize a Drive */ 59 | /*-----------------------------------------------------------------------*/ 60 | 61 | DSTATUS disk_initialize ( 62 | BYTE pdrv /* Physical drive nmuber to identify the drive */ 63 | ) 64 | { 65 | DSTATUS stat; 66 | int result; 67 | 68 | switch (pdrv) { 69 | case DEV_RAM : 70 | result = RAM_disk_initialize(); 71 | 72 | // translate the reslut code here 73 | 74 | return stat; 75 | 76 | case DEV_MMC : 77 | result = MMC_disk_initialize(); 78 | 79 | // translate the reslut code here 80 | 81 | return stat; 82 | 83 | case DEV_USB : 84 | result = USB_disk_initialize(); 85 | 86 | // translate the reslut code here 87 | 88 | return stat; 89 | } 90 | return STA_NOINIT; 91 | } 92 | 93 | 94 | 95 | /*-----------------------------------------------------------------------*/ 96 | /* Read Sector(s) */ 97 | /*-----------------------------------------------------------------------*/ 98 | 99 | DRESULT disk_read ( 100 | BYTE pdrv, /* Physical drive nmuber to identify the drive */ 101 | BYTE *buff, /* Data buffer to store read data */ 102 | LBA_t sector, /* Start sector in LBA */ 103 | UINT count /* Number of sectors to read */ 104 | ) 105 | { 106 | DRESULT res; 107 | int result; 108 | 109 | switch (pdrv) { 110 | case DEV_RAM : 111 | // translate the arguments here 112 | 113 | result = RAM_disk_read(buff, sector, count); 114 | 115 | // translate the reslut code here 116 | 117 | return res; 118 | 119 | case DEV_MMC : 120 | // translate the arguments here 121 | 122 | result = MMC_disk_read(buff, sector, count); 123 | 124 | // translate the reslut code here 125 | 126 | return res; 127 | 128 | case DEV_USB : 129 | // translate the arguments here 130 | 131 | result = USB_disk_read(buff, sector, count); 132 | 133 | // translate the reslut code here 134 | 135 | return res; 136 | } 137 | 138 | return RES_PARERR; 139 | } 140 | 141 | 142 | 143 | /*-----------------------------------------------------------------------*/ 144 | /* Write Sector(s) */ 145 | /*-----------------------------------------------------------------------*/ 146 | 147 | #if FF_FS_READONLY == 0 148 | 149 | DRESULT disk_write ( 150 | BYTE pdrv, /* Physical drive nmuber to identify the drive */ 151 | const BYTE *buff, /* Data to be written */ 152 | LBA_t sector, /* Start sector in LBA */ 153 | UINT count /* Number of sectors to write */ 154 | ) 155 | { 156 | DRESULT res; 157 | int result; 158 | 159 | switch (pdrv) { 160 | case DEV_RAM : 161 | // translate the arguments here 162 | 163 | result = RAM_disk_write(buff, sector, count); 164 | 165 | // translate the reslut code here 166 | 167 | return res; 168 | 169 | case DEV_MMC : 170 | // translate the arguments here 171 | 172 | result = MMC_disk_write(buff, sector, count); 173 | 174 | // translate the reslut code here 175 | 176 | return res; 177 | 178 | case DEV_USB : 179 | // translate the arguments here 180 | 181 | result = USB_disk_write(buff, sector, count); 182 | 183 | // translate the reslut code here 184 | 185 | return res; 186 | } 187 | 188 | return RES_PARERR; 189 | } 190 | 191 | #endif 192 | 193 | 194 | /*-----------------------------------------------------------------------*/ 195 | /* Miscellaneous Functions */ 196 | /*-----------------------------------------------------------------------*/ 197 | 198 | DRESULT disk_ioctl ( 199 | BYTE pdrv, /* Physical drive nmuber (0..) */ 200 | BYTE cmd, /* Control code */ 201 | void *buff /* Buffer to send/receive control data */ 202 | ) 203 | { 204 | DRESULT res; 205 | int result; 206 | 207 | switch (pdrv) { 208 | case DEV_RAM : 209 | 210 | // Process of the command for the RAM drive 211 | 212 | return res; 213 | 214 | case DEV_MMC : 215 | 216 | // Process of the command for the MMC/SD card 217 | 218 | return res; 219 | 220 | case DEV_USB : 221 | 222 | // Process of the command the USB drive 223 | 224 | return res; 225 | } 226 | 227 | return RES_PARERR; 228 | } 229 | 230 | -------------------------------------------------------------------------------- /FatFs/diskio.h: -------------------------------------------------------------------------------- 1 | /*-----------------------------------------------------------------------/ 2 | / Low level disk interface modlue include file (C)ChaN, 2019 / 3 | /-----------------------------------------------------------------------*/ 4 | 5 | #ifndef _DISKIO_DEFINED 6 | #define _DISKIO_DEFINED 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | /* Status of Disk Functions */ 13 | typedef BYTE DSTATUS; 14 | 15 | /* Results of Disk Functions */ 16 | typedef enum { 17 | RES_OK = 0, /* 0: Successful */ 18 | RES_ERROR, /* 1: R/W Error */ 19 | RES_WRPRT, /* 2: Write Protected */ 20 | RES_NOTRDY, /* 3: Not Ready */ 21 | RES_PARERR /* 4: Invalid Parameter */ 22 | } DRESULT; 23 | 24 | 25 | /*---------------------------------------*/ 26 | /* Prototypes for disk control functions */ 27 | 28 | 29 | DSTATUS disk_initialize (BYTE pdrv); 30 | DSTATUS disk_status (BYTE pdrv); 31 | DRESULT disk_read (BYTE pdrv, BYTE* buff, LBA_t sector, UINT count); 32 | DRESULT disk_write (BYTE pdrv, const BYTE* buff, LBA_t sector, UINT count); 33 | DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff); 34 | 35 | 36 | /* Disk Status Bits (DSTATUS) */ 37 | 38 | #define STA_NOINIT 0x01 /* Drive not initialized */ 39 | #define STA_NODISK 0x02 /* No medium in the drive */ 40 | #define STA_PROTECT 0x04 /* Write protected */ 41 | 42 | 43 | /* Command code for disk_ioctrl fucntion */ 44 | 45 | /* Generic command (Used by FatFs) */ 46 | #define CTRL_SYNC 0 /* Complete pending write process (needed at FF_FS_READONLY == 0) */ 47 | #define GET_SECTOR_COUNT 1 /* Get media size (needed at FF_USE_MKFS == 1) */ 48 | #define GET_SECTOR_SIZE 2 /* Get sector size (needed at FF_MAX_SS != FF_MIN_SS) */ 49 | #define GET_BLOCK_SIZE 3 /* Get erase block size (needed at FF_USE_MKFS == 1) */ 50 | #define CTRL_TRIM 4 /* Inform device that the data on the block of sectors is no longer used (needed at FF_USE_TRIM == 1) */ 51 | 52 | /* Generic command (Not used by FatFs) */ 53 | #define CTRL_POWER 5 /* Get/Set power status */ 54 | #define CTRL_LOCK 6 /* Lock/Unlock media removal */ 55 | #define CTRL_EJECT 7 /* Eject media */ 56 | #define CTRL_FORMAT 8 /* Create physical format on the media */ 57 | 58 | /* MMC/SDC specific ioctl command */ 59 | #define MMC_GET_TYPE 10 /* Get card type */ 60 | #define MMC_GET_CSD 11 /* Get CSD */ 61 | #define MMC_GET_CID 12 /* Get CID */ 62 | #define MMC_GET_OCR 13 /* Get OCR */ 63 | #define MMC_GET_SDSTAT 14 /* Get SD status */ 64 | #define ISDIO_READ 55 /* Read data form SD iSDIO register */ 65 | #define ISDIO_WRITE 56 /* Write data to SD iSDIO register */ 66 | #define ISDIO_MRITE 57 /* Masked write data to SD iSDIO register */ 67 | 68 | /* ATA/CF specific ioctl command */ 69 | #define ATA_GET_REV 20 /* Get F/W revision */ 70 | #define ATA_GET_MODEL 21 /* Get model name */ 71 | #define ATA_GET_SN 22 /* Get serial number */ 72 | 73 | #ifdef __cplusplus 74 | } 75 | #endif 76 | 77 | #endif 78 | -------------------------------------------------------------------------------- /FatFs/ffsystem.c: -------------------------------------------------------------------------------- 1 | /*------------------------------------------------------------------------*/ 2 | /* Sample Code of OS Dependent Functions for FatFs */ 3 | /* (C)ChaN, 2018 */ 4 | /*------------------------------------------------------------------------*/ 5 | 6 | 7 | #include "ff.h" 8 | 9 | 10 | #if FF_USE_LFN == 3 /* Dynamic memory allocation */ 11 | 12 | /*------------------------------------------------------------------------*/ 13 | /* Allocate a memory block */ 14 | /*------------------------------------------------------------------------*/ 15 | 16 | void* ff_memalloc ( /* Returns pointer to the allocated memory block (null if not enough core) */ 17 | UINT msize /* Number of bytes to allocate */ 18 | ) 19 | { 20 | return malloc(msize); /* Allocate a new memory block with POSIX API */ 21 | } 22 | 23 | 24 | /*------------------------------------------------------------------------*/ 25 | /* Free a memory block */ 26 | /*------------------------------------------------------------------------*/ 27 | 28 | void ff_memfree ( 29 | void* mblock /* Pointer to the memory block to free (nothing to do if null) */ 30 | ) 31 | { 32 | free(mblock); /* Free the memory block with POSIX API */ 33 | } 34 | 35 | #endif 36 | 37 | 38 | 39 | #if FF_FS_REENTRANT /* Mutal exclusion */ 40 | 41 | /*------------------------------------------------------------------------*/ 42 | /* Create a Synchronization Object */ 43 | /*------------------------------------------------------------------------*/ 44 | /* This function is called in f_mount() function to create a new 45 | / synchronization object for the volume, such as semaphore and mutex. 46 | / When a 0 is returned, the f_mount() function fails with FR_INT_ERR. 47 | */ 48 | 49 | //const osMutexDef_t Mutex[FF_VOLUMES]; /* Table of CMSIS-RTOS mutex */ 50 | 51 | 52 | int ff_cre_syncobj ( /* 1:Function succeeded, 0:Could not create the sync object */ 53 | BYTE vol, /* Corresponding volume (logical drive number) */ 54 | FF_SYNC_t* sobj /* Pointer to return the created sync object */ 55 | ) 56 | { 57 | /* Win32 */ 58 | *sobj = CreateMutex(NULL, FALSE, NULL); 59 | return (int)(*sobj != INVALID_HANDLE_VALUE); 60 | 61 | /* uITRON */ 62 | // T_CSEM csem = {TA_TPRI,1,1}; 63 | // *sobj = acre_sem(&csem); 64 | // return (int)(*sobj > 0); 65 | 66 | /* uC/OS-II */ 67 | // OS_ERR err; 68 | // *sobj = OSMutexCreate(0, &err); 69 | // return (int)(err == OS_NO_ERR); 70 | 71 | /* FreeRTOS */ 72 | // *sobj = xSemaphoreCreateMutex(); 73 | // return (int)(*sobj != NULL); 74 | 75 | /* CMSIS-RTOS */ 76 | // *sobj = osMutexCreate(&Mutex[vol]); 77 | // return (int)(*sobj != NULL); 78 | } 79 | 80 | 81 | /*------------------------------------------------------------------------*/ 82 | /* Delete a Synchronization Object */ 83 | /*------------------------------------------------------------------------*/ 84 | /* This function is called in f_mount() function to delete a synchronization 85 | / object that created with ff_cre_syncobj() function. When a 0 is returned, 86 | / the f_mount() function fails with FR_INT_ERR. 87 | */ 88 | 89 | int ff_del_syncobj ( /* 1:Function succeeded, 0:Could not delete due to an error */ 90 | FF_SYNC_t sobj /* Sync object tied to the logical drive to be deleted */ 91 | ) 92 | { 93 | /* Win32 */ 94 | return (int)CloseHandle(sobj); 95 | 96 | /* uITRON */ 97 | // return (int)(del_sem(sobj) == E_OK); 98 | 99 | /* uC/OS-II */ 100 | // OS_ERR err; 101 | // OSMutexDel(sobj, OS_DEL_ALWAYS, &err); 102 | // return (int)(err == OS_NO_ERR); 103 | 104 | /* FreeRTOS */ 105 | // vSemaphoreDelete(sobj); 106 | // return 1; 107 | 108 | /* CMSIS-RTOS */ 109 | // return (int)(osMutexDelete(sobj) == osOK); 110 | } 111 | 112 | 113 | /*------------------------------------------------------------------------*/ 114 | /* Request Grant to Access the Volume */ 115 | /*------------------------------------------------------------------------*/ 116 | /* This function is called on entering file functions to lock the volume. 117 | / When a 0 is returned, the file function fails with FR_TIMEOUT. 118 | */ 119 | 120 | int ff_req_grant ( /* 1:Got a grant to access the volume, 0:Could not get a grant */ 121 | FF_SYNC_t sobj /* Sync object to wait */ 122 | ) 123 | { 124 | /* Win32 */ 125 | return (int)(WaitForSingleObject(sobj, FF_FS_TIMEOUT) == WAIT_OBJECT_0); 126 | 127 | /* uITRON */ 128 | // return (int)(wai_sem(sobj) == E_OK); 129 | 130 | /* uC/OS-II */ 131 | // OS_ERR err; 132 | // OSMutexPend(sobj, FF_FS_TIMEOUT, &err)); 133 | // return (int)(err == OS_NO_ERR); 134 | 135 | /* FreeRTOS */ 136 | // return (int)(xSemaphoreTake(sobj, FF_FS_TIMEOUT) == pdTRUE); 137 | 138 | /* CMSIS-RTOS */ 139 | // return (int)(osMutexWait(sobj, FF_FS_TIMEOUT) == osOK); 140 | } 141 | 142 | 143 | /*------------------------------------------------------------------------*/ 144 | /* Release Grant to Access the Volume */ 145 | /*------------------------------------------------------------------------*/ 146 | /* This function is called on leaving file functions to unlock the volume. 147 | */ 148 | 149 | void ff_rel_grant ( 150 | FF_SYNC_t sobj /* Sync object to be signaled */ 151 | ) 152 | { 153 | /* Win32 */ 154 | ReleaseMutex(sobj); 155 | 156 | /* uITRON */ 157 | // sig_sem(sobj); 158 | 159 | /* uC/OS-II */ 160 | // OSMutexPost(sobj); 161 | 162 | /* FreeRTOS */ 163 | // xSemaphoreGive(sobj); 164 | 165 | /* CMSIS-RTOS */ 166 | // osMutexRelease(sobj); 167 | } 168 | 169 | #endif 170 | 171 | -------------------------------------------------------------------------------- /FatFs/integer.h: -------------------------------------------------------------------------------- 1 | /*-------------------------------------------*/ 2 | /* Integer type definitions for FatFs module */ 3 | /*-------------------------------------------*/ 4 | 5 | #ifndef FF_INTEGER 6 | #define FF_INTEGER 7 | 8 | #ifdef _WIN32 /* FatFs development platform */ 9 | 10 | #include 11 | #include 12 | typedef unsigned __int64 QWORD; 13 | 14 | 15 | #else /* Embedded platform */ 16 | 17 | /* These types MUST be 16-bit or 32-bit */ 18 | typedef int INT; 19 | typedef unsigned int UINT; 20 | 21 | /* This type MUST be 8-bit */ 22 | typedef unsigned char BYTE; 23 | 24 | /* These types MUST be 16-bit */ 25 | typedef short SHORT; 26 | typedef unsigned short WORD; 27 | typedef unsigned short WCHAR; 28 | 29 | /* These types MUST be 32-bit */ 30 | typedef long LONG; 31 | typedef unsigned long DWORD; 32 | 33 | /* This type MUST be 64-bit (Remove this for ANSI C (C89) compatibility) */ 34 | typedef unsigned long long QWORD; 35 | 36 | #endif 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | ############################################################################## 2 | # Build global options 3 | # NOTE: Can be overridden externally. 4 | # 5 | 6 | #Build target 7 | ifeq ($(TARGET),) 8 | TARGET = F072 9 | endif 10 | #TARGET=F303 11 | 12 | # Compiler options here. 13 | ifeq ($(USE_OPT),) 14 | ifeq ($(TARGET),F303) 15 | USE_OPT = -O2 -fno-inline-small-functions -ggdb -fomit-frame-pointer -falign-functions=16 --specs=nano.specs -fstack-usage -std=c11 16 | #USE_OPT+=-fstack-protector-strong 17 | else 18 | USE_OPT = -O2 -fno-inline-small-functions -ggdb -fomit-frame-pointer -falign-functions=16 --specs=nano.specs -fstack-usage -std=c11 19 | endif 20 | endif 21 | # additional options, use math optimisations 22 | USE_OPT+= -ffast-math -fsingle-precision-constant 23 | #USE_OPT+= -D__MS5351__ 24 | 25 | 26 | # C specific options here (added to USE_OPT). 27 | ifeq ($(USE_COPT),) 28 | USE_COPT = 29 | endif 30 | 31 | # C++ specific options here (added to USE_OPT). 32 | ifeq ($(USE_CPPOPT),) 33 | USE_CPPOPT = -fno-rtti 34 | endif 35 | 36 | # Enable this if you want the linker to remove unused code and data 37 | ifeq ($(USE_LINK_GC),) 38 | USE_LINK_GC = yes 39 | endif 40 | 41 | # Linker extra options here. 42 | ifeq ($(USE_LDOPT),) 43 | USE_LDOPT = 44 | endif 45 | 46 | # Enable this if you want link time optimizations (LTO) 47 | ifeq ($(USE_LTO),) 48 | USE_LTO = yes 49 | endif 50 | 51 | # If enabled, this option allows to compile the application in THUMB mode. 52 | ifeq ($(USE_THUMB),) 53 | USE_THUMB = yes 54 | endif 55 | 56 | # Enable this if you want to see the full log while compiling. 57 | ifeq ($(USE_VERBOSE_COMPILE),) 58 | USE_VERBOSE_COMPILE = no 59 | endif 60 | 61 | # If enabled, this option makes the build process faster by not compiling 62 | # modules not used in the current configuration. 63 | ifeq ($(USE_SMART_BUILD),) 64 | USE_SMART_BUILD = yes 65 | endif 66 | 67 | # 68 | # Build global options 69 | ############################################################################## 70 | 71 | ifeq ($(VERSION),) 72 | VERSION="$(shell git describe --tags)" 73 | endif 74 | 75 | ############################################################################## 76 | # Architecture or project specific options 77 | # 78 | ifeq ($(TARGET),F303) 79 | USE_FPU = hard 80 | endif 81 | 82 | # Stack size to be allocated to the Cortex-M process stack. This stack is 83 | # the stack used by the main() thread. 84 | ifeq ($(USE_PROCESS_STACKSIZE),) 85 | USE_PROCESS_STACKSIZE = 0x200 86 | endif 87 | # Stack size to the allocated to the Cortex-M main/exceptions stack. This 88 | # stack is used for processing interrupts and exceptions. 89 | ifeq ($(USE_EXCEPTIONS_STACKSIZE),) 90 | USE_EXCEPTIONS_STACKSIZE = 0x100 91 | endif 92 | # 93 | # Architecture or project specific options 94 | ############################################################################## 95 | 96 | ############################################################################## 97 | # Project, sources and paths 98 | # 99 | 100 | # Define project name here 101 | ifeq ($(TARGET),F303) 102 | PROJECT = H4 103 | else 104 | PROJECT = H 105 | endif 106 | 107 | # Imported source files and paths 108 | #CHIBIOS = ../ChibiOS-RT 109 | CHIBIOS = ChibiOS 110 | PROJ = . 111 | # Startup files. 112 | # HAL-OSAL files (optional). 113 | ifeq ($(TARGET),F303) 114 | include $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/mk/startup_stm32f3xx.mk 115 | include $(CHIBIOS)/os/hal/hal.mk 116 | include $(CHIBIOS)/os/hal/ports/STM32/STM32F3xx/platform.mk 117 | include NANOVNA_STM32_F303/board.mk 118 | else 119 | include $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/mk/startup_stm32f0xx.mk 120 | include $(CHIBIOS)/os/hal/hal.mk 121 | include $(CHIBIOS)/os/hal/ports/STM32/STM32F0xx/platform.mk 122 | include NANOVNA_STM32_F072/board.mk 123 | endif 124 | 125 | include $(CHIBIOS)/os/hal/osal/rt/osal.mk 126 | # RTOS files (optional). 127 | include $(CHIBIOS)/os/rt/rt.mk 128 | ifeq ($(TARGET),F303) 129 | include $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/mk/port_v7m.mk 130 | else 131 | include $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/mk/port_v6m.mk 132 | endif 133 | # Other files (optional). 134 | #include $(CHIBIOS)/test/rt/test.mk 135 | include $(CHIBIOS)/os/hal/lib/streams/streams.mk 136 | #include $(CHIBIOS)/os/various/shell/shell.mk 137 | 138 | # Define linker script file here 139 | ifeq ($(TARGET),F303) 140 | LDSCRIPT= NANOVNA_STM32_F303/STM32F303xC.ld 141 | else 142 | LDSCRIPT= NANOVNA_STM32_F072/STM32F072xB.ld 143 | endif 144 | 145 | # C sources that can be compiled in ARM or THUMB mode depending on the global 146 | # setting. 147 | CSRC = $(STARTUPSRC) \ 148 | $(KERNSRC) \ 149 | $(PORTSRC) \ 150 | $(OSALSRC) \ 151 | $(HALSRC) \ 152 | $(PLATFORMSRC) \ 153 | $(BOARDSRC) \ 154 | $(STREAMSSRC) \ 155 | FatFs/ff.c \ 156 | FatFs/ffunicode.c \ 157 | fonts/numfont16x22.c \ 158 | fonts/Font5x7.c \ 159 | fonts/Font6x10.c \ 160 | fonts/Font7x11b.c \ 161 | fonts/Font11x14.c \ 162 | usbcfg.c \ 163 | main.c common.c si5351.c tlv320aic3204.c dsp.c plot.c ui.c lcd.c data_storage.c hardware.c vna_math.c 164 | 165 | # C++ sources that can be compiled in ARM or THUMB mode depending on the global 166 | # setting. 167 | CPPSRC = 168 | 169 | # C sources to be compiled in ARM mode regardless of the global setting. 170 | # NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler 171 | # option that results in lower performance and larger code size. 172 | ACSRC = 173 | 174 | # C++ sources to be compiled in ARM mode regardless of the global setting. 175 | # NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler 176 | # option that results in lower performance and larger code size. 177 | ACPPSRC = 178 | 179 | # C sources to be compiled in THUMB mode regardless of the global setting. 180 | # NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler 181 | # option that results in lower performance and larger code size. 182 | TCSRC = 183 | 184 | # C sources to be compiled in THUMB mode regardless of the global setting. 185 | # NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler 186 | # option that results in lower performance and larger code size. 187 | TCPPSRC = 188 | 189 | # List ASM source files here 190 | ASMSRC = $(STARTUPASM) $(PORTASM) $(OSALASM) 191 | 192 | INCDIR = $(STARTUPINC) $(KERNINC) $(PORTINC) $(OSALINC) \ 193 | $(HALINC) $(PLATFORMINC) $(BOARDINC) \ 194 | $(STREAMSINC) 195 | 196 | # 197 | # Project, sources and paths 198 | ############################################################################## 199 | 200 | ############################################################################## 201 | # Compiler settings 202 | # 203 | 204 | ifeq ($(TARGET),F303) 205 | MCU = cortex-m4 206 | else 207 | MCU = cortex-m0 208 | endif 209 | 210 | #TRGT = arm-elf- 211 | TRGT = arm-none-eabi- 212 | CC = $(TRGT)gcc 213 | CPPC = $(TRGT)g++ 214 | # Enable loading with g++ only if you need C++ runtime support. 215 | # NOTE: You can use C++ even without C++ support if you are careful. C++ 216 | # runtime support makes code size explode. 217 | LD = $(TRGT)gcc 218 | #LD = $(TRGT)g++ 219 | CP = $(TRGT)objcopy 220 | AS = $(TRGT)gcc -x assembler-with-cpp 221 | AR = $(TRGT)ar 222 | OD = $(TRGT)objdump 223 | SZ = $(TRGT)size 224 | HEX = $(CP) -O ihex 225 | BIN = $(CP) -O binary 226 | ELF = $(CP) -O elf 227 | 228 | # ARM-specific options here 229 | AOPT = 230 | 231 | # THUMB-specific options here 232 | TOPT = -mthumb -DTHUMB 233 | 234 | # Define C warning options here 235 | CWARN = -Wall -Wextra -Wundef -Wstrict-prototypes 236 | 237 | # Define C++ warning options here 238 | CPPWARN = -Wall -Wextra -Wundef 239 | 240 | # 241 | # Compiler settings 242 | ############################################################################## 243 | 244 | ############################################################################## 245 | # Start of user section 246 | # 247 | 248 | # List all user C define here, like -D_DEBUG=1 249 | ifeq ($(TARGET),F303) 250 | UDEFS = -DARM_MATH_CM4 -DVERSION=\"$(VERSION)\" -DNANOVNA_F303 251 | else 252 | UDEFS = -DARM_MATH_CM0 -DVERSION=\"$(VERSION)\" 253 | endif 254 | #Enable if use RTC and need auto select source LSE or LSI 255 | UDEFS+= -DVNA_AUTO_SELECT_RTC_SOURCE 256 | #Enable if install external 32.768kHz clock quartz on PC14 and PC15 pins on STM32 CPU and no VNA_AUTO_SELECT_RTC_SOURCE 257 | #UDEFS+= -DVNA_USE_LSE 258 | #UDEFS+= -D__VNA_Z_RENORMALIZATION__ -D__VNA_FAST_LINES__ 259 | 260 | # Define ASM defines here 261 | UADEFS = 262 | 263 | # List all user directories here 264 | UINCDIR = 265 | 266 | # List the user directory to look for the libraries here 267 | ULIBDIR = 268 | 269 | # List all user libraries here 270 | ULIBS = -lm 271 | 272 | # 273 | # End of user defines 274 | ############################################################################## 275 | 276 | RULESPATH = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC 277 | include $(RULESPATH)/rules.mk 278 | 279 | flash: build/$(PROJECT).bin 280 | dfu-util -d 0483:df11 -a 0 -s 0x08000000:leave -D build/$(PROJECT).bin 281 | 282 | dfu: 283 | -@printf "reset dfu\r" >/dev/cu.usbmodem401 284 | 285 | TAGS: Makefile 286 | ifeq ($(TARGET),F303) 287 | @etags *.[ch] NANOVNA_STM32_F303/*.[ch] $(shell find ChibiOS/os/hal/ports/STM32/STM32F3xx ChibiOS/os -name \*.\[ch\] -print) 288 | else 289 | @etags *.[ch] NANOVNA_STM32_F072/*.[ch] $(shell find ChibiOS/os/hal/ports/STM32/STM32F0xx ChibiOS/os -name \*.\[ch\] -print) 290 | endif 291 | @ls -l TAGS 292 | 293 | -------------------------------------------------------------------------------- /NANOVNA_STM32_F072/STM32F072xB.ld: -------------------------------------------------------------------------------- 1 | /* 2 | ChibiOS - Copyright (C) 2006..2016 Giovanni Di Sirio 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | /* 18 | * STM32F072xB memory setup. 19 | */ 20 | MEMORY 21 | { 22 | flash0 : org = 0x08000000, len = 96k 23 | flash1 : org = 0x00000000, len = 0 24 | flash2 : org = 0x00000000, len = 0 25 | flash3 : org = 0x00000000, len = 0 26 | flash4 : org = 0x00000000, len = 0 27 | flash5 : org = 0x00000000, len = 0 28 | flash6 : org = 0x00000000, len = 0 29 | flash7 : org = 0x08018000, len = 32k 30 | ram0 : org = 0x20000000, len = 16k 31 | ram1 : org = 0x00000000, len = 0 32 | ram2 : org = 0x00000000, len = 0 33 | ram3 : org = 0x00000000, len = 0 34 | ram4 : org = 0x00000000, len = 0 35 | ram5 : org = 0x00000000, len = 0 36 | ram6 : org = 0x00000000, len = 0 37 | ram7 : org = 0x00000000, len = 0 38 | } 39 | 40 | /* For each data/text section two region are defined, a virtual region 41 | and a load region (_LMA suffix).*/ 42 | 43 | /* Flash region to be used for exception vectors.*/ 44 | REGION_ALIAS("VECTORS_FLASH", flash0); 45 | REGION_ALIAS("VECTORS_FLASH_LMA", flash0); 46 | 47 | /* Flash region to be used for constructors and destructors.*/ 48 | REGION_ALIAS("XTORS_FLASH", flash0); 49 | REGION_ALIAS("XTORS_FLASH_LMA", flash0); 50 | 51 | /* Flash region to be used for code text.*/ 52 | REGION_ALIAS("TEXT_FLASH", flash0); 53 | REGION_ALIAS("TEXT_FLASH_LMA", flash0); 54 | 55 | /* Flash region to be used for read only data.*/ 56 | REGION_ALIAS("RODATA_FLASH", flash0); 57 | REGION_ALIAS("RODATA_FLASH_LMA", flash0); 58 | 59 | /* Flash region to be used for various.*/ 60 | REGION_ALIAS("VARIOUS_FLASH", flash0); 61 | REGION_ALIAS("VARIOUS_FLASH_LMA", flash0); 62 | 63 | /* Flash region to be used for RAM(n) initialization data.*/ 64 | REGION_ALIAS("RAM_INIT_FLASH_LMA", flash0); 65 | 66 | /* Flash region to be saved calibration data */ 67 | REGION_ALIAS("CALDATA_FLASH", flash7); 68 | 69 | /* RAM region to be used for Main stack. This stack accommodates the processing 70 | of all exceptions and interrupts.*/ 71 | REGION_ALIAS("MAIN_STACK_RAM", ram0); 72 | 73 | /* RAM region to be used for the process stack. This is the stack used by 74 | the main() function.*/ 75 | REGION_ALIAS("PROCESS_STACK_RAM", ram0); 76 | 77 | /* RAM region to be used for data segment.*/ 78 | REGION_ALIAS("DATA_RAM", ram0); 79 | REGION_ALIAS("DATA_RAM_LMA", flash0); 80 | 81 | /* RAM region to be used for BSS segment.*/ 82 | REGION_ALIAS("BSS_RAM", ram0); 83 | 84 | /* RAM region to be used for the default heap.*/ 85 | REGION_ALIAS("HEAP_RAM", ram0); 86 | 87 | /* Generic rules inclusion.*/ 88 | INCLUDE rules.ld 89 | 90 | SECTIONS 91 | { 92 | .calsave (NOLOAD) : ALIGN(4) 93 | { 94 | *(.calsave) 95 | } > CALDATA_FLASH 96 | } 97 | -------------------------------------------------------------------------------- /NANOVNA_STM32_F072/adc_v1.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2021, Dmitry (DiSlord) dislordlive@gmail.com 3 | * Based on TAKAHASHI Tomohiro (TTRFTECH) edy555@gmail.com 4 | * All rights reserved. 5 | * 6 | * This is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3, or (at your option) 9 | * any later version. 10 | * 11 | * The software is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with GNU Radio; see the file COPYING. If not, write to 18 | * the Free Software Foundation, Inc., 51 Franklin Street, 19 | * Boston, MA 02110-1301, USA. 20 | */ 21 | 22 | #define ADC_TR(low, high) (((uint32_t)(high) << 16U) | \ 23 | (uint32_t)(low)) 24 | #define ADC_SMPR_SMP_1P5 0U /**< @brief 14 cycles conversion time */ 25 | #define ADC_SMPR_SMP_239P5 7U /**< @brief 252 cycles conversion time. */ 26 | #define ADC_CFGR1_RES_12BIT (0U << 3U) 27 | 28 | // External Event Select for regular group 29 | #define ADC_TIM1_TRGO 0 // 0b000 30 | #define ADC_TIM1_CC4 (ADC_CFGR1_EXTSEL_0) // 0b001 31 | #define ADC_TIM2_TRGO (ADC_CFGR1_EXTSEL_1) // 0b010 32 | #define ADC_TIM3_TRGO (ADC_CFGR1_EXTSEL_1|ADC_CFGR1_EXTSEL_0) // 0b011 33 | #define ADC_TIM15_TRGO (ADC_CFGR1_EXTSEL_2) // 0b100 34 | 35 | #define VNA_ADC ADC1 36 | 37 | void adc_init(void) 38 | { 39 | rccEnableADC1(FALSE); 40 | nvicEnableVector(ADC1_COMP_IRQn, STM32_EXT_EXTI21_22_IRQ_PRIORITY); // Shared vs GPIO handler 41 | VNA_ADC->CFGR1 = 0; 42 | /* Ensure flag states */ 43 | VNA_ADC->ISR = VNA_ADC->ISR; // clear ISR 44 | VNA_ADC->IER = 0; 45 | 46 | /* Calibration procedure.*/ 47 | if (VNA_ADC->CR & ADC_CR_ADEN) { //Ensure that ADEN = 0 48 | VNA_ADC->CR |= ~ADC_CR_ADDIS; // Disable ADC 49 | while (VNA_ADC->CR & ADC_CR_ADEN); // Wait completion 50 | } 51 | VNA_ADC->CR |= ADC_CR_ADCAL; //Launch the calibration by setting ADCAL 52 | while (VNA_ADC->CR & ADC_CR_ADCAL); //Wait until ADCAL=0 53 | 54 | if (VNA_ADC->ISR & ADC_ISR_ADRDY) // Ensure that ADRDY = 0 55 | { 56 | VNA_ADC->ISR |= ADC_ISR_ADRDY; // Clear ADRDY 57 | } 58 | VNA_ADC->CR |= ADC_CR_ADEN; // Enable ADC 59 | while (!(VNA_ADC->ISR & ADC_ISR_ADRDY)); // Wait until ADC ready 60 | // VBATEN enables resiter devider circuit. It consume vbat power. 61 | ADC->CCR = ADC_CCR_VREFEN | ADC_CCR_VBATEN; 62 | } 63 | 64 | #define ADC_AVERAGE_N 3 65 | uint16_t adc_single_read(uint32_t chsel) 66 | { 67 | // ADC setup 68 | VNA_ADC->ISR = VNA_ADC->ISR; 69 | VNA_ADC->IER = 0; 70 | VNA_ADC->TR = ADC_TR(0, 0); 71 | VNA_ADC->SMPR = ADC_SMPR_SMP_239P5; 72 | VNA_ADC->CFGR1 = ADC_CFGR1_RES_12BIT; 73 | VNA_ADC->CHSELR = chsel; 74 | uint16_t count = 1<CR |= ADC_CR_ADSTART; // ADC conversion start 78 | while (VNA_ADC->CR & ADC_CR_ADSTART); 79 | sample+=VNA_ADC->DR; 80 | } while(--count); 81 | return sample>>ADC_AVERAGE_N; 82 | } 83 | 84 | int16_t adc_vbat_read(void) 85 | { 86 | static int16_t vbat_raw = 0; 87 | #ifdef VBAT_MEASURE_INTERVAL 88 | static systime_t vbat_time = -VBAT_MEASURE_INTERVAL-1; 89 | systime_t _time = chVTGetSystemTimeX(); 90 | if (_time - vbat_time < VBAT_MEASURE_INTERVAL) 91 | goto return_cached; 92 | vbat_time = _time; 93 | #endif 94 | // 13.9 Temperature sensor and internal reference voltage 95 | // VREFINT_CAL calibrated on 3.3V, need get value in mV 96 | const uint16_t VREFINT = 3300; 97 | const uint16_t VREFINT_CAL = (*((uint16_t*)0x1FFFF7BA)); 98 | uint8_t restart_touch = 0; 99 | if (VNA_ADC->CR & ADC_CR_ADSTART){ 100 | adc_stop_analog_watchdog(); 101 | restart_touch = 1; 102 | } 103 | uint32_t vrefint = adc_single_read(ADC_CHSELR_CHSEL17); // VREFINT == ADC_IN17 104 | uint32_t vbat = adc_single_read(ADC_CHSELR_CHSEL18); // VBAT == ADC_IN18 105 | 106 | if (restart_touch) 107 | adc_start_analog_watchdog(); 108 | 109 | // vbat_raw = (VREFINT * 2 * vbat / 4095) * (VREFINT_CAL / vrefint) 110 | // uint16_t vbat_raw = (VREFINT * VREFINT_CAL * (float)vbat * 2 / (vrefint * ((1<<12)-1))); 111 | // For speed divide not on 4095, divide on 4096, get little error, but no matter 112 | vbat_raw = ((VREFINT * 2 * vbat)>>12) * VREFINT_CAL / vrefint; 113 | return_cached: 114 | if (vbat_raw < 100) { 115 | // maybe D2 is not installed 116 | return -1; 117 | } 118 | return vbat_raw + config._vbat_offset; 119 | } 120 | 121 | void adc_start_analog_watchdog(void) 122 | { 123 | // ADC setup, if it is defined a callback for the analog watch dog then it is enabled. 124 | VNA_ADC->ISR = VNA_ADC->ISR; 125 | VNA_ADC->IER = ADC_IER_AWDIE; 126 | VNA_ADC->TR = ADC_TR(0, TOUCH_THRESHOLD); 127 | VNA_ADC->SMPR = ADC_SMPR_SMP_1P5; 128 | VNA_ADC->CHSELR = ADC_TOUCH_Y; 129 | 130 | /* ADC configuration and start.*/ 131 | VNA_ADC->CFGR1 = ADC_CFGR1_RES_12BIT | ADC_CFGR1_AWDEN 132 | | ADC_CFGR1_EXTEN_0 // rising edge of external trigger 133 | | ADC_TIM3_TRGO; // External trigger is timer TIM3 134 | /* ADC conversion start.*/ 135 | VNA_ADC->CR |= ADC_CR_ADSTART; 136 | } 137 | 138 | void adc_stop_analog_watchdog(void) 139 | { 140 | if (VNA_ADC->CR & ADC_CR_ADSTART) { 141 | VNA_ADC->CR |= ADC_CR_ADSTP; 142 | while (VNA_ADC->CR & ADC_CR_ADSTP); 143 | } 144 | } 145 | 146 | static void adc_interrupt(void) 147 | { 148 | uint32_t isr = VNA_ADC->ISR; 149 | VNA_ADC->ISR = isr; 150 | // if (isr & ADC_ISR_OVR) { // ADC overflow condition 151 | // } 152 | if (isr & ADC_ISR_AWD) { // Analog watchdog error. 153 | handle_touch_interrupt(); 154 | } 155 | } 156 | 157 | OSAL_IRQ_HANDLER(STM32_ADC1_HANDLER) 158 | { 159 | OSAL_IRQ_PROLOGUE(); 160 | 161 | adc_interrupt(); 162 | 163 | OSAL_IRQ_EPILOGUE(); 164 | } 165 | -------------------------------------------------------------------------------- /NANOVNA_STM32_F072/board.c: -------------------------------------------------------------------------------- 1 | /* 2 | ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include "hal.h" 18 | 19 | #if HAL_USE_PAL || defined(__DOXYGEN__) 20 | /** 21 | * @brief PAL setup. 22 | * @details Digital I/O ports static configuration as defined in @p board.h. 23 | * This variable is used by the HAL when initializing the PAL driver. 24 | */ 25 | const PALConfig pal_default_config = { 26 | #if STM32_HAS_GPIOA 27 | {VAL_GPIOA_MODER, VAL_GPIOA_OTYPER, VAL_GPIOA_OSPEEDR, VAL_GPIOA_PUPDR, 28 | VAL_GPIOA_ODR, VAL_GPIOA_AFRL, VAL_GPIOA_AFRH}, 29 | #endif 30 | #if STM32_HAS_GPIOB 31 | {VAL_GPIOB_MODER, VAL_GPIOB_OTYPER, VAL_GPIOB_OSPEEDR, VAL_GPIOB_PUPDR, 32 | VAL_GPIOB_ODR, VAL_GPIOB_AFRL, VAL_GPIOB_AFRH}, 33 | #endif 34 | #if STM32_HAS_GPIOC 35 | {VAL_GPIOC_MODER, VAL_GPIOC_OTYPER, VAL_GPIOC_OSPEEDR, VAL_GPIOC_PUPDR, 36 | VAL_GPIOC_ODR, VAL_GPIOC_AFRL, VAL_GPIOC_AFRH}, 37 | #endif 38 | #if STM32_HAS_GPIOD 39 | {VAL_GPIOD_MODER, VAL_GPIOD_OTYPER, VAL_GPIOD_OSPEEDR, VAL_GPIOD_PUPDR, 40 | VAL_GPIOD_ODR, VAL_GPIOD_AFRL, VAL_GPIOD_AFRH}, 41 | #endif 42 | #if STM32_HAS_GPIOE 43 | {VAL_GPIOE_MODER, VAL_GPIOE_OTYPER, VAL_GPIOE_OSPEEDR, VAL_GPIOE_PUPDR, 44 | VAL_GPIOE_ODR, VAL_GPIOE_AFRL, VAL_GPIOE_AFRH}, 45 | #endif 46 | #if STM32_HAS_GPIOF 47 | {VAL_GPIOF_MODER, VAL_GPIOF_OTYPER, VAL_GPIOF_OSPEEDR, VAL_GPIOF_PUPDR, 48 | VAL_GPIOF_ODR, VAL_GPIOF_AFRL, VAL_GPIOF_AFRH}, 49 | #endif 50 | #if STM32_HAS_GPIOG 51 | {VAL_GPIOG_MODER, VAL_GPIOG_OTYPER, VAL_GPIOG_OSPEEDR, VAL_GPIOG_PUPDR, 52 | VAL_GPIOG_ODR, VAL_GPIOG_AFRL, VAL_GPIOG_AFRH}, 53 | #endif 54 | #if STM32_HAS_GPIOH 55 | {VAL_GPIOH_MODER, VAL_GPIOH_OTYPER, VAL_GPIOH_OSPEEDR, VAL_GPIOH_PUPDR, 56 | VAL_GPIOH_ODR, VAL_GPIOH_AFRL, VAL_GPIOH_AFRH}, 57 | #endif 58 | #if STM32_HAS_GPIOI 59 | {VAL_GPIOI_MODER, VAL_GPIOI_OTYPER, VAL_GPIOI_OSPEEDR, VAL_GPIOI_PUPDR, 60 | VAL_GPIOI_ODR, VAL_GPIOI_AFRL, VAL_GPIOI_AFRH} 61 | #endif 62 | }; 63 | #endif 64 | 65 | static bool needDFU(void) { 66 | // Magick data in memory before reset 67 | if (*((unsigned long *)BOOT_FROM_SYTEM_MEMORY_MAGIC_ADDRESS) == BOOT_FROM_SYTEM_MEMORY_MAGIC) 68 | return true; 69 | // init PortA (leveler port) and check press 70 | rccEnableAHB(STM32_GPIO_EN_MASK, FALSE); 71 | GPIOA->OTYPER = VAL_GPIOA_OTYPER; 72 | // GPIOA->OSPEEDR = VAL_GPIOA_OSPEEDR; 73 | GPIOA->PUPDR = VAL_GPIOA_PUPDR; 74 | GPIOA->ODR = VAL_GPIOA_ODR; 75 | // GPIOA->AFR[0] = VAL_GPIOA_AFRL; 76 | // GPIOA->AFR[1] = VAL_GPIOA_AFRH; 77 | GPIOA->MODER = VAL_GPIOA_MODER; 78 | if (GPIOA->IDR & (1<IDR & (1<APB2ENR |= RCC_APB2ENR_SYSCFGEN; 103 | // SYSCFG->CFGR1 = 0x01; 104 | // set msp for system memory 105 | __set_MSP(SYSTEM_BOOT_MSP); 106 | // jump to system memory 107 | ((void (*)(void))(*((uint32_t *)(STM32F072xB_SYSTEM_MEMORY + 4))))(); 108 | while (1); 109 | } 110 | 111 | stm32_clock_init(); 112 | } 113 | 114 | /* 115 | * Board-specific initialization code. 116 | */ 117 | void boardInit(void) { 118 | } 119 | -------------------------------------------------------------------------------- /NANOVNA_STM32_F072/board.mk: -------------------------------------------------------------------------------- 1 | # List of all the board related files. 2 | BOARDSRC = ${PROJ}/NANOVNA_STM32_F072/board.c 3 | 4 | # Required include directories 5 | BOARDINC = ${PROJ}/NANOVNA_STM32_F072 6 | -------------------------------------------------------------------------------- /NANOVNA_STM32_F072/board/stm32f0discovery.cfg: -------------------------------------------------------------------------------- 1 | # This is an STM32F0 discovery board with a single STM32F051R8T6 chip. 2 | # http://www.st.com/internet/evalboard/product/253215.jsp 3 | 4 | source [find interface/stlink.cfg] 5 | 6 | transport select hla_swd 7 | 8 | set WORKAREASIZE 0x2000 9 | source [find target/stm32f0x.cfg] 10 | 11 | reset_config srst_only 12 | -------------------------------------------------------------------------------- /NANOVNA_STM32_F072/board/stm32f3discovery.cfg: -------------------------------------------------------------------------------- 1 | # This is an STM32F3 discovery board with a single STM32F303VCT6 chip. 2 | # http://www.st.com/internet/evalboard/product/254044.jsp 3 | 4 | source [find interface/stlink.cfg] 5 | 6 | transport select hla_swd 7 | 8 | source [find target/stm32f3x.cfg] 9 | 10 | #reset_config srst_only 11 | reset_config none 12 | 13 | -------------------------------------------------------------------------------- /NANOVNA_STM32_F072/dac_v1.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2021, Dmitry (DiSlord) dislordlive@gmail.com 3 | * Based on TAKAHASHI Tomohiro (TTRFTECH) edy555@gmail.com 4 | * All rights reserved. 5 | * 6 | * This is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3, or (at your option) 9 | * any later version. 10 | * 11 | * The software is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with GNU Radio; see the file COPYING. If not, write to 18 | * the Free Software Foundation, Inc., 51 Franklin Street, 19 | * Boston, MA 02110-1301, USA. 20 | */ 21 | 22 | void dac_init(void) { 23 | rccEnableDAC1(false); // Use DAC1 24 | DAC->CR|= DAC_CR_EN2; // Enable DAC1 ch2 25 | } 26 | 27 | void dac_setvalue_ch1(uint16_t v) {DAC->DHR12R1 = v;} 28 | void dac_setvalue_ch2(uint16_t v) {DAC->DHR12R2 = v;} 29 | -------------------------------------------------------------------------------- /NANOVNA_STM32_F072/debug/STM32F3xx-ADC (OpenOCD, Flash and Run).launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /NANOVNA_STM32_F072/dma_v1.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2020, Dmitry (DiSlord) dislordlive@gmail.com 3 | * Based on TAKAHASHI Tomohiro (TTRFTECH) edy555@gmail.com 4 | * All rights reserved. 5 | * 6 | * This is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3, or (at your option) 9 | * any later version. 10 | * 11 | * The software is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with GNU Radio; see the file COPYING. If not, write to 18 | * the Free Software Foundation, Inc., 51 Franklin Street, 19 | * Boston, MA 02110-1301, USA. 20 | */ 21 | // Add all handlers (for reset DMA interrupt) 22 | //#define DMA1_USE_ALL_HANDLERS 23 | // F072 DMA1 interrupts handler function 24 | #define STM32_SPI2_DMA_IRQ_NUMBER DMA1_Channel4_5_6_7_IRQn 25 | 26 | #if defined(DMA1_CH1_HANDLER_FUNC) || defined(DMA1_USE_ALL_HANDLERS) 27 | OSAL_IRQ_HANDLER(STM32_DMA1_CH1_HANDLER) { 28 | uint32_t flags = DMA1->ISR; DMA1->IFCR = flags; // reset interrupt vector 29 | #ifdef DMA1_CH1_HANDLER_FUNC 30 | if (flags & (STM32_DMA_ISR_MASK<<0)) DMA1_CH1_HANDLER_FUNC((flags>>0)&STM32_DMA_ISR_MASK); // DMA Channel 1 handler 31 | #endif 32 | } 33 | #endif 34 | 35 | #if defined(DMA1_CH2_HANDLER_FUNC) || defined(DMA1_CH3_HANDLER_FUNC) || defined(DMA1_USE_ALL_HANDLERS) 36 | OSAL_IRQ_HANDLER(STM32_DMA1_CH23_HANDLER) { 37 | uint32_t flags = DMA1->ISR; DMA1->IFCR = flags; // reset interrupt vector 38 | #ifdef DMA1_CH2_HANDLER_FUNC 39 | if (flags & (STM32_DMA_ISR_MASK<<4)) DMA1_CH2_HANDLER_FUNC((flags>>4)&STM32_DMA_ISR_MASK); // DMA Channel 2 handler 40 | #endif 41 | #ifdef DMA1_CH3_HANDLER_FUNC 42 | if (flags & (STM32_DMA_ISR_MASK<<8)) DMA1_CH3_HANDLER_FUNC((flags>>8)&STM32_DMA_ISR_MASK); // DMA Channel 3 handler 43 | #endif 44 | } 45 | #endif 46 | 47 | #if defined(DMA1_CH4_HANDLER_FUNC) || defined(DMA1_CH5_HANDLER_FUNC) || \ 48 | defined(DMA1_CH6_HANDLER_FUNC) || defined(DMA1_CH7_HANDLER_FUNC) || defined(DMA1_USE_ALL_HANDLERS) 49 | OSAL_IRQ_HANDLER(STM32_DMA1_CH4567_HANDLER) { 50 | uint32_t flags = DMA1->ISR; DMA1->IFCR = flags; // reset interrupt vector 51 | #ifdef DMA1_CH4_HANDLER_FUNC 52 | if (flags & (STM32_DMA_ISR_MASK<<12)) DMA1_CH4_HANDLER_FUNC((flags>>12)&STM32_DMA_ISR_MASK); // DMA Channel 4 handler 53 | #endif 54 | #ifdef DMA1_CH5_HANDLER_FUNC 55 | if (flags & (STM32_DMA_ISR_MASK<<16)) DMA1_CH5_HANDLER_FUNC((flags>>16)&STM32_DMA_ISR_MASK); // DMA Channel 5 handler 56 | #endif 57 | #ifdef DMA1_CH6_HANDLER_FUNC 58 | if (flags & (STM32_DMA_ISR_MASK<<20)) DMA1_CH6_HANDLER_FUNC((flags>>20)&STM32_DMA_ISR_MASK); // DMA Channel 6 handler 59 | #endif 60 | #ifdef DMA1_CH7_HANDLER_FUNC 61 | if (flags & (STM32_DMA_ISR_MASK<<24)) DMA1_CH7_HANDLER_FUNC((flags>>24)&STM32_DMA_ISR_MASK); // DMA Channel 7 handler 62 | #endif 63 | } 64 | #endif 65 | -------------------------------------------------------------------------------- /NANOVNA_STM32_F072/exti_v1.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2020, Dmitry (DiSlord) dislordlive@gmail.com 3 | * Based on TAKAHASHI Tomohiro (TTRFTECH) edy555@gmail.com 4 | * All rights reserved. 5 | * 6 | * This is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3, or (at your option) 9 | * any later version. 10 | * 11 | * The software is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with GNU Radio; see the file COPYING. If not, write to 18 | * the Free Software Foundation, Inc., 51 Franklin Street, 19 | * Boston, MA 02110-1301, USA. 20 | */ 21 | // F072 Ext interrupts handler function 22 | #if HAL_USE_EXT == FALSE 23 | extern void handle_button_interrupt(uint16_t channel); 24 | 25 | //#define EXT_CH0_HANDLER_FUNC 26 | #define EXT_CH1_HANDLER_FUNC handle_button_interrupt 27 | #define EXT_CH2_HANDLER_FUNC handle_button_interrupt 28 | #define EXT_CH3_HANDLER_FUNC handle_button_interrupt 29 | //#define EXT_CH4_HANDLER_FUNC 30 | //#define EXT_CH5_HANDLER_FUNC 31 | //#define EXT_CH6_HANDLER_FUNC 32 | //#define EXT_CH7_HANDLER_FUNC 33 | //#define EXT_CH8_HANDLER_FUNC 34 | //#define EXT_CH9_HANDLER_FUNC 35 | //#define EXT_CH10_HANDLER_FUNC 36 | //#define EXT_CH11_HANDLER_FUNC 37 | //#define EXT_CH12_HANDLER_FUNC 38 | //#define EXT_CH13_HANDLER_FUNC 39 | //#define EXT_CH14_HANDLER_FUNC 40 | //#define EXT_CH15_HANDLER_FUNC 41 | 42 | #if defined(EXT_CH0_HANDLER_FUNC) || defined(EXT_CH1_HANDLER_FUNC) 43 | OSAL_IRQ_HANDLER(Vector54) { // EXTI[0]...EXTI[1] interrupt handler. 44 | uint32_t pr = EXTI->PR & ((1U << 0) | (1U << 1)); 45 | EXTI->PR = pr; 46 | #ifdef EXT_CH0_HANDLER_FUNC 47 | if (pr & (1U << 0)) EXT_CH0_HANDLER_FUNC(0); 48 | #endif 49 | #ifdef EXT_CH1_HANDLER_FUNC 50 | if (pr & (1U << 1)) EXT_CH1_HANDLER_FUNC(1); 51 | #endif 52 | } 53 | #endif 54 | 55 | #if defined(EXT_CH2_HANDLER_FUNC) || defined(EXT_CH3_HANDLER_FUNC) 56 | OSAL_IRQ_HANDLER(Vector58) { // EXTI[2]...EXTI[3] interrupt handler. 57 | uint32_t pr = EXTI->PR & ((1U << 2) | (1U << 3)); 58 | EXTI->PR = pr; 59 | #ifdef EXT_CH2_HANDLER_FUNC 60 | if (pr & (1U << 2)) EXT_CH2_HANDLER_FUNC(2); 61 | #endif 62 | #ifdef EXT_CH3_HANDLER_FUNC 63 | if (pr & (1U << 3)) EXT_CH3_HANDLER_FUNC(3); 64 | #endif 65 | } 66 | #endif 67 | 68 | #if defined(EXT_CH4_HANDLER_FUNC) || defined(EXT_CH5_HANDLER_FUNC) || defined(EXT_CH6_HANDLER_FUNC) || defined(EXT_CH7_HANDLER_FUNC) || \ 69 | defined(EXT_CH8_HANDLER_FUNC) || defined(EXT_CH9_HANDLER_FUNC) || defined(EXT_CH10_HANDLER_FUNC) || defined(EXT_CH11_HANDLER_FUNC) || \ 70 | defined(EXT_CH12_HANDLER_FUNC) || defined(EXT_CH13_HANDLER_FUNC) || defined(EXT_CH14_HANDLER_FUNC) || defined(EXTI_CH15_HANDLER_FUNC) 71 | OSAL_IRQ_HANDLER(Vector5C) { // EXTI[4]...EXTI[15] interrupt handler 72 | uint32_t pr = EXTI->PR & ((1U << 4) | (1U << 5) | (1U << 6) | (1U << 7) | (1U << 8) | 73 | (1U << 9) | (1U << 10) | (1U << 11) | (1U << 12) | (1U << 13) | 74 | (1U << 14) | (1U << 15)); 75 | EXTI->PR = pr; 76 | #ifdef EXT_CH4_HANDLER_FUNC 77 | if (pr & (1U << 4)) EXT_CH4_HANDLER_FUNC(4); 78 | #endif 79 | #ifdef EXT_CH5_HANDLER_FUNC 80 | if (pr & (1U << 5)) EXT_CH5_HANDLER_FUNC(5); 81 | #endif 82 | #ifdef EXT_CH6_HANDLER_FUNC 83 | if (pr & (1U << 6)) EXT_CH6_HANDLER_FUNC(6); 84 | #endif 85 | #ifdef EXT_CH7_HANDLER_FUNC 86 | if (pr & (1U << 7)) EXT_CH7_HANDLER_FUNC(7); 87 | #endif 88 | #ifdef EXT_CH8_HANDLER_FUNC 89 | if (pr & (1U << 8)) EXT_CH8_HANDLER_FUNC(8); 90 | #endif 91 | #ifdef EXT_CH9_HANDLER_FUNC 92 | if (pr & (1U << 9)) EXT_CH9_HANDLER_FUNC(9); 93 | #endif 94 | #ifdef EXT_CH10_HANDLER_FUNC 95 | if (pr & (1U << 10)) EXT_CH10_HANDLER_FUNC(10); 96 | #endif 97 | #ifdef EXT_CH11_HANDLER_FUNC 98 | if (pr & (1U << 11)) EXT_CH11_HANDLER_FUNC(11); 99 | #endif 100 | #ifdef EXT_CH12_HANDLER_FUNC 101 | if (pr & (1U << 12)) EXT_CH12_HANDLER_FUNC(12); 102 | #endif 103 | #ifdef EXT_CH13_HANDLER_FUNC 104 | if (pr & (1U << 13)) EXT_CH13_HANDLER_FUNC(13); 105 | #endif 106 | #ifdef EXT_CH14_HANDLER_FUNC 107 | if (pr & (1U << 14)) EXT_CH14_HANDLER_FUNC(14); 108 | #endif 109 | #ifdef EXT_CH15_HANDLER_FUNC 110 | if (pr & (1U << 15)) EXT_CH15_HANDLER_FUNC(15); 111 | #endif 112 | } 113 | #endif 114 | 115 | void extStart(void) { 116 | #if defined(EXT_CH0_HANDLER_FUNC) || defined(EXT_CH1_HANDLER_FUNC) 117 | nvicEnableVector(EXTI0_1_IRQn, STM32_EXT_EXTI0_1_IRQ_PRIORITY); 118 | #endif 119 | #if defined(EXT_CH2_HANDLER_FUNC) || defined(EXT_CH3_HANDLER_FUNC) 120 | nvicEnableVector(EXTI2_3_IRQn, STM32_EXT_EXTI2_3_IRQ_PRIORITY); 121 | #endif 122 | #if defined(EXT_CH4_HANDLER_FUNC) || defined(EXT_CH5_HANDLER_FUNC) || defined(EXT_CH6_HANDLER_FUNC) || defined(EXT_CH7_HANDLER_FUNC) || \ 123 | defined(EXT_CH8_HANDLER_FUNC) || defined(EXT_CH9_HANDLER_FUNC) || defined(EXT_CH10_HANDLER_FUNC) || defined(EXT_CH11_HANDLER_FUNC) || \ 124 | defined(EXT_CH12_HANDLER_FUNC) || defined(EXT_CH13_HANDLER_FUNC) || defined(EXT_CH14_HANDLER_FUNC) || defined(EXTI_CH15_HANDLER_FUNC) 125 | nvicEnableVector(EXTI4_15_IRQn, STM32_EXT_EXTI4_15_IRQ_PRIORITY); 126 | #endif 127 | // nvicEnableVector(PVD_IRQn, STM32_EXT_EXTI16_IRQ_PRIORITY); 128 | // nvicEnableVector(ADC1_COMP_IRQn, STM32_EXT_EXTI21_22_IRQ_PRIORITY); 129 | // nvicEnableVector(RTC_IRQn, STM32_EXT_EXTI17_20_IRQ_PRIORITY); 130 | } 131 | 132 | void ext_channel_enable(uint16_t channel, uint16_t mode) { 133 | uint32_t cmask = (1 << (channel & 0x1F)); 134 | // Setting the associated GPIO for external channels. 135 | if (channel < 16) { 136 | uint16_t port = (mode & EXT_MODE_GPIO_MASK) >> EXT_MODE_GPIO_OFF; 137 | uint32_t old_reg = SYSCFG->EXTICR[channel>>2] & ~(0xF << ((channel & 3) * 4)); 138 | SYSCFG->EXTICR[channel>>2] = old_reg | (port<< ((channel & 3) * 4)); 139 | } 140 | // Programming edge registers. 141 | if (mode & EXT_CH_MODE_RISING_EDGE) EXTI->RTSR|= cmask; 142 | else EXTI->RTSR&=~cmask; 143 | if (mode & EXT_CH_MODE_FALLING_EDGE) EXTI->FTSR|= cmask; 144 | else EXTI->FTSR&=~cmask; 145 | // Programming interrupt and event registers. 146 | EXTI->IMR|= cmask; 147 | EXTI->EMR&=~cmask; 148 | } 149 | #endif 150 | -------------------------------------------------------------------------------- /NANOVNA_STM32_F072/flash.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2020, Dmitry (DiSlord) dislordlive@gmail.com 3 | * Based on TAKAHASHI Tomohiro (TTRFTECH) edy555@gmail.com 4 | * All rights reserved. 5 | * 6 | * This is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3, or (at your option) 9 | * any later version. 10 | * 11 | * The software is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with GNU Radio; see the file COPYING. If not, write to 18 | * the Free Software Foundation, Inc., 51 Franklin Street, 19 | * Boston, MA 02110-1301, USA. 20 | */ 21 | 22 | static inline void flash_wait_for_last_operation(void) 23 | { 24 | while (FLASH->SR == FLASH_SR_BSY) { 25 | //WWDG->CR = WWDG_CR_T; 26 | } 27 | // return FLASH->SR; 28 | } 29 | 30 | static void flash_erase_page0(uint32_t page_address) 31 | { 32 | flash_wait_for_last_operation(); 33 | FLASH->CR |= FLASH_CR_PER; 34 | FLASH->AR = page_address; 35 | FLASH->CR |= FLASH_CR_STRT; 36 | flash_wait_for_last_operation(); 37 | FLASH->CR &= ~FLASH_CR_PER; 38 | } 39 | 40 | static inline void flash_unlock(void) 41 | { 42 | // unlock sequence 43 | FLASH->KEYR = FLASH_KEY1; 44 | FLASH->KEYR = FLASH_KEY2; 45 | } 46 | 47 | void flash_erase_pages(uint32_t page_address, uint32_t size) 48 | { 49 | // Unlock for erase 50 | flash_unlock(); 51 | // erase flash pages 52 | size+=page_address; 53 | for (; page_address < size; page_address+=FLASH_PAGESIZE) 54 | flash_erase_page0(page_address); 55 | } 56 | 57 | void flash_program_half_word_buffer(uint16_t* dst, uint16_t *data, uint16_t size) 58 | { 59 | uint32_t i; 60 | // unlock, and erase flash pages for buffer (aligned to FLASH_PAGESIZE) 61 | flash_erase_pages((uint32_t)dst, size); 62 | // Save buffer 63 | __IO uint16_t* p = dst; 64 | for (i = 0; i < size/sizeof(uint16_t); i++){ 65 | flash_wait_for_last_operation(); 66 | FLASH->CR |= FLASH_CR_PG; 67 | p[i] = data[i]; 68 | flash_wait_for_last_operation(); 69 | FLASH->CR &= ~FLASH_CR_PG; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /NANOVNA_STM32_F072/gpio_v2.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2020, Dmitry (DiSlord) dislordlive@gmail.com 3 | * All rights reserved. 4 | * 5 | * This is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 3, or (at your option) 8 | * any later version. 9 | * 10 | * The software is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with GNU Radio; see the file COPYING. If not, write to 17 | * the Free Software Foundation, Inc., 51 Franklin Street, 18 | * Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | typedef struct { 22 | uint32_t moder; 23 | uint32_t otyper; 24 | uint32_t ospeedr; 25 | uint32_t pupdr; 26 | uint32_t odr; 27 | uint32_t afrl; 28 | uint32_t afrh; 29 | } pal_conf_t; 30 | 31 | const pal_conf_t pal_config[] = { 32 | #if STM32_HAS_GPIOA 33 | {VAL_GPIOA_MODER, VAL_GPIOA_OTYPER, VAL_GPIOA_OSPEEDR, VAL_GPIOA_PUPDR, VAL_GPIOA_ODR, VAL_GPIOA_AFRL, VAL_GPIOA_AFRH}, 34 | #endif 35 | #if STM32_HAS_GPIOB 36 | {VAL_GPIOB_MODER, VAL_GPIOB_OTYPER, VAL_GPIOB_OSPEEDR, VAL_GPIOB_PUPDR, VAL_GPIOB_ODR, VAL_GPIOB_AFRL, VAL_GPIOB_AFRH}, 37 | #endif 38 | #if STM32_HAS_GPIOC 39 | {VAL_GPIOC_MODER, VAL_GPIOC_OTYPER, VAL_GPIOC_OSPEEDR, VAL_GPIOC_PUPDR, VAL_GPIOC_ODR, VAL_GPIOC_AFRL, VAL_GPIOC_AFRH}, 40 | #endif 41 | /* 42 | #if STM32_HAS_GPIOD 43 | {VAL_GPIOD_MODER, VAL_GPIOD_OTYPER, VAL_GPIOD_OSPEEDR, VAL_GPIOD_PUPDR, VAL_GPIOD_ODR, VAL_GPIOD_AFRL, VAL_GPIOD_AFRH}, 44 | #endif 45 | #if STM32_HAS_GPIOE 46 | {VAL_GPIOE_MODER, VAL_GPIOE_OTYPER, VAL_GPIOE_OSPEEDR, VAL_GPIOE_PUPDR, VAL_GPIOE_ODR, VAL_GPIOE_AFRL, VAL_GPIOE_AFRH}, 47 | #endif 48 | #if STM32_HAS_GPIOF 49 | {VAL_GPIOF_MODER, VAL_GPIOF_OTYPER, VAL_GPIOF_OSPEEDR, VAL_GPIOF_PUPDR, VAL_GPIOF_ODR, VAL_GPIOF_AFRL, VAL_GPIOF_AFRH}, 50 | #endif 51 | #if STM32_HAS_GPIOG 52 | {VAL_GPIOG_MODER, VAL_GPIOG_OTYPER, VAL_GPIOG_OSPEEDR, VAL_GPIOG_PUPDR, VAL_GPIOG_ODR, VAL_GPIOG_AFRL, VAL_GPIOG_AFRH}, 53 | #endif 54 | #if STM32_HAS_GPIOH 55 | {VAL_GPIOH_MODER, VAL_GPIOH_OTYPER, VAL_GPIOH_OSPEEDR, VAL_GPIOH_PUPDR, VAL_GPIOH_ODR, VAL_GPIOH_AFRL, VAL_GPIOH_AFRH}, 56 | #endif 57 | #if STM32_HAS_GPIOI 58 | {VAL_GPIOI_MODER, VAL_GPIOI_OTYPER, VAL_GPIOI_OSPEEDR, VAL_GPIOI_PUPDR, VAL_GPIOI_ODR, VAL_GPIOI_AFRL, VAL_GPIOI_AFRH} 59 | #endif 60 | */ 61 | }; 62 | 63 | static void initgpio(GPIO_TypeDef *port, const pal_conf_t *config) { 64 | port->OTYPER = config->otyper; 65 | port->OSPEEDR = config->ospeedr; 66 | port->PUPDR = config->pupdr; 67 | port->ODR = config->odr; 68 | port->AFR[0] = config->afrl; 69 | port->AFR[1] = config->afrh; 70 | port->MODER = config->moder; 71 | } 72 | 73 | void initPal(void) { 74 | rccEnableAHB(STM32_GPIO_EN_MASK, FALSE); 75 | initgpio(GPIOA, &pal_config[0]); 76 | initgpio(GPIOB, &pal_config[1]); 77 | initgpio(GPIOC, &pal_config[2]); 78 | // initgpio(GPIOD, &pal_config[3]); 79 | } 80 | 81 | void palSetPadGroupMode(GPIO_TypeDef *port, uint32_t mask, uint32_t mode) { 82 | uint32_t moder = (mode & PAL_STM32_MODE_MASK) >> 0; 83 | uint32_t otyper = (mode & PAL_STM32_OTYPE_MASK) >> 2; 84 | uint32_t ospeedr = (mode & PAL_STM32_OSPEED_MASK) >> 3; 85 | uint32_t pupdr = (mode & PAL_STM32_PUPDR_MASK) >> 5; 86 | uint32_t altr = (mode & PAL_STM32_ALTERNATE_MASK) >> 7; 87 | uint32_t bit = 0; 88 | while (true) { 89 | if ((mask & 1) != 0) { 90 | uint32_t altrmask, m1, m2, m4; 91 | 92 | altrmask = altr << ((bit & 7) * 4); 93 | m1 = 1 << bit; 94 | m2 = 3 << (bit * 2); 95 | m4 = 15 << ((bit & 7) * 4); 96 | port->OTYPER = (port->OTYPER & ~m1) | otyper; 97 | port->OSPEEDR = (port->OSPEEDR & ~m2) | ospeedr; 98 | port->PUPDR = (port->PUPDR & ~m2) | pupdr; 99 | if (moder == PAL_STM32_MODE_ALTERNATE) { 100 | // If going in alternate mode then the alternate number is set before switching mode in order to avoid glitches. 101 | port->AFR[(bit>>3)&1] = (port->AFR[(bit>>3)&1] & ~m4) | altrmask; 102 | port->MODER = (port->MODER & ~m2) | moder; 103 | } 104 | else { 105 | // If going into a non-alternate mode then the mode is switched before setting the alternate mode in order to avoid glitches. 106 | port->MODER = (port->MODER & ~m2) | moder; 107 | port->AFR[(bit>>3)&1] = (port->AFR[(bit>>3)&1] & ~m4) | altrmask; 108 | } 109 | } 110 | mask >>= 1; 111 | if (!mask) 112 | return; 113 | otyper <<= 1; 114 | ospeedr <<= 2; 115 | pupdr <<= 2; 116 | moder <<= 2; 117 | bit++; 118 | } 119 | } 120 | 121 | void palSetPadMode(GPIO_TypeDef *port, int bit, uint32_t mode) { 122 | uint32_t otyper = ((mode & PAL_STM32_OTYPE_MASK) >> 2)<<(bit*1); 123 | uint32_t ospeedr = ((mode & PAL_STM32_OSPEED_MASK) >> 3)<<(bit*2); 124 | uint32_t pupdr = ((mode & PAL_STM32_PUPDR_MASK) >> 5)<<(bit*2); 125 | uint32_t moder = ((mode & PAL_STM32_MODE_MASK) >> 0)<<(bit*2); 126 | uint32_t m1 = 0x1 << (bit * 1); 127 | uint32_t m2 = 0x3 << (bit * 2); 128 | 129 | port->OTYPER = (port->OTYPER & ~m1) | otyper; 130 | port->OSPEEDR = (port->OSPEEDR & ~m2) | ospeedr; 131 | port->PUPDR = (port->PUPDR & ~m2) | pupdr; 132 | #if 0 133 | port->MODER = (port->MODER & ~m2) | moder; 134 | #else 135 | uint32_t altrmask = ((mode & PAL_STM32_ALTERNATE_MASK) >> 7) << ((bit&7) * 4); 136 | uint32_t m4 = 0xF << ((bit&7) * 4); 137 | if (moder == PAL_STM32_MODE_ALTERNATE) { 138 | // If going in alternate mode then the alternate number is set before switching mode in order to avoid glitches. 139 | port->AFR[(bit>>3)&1] = (port->AFR[(bit>>3)&1] & ~m4) | altrmask; 140 | port->MODER = (port->MODER & ~m2) | moder; 141 | } 142 | else { 143 | // If going into a non-alternate mode then the mode is switched before setting the alternate mode in order to avoid glitches. 144 | port->MODER = (port->MODER & ~m2) | moder; 145 | port->AFR[(bit>>3)&1] = (port->AFR[(bit>>3)&1] & ~m4) | altrmask; 146 | } 147 | #endif 148 | } 149 | -------------------------------------------------------------------------------- /NANOVNA_STM32_F072/i2c_v2.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2020, Dmitry (DiSlord) dislordlive@gmail.com 3 | * All rights reserved. 4 | * 5 | * This is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 3, or (at your option) 8 | * any later version. 9 | * 10 | * The software is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with GNU Radio; see the file COPYING. If not, write to 17 | * the Free Software Foundation, Inc., 51 Franklin Street, 18 | * Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | #define VNA_I2C I2C1 22 | #define I2C_CR2_SADD_7BIT_SHIFT 1 23 | #define I2C_CR2_NBYTES_SHIFT 16 24 | 25 | void i2c_set_timings(uint32_t timings) { 26 | VNA_I2C->CR1&=~I2C_CR1_PE; 27 | VNA_I2C->TIMINGR = timings; 28 | VNA_I2C->CR1|= I2C_CR1_PE; 29 | } 30 | 31 | void i2c_start(void) { 32 | rccEnableI2C1(FALSE); 33 | i2c_set_timings(STM32_I2C_INIT_T); 34 | } 35 | 36 | // I2C TX only (compact version) 37 | bool i2c_transfer(uint8_t addr, const uint8_t *w, size_t wn) 38 | { 39 | //if (wn == 0) return false; 40 | while(VNA_I2C->ISR & I2C_ISR_BUSY); // wait last transaction 41 | VNA_I2C->CR1|= I2C_CR1_PE; 42 | VNA_I2C->CR2 = (addr << I2C_CR2_SADD_7BIT_SHIFT) | (wn << I2C_CR2_NBYTES_SHIFT) | I2C_CR2_AUTOEND | I2C_CR2_START; 43 | do { 44 | while ((VNA_I2C->ISR & (I2C_ISR_TXE|I2C_ISR_NACKF)) == 0); 45 | if (VNA_I2C->ISR & I2C_ISR_NACKF) {VNA_I2C->CR1 = 0; return false;} // NO ASK error 46 | VNA_I2C->TXDR = *w++; 47 | } while (--wn); 48 | return true; 49 | } 50 | 51 | // I2C TX and RX variant 52 | bool i2c_receive(uint8_t addr, const uint8_t *w, size_t wn, uint8_t *r, size_t rn) 53 | { 54 | while(VNA_I2C->ISR & I2C_ISR_BUSY); // wait last transaction 55 | VNA_I2C->CR1|= I2C_CR1_PE; 56 | if (wn) { 57 | VNA_I2C->CR2 = (addr << I2C_CR2_SADD_7BIT_SHIFT) | (wn << I2C_CR2_NBYTES_SHIFT); 58 | if (rn == 0) VNA_I2C->CR2|= I2C_CR2_AUTOEND; 59 | VNA_I2C->CR2|= I2C_CR2_START; 60 | do { 61 | while ((VNA_I2C->ISR & (I2C_ISR_TXE|I2C_ISR_NACKF)) == 0); 62 | if (VNA_I2C->ISR & I2C_ISR_NACKF) {VNA_I2C->CR1 = 0; return false;} // NO ASK error 63 | VNA_I2C->TXDR = *w++; 64 | } while (--wn); 65 | } 66 | 67 | if (rn) { 68 | while (!(VNA_I2C->ISR & I2C_ISR_TC)); // wait transfer completion if need 69 | VNA_I2C->CR2 = (addr << I2C_CR2_SADD_7BIT_SHIFT) | (rn << I2C_CR2_NBYTES_SHIFT) | I2C_CR2_RD_WRN; 70 | VNA_I2C->CR2|= I2C_CR2_START | I2C_CR2_AUTOEND; // start transfer 71 | //VNA_I2C->CR2|= I2C_CR2_AUTOEND; // important to do it afterwards to do a proper repeated start! 72 | do { 73 | while((VNA_I2C->ISR & (I2C_ISR_RXNE|I2C_ISR_NACKF)) == 0); 74 | if (VNA_I2C->ISR & I2C_ISR_NACKF) {VNA_I2C->CR1 = 0; return false;} // NO ASK error 75 | *r++ = VNA_I2C->RXDR; 76 | } while (--rn); 77 | } 78 | return true; 79 | } 80 | 81 | -------------------------------------------------------------------------------- /NANOVNA_STM32_F072/i2s.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2020, Dmitry (DiSlord) dislordlive@gmail.com 3 | * Based on TAKAHASHI Tomohiro (TTRFTECH) edy555@gmail.com 4 | * All rights reserved. 5 | * 6 | * This is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3, or (at your option) 9 | * any later version. 10 | * 11 | * The software is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with GNU Radio; see the file COPYING. If not, write to 18 | * the Free Software Foundation, Inc., 51 Franklin Street, 19 | * Boston, MA 02110-1301, USA. 20 | */ 21 | 22 | // F072 SPI2 RX DMA1 interrupt 23 | #define STM32_SPI2_RX_DMA_IRQ_NUMBER DMA1_Channel4_5_6_7_IRQn 24 | 25 | #define SPI_I2S_FHILLIPS_MODE ( 0) 26 | #define SPI_I2S_MSB_MODE (SPI_I2SCFGR_I2SSTD_0) 27 | #define SPI_I2S_LSB_MODE (SPI_I2SCFGR_I2SSTD_1) 28 | #define SPI_I2S_PCM_MODE (SPI_I2SCFGR_I2SSTD_0 | SPI_I2SCFGR_I2SSTD_1) 29 | 30 | /* 31 | * Run I2S bus in Circular mode, fill buffer, and handle read in I2S DMA RX interrupt 32 | */ 33 | void initI2S(void *buffer, uint16_t count) { 34 | const uint16_t I2S_DMA_RX_ccr = 0 35 | | STM32_DMA_CR_PL(3) // 3 - Very High 36 | | STM32_DMA_CR_PSIZE_HWORD // 16 bit 37 | | STM32_DMA_CR_MSIZE_HWORD // 16 bit 38 | | STM32_DMA_CR_DIR_P2M // Read from peripheral 39 | | STM32_DMA_CR_MINC // Memory increment mode 40 | | STM32_DMA_CR_CIRC // Circular mode 41 | | STM32_DMA_CR_HTIE // Half transfer complete interrupt enable 42 | | STM32_DMA_CR_TCIE // Full transfer complete interrupt enable 43 | // | STM32_DMA_CR_TEIE // Transfer error interrupt enable 44 | ; 45 | // I2S RX DMA setup. 46 | nvicEnableVector(STM32_SPI2_RX_DMA_IRQ_NUMBER, STM32_I2S_SPI2_IRQ_PRIORITY); 47 | dmaChannelSetTransactionSize(I2S_DMA_RX, count); // number of data register 48 | dmaChannelSetPeripheral(I2S_DMA_RX, &SPI2->DR); // peripheral address register 49 | dmaChannelSetMemory(I2S_DMA_RX, buffer); // memory address register 50 | dmaChannelSetMode(I2S_DMA_RX, I2S_DMA_RX_ccr | STM32_DMA_CR_EN); // configuration register 51 | 52 | // Starting I2S 53 | rccEnableSPI2(FALSE); // Enabling I2S unit clock. 54 | SPI2->CR1 = 0; // CRs settings 55 | SPI2->CR2 = SPI_CR2_RXDMAEN; // Enable RX DMA 56 | SPI2->I2SPR = 0; // I2S (re)configuration. 57 | SPI2->I2SCFGR = 0 58 | | SPI_I2SCFGR_I2SCFG_0 // 01: Slave - receive 59 | // | SPI_I2SCFGR_I2SCFG_1 // 60 | | SPI_I2SCFGR_I2SMOD // I2S mode is selected 61 | | SPI_I2S_PCM_MODE // I2S PCM standard (aic3204 use DSP mode, short sync) 62 | | SPI_I2SCFGR_PCMSYNC // Short sync 63 | | SPI_I2SCFGR_I2SE // I2S enable 64 | ; 65 | } 66 | -------------------------------------------------------------------------------- /NANOVNA_STM32_F072/interface/stlink.cfg: -------------------------------------------------------------------------------- 1 | # 2 | # STMicroelectronics ST-LINK/V1, ST-LINK/V2, ST-LINK/V2-1, STLINK-V3 in-circuit 3 | # debugger/programmer 4 | # 5 | 6 | interface hla 7 | hla_layout stlink 8 | hla_device_desc "ST-LINK" 9 | hla_vid_pid 0x0483 0x3744 0x0483 0x3748 0x0483 0x374b 0x0483 0x374d 0x0483 0x374e 0x0483 0x374f 0x0483 0x3752 0x0483 0x3753 10 | 11 | # Optionally specify the serial number of ST-LINK/V2 usb device. ST-LINK/V2 12 | # devices seem to have serial numbers with unreadable characters. ST-LINK/V2 13 | # firmware version >= V2.J21.S4 recommended to avoid issues with adapter serial 14 | # number reset issues. 15 | # eg. 16 | #hla_serial "\xaa\xbc\x6e\x06\x50\x75\xff\x55\x17\x42\x19\x3f" 17 | 18 | -------------------------------------------------------------------------------- /NANOVNA_STM32_F072/mcuconf.h: -------------------------------------------------------------------------------- 1 | /* 2 | ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #ifndef MCUCONF_H 18 | #define MCUCONF_H 19 | 20 | /* 21 | * STM32F0xx drivers configuration. 22 | * The following settings override the default settings present in 23 | * the various device driver implementation headers. 24 | * Note that the settings for each driver only have effect if the whole 25 | * driver is enabled in halconf.h. 26 | * 27 | * IRQ priorities: 28 | * 3...0 Lowest...Highest. 29 | * 30 | * DMA priorities: 31 | * 0...3 Lowest...Highest. 32 | */ 33 | 34 | #define STM32F0xx_MCUCONF 35 | 36 | /* 37 | * HAL driver system settings. 38 | */ 39 | #define STM32_NO_INIT FALSE 40 | #define STM32_PVD_ENABLE FALSE 41 | #define STM32_PLS STM32_PLS_LEV0 42 | #define STM32_HSI_ENABLED TRUE 43 | #define STM32_HSI14_ENABLED FALSE 44 | #define STM32_HSI48_ENABLED TRUE 45 | #define STM32_HSE_ENABLED FALSE 46 | #define STM32_SW STM32_SW_PLL 47 | #define STM32_PLLSRC STM32_PLLSRC_HSI_DIV2 48 | #define STM32_PREDIV_VALUE 1 49 | #define STM32_PLLMUL_VALUE 12 50 | #define STM32_HPRE STM32_HPRE_DIV1 51 | #define STM32_PPRE STM32_PPRE_DIV1 52 | #define STM32_ADCPRE STM32_ADCPRE_DIV4 53 | #define STM32_MCOSEL STM32_MCOSEL_PLLDIV2 54 | #define STM32_USBSW STM32_USBSW_HSI48 55 | #define STM32_CECSW STM32_CECSW_HSI 56 | //#define STM32_I2C1SW STM32_I2C1SW_HSI 57 | #define STM32_I2C1SW STM32_I2C1SW_SYSCLK 58 | #define STM32_USART1SW STM32_USART1SW_PCLK 59 | 60 | // Define STM32_I2C1_CLOCK as 48MHz (STM32_I2C1SW is STM32_I2C1SW_SYSCLK) 61 | #define STM32_I2C1_CLOCK 48 62 | // Core clock in MHz 63 | #define STM32_CORE_CLOCK 48 64 | 65 | /* 66 | * RTC driver system settings for stm32f072 67 | */ 68 | #define RTC_PRER(a, s) ((((a) - 1) << 16) | ((s) - 1)) 69 | 70 | // LSE for 32768 quartz 71 | #define STM32_RTC_LSE_PRER RTC_PRER(128, 256) 72 | // LSI 40k 73 | #define STM32_RTC_LSI_PRER RTC_PRER( 40, 1000) 74 | 75 | // Use auto select source (LSE or LSI) 76 | //!!!! Need disable hal_lld_backup_domain_init() in hal_lld.c for current CPU!!!! 77 | // And if need correct rtc_init part 78 | #ifdef VNA_AUTO_SELECT_RTC_SOURCE 79 | #define STM32_LSEDRV (3 << 3) 80 | #define STM32_RTCSEL STM32_RTCSEL_NOCLOCK 81 | #define STM32_LSI_ENABLED FALSE 82 | #define STM32_LSE_ENABLED FALSE 83 | // Disable this function call in ChibiOS, backup domain init on auto select RTC source 84 | #define STM32_NO_BACKUP_DOMAIN_INIT 85 | #define hal_lld_backup_domain_init 86 | #else 87 | #ifndef VNA_USE_LSE 88 | // Use 40kHz LSI 89 | #define STM32_LSE_ENABLED FALSE 90 | #define STM32_LSI_ENABLED TRUE 91 | #define STM32_RTCSEL STM32_RTCSEL_LSI 92 | #else 93 | // Use 32768Hz LSE 94 | #define STM32_LSE_ENABLED TRUE 95 | #define STM32_LSI_ENABLED FALSE 96 | #define STM32_RTCSEL STM32_RTCSEL_LSE 97 | #define STM32_LSEDRV (3 << 3) 98 | #endif 99 | #endif 100 | 101 | /* 102 | * ADC driver system settings. 103 | */ 104 | #define STM32_ADC_USE_ADC1 FALSE 105 | #define STM32_ADC_ADC1_CKMODE STM32_ADC_CKMODE_ADCCLK 106 | #define STM32_ADC_ADC1_DMA_PRIORITY 2 107 | #define STM32_ADC_IRQ_PRIORITY 2 108 | #define STM32_ADC_ADC1_DMA_IRQ_PRIORITY 2 109 | #define STM32_ADC_ADC1_DMA_STREAM STM32_DMA_STREAM_ID(1, 1) 110 | 111 | /* 112 | * DAC driver system settings. 113 | */ 114 | #define STM32_DAC_DUAL_MODE FALSE 115 | #define STM32_DAC_USE_DAC1_CH1 TRUE 116 | #define STM32_DAC_USE_DAC1_CH2 TRUE 117 | #define STM32_DAC_DAC1_CH1_IRQ_PRIORITY 10 118 | #define STM32_DAC_DAC1_CH2_IRQ_PRIORITY 10 119 | #define STM32_DAC_DAC1_CH1_DMA_PRIORITY 2 120 | #define STM32_DAC_DAC1_CH2_DMA_PRIORITY 2 121 | #define STM32_DAC_DAC1_CH1_DMA_STREAM STM32_DMA_STREAM_ID(1, 3) 122 | #define STM32_DAC_DAC1_CH2_DMA_STREAM STM32_DMA_STREAM_ID(1, 4) 123 | 124 | /* 125 | * EXT driver system settings. 126 | */ 127 | #define STM32_EXT_EXTI0_1_IRQ_PRIORITY 3 128 | #define STM32_EXT_EXTI2_3_IRQ_PRIORITY 3 129 | #define STM32_EXT_EXTI4_15_IRQ_PRIORITY 3 130 | #define STM32_EXT_EXTI16_IRQ_PRIORITY 3 131 | #define STM32_EXT_EXTI17_IRQ_PRIORITY 3 132 | #define STM32_EXT_EXTI21_22_IRQ_PRIORITY 3 133 | 134 | #define STM32_DISABLE_EXTI2122_HANDLER TRUE 135 | 136 | /* 137 | * GPT driver system settings. 138 | */ 139 | #define STM32_GPT_USE_TIM1 FALSE 140 | #define STM32_GPT_USE_TIM2 FALSE 141 | #define STM32_GPT_USE_TIM3 TRUE 142 | #define STM32_GPT_USE_TIM14 FALSE 143 | #define STM32_GPT_TIM1_IRQ_PRIORITY 2 144 | #define STM32_GPT_TIM2_IRQ_PRIORITY 2 145 | #define STM32_GPT_TIM3_IRQ_PRIORITY 2 146 | #define STM32_GPT_TIM14_IRQ_PRIORITY 2 147 | 148 | #define STM32_TIM3_SUPPRESS_ISR 149 | /* 150 | * I2C driver system settings. 151 | */ 152 | #define STM32_I2C_USE_I2C1 TRUE 153 | #define STM32_I2C_USE_I2C2 FALSE 154 | #define STM32_I2C_BUSY_TIMEOUT 50 155 | #define STM32_I2C_I2C1_IRQ_PRIORITY 3 156 | #define STM32_I2C_I2C2_IRQ_PRIORITY 3 157 | 158 | // I2C1 rx operation use DMA3, some as SPI1 DMA Tx used by LCD 159 | #define STM32_I2C_USE_DMA FALSE 160 | #define STM32_I2C_I2C1_DMA_PRIORITY 1 161 | #define STM32_I2C_I2C2_DMA_PRIORITY 1 162 | #define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3) 163 | #define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2) 164 | #define STM32_I2C_I2C2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5) 165 | #define STM32_I2C_I2C2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4) 166 | #define STM32_I2C_DMA_ERROR_HOOK(i2cp) osalSysHalt("DMA failure") 167 | 168 | /* 169 | * I2S driver system settings. 170 | */ 171 | #define STM32_I2S_USE_SPI1 FALSE 172 | #define STM32_I2S_USE_SPI2 TRUE 173 | #define STM32_I2S_SPI1_MODE (STM32_I2S_MODE_MASTER | \ 174 | STM32_I2S_MODE_RX) 175 | #define STM32_I2S_SPI2_MODE (STM32_I2S_MODE_SLAVE | \ 176 | STM32_I2S_MODE_RX) 177 | #define STM32_I2S_SPI1_IRQ_PRIORITY 3 178 | #define STM32_I2S_SPI2_IRQ_PRIORITY 3 179 | #define STM32_I2S_SPI1_DMA_PRIORITY 1 180 | #define STM32_I2S_SPI2_DMA_PRIORITY 1 181 | #define STM32_I2S_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2) 182 | #define STM32_I2S_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3) 183 | #define STM32_I2S_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4) 184 | #define STM32_I2S_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5) 185 | #define STM32_I2S_DMA_ERROR_HOOK(i2sp) osalSysHalt("DMA failure") 186 | 187 | /* 188 | * ICU driver system settings. 189 | */ 190 | #define STM32_ICU_USE_TIM1 FALSE 191 | #define STM32_ICU_USE_TIM2 FALSE 192 | #define STM32_ICU_USE_TIM3 FALSE 193 | #define STM32_ICU_TIM1_IRQ_PRIORITY 3 194 | #define STM32_ICU_TIM2_IRQ_PRIORITY 3 195 | #define STM32_ICU_TIM3_IRQ_PRIORITY 3 196 | // disable interrupt handlers 197 | #define STM32_TIM1_SUPPRESS_ISR 198 | #define STM32_TIM2_SUPPRESS_ISR 199 | #define STM32_TIM3_SUPPRESS_ISR 200 | 201 | /* 202 | * PWM driver system settings. 203 | */ 204 | #define STM32_PWM_USE_ADVANCED FALSE 205 | #define STM32_PWM_USE_TIM1 FALSE 206 | #define STM32_PWM_USE_TIM2 FALSE 207 | #define STM32_PWM_USE_TIM3 FALSE 208 | #define STM32_PWM_TIM1_IRQ_PRIORITY 3 209 | #define STM32_PWM_TIM2_IRQ_PRIORITY 3 210 | #define STM32_PWM_TIM3_IRQ_PRIORITY 3 211 | 212 | /* 213 | * SERIAL driver system settings. 214 | */ 215 | #define STM32_SERIAL_USE_USART1 TRUE 216 | #define STM32_SERIAL_USE_USART2 FALSE 217 | #define STM32_SERIAL_USART1_PRIORITY 2 218 | #define STM32_SERIAL_USART2_PRIORITY 3 219 | 220 | /* 221 | * SPI driver system settings. 222 | */ 223 | #define STM32_SPI_USE_SPI1 FALSE 224 | #define STM32_SPI_USE_SPI2 FALSE 225 | #define STM32_SPI_SPI1_DMA_PRIORITY 1 226 | #define STM32_SPI_SPI2_DMA_PRIORITY 1 227 | #define STM32_SPI_SPI1_IRQ_PRIORITY 3 228 | #define STM32_SPI_SPI2_IRQ_PRIORITY 3 229 | #define STM32_SPI_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2) 230 | #define STM32_SPI_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3) 231 | #define STM32_SPI_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4) 232 | #define STM32_SPI_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5) 233 | #define STM32_SPI_DMA_ERROR_HOOK(spip) osalSysHalt("DMA failure") 234 | 235 | /* 236 | * ST driver system settings. 237 | */ 238 | #define STM32_ST_IRQ_PRIORITY 2 239 | #define STM32_ST_USE_TIMER 2 240 | 241 | /* 242 | * UART driver system settings. 243 | */ 244 | #define STM32_UART_USE_USART1 FALSE 245 | #define STM32_UART_USE_USART2 FALSE 246 | #define STM32_UART_USART1_IRQ_PRIORITY 3 247 | #define STM32_UART_USART2_IRQ_PRIORITY 3 248 | #define STM32_UART_USART1_DMA_PRIORITY 0 249 | #define STM32_UART_USART2_DMA_PRIORITY 0 250 | #define STM32_UART_USART1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3) 251 | #define STM32_UART_USART1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2) 252 | #define STM32_UART_USART2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5) 253 | #define STM32_UART_USART2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4) 254 | #define STM32_UART_DMA_ERROR_HOOK(uartp) osalSysHalt("DMA failure") 255 | 256 | /* 257 | * USB driver system settings. 258 | */ 259 | #define STM32_USB_USE_USB1 TRUE 260 | #define STM32_USB_LOW_POWER_ON_SUSPEND FALSE 261 | #define STM32_USB_USB1_LP_IRQ_PRIORITY 3 262 | 263 | /* 264 | * WDG driver system settings. 265 | */ 266 | #define STM32_WDG_USE_IWDG FALSE 267 | 268 | #endif /* MCUCONF_H */ 269 | -------------------------------------------------------------------------------- /NANOVNA_STM32_F072/rtc_v2.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2020, Dmitry (DiSlord) dislordlive@gmail.com 3 | * All rights reserved. 4 | * 5 | * This is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 3, or (at your option) 8 | * any later version. 9 | * 10 | * The software is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with GNU Radio; see the file COPYING. If not, write to 17 | * the Free Software Foundation, Inc., 51 Franklin Street, 18 | * Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | // Get RTC time as binary structure in 0x00HHMMSS 22 | uint32_t rtc_get_tr_bin(void){ 23 | uint32_t tr = RTC->TR; 24 | uint32_t v = (tr&0x0F0F0F) + ((tr&0x707070)>>1) + ((tr&0x707070)>>3); 25 | return v; 26 | } 27 | 28 | // Get RTC time as binary structure in 0x00YYMMDD 29 | uint32_t rtc_get_dr_bin(void){ 30 | uint32_t dr = RTC->DR; 31 | uint32_t v = (dr&0x000F0F0F) + ((dr&0x00F01030)>>1) + ((dr&0x00F01030)>>3); 32 | return v;// | ((dr&0xE000)<<15); // day of week at end 33 | } 34 | 35 | uint32_t rtc_get_FAT(void) { 36 | uint32_t fattime; 37 | uint32_t tr = rtc_get_tr_bin(); 38 | uint32_t dr = rtc_get_dr_bin(); 39 | fattime = ((tr>> 0)&0xFF) >> 1U; // Seconds / 2 40 | fattime |= ((tr>> 8)&0xFF) << 5U; // Minutes 41 | fattime |= ((tr>>16)&0xFF) << 11U; // Hour 42 | fattime |= ((dr>> 0)&0xFF) << 16U; // Day 43 | fattime |= ((dr>> 8)&0xFF) << 21U; // Month 44 | fattime |= (((dr>>16)&0xFF) + RTC_START_YEAR - 1980) << 25U; // Local year begin from 2000, fat from 1980 45 | return fattime; 46 | } 47 | 48 | // Finish of configuration procedure. 49 | static void rtc_exit_init(void) { 50 | RTC->ISR &= ~RTC_ISR_INIT; 51 | } 52 | 53 | // Beginning of configuration procedure. 54 | static bool rtc_enter_init(void){ 55 | RTC->ISR |= RTC_ISR_INIT; 56 | uint32_t count = 4*65536; 57 | while (--count) 58 | if (RTC->ISR & RTC_ISR_INITF) 59 | return true; 60 | return false; 61 | } 62 | 63 | void rtc_set_time(uint32_t dr, uint32_t tr) { 64 | if (rtc_enter_init()){ 65 | RTC->TR = tr; // Write TR register 66 | RTC->DR = dr; // Write TD register 67 | } 68 | rtc_exit_init(); 69 | } 70 | 71 | #ifdef VNA_AUTO_SELECT_RTC_SOURCE 72 | 73 | // Enable LSE bypass if need 74 | #if defined(STM32_LSE_BYPASS) 75 | #define STM32_LSE_BYPASS RCC_BDCR_LSEBYP 76 | #else 77 | #define STM32_LSE_BYPASS 0 78 | #endif 79 | 80 | // Startup LSE or if not work, LSI generator 81 | static void rtc_start_source(void){ 82 | // LSE already work (enabled and ready) 83 | if ((RCC->BDCR & (RCC_BDCR_LSEON|RCC_BDCR_LSERDY|STM32_LSE_BYPASS)) == (RCC_BDCR_LSEON|RCC_BDCR_LSERDY|STM32_LSE_BYPASS)) 84 | return; 85 | 86 | // If LSE not enabled, try startup 87 | RCC->BDCR |= STM32_LSEDRV | STM32_LSE_BYPASS | RCC_BDCR_LSEON; 88 | // Waits until LSE is stable (need ~150ms for startup). 89 | chThdSleepMilliseconds(200); 90 | if (RCC->BDCR & RCC_BDCR_LSERDY) return; 91 | 92 | // Startup LSI if not allow start LSE 93 | RCC->CSR |= RCC_CSR_LSION; 94 | while ((RCC->CSR & RCC_CSR_LSIRDY) == 0); 95 | } 96 | 97 | static void resetBCDR(uint32_t rtc_drv){ 98 | // Backup domain reset, for change source. 99 | RCC->BDCR = RCC_BDCR_BDRST; 100 | RCC->BDCR = 0; 101 | // Startup again source generator 102 | rtc_start_source(); 103 | // Select new clock source. And enable 104 | RCC->BDCR|= rtc_drv; 105 | } 106 | 107 | void auto_backup_domain_init(void){ 108 | // Init Backup domain, RTC clock source 109 | uint32_t rtc_drv; 110 | // Backup domain access enabled and left open. 111 | PWR->CR |= PWR_CR_DBP; 112 | // Start/check source 113 | rtc_start_source(); 114 | // Check LSE ready, if ok, select as source 115 | rtc_drv = RCC->BDCR & RCC_BDCR_LSERDY ? STM32_RTCSEL_LSE|RCC_BDCR_RTCEN : // Select LSE as source 116 | STM32_RTCSEL_LSI|RCC_BDCR_RTCEN; // Select LSI as source 117 | // If the backup domain hasn't been initialized yet or work on different source, then proceed with initialization 118 | if ((RCC->BDCR & (STM32_RTCSEL_MASK|RCC_BDCR_RTCEN)) != rtc_drv) 119 | resetBCDR(rtc_drv); 120 | /* 121 | // Check RTC clock, and reset backup domain to LSI if clock not start 122 | if (rtc_enter_init()) 123 | rtc_exit_init(); 124 | else 125 | resetBCDR(STM32_RTCSEL_LSI|RCC_BDCR_RTCEN); 126 | */ 127 | } 128 | #endif 129 | 130 | // Initiate RTC clock 131 | void rtc_init(void){ 132 | #ifdef VNA_AUTO_SELECT_RTC_SOURCE 133 | // Auto start LSE or LSI source for RTC 134 | auto_backup_domain_init(); 135 | #else 136 | // ChibiOS init BDCR LSE or LSI source by self from user defined in mcuconf.h source 137 | // For add auto select RTC source need rewrite it 138 | // see hal_lld_backup_domain_init() in hal_lld.c for every CPU 139 | // Default RTC clock is LSE, but it possible not launch if no quartz installed 140 | #endif 141 | uint32_t src = RCC->BDCR & STM32_RTCSEL_MASK; 142 | if (src == STM32_RTCSEL_NOCLOCK) return; 143 | // If calendar has not been initialized yet or different PRER settings then proceed with the initial setup. 144 | // Disable write protection. 145 | RTC->WPR = 0xCA; 146 | RTC->WPR = 0x53; 147 | uint32_t rtc_prer = (src == STM32_RTCSEL_LSE) ? STM32_RTC_LSE_PRER : 148 | STM32_RTC_LSI_PRER; 149 | // If calendar has not been initialized yet then proceed with the initial setup. 150 | if ((RTC->ISR & RTC_ISR_INITS) == 0 || RTC->PRER != rtc_prer) { 151 | if (rtc_enter_init()){ 152 | RTC->CR = 0 153 | // | RTC_CR_COSEL // RTC output 1Hz (or 512Hz if disabled) 154 | ; 155 | RTC->ISR = RTC_ISR_INIT; // Clearing all but RTC_ISR_INIT. 156 | RTC->PRER = rtc_prer; // Prescaler value loaded in registers 2 times 157 | RTC->PRER = rtc_prer; 158 | } 159 | // Finalizing of configuration procedure. 160 | rtc_exit_init(); 161 | } 162 | else 163 | RTC->ISR &= ~RTC_ISR_RSF; 164 | } 165 | 166 | void rtc_set_cal(float ppm) { 167 | int32_t cal = ppm * (1<<20) / 1000000.0f + 511.5f; 168 | if ((RTC->ISR & RTC_ISR_RECALPF) || (uint32_t)cal > 1024) 169 | return; 170 | RTC->CALR = (511 - cal) & (RTC_CALR_CALP | RTC_CALR_CALM); 171 | } 172 | 173 | float rtc_get_cal(void) { 174 | int32_t cal = -(RTC->CALR & RTC_CALR_CALM); 175 | if (RTC->CALR & RTC_CALR_CALP) 176 | cal += 512; 177 | return cal * (1000000.0f / (1<<20)); 178 | } 179 | -------------------------------------------------------------------------------- /NANOVNA_STM32_F072/run_openocd: -------------------------------------------------------------------------------- 1 | ~/opt/xPacks/@gnu-mcu-eclipse/openocd/0.10.0-12.1/.content/bin/openocd -f board/stm32f0discovery.cfg 2 | -------------------------------------------------------------------------------- /NANOVNA_STM32_F072/target/stm32f0x.cfg: -------------------------------------------------------------------------------- 1 | # script for stm32f0x family 2 | 3 | # 4 | # stm32 devices support SWD transports only. 5 | # 6 | source [find target/swj-dp.tcl] 7 | source [find mem_helper.tcl] 8 | 9 | if { [info exists CHIPNAME] } { 10 | set _CHIPNAME $CHIPNAME 11 | } else { 12 | set _CHIPNAME stm32f0x 13 | } 14 | 15 | set _ENDIAN little 16 | 17 | # Work-area is a space in RAM used for flash programming 18 | # By default use 4kB 19 | if { [info exists WORKAREASIZE] } { 20 | set _WORKAREASIZE $WORKAREASIZE 21 | } else { 22 | set _WORKAREASIZE 0x1000 23 | } 24 | 25 | # Allow overriding the Flash bank size 26 | if { [info exists FLASH_SIZE] } { 27 | set _FLASH_SIZE $FLASH_SIZE 28 | } else { 29 | # autodetect size 30 | set _FLASH_SIZE 0 31 | } 32 | 33 | #jtag scan chain 34 | if { [info exists CPUTAPID] } { 35 | set _CPUTAPID $CPUTAPID 36 | } else { 37 | # See STM Document RM0091 38 | # Section 29.5.3 39 | set _CPUTAPID 0x0bb11477 40 | } 41 | 42 | swj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID 43 | dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu 44 | 45 | set _TARGETNAME $_CHIPNAME.cpu 46 | target create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap 47 | 48 | $_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0 49 | 50 | # flash size will be probed 51 | set _FLASHNAME $_CHIPNAME.flash 52 | flash bank $_FLASHNAME stm32f1x 0x08000000 $_FLASH_SIZE 0 0 $_TARGETNAME 53 | 54 | # adapter speed should be <= F_CPU/6. F_CPU after reset is 8MHz, so use F_JTAG = 1MHz 55 | adapter_khz 1000 56 | 57 | adapter_nsrst_delay 100 58 | 59 | reset_config srst_nogate 60 | 61 | if {![using_hla]} { 62 | # if srst is not fitted use SYSRESETREQ to 63 | # perform a soft reset 64 | cortex_m reset_config sysresetreq 65 | } 66 | 67 | proc stm32f0x_default_reset_start {} { 68 | # Reset clock is HSI (8 MHz) 69 | adapter_khz 1000 70 | } 71 | 72 | proc stm32f0x_default_examine_end {} { 73 | # Enable debug during low power modes (uses more power) 74 | mmw 0x40015804 0x00000006 0 ;# DBGMCU_CR |= DBG_STANDBY | DBG_STOP 75 | 76 | # Stop watchdog counters during halt 77 | mmw 0x40015808 0x00001800 0 ;# DBGMCU_APB1_FZ |= DBG_IWDG_STOP | DBG_WWDG_STOP 78 | } 79 | 80 | proc stm32f0x_default_reset_init {} { 81 | # Configure PLL to boost clock to HSI x 6 (48 MHz) 82 | mww 0x40021004 0x00100000 ;# RCC_CFGR = PLLMUL[2] 83 | mmw 0x40021000 0x01000000 0 ;# RCC_CR[31:16] |= PLLON 84 | mww 0x40022000 0x00000011 ;# FLASH_ACR = PRFTBE | LATENCY[0] 85 | sleep 10 ;# Wait for PLL to lock 86 | mmw 0x40021004 0x00000002 0 ;# RCC_CFGR |= SW[1] 87 | 88 | # Boost JTAG frequency 89 | adapter_khz 8000 90 | } 91 | 92 | # Default hooks 93 | $_TARGETNAME configure -event examine-end { stm32f0x_default_examine_end } 94 | $_TARGETNAME configure -event reset-start { stm32f0x_default_reset_start } 95 | $_TARGETNAME configure -event reset-init { stm32f0x_default_reset_init } 96 | -------------------------------------------------------------------------------- /NANOVNA_STM32_F072/target/stm32f3x.cfg: -------------------------------------------------------------------------------- 1 | # script for stm32f3x family 2 | 3 | # 4 | # stm32 devices support both JTAG and SWD transports. 5 | # 6 | source [find target/swj-dp.tcl] 7 | source [find mem_helper.tcl] 8 | 9 | if { [info exists CHIPNAME] } { 10 | set _CHIPNAME $CHIPNAME 11 | } else { 12 | set _CHIPNAME stm32f3x 13 | } 14 | 15 | set _ENDIAN little 16 | 17 | # Work-area is a space in RAM used for flash programming 18 | # By default use 16kB 19 | if { [info exists WORKAREASIZE] } { 20 | set _WORKAREASIZE $WORKAREASIZE 21 | } else { 22 | set _WORKAREASIZE 0x8000 23 | } 24 | 25 | # JTAG speed should be <= F_CPU/6. F_CPU after reset is 8MHz, so use F_JTAG = 1MHz 26 | # 27 | # Since we may be running of an RC oscilator, we crank down the speed a 28 | # bit more to be on the safe side. Perhaps superstition, but if are 29 | # running off a crystal, we can run closer to the limit. Note 30 | # that there can be a pretty wide band where things are more or less stable. 31 | adapter_khz 950 32 | 33 | adapter_nsrst_delay 1000 34 | if {[using_jtag]} { 35 | jtag_ntrst_delay 1000 36 | } 37 | 38 | #jtag scan chain 39 | if { [info exists CPUTAPID] } { 40 | set _CPUTAPID $CPUTAPID 41 | } else { 42 | if { [using_jtag] } { 43 | # See STM Document RM0316 44 | # Section 29.6.3 - corresponds to Cortex-M4 r0p1 45 | set _CPUTAPID 0x4ba00477 46 | } { 47 | set _CPUTAPID 0x2ba01477 48 | } 49 | } 50 | 51 | swj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID 52 | dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu 53 | 54 | if {[using_jtag]} { 55 | jtag newtap $_CHIPNAME bs -irlen 5 56 | } 57 | 58 | set _TARGETNAME $_CHIPNAME.cpu 59 | target create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap 60 | 61 | $_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0 -rtos ChibiOS 62 | #$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0 63 | 64 | set _FLASHNAME $_CHIPNAME.flash 65 | flash bank $_FLASHNAME stm32f1x 0 0 0 0 $_TARGETNAME 66 | 67 | reset_config srst_nogate 68 | 69 | if {![using_hla]} { 70 | # if srst is not fitted use SYSRESETREQ to 71 | # perform a soft reset 72 | cortex_m reset_config sysresetreq 73 | } 74 | 75 | proc stm32f3x_default_reset_start {} { 76 | # Reset clock is HSI (8 MHz) 77 | adapter_khz 950 78 | } 79 | 80 | proc stm32f3x_default_examine_end {} { 81 | # Enable debug during low power modes (uses more power) 82 | mmw 0xe0042004 0x00000007 0 ;# DBGMCU_CR |= DBG_STANDBY | DBG_STOP | DBG_SLEEP 83 | 84 | # Stop watchdog counters during halt 85 | mmw 0xe0042008 0x00001800 0 ;# DBGMCU_APB1_FZ |= DBG_IWDG_STOP | DBG_WWDG_STOP 86 | } 87 | 88 | proc stm32f3x_default_reset_init {} { 89 | # Configure PLL to boost clock to HSI x 8 (64 MHz) 90 | mww 0x40021004 0x00380400 ;# RCC_CFGR = PLLMUL[3:1] | PPRE1[2] 91 | mmw 0x40021000 0x01000000 0 ;# RCC_CR |= PLLON 92 | mww 0x40022000 0x00000012 ;# FLASH_ACR = PRFTBE | LATENCY[1] 93 | sleep 10 ;# Wait for PLL to lock 94 | mmw 0x40021004 0x00000002 0 ;# RCC_CFGR |= SW[1] 95 | 96 | # Boost JTAG frequency 97 | adapter_khz 2000 98 | } 99 | 100 | # Default hooks 101 | $_TARGETNAME configure -event examine-end { stm32f3x_default_examine_end } 102 | $_TARGETNAME configure -event reset-start { stm32f3x_default_reset_start } 103 | $_TARGETNAME configure -event reset-init { stm32f3x_default_reset_init } 104 | 105 | $_TARGETNAME configure -event trace-config { 106 | # Set TRACE_IOEN; TRACE_MODE is set to async; when using sync 107 | # change this value accordingly to configure trace pins 108 | # assignment 109 | mmw 0xe0042004 0x00000020 0 110 | } 111 | 112 | $_TARGETNAME configure -event gdb-attach { 113 | halt 114 | } 115 | $_TARGETNAME configure -event gdb-attach { 116 | reset init 117 | } 118 | 119 | -------------------------------------------------------------------------------- /NANOVNA_STM32_F072/target/swj-dp.tcl: -------------------------------------------------------------------------------- 1 | # ARM Debug Interface V5 (ADI_V5) utility 2 | # ... Mostly for SWJ-DP (not SW-DP or JTAG-DP, since 3 | # SW-DP and JTAG-DP targets don't need to switch based 4 | # on which transport is active. 5 | # 6 | # declare a JTAG or SWD Debug Access Point (DAP) 7 | # based on the transport in use with this session. 8 | # You can't access JTAG ops when SWD is active, etc. 9 | 10 | # params are currently what "jtag newtap" uses 11 | # because OpenOCD internals are still strongly biased 12 | # to JTAG .... but for SWD, "irlen" etc are ignored, 13 | # and the internals work differently 14 | 15 | # for now, ignore non-JTAG and non-SWD transports 16 | # (e.g. initial flash programming via SPI or UART) 17 | 18 | # split out "chip" and "tag" so we can someday handle 19 | # them more uniformly irlen too...) 20 | 21 | if [catch {transport select}] { 22 | echo "Error: unable to select a session transport. Can't continue." 23 | shutdown 24 | } 25 | 26 | proc swj_newdap {chip tag args} { 27 | if [using_hla] { 28 | eval hla newtap $chip $tag $args 29 | } elseif [using_jtag] { 30 | eval jtag newtap $chip $tag $args 31 | } elseif [using_swd] { 32 | eval swd newdap $chip $tag $args 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /NANOVNA_STM32_F303/STM32F303xC.ld: -------------------------------------------------------------------------------- 1 | /* 2 | ChibiOS - Copyright (C) 2006..2016 Giovanni Di Sirio 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | /* 18 | * STM32F303xC memory setup. 19 | */ 20 | MEMORY 21 | { 22 | flash0 : org = 0x08000000, len = 142k 23 | flash1 : org = 0x00000000, len = 0 24 | flash2 : org = 0x00000000, len = 0 25 | flash3 : org = 0x00000000, len = 0 26 | flash4 : org = 0x00000000, len = 0 27 | flash5 : org = 0x00000000, len = 0 28 | flash6 : org = 0x00000000, len = 0 29 | flash7 : org = 0x0801C800, len = 114k 30 | ram0 : org = 0x20000000, len = 40k 31 | ram1 : org = 0x00000000, len = 0 32 | ram2 : org = 0x00000000, len = 0 33 | ram3 : org = 0x00000000, len = 0 34 | ram4 : org = 0x10000000, len = 8k 35 | ram5 : org = 0x00000000, len = 0 36 | ram6 : org = 0x00000000, len = 0 37 | ram7 : org = 0x00000000, len = 0 38 | } 39 | 40 | /* For each data/text section two region are defined, a virtual region 41 | and a load region (_LMA suffix).*/ 42 | 43 | /* Flash region to be used for exception vectors.*/ 44 | REGION_ALIAS("VECTORS_FLASH", flash0); 45 | REGION_ALIAS("VECTORS_FLASH_LMA", flash0); 46 | 47 | /* Flash region to be used for constructors and destructors.*/ 48 | REGION_ALIAS("XTORS_FLASH", flash0); 49 | REGION_ALIAS("XTORS_FLASH_LMA", flash0); 50 | 51 | /* Flash region to be used for code text.*/ 52 | REGION_ALIAS("TEXT_FLASH", flash0); 53 | REGION_ALIAS("TEXT_FLASH_LMA", flash0); 54 | 55 | /* Flash region to be used for read only data.*/ 56 | REGION_ALIAS("RODATA_FLASH", flash0); 57 | REGION_ALIAS("RODATA_FLASH_LMA", flash0); 58 | 59 | /* Flash region to be used for various.*/ 60 | REGION_ALIAS("VARIOUS_FLASH", flash0); 61 | REGION_ALIAS("VARIOUS_FLASH_LMA", flash0); 62 | 63 | /* Flash region to be used for RAM(n) initialization data.*/ 64 | REGION_ALIAS("RAM_INIT_FLASH_LMA", flash0); 65 | 66 | /* Flash region to be saved calibration data */ 67 | REGION_ALIAS("CALDATA_FLASH", flash7); 68 | 69 | /* RAM region to be used for Main stack. This stack accommodates the processing 70 | of all exceptions and interrupts.*/ 71 | REGION_ALIAS("MAIN_STACK_RAM", ram0); 72 | 73 | /* RAM region to be used for the process stack. This is the stack used by 74 | the main() function.*/ 75 | REGION_ALIAS("PROCESS_STACK_RAM", ram0); 76 | 77 | /* RAM region to be used for data segment.*/ 78 | REGION_ALIAS("DATA_RAM", ram0); 79 | REGION_ALIAS("DATA_RAM_LMA", flash0); 80 | 81 | /* RAM region to be used for BSS segment.*/ 82 | REGION_ALIAS("BSS_RAM", ram0); 83 | 84 | /* RAM region to be used for the default heap.*/ 85 | REGION_ALIAS("HEAP_RAM", ram0); 86 | 87 | /* Generic rules inclusion.*/ 88 | INCLUDE rules.ld 89 | 90 | SECTIONS 91 | { 92 | .calsave (NOLOAD) : ALIGN(4) 93 | { 94 | *(.calsave) 95 | } > CALDATA_FLASH 96 | } 97 | -------------------------------------------------------------------------------- /NANOVNA_STM32_F303/board.c: -------------------------------------------------------------------------------- 1 | /* 2 | ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include "hal.h" 18 | 19 | #if HAL_USE_PAL || defined(__DOXYGEN__) 20 | /** 21 | * @brief PAL setup. 22 | * @details Digital I/O ports static configuration as defined in @p board.h. 23 | * This variable is used by the HAL when initializing the PAL driver. 24 | */ 25 | const PALConfig pal_default_config = { 26 | #if STM32_HAS_GPIOA 27 | {VAL_GPIOA_MODER, VAL_GPIOA_OTYPER, VAL_GPIOA_OSPEEDR, VAL_GPIOA_PUPDR, 28 | VAL_GPIOA_ODR, VAL_GPIOA_AFRL, VAL_GPIOA_AFRH}, 29 | #endif 30 | #if STM32_HAS_GPIOB 31 | {VAL_GPIOB_MODER, VAL_GPIOB_OTYPER, VAL_GPIOB_OSPEEDR, VAL_GPIOB_PUPDR, 32 | VAL_GPIOB_ODR, VAL_GPIOB_AFRL, VAL_GPIOB_AFRH}, 33 | #endif 34 | #if STM32_HAS_GPIOC 35 | {VAL_GPIOC_MODER, VAL_GPIOC_OTYPER, VAL_GPIOC_OSPEEDR, VAL_GPIOC_PUPDR, 36 | VAL_GPIOC_ODR, VAL_GPIOC_AFRL, VAL_GPIOC_AFRH}, 37 | #endif 38 | #if STM32_HAS_GPIOD 39 | {VAL_GPIOD_MODER, VAL_GPIOD_OTYPER, VAL_GPIOD_OSPEEDR, VAL_GPIOD_PUPDR, 40 | VAL_GPIOD_ODR, VAL_GPIOD_AFRL, VAL_GPIOD_AFRH}, 41 | #endif 42 | #if STM32_HAS_GPIOE 43 | {VAL_GPIOE_MODER, VAL_GPIOE_OTYPER, VAL_GPIOE_OSPEEDR, VAL_GPIOE_PUPDR, 44 | VAL_GPIOE_ODR, VAL_GPIOE_AFRL, VAL_GPIOE_AFRH}, 45 | #endif 46 | #if STM32_HAS_GPIOF 47 | {VAL_GPIOF_MODER, VAL_GPIOF_OTYPER, VAL_GPIOF_OSPEEDR, VAL_GPIOF_PUPDR, 48 | VAL_GPIOF_ODR, VAL_GPIOF_AFRL, VAL_GPIOF_AFRH}, 49 | #endif 50 | #if STM32_HAS_GPIOG 51 | {VAL_GPIOG_MODER, VAL_GPIOG_OTYPER, VAL_GPIOG_OSPEEDR, VAL_GPIOG_PUPDR, 52 | VAL_GPIOG_ODR, VAL_GPIOG_AFRL, VAL_GPIOG_AFRH}, 53 | #endif 54 | #if STM32_HAS_GPIOH 55 | {VAL_GPIOH_MODER, VAL_GPIOH_OTYPER, VAL_GPIOH_OSPEEDR, VAL_GPIOH_PUPDR, 56 | VAL_GPIOH_ODR, VAL_GPIOH_AFRL, VAL_GPIOH_AFRH}, 57 | #endif 58 | #if STM32_HAS_GPIOI 59 | {VAL_GPIOI_MODER, VAL_GPIOI_OTYPER, VAL_GPIOI_OSPEEDR, VAL_GPIOI_PUPDR, 60 | VAL_GPIOI_ODR, VAL_GPIOI_AFRL, VAL_GPIOI_AFRH} 61 | #endif 62 | }; 63 | #endif 64 | 65 | void boardDFUEnter(void) { 66 | __set_MSP(*((uint32_t *)(STM32F303xC_SYSTEM_MEMORY))); 67 | ((void (*)(void))(*((uint32_t *)(STM32F303xC_SYSTEM_MEMORY + 4))))(); // jump to DFU 68 | } 69 | 70 | /* 71 | * Early initialization code. 72 | * This initialization must be performed just after stack setup and before 73 | * any other initialization. 74 | */ 75 | void __early_init(void) { 76 | stm32_clock_init(); 77 | } 78 | 79 | /* 80 | * Board-specific initialization code. 81 | */ 82 | void boardInit(void) { 83 | // Speedup flash latency 84 | FLASH->ACR= FLASH_ACR_PRFTBE | FLASH_ACR_LATENCY_0; 85 | } 86 | -------------------------------------------------------------------------------- /NANOVNA_STM32_F303/board.mk: -------------------------------------------------------------------------------- 1 | # List of all the board related files. 2 | BOARDSRC = ${PROJ}/NANOVNA_STM32_F303/board.c 3 | 4 | # Required include directories 5 | BOARDINC = ${PROJ}/NANOVNA_STM32_F303 6 | -------------------------------------------------------------------------------- /NANOVNA_STM32_F303/board/stm32f3discovery.cfg: -------------------------------------------------------------------------------- 1 | # This is an STM32F3 discovery board with a single STM32F303VCT6 chip. 2 | # http://www.st.com/internet/evalboard/product/254044.jsp 3 | 4 | source [find interface/stlink.cfg] 5 | 6 | transport select hla_swd 7 | 8 | source [find target/stm32f3x.cfg] 9 | 10 | #reset_config srst_only 11 | reset_config none 12 | 13 | -------------------------------------------------------------------------------- /NANOVNA_STM32_F303/dac_v1.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2021, Dmitry (DiSlord) dislordlive@gmail.com 3 | * Based on TAKAHASHI Tomohiro (TTRFTECH) edy555@gmail.com 4 | * All rights reserved. 5 | * 6 | * This is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3, or (at your option) 9 | * any later version. 10 | * 11 | * The software is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with GNU Radio; see the file COPYING. If not, write to 18 | * the Free Software Foundation, Inc., 51 Franklin Street, 19 | * Boston, MA 02110-1301, USA. 20 | */ 21 | 22 | void dac_init(void) { 23 | rccEnableDAC1(false); // Use DAC1 24 | DAC->CR|= DAC_CR_EN2; // Enable DAC1 ch2 25 | } 26 | 27 | void dac_setvalue_ch1(uint16_t v) {DAC->DHR12R1 = v;} 28 | void dac_setvalue_ch2(uint16_t v) {DAC->DHR12R2 = v;} 29 | -------------------------------------------------------------------------------- /NANOVNA_STM32_F303/debug/STM32F3xx-ADC (OpenOCD, Flash and Run).launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /NANOVNA_STM32_F303/dma_v1.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2020, Dmitry (DiSlord) dislordlive@gmail.com 3 | * Based on TAKAHASHI Tomohiro (TTRFTECH) edy555@gmail.com 4 | * All rights reserved. 5 | * 6 | * This is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3, or (at your option) 9 | * any later version. 10 | * 11 | * The software is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with GNU Radio; see the file COPYING. If not, write to 18 | * the Free Software Foundation, Inc., 51 Franklin Street, 19 | * Boston, MA 02110-1301, USA. 20 | */ 21 | // Add all handlers (for reset DMA interrupt) 22 | //#define DMA1_USE_ALL_HANDLERS 23 | 24 | // F303 DMA1 interrupts handler function 25 | #if defined(DMA1_CH1_HANDLER_FUNC) || defined(DMA1_USE_ALL_HANDLERS) 26 | OSAL_IRQ_HANDLER(STM32_DMA1_CH1_HANDLER) { 27 | uint32_t flags = DMA1->ISR; DMA1->IFCR = flags; // reset interrupt vector 28 | #ifdef DMA1_CH1_HANDLER_FUNC 29 | if (flags & (STM32_DMA_ISR_MASK<<0)) DMA1_CH1_HANDLER_FUNC((flags>>0)&STM32_DMA_ISR_MASK); // DMA Channel 1 handler 30 | #endif 31 | } 32 | #endif 33 | 34 | #if defined(DMA1_CH2_HANDLER_FUNC) || defined(DMA1_USE_ALL_HANDLERS) 35 | OSAL_IRQ_HANDLER(STM32_DMA1_CH2_HANDLER) { 36 | uint32_t flags = DMA1->ISR; DMA1->IFCR = flags; // reset interrupt vector 37 | #ifdef DMA1_CH2_HANDLER_FUNC 38 | if (flags & (STM32_DMA_ISR_MASK<<4)) DMA1_CH2_HANDLER_FUNC((flags>>4)&STM32_DMA_ISR_MASK); // DMA Channel 2 handler 39 | #endif 40 | } 41 | #endif 42 | 43 | #if defined(DMA1_CH3_HANDLER_FUNC) || defined(DMA1_USE_ALL_HANDLERS) 44 | OSAL_IRQ_HANDLER(STM32_DMA1_CH3_HANDLER) { 45 | uint32_t flags = DMA1->ISR; DMA1->IFCR = flags; // reset interrupt vector 46 | #ifdef DMA1_CH3_HANDLER_FUNC 47 | if (flags & (STM32_DMA_ISR_MASK<<8)) DMA1_CH3_HANDLER_FUNC((flags>>8)&STM32_DMA_ISR_MASK); // DMA Channel 3 handler 48 | #endif 49 | } 50 | #endif 51 | 52 | #if defined(DMA1_CH4_HANDLER_FUNC) || defined(DMA1_USE_ALL_HANDLERS) 53 | OSAL_IRQ_HANDLER(STM32_DMA1_CH4_HANDLER) { 54 | uint32_t flags = DMA1->ISR; DMA1->IFCR = flags; // reset interrupt vector 55 | #ifdef DMA1_CH4_HANDLER_FUNC 56 | if (flags & (STM32_DMA_ISR_MASK<<12)) DMA1_CH4_HANDLER_FUNC((flags>>12)&STM32_DMA_ISR_MASK); // DMA Channel 4 handler 57 | #endif 58 | } 59 | #endif 60 | 61 | #if defined(DMA1_CH5_HANDLER_FUNC) || defined(DMA1_USE_ALL_HANDLERS) 62 | OSAL_IRQ_HANDLER(STM32_DMA1_CH5_HANDLER) { 63 | uint32_t flags = DMA1->ISR; DMA1->IFCR = flags; // reset interrupt vector 64 | #ifdef DMA1_CH5_HANDLER_FUNC 65 | if (flags & (STM32_DMA_ISR_MASK<<16)) DMA1_CH5_HANDLER_FUNC((flags>>16)&STM32_DMA_ISR_MASK); // DMA Channel 5 handler 66 | #endif 67 | } 68 | #endif 69 | 70 | #if defined(DMA1_CH6_HANDLER_FUNC) || defined(DMA1_USE_ALL_HANDLERS) 71 | OSAL_IRQ_HANDLER(STM32_DMA1_CH6_HANDLER) { 72 | uint32_t flags = DMA1->ISR; DMA1->IFCR = flags; // reset interrupt vector 73 | #ifdef DMA1_CH6_HANDLER_FUNC 74 | if (flags & (STM32_DMA_ISR_MASK<<20)) DMA1_CH6_HANDLER_FUNC((flags>>20)&STM32_DMA_ISR_MASK); // DMA Channel 6 handler 75 | #endif 76 | } 77 | #endif 78 | 79 | #if defined(DMA1_CH7_HANDLER_FUNC) || defined(DMA1_USE_ALL_HANDLERS) 80 | OSAL_IRQ_HANDLER(STM32_DMA1_CH7_HANDLER) { 81 | uint32_t flags = DMA1->ISR; DMA1->IFCR = flags; // reset interrupt vector 82 | #ifdef DMA1_CH7_HANDLER_FUNC 83 | if (flags & (STM32_DMA_ISR_MASK<<24)) DMA1_CH7_HANDLER_FUNC((flags>>24)&STM32_DMA_ISR_MASK); // DMA Channel 7 handler 84 | #endif 85 | } 86 | #endif 87 | -------------------------------------------------------------------------------- /NANOVNA_STM32_F303/exti_v1.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2020, Dmitry (DiSlord) dislordlive@gmail.com 3 | * Based on TAKAHASHI Tomohiro (TTRFTECH) edy555@gmail.com 4 | * All rights reserved. 5 | * 6 | * This is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3, or (at your option) 9 | * any later version. 10 | * 11 | * The software is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with GNU Radio; see the file COPYING. If not, write to 18 | * the Free Software Foundation, Inc., 51 Franklin Street, 19 | * Boston, MA 02110-1301, USA. 20 | */ 21 | // F072 Ext interrupts handler function 22 | #if HAL_USE_EXT == FALSE 23 | extern void handle_button_interrupt(uint16_t channel); 24 | 25 | //#define EXT_CH0_HANDLER_FUNC 26 | #define EXT_CH1_HANDLER_FUNC handle_button_interrupt 27 | #define EXT_CH2_HANDLER_FUNC handle_button_interrupt 28 | #define EXT_CH3_HANDLER_FUNC handle_button_interrupt 29 | //#define EXT_CH4_HANDLER_FUNC 30 | //#define EXT_CH5_HANDLER_FUNC 31 | //#define EXT_CH6_HANDLER_FUNC 32 | //#define EXT_CH7_HANDLER_FUNC 33 | //#define EXT_CH8_HANDLER_FUNC 34 | //#define EXT_CH9_HANDLER_FUNC 35 | //#define EXT_CH10_HANDLER_FUNC 36 | //#define EXT_CH11_HANDLER_FUNC 37 | //#define EXT_CH12_HANDLER_FUNC 38 | //#define EXT_CH13_HANDLER_FUNC 39 | //#define EXT_CH14_HANDLER_FUNC 40 | //#define EXT_CH15_HANDLER_FUNC 41 | 42 | #define STM32_EXT_EXTI0_IRQ_PRIORITY 6 43 | #define STM32_EXT_EXTI1_IRQ_PRIORITY 6 44 | #define STM32_EXT_EXTI2_IRQ_PRIORITY 6 45 | #define STM32_EXT_EXTI3_IRQ_PRIORITY 6 46 | #define STM32_EXT_EXTI4_IRQ_PRIORITY 6 47 | #define STM32_EXT_EXTI5_9_IRQ_PRIORITY 6 48 | #define STM32_EXT_EXTI10_15_IRQ_PRIORITY 6 49 | 50 | #if defined(EXT_CH0_HANDLER_FUNC) 51 | OSAL_IRQ_HANDLER(Vector58) { // EXTI[0] interrupt handler. 52 | uint32_t pr = EXTI->PR & (1U << 0); 53 | EXTI->PR = pr; 54 | #ifdef EXT_CH0_HANDLER_FUNC 55 | if (pr & (1U << 0)) EXT_CH0_HANDLER_FUNC(0); 56 | #endif 57 | } 58 | #endif 59 | 60 | #if defined(EXT_CH1_HANDLER_FUNC) 61 | OSAL_IRQ_HANDLER(Vector5C) { // EXTI[1] interrupt handler. 62 | uint32_t pr = EXTI->PR & (1U << 1); 63 | EXTI->PR = pr; 64 | #ifdef EXT_CH1_HANDLER_FUNC 65 | if (pr & (1U << 1)) EXT_CH1_HANDLER_FUNC(1); 66 | #endif 67 | } 68 | #endif 69 | 70 | #if defined(EXT_CH2_HANDLER_FUNC) 71 | OSAL_IRQ_HANDLER(Vector60) { // EXTI[2] interrupt handler. 72 | uint32_t pr = EXTI->PR & (1U << 2); 73 | EXTI->PR = pr; 74 | #ifdef EXT_CH2_HANDLER_FUNC 75 | if (pr & (1U << 2)) EXT_CH2_HANDLER_FUNC(2); 76 | #endif 77 | } 78 | #endif 79 | 80 | #if defined(EXT_CH3_HANDLER_FUNC) 81 | OSAL_IRQ_HANDLER(Vector64) { // EXTI[3] interrupt handler. 82 | uint32_t pr = EXTI->PR & (1U << 3); 83 | EXTI->PR = pr; 84 | #ifdef EXT_CH3_HANDLER_FUNC 85 | if (pr & (1U << 3)) EXT_CH3_HANDLER_FUNC(3); 86 | #endif 87 | } 88 | #endif 89 | 90 | #if defined(EXT_CH4_HANDLER_FUNC) 91 | OSAL_IRQ_HANDLER(Vector68) { // EXTI[4] interrupt handler. 92 | uint32_t pr = EXTI->PR & (1U << 4); 93 | EXTI->PR = pr; 94 | #ifdef EXT_CH4_HANDLER_FUNC 95 | if (pr & (1U << 4)) EXT_CH4_HANDLER_FUNC(4); 96 | #endif 97 | } 98 | #endif 99 | 100 | #if defined(EXT_CH5_HANDLER_FUNC) || defined(EXT_CH6_HANDLER_FUNC) || defined(EXT_CH7_HANDLER_FUNC) || \ 101 | defined(EXT_CH8_HANDLER_FUNC) || defined(EXT_CH9_HANDLER_FUNC) 102 | OSAL_IRQ_HANDLER(Vector9C) { // EXTI[5]...EXTI[9] interrupt handler 103 | uint32_t pr = EXTI->PR & ((1U << 5) | (1U << 6) | (1U << 7) | (1U << 8) | (1U << 9)); 104 | EXTI->PR = pr; 105 | #ifdef EXT_CH5_HANDLER_FUNC 106 | if (pr & (1U << 5)) EXT_CH5_HANDLER_FUNC(5); 107 | #endif 108 | #ifdef EXT_CH6_HANDLER_FUNC 109 | if (pr & (1U << 6)) EXT_CH6_HANDLER_FUNC(6); 110 | #endif 111 | #ifdef EXT_CH7_HANDLER_FUNC 112 | if (pr & (1U << 7)) EXT_CH7_HANDLER_FUNC(7); 113 | #endif 114 | #ifdef EXT_CH8_HANDLER_FUNC 115 | if (pr & (1U << 8)) EXT_CH8_HANDLER_FUNC(8); 116 | #endif 117 | #ifdef EXT_CH9_HANDLER_FUNC 118 | if (pr & (1U << 9)) EXT_CH9_HANDLER_FUNC(9); 119 | #endif 120 | } 121 | #endif 122 | 123 | #if defined(EXT_CH10_HANDLER_FUNC) || defined(EXT_CH11_HANDLER_FUNC) || defined(EXT_CH12_HANDLER_FUNC) || \ 124 | defined(EXT_CH13_HANDLER_FUNC) || defined(EXT_CH14_HANDLER_FUNC) || defined(EXTI_CH15_HANDLER_FUNC) 125 | OSAL_IRQ_HANDLER(VectorE0) { // EXTI[4]...EXTI[15] interrupt handler 126 | uint32_t pr = EXTI->PR & ((1U << 10) | (1U << 11) | (1U << 12) | 127 | (1U << 13) | (1U << 14) | (1U << 15)); 128 | EXTI->PR = pr; 129 | #ifdef EXT_CH10_HANDLER_FUNC 130 | if (pr & (1U << 10)) EXT_CH10_HANDLER_FUNC(10); 131 | #endif 132 | #ifdef EXT_CH11_HANDLER_FUNC 133 | if (pr & (1U << 11)) EXT_CH11_HANDLER_FUNC(11); 134 | #endif 135 | #ifdef EXT_CH12_HANDLER_FUNC 136 | if (pr & (1U << 12)) EXT_CH12_HANDLER_FUNC(12); 137 | #endif 138 | #ifdef EXT_CH13_HANDLER_FUNC 139 | if (pr & (1U << 13)) EXT_CH13_HANDLER_FUNC(13); 140 | #endif 141 | #ifdef EXT_CH14_HANDLER_FUNC 142 | if (pr & (1U << 14)) EXT_CH14_HANDLER_FUNC(14); 143 | #endif 144 | #ifdef EXT_CH15_HANDLER_FUNC 145 | if (pr & (1U << 15)) EXT_CH15_HANDLER_FUNC(15); 146 | #endif 147 | } 148 | #endif 149 | 150 | void extStart(void) { 151 | #ifdef EXT_CH0_HANDLER_FUNC 152 | nvicEnableVector(EXTI0_IRQn, STM32_EXT_EXTI0_IRQ_PRIORITY); 153 | #endif 154 | #ifdef EXT_CH1_HANDLER_FUNC 155 | nvicEnableVector(EXTI1_IRQn, STM32_EXT_EXTI1_IRQ_PRIORITY); 156 | #endif 157 | #ifdef EXT_CH2_HANDLER_FUNC 158 | nvicEnableVector(EXTI2_TSC_IRQn, STM32_EXT_EXTI2_IRQ_PRIORITY); 159 | #endif 160 | #ifdef EXT_CH3_HANDLER_FUNC 161 | nvicEnableVector(EXTI3_IRQn, STM32_EXT_EXTI3_IRQ_PRIORITY); 162 | #endif 163 | #ifdef EXT_CH4_HANDLER_FUNC 164 | nvicEnableVector(EXTI4_IRQn, STM32_EXT_EXTI4_IRQ_PRIORITY); 165 | #endif 166 | #if defined(EXT_CH5_HANDLER_FUNC) || defined(EXT_CH6_HANDLER_FUNC) || defined(EXT_CH7_HANDLER_FUNC) || \ 167 | defined(EXT_CH8_HANDLER_FUNC) || defined(EXT_CH9_HANDLER_FUNC) 168 | nvicEnableVector(EXTI9_5_IRQn, STM32_EXT_EXTI5_9_IRQ_PRIORITY); 169 | #endif 170 | #if defined(EXT_CH10_HANDLER_FUNC) || defined(EXT_CH11_HANDLER_FUNC) || defined(EXT_CH12_HANDLER_FUNC) || \ 171 | defined(EXT_CH13_HANDLER_FUNC) || defined(EXT_CH14_HANDLER_FUNC) || defined(EXTI_CH15_HANDLER_FUNC) 172 | nvicEnableVector(EXTI15_10_IRQn, STM32_EXT_EXTI10_15_IRQ_PRIORITY); 173 | #endif 174 | // nvicEnableVector(PVD_IRQn, STM32_EXT_EXTI16_IRQ_PRIORITY); 175 | // nvicEnableVector(RTC_Alarm_IRQn, STM32_EXT_EXTI17_IRQ_PRIORITY); 176 | } 177 | 178 | void ext_channel_enable(uint16_t channel, uint16_t mode) { 179 | // Setting the associated GPIO for external channels. 180 | if (channel < 16) { 181 | uint16_t port = (mode & EXT_MODE_GPIO_MASK) >> EXT_MODE_GPIO_OFF; 182 | uint32_t old_reg = SYSCFG->EXTICR[channel>>2] & ~(0xF << ((channel & 3) * 4)); 183 | SYSCFG->EXTICR[channel>>2] = old_reg | (port<< ((channel & 3) * 4)); 184 | } 185 | uint32_t cmask = (1 << (channel & 0x1F)); 186 | // Programming edge registers. 187 | if (mode & EXT_CH_MODE_RISING_EDGE) EXTI->RTSR|= cmask; 188 | else EXTI->RTSR&=~cmask; 189 | if (mode & EXT_CH_MODE_FALLING_EDGE) EXTI->FTSR|= cmask; 190 | else EXTI->FTSR&=~cmask; 191 | // Programming interrupt and event registers. 192 | EXTI->IMR|= cmask; 193 | EXTI->EMR&=~cmask; 194 | } 195 | #endif 196 | -------------------------------------------------------------------------------- /NANOVNA_STM32_F303/flash.c: -------------------------------------------------------------------------------- 1 | static inline void flash_wait_for_last_operation(void) 2 | { 3 | while (FLASH->SR == FLASH_SR_BSY) { 4 | //WWDG->CR = WWDG_CR_T; 5 | } 6 | // return FLASH->SR; 7 | } 8 | 9 | static void flash_erase_page0(uint32_t page_address) 10 | { 11 | flash_wait_for_last_operation(); 12 | FLASH->CR|= FLASH_CR_PER; 13 | FLASH->AR = page_address; 14 | FLASH->CR|= FLASH_CR_STRT; 15 | flash_wait_for_last_operation(); 16 | FLASH->CR&=~FLASH_CR_PER; 17 | } 18 | 19 | static inline void flash_unlock(void) 20 | { 21 | // unlock sequence 22 | FLASH->KEYR = FLASH_KEY1; 23 | FLASH->KEYR = FLASH_KEY2; 24 | } 25 | 26 | void flash_erase_pages(uint32_t page_address, uint32_t size) 27 | { 28 | // Unlock for erase 29 | flash_unlock(); 30 | // erase flash pages 31 | size+=page_address; 32 | for (; page_address < size; page_address+= FLASH_PAGESIZE) 33 | flash_erase_page0(page_address); 34 | } 35 | 36 | void flash_program_half_word_buffer(uint16_t* dst, uint16_t *data, uint16_t size) 37 | { 38 | uint32_t i; 39 | // unlock, and erase flash pages for buffer (aligned to FLASH_PAGESIZE) 40 | flash_erase_pages((uint32_t)dst, size); 41 | // Save buffer 42 | __IO uint16_t* p = dst; 43 | for (i = 0; i < size/sizeof(uint16_t); i++){ 44 | flash_wait_for_last_operation(); 45 | FLASH->CR|= FLASH_CR_PG; 46 | p[i] = data[i]; 47 | flash_wait_for_last_operation(); 48 | FLASH->CR&=~FLASH_CR_PG; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /NANOVNA_STM32_F303/gpio_v2.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2020, Dmitry (DiSlord) dislordlive@gmail.com 3 | * All rights reserved. 4 | * 5 | * This is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 3, or (at your option) 8 | * any later version. 9 | * 10 | * The software is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with GNU Radio; see the file COPYING. If not, write to 17 | * the Free Software Foundation, Inc., 51 Franklin Street, 18 | * Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | typedef struct { 22 | uint32_t moder; 23 | uint32_t otyper; 24 | uint32_t ospeedr; 25 | uint32_t pupdr; 26 | uint32_t odr; 27 | uint32_t afrl; 28 | uint32_t afrh; 29 | } pal_conf_t; 30 | 31 | const pal_conf_t pal_config[] = { 32 | #if STM32_HAS_GPIOA 33 | {VAL_GPIOA_MODER, VAL_GPIOA_OTYPER, VAL_GPIOA_OSPEEDR, VAL_GPIOA_PUPDR, VAL_GPIOA_ODR, VAL_GPIOA_AFRL, VAL_GPIOA_AFRH}, 34 | #endif 35 | #if STM32_HAS_GPIOB 36 | {VAL_GPIOB_MODER, VAL_GPIOB_OTYPER, VAL_GPIOB_OSPEEDR, VAL_GPIOB_PUPDR, VAL_GPIOB_ODR, VAL_GPIOB_AFRL, VAL_GPIOB_AFRH}, 37 | #endif 38 | #if STM32_HAS_GPIOC 39 | {VAL_GPIOC_MODER, VAL_GPIOC_OTYPER, VAL_GPIOC_OSPEEDR, VAL_GPIOC_PUPDR, VAL_GPIOC_ODR, VAL_GPIOC_AFRL, VAL_GPIOC_AFRH}, 40 | #endif 41 | /* 42 | #if STM32_HAS_GPIOD 43 | {VAL_GPIOD_MODER, VAL_GPIOD_OTYPER, VAL_GPIOD_OSPEEDR, VAL_GPIOD_PUPDR, VAL_GPIOD_ODR, VAL_GPIOD_AFRL, VAL_GPIOD_AFRH}, 44 | #endif 45 | #if STM32_HAS_GPIOE 46 | {VAL_GPIOE_MODER, VAL_GPIOE_OTYPER, VAL_GPIOE_OSPEEDR, VAL_GPIOE_PUPDR, VAL_GPIOE_ODR, VAL_GPIOE_AFRL, VAL_GPIOE_AFRH}, 47 | #endif 48 | #if STM32_HAS_GPIOF 49 | {VAL_GPIOF_MODER, VAL_GPIOF_OTYPER, VAL_GPIOF_OSPEEDR, VAL_GPIOF_PUPDR, VAL_GPIOF_ODR, VAL_GPIOF_AFRL, VAL_GPIOF_AFRH}, 50 | #endif 51 | #if STM32_HAS_GPIOG 52 | {VAL_GPIOG_MODER, VAL_GPIOG_OTYPER, VAL_GPIOG_OSPEEDR, VAL_GPIOG_PUPDR, VAL_GPIOG_ODR, VAL_GPIOG_AFRL, VAL_GPIOG_AFRH}, 53 | #endif 54 | #if STM32_HAS_GPIOH 55 | {VAL_GPIOH_MODER, VAL_GPIOH_OTYPER, VAL_GPIOH_OSPEEDR, VAL_GPIOH_PUPDR, VAL_GPIOH_ODR, VAL_GPIOH_AFRL, VAL_GPIOH_AFRH}, 56 | #endif 57 | #if STM32_HAS_GPIOI 58 | {VAL_GPIOI_MODER, VAL_GPIOI_OTYPER, VAL_GPIOI_OSPEEDR, VAL_GPIOI_PUPDR, VAL_GPIOI_ODR, VAL_GPIOI_AFRL, VAL_GPIOI_AFRH} 59 | #endif 60 | */ 61 | }; 62 | 63 | static void initgpio(GPIO_TypeDef *port, const pal_conf_t *config) { 64 | port->OTYPER = config->otyper; 65 | port->OSPEEDR = config->ospeedr; 66 | port->PUPDR = config->pupdr; 67 | port->ODR = config->odr; 68 | port->AFR[0] = config->afrl; 69 | port->AFR[1] = config->afrh; 70 | port->MODER = config->moder; 71 | } 72 | 73 | void initPal(void) { 74 | rccEnableAHB(STM32_GPIO_EN_MASK, TRUE); 75 | initgpio(GPIOA, &pal_config[0]); 76 | initgpio(GPIOB, &pal_config[1]); 77 | initgpio(GPIOC, &pal_config[2]); 78 | // initgpio(GPIOD, &pal_config[3]); 79 | } 80 | 81 | void palSetPadGroupMode(GPIO_TypeDef *port, uint32_t mask, uint32_t mode) { 82 | uint32_t moder = (mode & PAL_STM32_MODE_MASK) >> 0; 83 | uint32_t otyper = (mode & PAL_STM32_OTYPE_MASK) >> 2; 84 | uint32_t ospeedr = (mode & PAL_STM32_OSPEED_MASK) >> 3; 85 | uint32_t pupdr = (mode & PAL_STM32_PUPDR_MASK) >> 5; 86 | uint32_t altr = (mode & PAL_STM32_ALTERNATE_MASK) >> 7; 87 | uint32_t bit = 0; 88 | while (true) { 89 | if ((mask & 1) != 0) { 90 | uint32_t altrmask, m1, m2, m4; 91 | 92 | altrmask = altr << ((bit & 7) * 4); 93 | m1 = 1 << bit; 94 | m2 = 3 << (bit * 2); 95 | m4 = 15 << ((bit & 7) * 4); 96 | port->OTYPER = (port->OTYPER & ~m1) | otyper; 97 | port->OSPEEDR = (port->OSPEEDR & ~m2) | ospeedr; 98 | port->PUPDR = (port->PUPDR & ~m2) | pupdr; 99 | if (moder == PAL_STM32_MODE_ALTERNATE) { 100 | // If going in alternate mode then the alternate number is set before switching mode in order to avoid glitches. 101 | port->AFR[(bit>>3)&1] = (port->AFR[(bit>>3)&1] & ~m4) | altrmask; 102 | port->MODER = (port->MODER & ~m2) | moder; 103 | } 104 | else { 105 | // If going into a non-alternate mode then the mode is switched before setting the alternate mode in order to avoid glitches. 106 | port->MODER = (port->MODER & ~m2) | moder; 107 | port->AFR[(bit>>3)&1] = (port->AFR[(bit>>3)&1] & ~m4) | altrmask; 108 | } 109 | } 110 | mask >>= 1; 111 | if (!mask) 112 | return; 113 | otyper <<= 1; 114 | ospeedr <<= 2; 115 | pupdr <<= 2; 116 | moder <<= 2; 117 | bit++; 118 | } 119 | } 120 | 121 | void palSetPadMode(GPIO_TypeDef *port, int bit, uint32_t mode) { 122 | uint32_t otyper = ((mode & PAL_STM32_OTYPE_MASK) >> 2)<<(bit*1); 123 | uint32_t ospeedr = ((mode & PAL_STM32_OSPEED_MASK) >> 3)<<(bit*2); 124 | uint32_t pupdr = ((mode & PAL_STM32_PUPDR_MASK) >> 5)<<(bit*2); 125 | uint32_t moder = ((mode & PAL_STM32_MODE_MASK) >> 0)<<(bit*2); 126 | uint32_t m1 = 0x1 << (bit * 1); 127 | uint32_t m2 = 0x3 << (bit * 2); 128 | 129 | port->OTYPER = (port->OTYPER & ~m1) | otyper; 130 | port->OSPEEDR = (port->OSPEEDR & ~m2) | ospeedr; 131 | port->PUPDR = (port->PUPDR & ~m2) | pupdr; 132 | #if 0 133 | port->MODER = (port->MODER & ~m2) | moder; 134 | #else 135 | uint32_t altrmask = ((mode & PAL_STM32_ALTERNATE_MASK) >> 7) << ((bit&7) * 4); 136 | uint32_t m4 = 0xF << ((bit&7) * 4); 137 | if (moder == PAL_STM32_MODE_ALTERNATE) { 138 | // If going in alternate mode then the alternate number is set before switching mode in order to avoid glitches. 139 | port->AFR[(bit>>3)&1] = (port->AFR[(bit>>3)&1] & ~m4) | altrmask; 140 | port->MODER = (port->MODER & ~m2) | moder; 141 | } 142 | else { 143 | // If going into a non-alternate mode then the mode is switched before setting the alternate mode in order to avoid glitches. 144 | port->MODER = (port->MODER & ~m2) | moder; 145 | port->AFR[(bit>>3)&1] = (port->AFR[(bit>>3)&1] & ~m4) | altrmask; 146 | } 147 | #endif 148 | } 149 | -------------------------------------------------------------------------------- /NANOVNA_STM32_F303/i2c_v2.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2020, Dmitry (DiSlord) dislordlive@gmail.com 3 | * All rights reserved. 4 | * 5 | * This is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 3, or (at your option) 8 | * any later version. 9 | * 10 | * The software is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with GNU Radio; see the file COPYING. If not, write to 17 | * the Free Software Foundation, Inc., 51 Franklin Street, 18 | * Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | #define VNA_I2C I2C1 22 | #define I2C_CR2_SADD_7BIT_SHIFT 1 23 | #define I2C_CR2_NBYTES_SHIFT 16 24 | 25 | void i2c_set_timings(uint32_t timings) { 26 | VNA_I2C->CR1&=~I2C_CR1_PE; 27 | VNA_I2C->TIMINGR = timings; 28 | VNA_I2C->CR1|= I2C_CR1_PE; 29 | } 30 | 31 | void i2c_start(void) { 32 | rccEnableI2C1(FALSE); 33 | i2c_set_timings(STM32_I2C_INIT_T); 34 | } 35 | 36 | // I2C TX only (compact version) 37 | bool i2c_transfer(uint8_t addr, const uint8_t *w, size_t wn) 38 | { 39 | //if (wn == 0) return false; 40 | while(VNA_I2C->ISR & I2C_ISR_BUSY); // wait last transaction 41 | VNA_I2C->CR1|= I2C_CR1_PE; 42 | VNA_I2C->CR2 = (addr << I2C_CR2_SADD_7BIT_SHIFT) | (wn << I2C_CR2_NBYTES_SHIFT) | I2C_CR2_AUTOEND | I2C_CR2_START; 43 | do { 44 | while ((VNA_I2C->ISR & (I2C_ISR_TXE|I2C_ISR_NACKF)) == 0); 45 | if (VNA_I2C->ISR & I2C_ISR_NACKF) {VNA_I2C->CR1 = 0; return false;} // NO ASK error 46 | VNA_I2C->TXDR = *w++; 47 | } while (--wn); 48 | return true; 49 | } 50 | 51 | // I2C TX and RX variant 52 | bool i2c_receive(uint8_t addr, const uint8_t *w, size_t wn, uint8_t *r, size_t rn) 53 | { 54 | while(VNA_I2C->ISR & I2C_ISR_BUSY); // wait last transaction 55 | VNA_I2C->CR1|= I2C_CR1_PE; 56 | if (wn) { 57 | VNA_I2C->CR2 = (addr << I2C_CR2_SADD_7BIT_SHIFT) | (wn << I2C_CR2_NBYTES_SHIFT); 58 | if (rn == 0) VNA_I2C->CR2|= I2C_CR2_AUTOEND; 59 | VNA_I2C->CR2|= I2C_CR2_START; 60 | do { 61 | while ((VNA_I2C->ISR & (I2C_ISR_TXE|I2C_ISR_NACKF)) == 0); 62 | if (VNA_I2C->ISR & I2C_ISR_NACKF) {VNA_I2C->CR1 = 0; return false;} // NO ASK error 63 | VNA_I2C->TXDR = *w++; 64 | } while (--wn); 65 | } 66 | 67 | if (rn) { 68 | while ((VNA_I2C->ISR & I2C_ISR_TC) == 0); // wait transfer completion if need 69 | VNA_I2C->CR2 = (addr << I2C_CR2_SADD_7BIT_SHIFT) | (rn << I2C_CR2_NBYTES_SHIFT) | I2C_CR2_RD_WRN | I2C_CR2_START | I2C_CR2_AUTOEND; // start transfer 70 | //VNA_I2C->CR2|= I2C_CR2_AUTOEND; // important to do it afterwards to do a proper repeated start! 71 | do { 72 | while((VNA_I2C->ISR & (I2C_ISR_RXNE|I2C_ISR_NACKF)) == 0); 73 | if (VNA_I2C->ISR & I2C_ISR_NACKF) {VNA_I2C->CR1 = 0; return false;} // NO ASK error 74 | *r++ = VNA_I2C->RXDR; 75 | } while (--rn); 76 | } 77 | return true; 78 | } 79 | 80 | -------------------------------------------------------------------------------- /NANOVNA_STM32_F303/i2s.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2020, Dmitry (DiSlord) dislordlive@gmail.com 3 | * Based on TAKAHASHI Tomohiro (TTRFTECH) edy555@gmail.com 4 | * All rights reserved. 5 | * 6 | * This is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3, or (at your option) 9 | * any later version. 10 | * 11 | * The software is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with GNU Radio; see the file COPYING. If not, write to 18 | * the Free Software Foundation, Inc., 51 Franklin Street, 19 | * Boston, MA 02110-1301, USA. 20 | */ 21 | 22 | // F303 SPI2 RX DMA1 interrupt 23 | #define STM32_SPI2_RX_DMA_IRQ_NUMBER DMA1_Channel4_IRQn 24 | 25 | #define SPI_I2S_FHILLIPS_MODE ( 0) 26 | #define SPI_I2S_MSB_MODE (SPI_I2SCFGR_I2SSTD_0) 27 | #define SPI_I2S_LSB_MODE (SPI_I2SCFGR_I2SSTD_1) 28 | #define SPI_I2S_PCM_MODE (SPI_I2SCFGR_I2SSTD_0 | SPI_I2SCFGR_I2SSTD_1) 29 | 30 | /* 31 | * Run I2S bus in Circular mode, fill buffer, and handle read in I2S DMA RX interrupt 32 | */ 33 | void initI2S(void *buffer, uint16_t count) { 34 | const uint16_t I2S_DMA_RX_ccr = 0 35 | | STM32_DMA_CR_PL(3) // 3 - Very High 36 | | STM32_DMA_CR_PSIZE_HWORD // 16 bit 37 | | STM32_DMA_CR_MSIZE_HWORD // 16 bit 38 | | STM32_DMA_CR_DIR_P2M // Read from peripheral 39 | | STM32_DMA_CR_MINC // Memory increment mode 40 | | STM32_DMA_CR_CIRC // Circular mode 41 | | STM32_DMA_CR_HTIE // Half transfer complete interrupt enable 42 | | STM32_DMA_CR_TCIE // Full transfer complete interrupt enable 43 | // | STM32_DMA_CR_TEIE // Transfer error interrupt enable 44 | ; 45 | // I2S RX DMA setup. 46 | nvicEnableVector(STM32_SPI2_RX_DMA_IRQ_NUMBER, STM32_I2S_SPI2_IRQ_PRIORITY); 47 | dmaChannelSetTransactionSize(I2S_DMA_RX, count); // number of data register 48 | dmaChannelSetPeripheral(I2S_DMA_RX, &SPI2->DR); // peripheral address register 49 | dmaChannelSetMemory(I2S_DMA_RX, buffer); // memory address register 50 | dmaChannelSetMode(I2S_DMA_RX, I2S_DMA_RX_ccr | STM32_DMA_CR_EN); // configuration register 51 | 52 | // Starting I2S 53 | rccEnableSPI2(FALSE); // Enabling I2S unit clock. 54 | SPI2->CR1 = 0; // CRs settings 55 | SPI2->CR2 = SPI_CR2_RXDMAEN; // Enable RX DMA 56 | SPI2->I2SPR = 0; // I2S (re)configuration. 57 | SPI2->I2SCFGR = 0 58 | | SPI_I2SCFGR_I2SCFG_0 // 01: Slave - receive 59 | // | SPI_I2SCFGR_I2SCFG_1 // 60 | | SPI_I2SCFGR_I2SMOD // I2S mode is selected 61 | | SPI_I2S_PCM_MODE // I2S PCM standard (aic3204 use DSP mode, short sync) 62 | | SPI_I2SCFGR_PCMSYNC // Short sync 63 | | SPI_I2SCFGR_I2SE // I2S enable 64 | ; 65 | } 66 | -------------------------------------------------------------------------------- /NANOVNA_STM32_F303/interface/stlink.cfg: -------------------------------------------------------------------------------- 1 | # 2 | # STMicroelectronics ST-LINK/V1, ST-LINK/V2, ST-LINK/V2-1, STLINK-V3 in-circuit 3 | # debugger/programmer 4 | # 5 | 6 | interface hla 7 | hla_layout stlink 8 | hla_device_desc "ST-LINK" 9 | hla_vid_pid 0x0483 0x3744 0x0483 0x3748 0x0483 0x374b 0x0483 0x374d 0x0483 0x374e 0x0483 0x374f 0x0483 0x3752 0x0483 0x3753 10 | 11 | # Optionally specify the serial number of ST-LINK/V2 usb device. ST-LINK/V2 12 | # devices seem to have serial numbers with unreadable characters. ST-LINK/V2 13 | # firmware version >= V2.J21.S4 recommended to avoid issues with adapter serial 14 | # number reset issues. 15 | # eg. 16 | #hla_serial "\xaa\xbc\x6e\x06\x50\x75\xff\x55\x17\x42\x19\x3f" 17 | 18 | -------------------------------------------------------------------------------- /NANOVNA_STM32_F303/mcuconf.h: -------------------------------------------------------------------------------- 1 | /* 2 | ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #ifndef MCUCONF_H 18 | #define MCUCONF_H 19 | 20 | /* 21 | * STM32F3xx drivers configuration. 22 | * The following settings override the default settings present in 23 | * the various device driver implementation headers. 24 | * Note that the settings for each driver only have effect if the whole 25 | * driver is enabled in halconf.h. 26 | * 27 | * IRQ priorities: 28 | * 15...0 Lowest...Highest. 29 | * 30 | * DMA priorities: 31 | * 0...3 Lowest...Highest. 32 | */ 33 | 34 | #define STM32F3xx_MCUCONF 35 | 36 | /* 37 | * HAL driver system settings. 38 | */ 39 | #define STM32_NO_INIT FALSE 40 | #define STM32_PVD_ENABLE FALSE 41 | #define STM32_PLS STM32_PLS_LEV0 42 | #define STM32_HSI_ENABLED FALSE 43 | #define STM32_HSE_ENABLED TRUE 44 | #define STM32_SW STM32_SW_PLL 45 | #define STM32_PLLSRC STM32_PLLSRC_HSE 46 | #define STM32_PREDIV_VALUE 1 47 | #define STM32_PLLMUL_VALUE 9 48 | #define STM32_HPRE STM32_HPRE_DIV1 49 | #define STM32_PPRE1 STM32_PPRE1_DIV2 50 | // Set SPI1 more faster use PPRE2 max speed 51 | #define STM32_PPRE2 STM32_PPRE2_DIV1 52 | #define STM32_MCOSEL STM32_MCOSEL_PLLDIV2 53 | #define STM32_ADC12PRES STM32_ADC12PRES_DIV2 54 | //#define STM32_ADC34PRES STM32_ADC34PRES_DIV1 55 | #define STM32_USART1SW STM32_USART1SW_PCLK 56 | //#define STM32_USART2SW STM32_USART2SW_PCLK 57 | //#define STM32_USART3SW STM32_USART3SW_PCLK 58 | #define STM32_I2C1SW STM32_I2C1SW_SYSCLK 59 | //#define STM32_I2C2SW STM32_I2C2SW_SYSCLK 60 | #define STM32_TIM1SW STM32_TIM1SW_PCLK2 61 | #define STM32_TIM8SW STM32_TIM8SW_PCLK2 62 | #define STM32_USB_CLOCK_REQUIRED TRUE 63 | #define STM32_USBPRE STM32_USBPRE_DIV1P5 64 | 65 | // Define STM32_I2C1_CLOCK as 72MHz (STM32_I2C1SW is STM32_I2C1SW_SYSCLK) 66 | #define STM32_I2C1_CLOCK 72 67 | // Core clock in MHz 68 | #define STM32_CORE_CLOCK 72 69 | 70 | /* 71 | * RTC driver system settings for stm32f303 72 | */ 73 | #define RTC_PRER(a, s) ((((a) - 1) << 16) | ((s) - 1)) 74 | 75 | // LSE for 32768 quartz 76 | #define STM32_RTC_LSE_PRER RTC_PRER(128, 256) 77 | // LSI 40k 78 | #define STM32_RTC_LSI_PRER RTC_PRER( 40, 1000) 79 | 80 | // Use auto select source (LSE or LSI) 81 | //!!!! Need disable hal_lld_backup_domain_init() in hal_lld.c for current CPU!!!! 82 | // And if need correct rtc_init part 83 | #ifdef VNA_AUTO_SELECT_RTC_SOURCE 84 | #define STM32_LSEDRV (3 << 3) 85 | #define STM32_RTCSEL STM32_RTCSEL_NOCLOCK 86 | #define STM32_LSI_ENABLED FALSE 87 | #define STM32_LSE_ENABLED FALSE 88 | // Disable this function call in ChibiOS, backup domain init on auto select RTC source 89 | #define STM32_NO_BACKUP_DOMAIN_INIT 90 | #define hal_lld_backup_domain_init 91 | #else 92 | #ifndef VNA_USE_LSE 93 | // Use 40kHz LSI 94 | #define STM32_LSE_ENABLED FALSE 95 | #define STM32_LSI_ENABLED TRUE 96 | #define STM32_RTCSEL STM32_RTCSEL_LSI 97 | #else 98 | // Use 32768Hz LSE 99 | #define STM32_LSE_ENABLED TRUE 100 | #define STM32_LSI_ENABLED FALSE 101 | #define STM32_RTCSEL STM32_RTCSEL_LSE 102 | #define STM32_LSEDRV (3 << 3) 103 | #endif 104 | #endif 105 | 106 | /* 107 | * ADC driver system settings. 108 | */ 109 | #define STM32_ADC_USE_ADC1 TRUE 110 | #define STM32_ADC_USE_ADC2 TRUE 111 | #define STM32_ADC_USE_ADC3 FALSE 112 | #define STM32_ADC_ADC1_DMA_STREAM STM32_DMA_STREAM_ID(1, 1) 113 | #define STM32_ADC_ADC2_DMA_STREAM STM32_DMA_STREAM_ID(2, 1) 114 | //#define STM32_ADC_ADC3_DMA_STREAM STM32_DMA_STREAM_ID(2, 5) 115 | //#define STM32_ADC_ADC4_DMA_STREAM STM32_DMA_STREAM_ID(2, 2) 116 | #define STM32_ADC_ADC12_DMA_PRIORITY 2 117 | //#define STM32_ADC_ADC34_DMA_PRIORITY 2 118 | #define STM32_ADC_ADC12_IRQ_PRIORITY 2 119 | //#define STM32_ADC_ADC34_IRQ_PRIORITY 5 120 | #define STM32_ADC_ADC12_DMA_IRQ_PRIORITY 2 121 | //#define STM32_ADC_ADC34_DMA_IRQ_PRIORITY 5 122 | //#define STM32_ADC_ADC12_CLOCK_MODE ADC_CCR_CKMODE_ADCCK 123 | //#define STM32_ADC_ADC12_CLOCK_MODE ADC_CCR_CKMODE_AHB_DIV2 124 | #define STM32_ADC_ADC12_CLOCK_MODE ADC_CCR_CKMODE_AHB_DIV1 125 | //#define STM32_ADC_ADC34_CLOCK_MODE ADC_CCR_CKMODE_AHB_DIV1 126 | #define STM32_ADC_DUAL_MODE FALSE 127 | 128 | /* 129 | * CAN driver system settings. 130 | */ 131 | #define STM32_CAN_USE_CAN1 FALSE 132 | #define STM32_CAN_CAN1_IRQ_PRIORITY 11 133 | 134 | /* 135 | * DAC driver system settings. 136 | */ 137 | #define STM32_DAC_DUAL_MODE FALSE 138 | #define STM32_DAC_USE_DAC1_CH1 TRUE 139 | #define STM32_DAC_USE_DAC1_CH2 TRUE 140 | #define STM32_DAC_DAC1_CH1_IRQ_PRIORITY 10 141 | #define STM32_DAC_DAC1_CH2_IRQ_PRIORITY 10 142 | #define STM32_DAC_DAC1_CH1_DMA_PRIORITY 2 143 | #define STM32_DAC_DAC1_CH2_DMA_PRIORITY 2 144 | 145 | /* 146 | * EXT driver system settings. 147 | */ 148 | #define STM32_EXT_EXTI0_1_IRQ_PRIORITY 3 149 | #define STM32_EXT_EXTI2_3_IRQ_PRIORITY 3 150 | #define STM32_EXT_EXTI4_15_IRQ_PRIORITY 3 151 | #define STM32_EXT_EXTI16_IRQ_PRIORITY 3 152 | #define STM32_EXT_EXTI17_IRQ_PRIORITY 3 153 | #define STM32_EXT_EXTI21_22_IRQ_PRIORITY 3 154 | 155 | #define STM32_DISABLE_EXTI2122_HANDLER TRUE 156 | 157 | /* 158 | * GPT driver system settings. 159 | */ 160 | #define STM32_GPT_USE_TIM1 FALSE 161 | #define STM32_GPT_USE_TIM2 FALSE 162 | #define STM32_GPT_USE_TIM3 TRUE 163 | #define STM32_GPT_USE_TIM4 FALSE 164 | #define STM32_GPT_TIM1_IRQ_PRIORITY 2 165 | #define STM32_GPT_TIM2_IRQ_PRIORITY 2 166 | #define STM32_GPT_TIM3_IRQ_PRIORITY 2 167 | #define STM32_GPT_TIM4_IRQ_PRIORITY 2 168 | // disable interrupt handlers 169 | #define STM32_TIM1_SUPPRESS_ISR 170 | #define STM32_TIM2_SUPPRESS_ISR 171 | #define STM32_TIM3_SUPPRESS_ISR 172 | #define STM32_TIM4_SUPPRESS_ISR 173 | 174 | /* 175 | * I2C driver system settings. 176 | */ 177 | #define STM32_I2C_USE_I2C1 TRUE 178 | #define STM32_I2C_USE_I2C2 FALSE 179 | #define STM32_I2C_BUSY_TIMEOUT 50 180 | #define STM32_I2C_I2C1_IRQ_PRIORITY 3 181 | #define STM32_I2C_I2C2_IRQ_PRIORITY 3 182 | #define STM32_I2C_USE_DMA FALSE 183 | #define STM32_I2C_I2C1_DMA_PRIORITY 1 184 | #define STM32_I2C_I2C2_DMA_PRIORITY 1 185 | #define STM32_I2C_DMA_ERROR_HOOK(i2cp) osalSysHalt("DMA failure") 186 | 187 | /* 188 | * I2S driver system settings. 189 | */ 190 | #define STM32_I2S_USE_SPI1 FALSE 191 | #define STM32_I2S_USE_SPI2 TRUE 192 | #define STM32_I2S_SPI1_MODE (STM32_I2S_MODE_MASTER | \ 193 | STM32_I2S_MODE_RX) 194 | #define STM32_I2S_SPI2_MODE (STM32_I2S_MODE_SLAVE | \ 195 | STM32_I2S_MODE_RX ) 196 | #define STM32_I2S_SPI1_IRQ_PRIORITY 3 197 | #define STM32_I2S_SPI2_IRQ_PRIORITY 3 198 | #define STM32_I2S_SPI1_DMA_PRIORITY 1 199 | #define STM32_I2S_SPI2_DMA_PRIORITY 1 200 | #define STM32_I2S_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2) 201 | #define STM32_I2S_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3) 202 | #define STM32_I2S_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4) 203 | #define STM32_I2S_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5) 204 | #define STM32_I2S_DMA_ERROR_HOOK(i2sp) osalSysHalt("DMA failure") 205 | 206 | /* 207 | * ICU driver system settings. 208 | */ 209 | #define STM32_ICU_USE_TIM1 FALSE 210 | #define STM32_ICU_USE_TIM2 FALSE 211 | #define STM32_ICU_USE_TIM3 FALSE 212 | #define STM32_ICU_TIM1_IRQ_PRIORITY 3 213 | #define STM32_ICU_TIM2_IRQ_PRIORITY 3 214 | #define STM32_ICU_TIM3_IRQ_PRIORITY 3 215 | 216 | /* 217 | * PWM driver system settings. 218 | */ 219 | #define STM32_PWM_USE_ADVANCED FALSE 220 | #define STM32_PWM_USE_TIM1 FALSE 221 | #define STM32_PWM_USE_TIM2 FALSE 222 | #define STM32_PWM_USE_TIM3 FALSE 223 | #define STM32_PWM_TIM1_IRQ_PRIORITY 3 224 | #define STM32_PWM_TIM2_IRQ_PRIORITY 3 225 | #define STM32_PWM_TIM3_IRQ_PRIORITY 3 226 | 227 | /* 228 | * SERIAL driver system settings. 229 | */ 230 | #define STM32_SERIAL_USE_USART1 TRUE 231 | #define STM32_SERIAL_USE_USART2 FALSE 232 | #define STM32_SERIAL_USART1_PRIORITY 2 233 | #define STM32_SERIAL_USART2_PRIORITY 3 234 | 235 | /* 236 | * SPI driver system settings. 237 | */ 238 | #define STM32_SPI_USE_SPI1 FALSE 239 | #define STM32_SPI_USE_SPI2 FALSE 240 | #define STM32_SPI_USE_SPI3 FALSE 241 | #define STM32_SPI_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2) 242 | #define STM32_SPI_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3) 243 | #define STM32_SPI_SPI1_DMA_PRIORITY 1 244 | #define STM32_SPI_SPI2_DMA_PRIORITY 1 245 | #define STM32_SPI_SPI1_IRQ_PRIORITY 3 246 | #define STM32_SPI_SPI2_IRQ_PRIORITY 3 247 | #define STM32_SPI_DMA_ERROR_HOOK(spip) osalSysHalt("DMA failure") 248 | 249 | /* 250 | * ST driver system settings. 251 | */ 252 | #define STM32_ST_IRQ_PRIORITY 2 253 | #define STM32_ST_USE_TIMER 2 254 | 255 | /* 256 | * UART driver system settings. 257 | */ 258 | #define STM32_UART_USE_USART1 FALSE 259 | #define STM32_UART_USE_USART2 FALSE 260 | #define STM32_UART_USART1_IRQ_PRIORITY 3 261 | #define STM32_UART_USART2_IRQ_PRIORITY 3 262 | #define STM32_UART_USART1_DMA_PRIORITY 0 263 | #define STM32_UART_USART2_DMA_PRIORITY 0 264 | #define STM32_UART_USART3_DMA_PRIORITY 0 265 | #define STM32_UART_DMA_ERROR_HOOK(uartp) osalSysHalt("DMA failure") 266 | 267 | /* 268 | * USB driver system settings. 269 | */ 270 | #define STM32_USB_USE_USB1 TRUE 271 | #define STM32_USB_LOW_POWER_ON_SUSPEND FALSE 272 | #define STM32_USB_USB1_LP_IRQ_PRIORITY 3 273 | 274 | /* 275 | * WDG driver system settings. 276 | */ 277 | #define STM32_WDG_USE_IWDG FALSE 278 | 279 | #endif /* MCUCONF_H */ 280 | -------------------------------------------------------------------------------- /NANOVNA_STM32_F303/rtc_v2.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2020, Dmitry (DiSlord) dislordlive@gmail.com 3 | * All rights reserved. 4 | * 5 | * This is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 3, or (at your option) 8 | * any later version. 9 | * 10 | * The software is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with GNU Radio; see the file COPYING. If not, write to 17 | * the Free Software Foundation, Inc., 51 Franklin Street, 18 | * Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | // Get RTC time as binary structure in 0x00HHMMSS 22 | uint32_t rtc_get_tr_bin(void){ 23 | uint32_t tr = RTC->TR; 24 | uint32_t v = (tr&0x0F0F0F) + ((tr&0x707070)>>1) + ((tr&0x707070)>>3); 25 | return v; 26 | } 27 | 28 | // Get RTC time as binary structure in 0x00YYMMDD 29 | uint32_t rtc_get_dr_bin(void){ 30 | uint32_t dr = RTC->DR; 31 | uint32_t v = (dr&0x000F0F0F) + ((dr&0x00F01030)>>1) + ((dr&0x00F01030)>>3); 32 | return v;// | ((dr&0xE000)<<15); // day of week at end 33 | } 34 | 35 | uint32_t rtc_get_FAT(void) { 36 | uint32_t fattime; 37 | uint32_t tr = rtc_get_tr_bin(); 38 | uint32_t dr = rtc_get_dr_bin(); 39 | fattime = ((tr>> 0)&0xFF) >> 1U; // Seconds / 2 40 | fattime |= ((tr>> 8)&0xFF) << 5U; // Minutes 41 | fattime |= ((tr>>16)&0xFF) << 11U; // Hour 42 | fattime |= ((dr>> 0)&0xFF) << 16U; // Day 43 | fattime |= ((dr>> 8)&0xFF) << 21U; // Month 44 | fattime |= (((dr>>16)&0xFF) + RTC_START_YEAR - 1980) << 25U; // Local year begin from 2000, fat from 1980 45 | return fattime; 46 | } 47 | 48 | // Finish of configuration procedure. 49 | static void rtc_exit_init(void) { 50 | RTC->ISR &= ~RTC_ISR_INIT; 51 | } 52 | 53 | // Beginning of configuration procedure. 54 | static bool rtc_enter_init(void){ 55 | RTC->ISR |= RTC_ISR_INIT; 56 | uint32_t count = 4*65536; 57 | while (--count) 58 | if (RTC->ISR & RTC_ISR_INITF) 59 | return true; 60 | return false; 61 | } 62 | 63 | void rtc_set_time(uint32_t dr, uint32_t tr) { 64 | if (rtc_enter_init()){ 65 | RTC->TR = tr; // Write TR register 66 | RTC->DR = dr; // Write TD register 67 | } 68 | rtc_exit_init(); 69 | } 70 | 71 | #ifdef VNA_AUTO_SELECT_RTC_SOURCE 72 | 73 | // Enable LSE bypass if need 74 | #if defined(STM32_LSE_BYPASS) 75 | #define STM32_LSE_BYPASS RCC_BDCR_LSEBYP 76 | #else 77 | #define STM32_LSE_BYPASS 0 78 | #endif 79 | 80 | // Startup LSE or if not work, LSI generator 81 | static void rtc_start_source(void){ 82 | // LSE already work (enabled and ready) 83 | if ((RCC->BDCR & (RCC_BDCR_LSEON|RCC_BDCR_LSERDY|STM32_LSE_BYPASS)) == (RCC_BDCR_LSEON|RCC_BDCR_LSERDY|STM32_LSE_BYPASS)) 84 | return; 85 | 86 | // If LSE not enabled, try startup 87 | RCC->BDCR |= STM32_LSEDRV | STM32_LSE_BYPASS | RCC_BDCR_LSEON; 88 | // Waits until LSE is stable (need ~150ms for startup). 89 | chThdSleepMilliseconds(200); 90 | if (RCC->BDCR & RCC_BDCR_LSERDY) return; 91 | 92 | // Startup LSI if not allow start LSE 93 | RCC->CSR |= RCC_CSR_LSION; 94 | while ((RCC->CSR & RCC_CSR_LSIRDY) == 0); 95 | } 96 | 97 | static void resetBCDR(uint32_t rtc_drv){ 98 | // Backup domain reset, for change source. 99 | RCC->BDCR = RCC_BDCR_BDRST; 100 | RCC->BDCR = 0; 101 | // Startup again source generator 102 | rtc_start_source(); 103 | // Select new clock source. And enable 104 | RCC->BDCR|= rtc_drv; 105 | } 106 | 107 | void auto_backup_domain_init(void){ 108 | // Init Backup domain, RTC clock source 109 | uint32_t rtc_drv; 110 | // Backup domain access enabled and left open. 111 | PWR->CR |= PWR_CR_DBP; 112 | // Start/check source 113 | rtc_start_source(); 114 | // Check LSE ready, if ok, select as source 115 | rtc_drv = RCC->BDCR & RCC_BDCR_LSERDY ? STM32_RTCSEL_LSE|RCC_BDCR_RTCEN : // Select LSE as source 116 | STM32_RTCSEL_LSI|RCC_BDCR_RTCEN; // Select LSI as source 117 | // If the backup domain hasn't been initialized yet or work on different source, then proceed with initialization 118 | if ((RCC->BDCR & (STM32_RTCSEL_MASK|RCC_BDCR_RTCEN)) != rtc_drv) 119 | resetBCDR(rtc_drv); 120 | /* 121 | // Check RTC clock, and reset backup domain to LSI if clock not start 122 | if (rtc_enter_init()) 123 | rtc_exit_init(); 124 | else 125 | resetBCDR(STM32_RTCSEL_LSI|RCC_BDCR_RTCEN); 126 | */ 127 | } 128 | #endif 129 | 130 | // Initiate RTC clock 131 | void rtc_init(void){ 132 | #ifdef VNA_AUTO_SELECT_RTC_SOURCE 133 | // Auto start LSE or LSI source for RTC 134 | auto_backup_domain_init(); 135 | #else 136 | // ChibiOS init BDCR LSE or LSI source by self from user defined in mcuconf.h source 137 | // For add auto select RTC source need rewrite it 138 | // see hal_lld_backup_domain_init() in hal_lld.c for every CPU 139 | // Default RTC clock is LSE, but it possible not launch if no quartz installed 140 | #endif 141 | uint32_t src = RCC->BDCR & STM32_RTCSEL_MASK; 142 | if (src == STM32_RTCSEL_NOCLOCK) return; 143 | // If calendar has not been initialized yet or different PRER settings then proceed with the initial setup. 144 | // Disable write protection. 145 | RTC->WPR = 0xCA; 146 | RTC->WPR = 0x53; 147 | uint32_t rtc_prer = (src == STM32_RTCSEL_LSE) ? STM32_RTC_LSE_PRER : 148 | STM32_RTC_LSI_PRER; 149 | // If calendar has not been initialized yet then proceed with the initial setup. 150 | if ((RTC->ISR & RTC_ISR_INITS) == 0 || RTC->PRER != rtc_prer) { 151 | if (rtc_enter_init()){ 152 | RTC->CR = 0 153 | // | RTC_CR_COSEL // RTC output 1Hz (or 512Hz if disabled) 154 | ; 155 | RTC->ISR = RTC_ISR_INIT; // Clearing all but RTC_ISR_INIT. 156 | RTC->PRER = rtc_prer; // Prescaler value loaded in registers 2 times 157 | RTC->PRER = rtc_prer; 158 | } 159 | // Finalizing of configuration procedure. 160 | rtc_exit_init(); 161 | } 162 | else 163 | RTC->ISR &= ~RTC_ISR_RSF; 164 | } 165 | 166 | void rtc_set_cal(float ppm) { 167 | int32_t cal = ppm * (1<<20) / 1000000.0f + 511.5f; 168 | if ((RTC->ISR & RTC_ISR_RECALPF) || (uint32_t)cal > 1024) 169 | return; 170 | RTC->CALR = ((511 - cal) & (RTC_CALR_CALP | RTC_CALR_CALM)); 171 | } 172 | 173 | float rtc_get_cal(void) { 174 | int32_t cal = -(RTC->CALR & RTC_CALR_CALM); 175 | if (RTC->CALR & RTC_CALR_CALP) 176 | cal += 512; 177 | return cal * (1000000.0f / (1<<20)); 178 | } 179 | -------------------------------------------------------------------------------- /NANOVNA_STM32_F303/run_openocd: -------------------------------------------------------------------------------- 1 | ~/opt/xPacks/@gnu-mcu-eclipse/openocd/0.10.0-12.1/.content/bin/openocd -f board/stm32f3discovery.cfg 2 | -------------------------------------------------------------------------------- /NANOVNA_STM32_F303/target/stm32f3x.cfg: -------------------------------------------------------------------------------- 1 | # script for stm32f3x family 2 | 3 | # 4 | # stm32 devices support both JTAG and SWD transports. 5 | # 6 | source [find target/swj-dp.tcl] 7 | source [find mem_helper.tcl] 8 | 9 | if { [info exists CHIPNAME] } { 10 | set _CHIPNAME $CHIPNAME 11 | } else { 12 | set _CHIPNAME stm32f3x 13 | } 14 | 15 | set _ENDIAN little 16 | 17 | # Work-area is a space in RAM used for flash programming 18 | # By default use 16kB 19 | if { [info exists WORKAREASIZE] } { 20 | set _WORKAREASIZE $WORKAREASIZE 21 | } else { 22 | set _WORKAREASIZE 0x8000 23 | } 24 | 25 | # JTAG speed should be <= F_CPU/6. F_CPU after reset is 8MHz, so use F_JTAG = 1MHz 26 | # 27 | # Since we may be running of an RC oscilator, we crank down the speed a 28 | # bit more to be on the safe side. Perhaps superstition, but if are 29 | # running off a crystal, we can run closer to the limit. Note 30 | # that there can be a pretty wide band where things are more or less stable. 31 | adapter_khz 950 32 | 33 | adapter_nsrst_delay 1000 34 | if {[using_jtag]} { 35 | jtag_ntrst_delay 1000 36 | } 37 | 38 | #jtag scan chain 39 | if { [info exists CPUTAPID] } { 40 | set _CPUTAPID $CPUTAPID 41 | } else { 42 | if { [using_jtag] } { 43 | # See STM Document RM0316 44 | # Section 29.6.3 - corresponds to Cortex-M4 r0p1 45 | set _CPUTAPID 0x4ba00477 46 | } { 47 | set _CPUTAPID 0x2ba01477 48 | } 49 | } 50 | 51 | swj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID 52 | dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu 53 | 54 | if {[using_jtag]} { 55 | jtag newtap $_CHIPNAME bs -irlen 5 56 | } 57 | 58 | set _TARGETNAME $_CHIPNAME.cpu 59 | target create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap 60 | 61 | $_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0 -rtos ChibiOS 62 | #$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0 63 | 64 | set _FLASHNAME $_CHIPNAME.flash 65 | flash bank $_FLASHNAME stm32f1x 0 0 0 0 $_TARGETNAME 66 | 67 | reset_config srst_nogate 68 | 69 | if {![using_hla]} { 70 | # if srst is not fitted use SYSRESETREQ to 71 | # perform a soft reset 72 | cortex_m reset_config sysresetreq 73 | } 74 | 75 | proc stm32f3x_default_reset_start {} { 76 | # Reset clock is HSI (8 MHz) 77 | adapter_khz 950 78 | } 79 | 80 | proc stm32f3x_default_examine_end {} { 81 | # Enable debug during low power modes (uses more power) 82 | mmw 0xe0042004 0x00000007 0 ;# DBGMCU_CR |= DBG_STANDBY | DBG_STOP | DBG_SLEEP 83 | 84 | # Stop watchdog counters during halt 85 | mmw 0xe0042008 0x00001800 0 ;# DBGMCU_APB1_FZ |= DBG_IWDG_STOP | DBG_WWDG_STOP 86 | } 87 | 88 | proc stm32f3x_default_reset_init {} { 89 | # Configure PLL to boost clock to HSI x 8 (64 MHz) 90 | mww 0x40021004 0x00380400 ;# RCC_CFGR = PLLMUL[3:1] | PPRE1[2] 91 | mmw 0x40021000 0x01000000 0 ;# RCC_CR |= PLLON 92 | mww 0x40022000 0x00000012 ;# FLASH_ACR = PRFTBE | LATENCY[1] 93 | sleep 10 ;# Wait for PLL to lock 94 | mmw 0x40021004 0x00000002 0 ;# RCC_CFGR |= SW[1] 95 | 96 | # Boost JTAG frequency 97 | adapter_khz 2000 98 | } 99 | 100 | # Default hooks 101 | $_TARGETNAME configure -event examine-end { stm32f3x_default_examine_end } 102 | $_TARGETNAME configure -event reset-start { stm32f3x_default_reset_start } 103 | $_TARGETNAME configure -event reset-init { stm32f3x_default_reset_init } 104 | 105 | $_TARGETNAME configure -event trace-config { 106 | # Set TRACE_IOEN; TRACE_MODE is set to async; when using sync 107 | # change this value accordingly to configure trace pins 108 | # assignment 109 | mmw 0xe0042004 0x00000020 0 110 | } 111 | 112 | $_TARGETNAME configure -event gdb-attach { 113 | halt 114 | } 115 | $_TARGETNAME configure -event gdb-attach { 116 | reset init 117 | } 118 | 119 | -------------------------------------------------------------------------------- /NANOVNA_STM32_F303/target/swj-dp.tcl: -------------------------------------------------------------------------------- 1 | # ARM Debug Interface V5 (ADI_V5) utility 2 | # ... Mostly for SWJ-DP (not SW-DP or JTAG-DP, since 3 | # SW-DP and JTAG-DP targets don't need to switch based 4 | # on which transport is active. 5 | # 6 | # declare a JTAG or SWD Debug Access Point (DAP) 7 | # based on the transport in use with this session. 8 | # You can't access JTAG ops when SWD is active, etc. 9 | 10 | # params are currently what "jtag newtap" uses 11 | # because OpenOCD internals are still strongly biased 12 | # to JTAG .... but for SWD, "irlen" etc are ignored, 13 | # and the internals work differently 14 | 15 | # for now, ignore non-JTAG and non-SWD transports 16 | # (e.g. initial flash programming via SPI or UART) 17 | 18 | # split out "chip" and "tag" so we can someday handle 19 | # them more uniformly irlen too...) 20 | 21 | if [catch {transport select}] { 22 | echo "Error: unable to select a session transport. Can't continue." 23 | shutdown 24 | } 25 | 26 | proc swj_newdap {chip tag args} { 27 | if [using_hla] { 28 | eval hla newtap $chip $tag $args 29 | } elseif [using_jtag] { 30 | eval jtag newtap $chip $tag $args 31 | } elseif [using_swd] { 32 | eval swd newdap $chip $tag $args 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /NanoVNA_DAP.cfg: -------------------------------------------------------------------------------- 1 | interface cmsis-dap 2 | transport select swd 3 | source [find target/stm32f3x.cfg] 4 | adapter_khz 8000 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | NanoVNA - Very tiny handheld Vector Network Analyzer 2 | ========================================================== 3 | DIY的矢量网络分析仪,原项目地址[https://github.com/ttrftech/NanoVNA](https://github.com/ttrftech/NanoVNA),修改了部分电路,增加了电池管理电路,重新设计了PCB。改进了的频率算法,可以利用si5351的奇次谐波扩展支持到900MHz的测量频率,设计了金属屏蔽片,可以减少外部干扰提高测量精度,si5351直接输出的50K-300MHz频段提供优于70dB的动态。最新版本的rev3.5版本硬件可以扩展到1.5GHz以上,更多信息请参考[NanoVNA.com](https://nanovna.com/)。 4 | 5 | We remade NanoVNA based on edy555 (https://github.com/ttrftech/NanoVNA) , but modified some circuits, added battery management circuits, and redesigned the PCB. The improved frequency algorithm can use the odd harmonic extension of si5351 to support the measurement frequency up to 900MHz. The metal shield is designed to reduce the external interference and improve the measurement accuracy. The 50k-300MHz frequency range of the si5351 direct output provides better than 70dB dynamic. The latest version of rev3.5 hardware can be extended to above 1.5GHz. For more information, please refer to [NanoVNA.com](https://nanovna.com/) . 6 | 7 | 8 | 9 | ![](doc/NanoVNA-H-2.jpg) 10 | 11 | 12 | ## 编译 13 | ## Build firmware 14 | NanoVNA-H `TARGET = F072` 15 | 16 | NanoVNA-H4 `TARGET = F303` 17 | 18 | 19 | 20 | It is recommended to compile with gcc-arm-none-eabi 8, and exceptions may occur with other versions of the compiler. 21 | Please sync the CibiOS submodule before compiling. 22 | 23 | ``` 24 | $ git submodule update --init --recursive 25 | ``` 26 | 27 | 28 | 29 | ### MacOSX 30 | 31 | Install cross tools and firmware updating tool. 32 | 33 | ``` 34 | $ brew tap px4/px4 35 | $ brew install gcc-arm-none-eabi-80 36 | $ brew install dfu-util 37 | 38 | ``` 39 | 40 | ### Linux 41 | 42 | Download arm cross tools from [here](https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads). 43 | 44 | ``` 45 | $ wget https://developer.arm.com/-/media/Files/downloads/gnu-rm/8-2018q4/gcc-arm-none-eabi-8-2018-q4-major-linux.tar.bz2 46 | $ sudo tar xfj -C /usr/local gcc-arm-none-eabi-8-2018-q4-major-linux.tar.bz2 47 | $ PATH=/usr/local/gcc-arm-none-eabi-8-2018-q4-major/bin:$PATH 48 | $ sudo apt install -y dfu-util 49 | ``` 50 | 51 | ``` 52 | $ make 53 | ``` 54 | 55 | 56 | 57 | ### Windows 58 | Follow [these instructions](https://gnu-mcu-eclipse.github.io/install/)to install gnu-mcu-eclipse. 59 | 60 | Existing Code as Makefile Projiect. 61 | Project > Properties > C/C++ Build > Setting: 62 | Confirm that Toolchains is "GNU MCU Eclipse ARM Embedded GCC (arm-none-eabi-gcc)" 63 | 64 | Project > Properties > C/C++ Build > Tool Chain Editor: 65 | ``` 66 | Current toolchain: ARM Cross GCC 67 | Current builder: Gnu Make Builder 68 | ``` 69 | 70 | Build Project. 71 | 72 | 73 | 74 | 当前版本源码基于**[DiSlord](https://github.com/DiSlord)**的源码修改,如果编译失败,请参考[NanoVNA-D](https://github.com/DiSlord/NanoVNA-D)的说明 75 | 76 | The source code of the current version is based on the source code modification of **[DiSlord](https://github.com/DiSlord)**. If the compilation fails, please refer to [NanoVNA-D](https://github.com/DiSlord/NanoVNA- D) Description 77 | 78 | https://github.com/DiSlord/NanoVNA-D/issues/1#issuecomment-698945620 79 | 80 | 81 | 82 | ### Debug use Eclipse + cmsis-dap +openocd 83 | Debugger Configurations > GBD OpenOCD Debugging, Double click to create a new setting, Select “Debugger“ label, add config option. 84 | ``` 85 | -f NanoVNA_DAP.cfg 86 | ``` 87 | 88 | 89 | 90 | 91 | 92 | 感谢[edy555](https://github.com/edy555)创建了这个项目,所有软件版权归edy555所有。 93 | Thanks to [edy555](https://github.com/edy555) for creating this project, all software copyrights are owned by edy555 94 | [https://github.com/ttrftech/NanoVNA](https://github.com/ttrftech/NanoVNA); 95 | 感谢[cho45](https://github.com/cho45)对项目做出重大改进。 96 | Thanks to cho45 for making major improvements to the project. [https://github.com/cho45/NanoVNA](https://github.com/cho45/NanoVNA) 97 | 98 | 感谢[DiSlord](https://github.com/DiSlord)对项目的持续改进。 99 | Thanks to [DiSlord](https://github.com/DiSlord) for continuous improvement of the project https://github.com/DiSlord/NanoVNA-D. 100 | 101 | 以下为原项目自述 102 | ========================================================== 103 | The following is the original project readme 104 | ========================================================== 105 | # About 106 | 107 | NanoVNA is very tiny handheld Vector Network Analyzer (VNA). It is standalone with lcd display, portable device with battery. This project aim to provide an RF gadget but useful instrument for enthusiast. 108 | 109 | This repository contains source of NanoVNA firmware. 110 | 111 | ## [](https://github.com/ttrftech/NanoVNA#prepare-arm-cross-tools)Prepare ARM Cross Tools 112 | 113 | **UPDATE**: Recent gcc version works to build NanoVNA, no need old version. 114 | 115 | ### [](https://github.com/ttrftech/NanoVNA#macosx)MacOSX 116 | 117 | Install cross tools and firmware updating tool. 118 | 119 | ``` 120 | $ brew tap px4/px4 121 | $ brew install gcc-arm-none-eabi-80 122 | $ brew install dfu-util 123 | 124 | ``` 125 | 126 | ### [](https://github.com/ttrftech/NanoVNA#linux-ubuntu)Linux (ubuntu) 127 | 128 | Download arm cross tools from [here](https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads). 129 | 130 | ``` 131 | $ wget https://developer.arm.com/-/media/Files/downloads/gnu-rm/8-2018q4/gcc-arm-none-eabi-8-2018-q4-major-linux.tar.bz2 132 | $ sudo tar xfj -C /usr/local gcc-arm-none-eabi-8-2018-q4-major-linux.tar.bz2 133 | $ PATH=/usr/local/gcc-arm-none-eabi-8-2018-q4-major/bin:$PATH 134 | $ sudo apt install -y dfu-util 135 | 136 | ``` 137 | 138 | ## [](https://github.com/ttrftech/NanoVNA#fetch-source-code)Fetch source code 139 | 140 | Fetch source and submodule. 141 | 142 | ``` 143 | $ git clone https://github.com/ttrftech/NanoVNA.git 144 | $ cd NanoVNA 145 | $ git submodule update --init --recursive 146 | 147 | ``` 148 | 149 | ## [](https://github.com/ttrftech/NanoVNA#build)Build 150 | 151 | Just make in the directory. 152 | 153 | ``` 154 | $ make 155 | 156 | ``` 157 | 158 | ### [](https://github.com/ttrftech/NanoVNA#build-firmware-using-docker)Build firmware using docker 159 | 160 | Using [this docker image](https://cloud.docker.com/u/edy555/repository/docker/edy555/arm-embedded) without installing arm toolchain. 161 | 162 | ``` 163 | $ cd NanoVNA 164 | $ docker run -it --rm -v $(PWD):/work edy555/arm-embedded:8.2 make 165 | 166 | ``` 167 | 168 | ## [](https://github.com/ttrftech/NanoVNA#flash-firmware)Flash firmware 169 | 170 | First, make device enter DFU mode by one of following methods. 171 | 172 | * Jumper BOOT0 pin at powering device 173 | * Select menu Config->DFU (needs recent firmware) 174 | 175 | Then, flash firmware using dfu-util via USB. 176 | 177 | ``` 178 | $ dfu-util -d 0483:df11 -a 0 -s 0x08000000:leave -D build/ch.bin 179 | 180 | ``` 181 | 182 | Or simply use make. 183 | 184 | ``` 185 | $ make flash 186 | 187 | ``` 188 | 189 | ## [](https://github.com/ttrftech/NanoVNA#control-from-pc)Control from PC 190 | 191 | See [python directory](https://github.com/ttrftech/NanoVNA/blob/master/python/README.md). 192 | 193 | ## [](https://github.com/ttrftech/NanoVNA#note)Note 194 | 195 | Hardware design material is disclosed to prevent bad quality clone. Please let me know if you would have your own unit. 196 | 197 | ## [](https://github.com/ttrftech/NanoVNA#reference)Reference 198 | 199 | * [Schematics](https://github.com/ttrftech/NanoVNA/blob/master/doc/nanovna-sch.pdf) 200 | * [PCB Photo](https://github.com/ttrftech/NanoVNA/blob/master/doc/nanovna-pcb-photo.jpg) 201 | * [Block Diagram](https://github.com/ttrftech/NanoVNA/blob/master/doc/nanovna-blockdiagram.png) 202 | * Kit available from [https://ttrf.tk/kit/nanovna](https://ttrf.tk/kit/nanovna) 203 | 204 | ## [](https://github.com/ttrftech/NanoVNA#credit)Credit 205 | 206 | * [@edy555](https://github.com/edy555) 207 | 208 | ### [](https://github.com/ttrftech/NanoVNA#contributors)Contributors 209 | 210 | * [@hugen79](https://github.com/hugen79) 211 | * [@cho45](https://github.com/cho45) 212 | -------------------------------------------------------------------------------- /common.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2024, Dmitry (DiSlord) dislordlive@gmail.com 3 | * Based on TAKAHASHI Tomohiro (TTRFTECH) edy555@gmail.com 4 | * All rights reserved. 5 | * 6 | * This is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3, or (at your option) 9 | * any later version. 10 | * 11 | * The software is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with GNU Radio; see the file COPYING. If not, write to 18 | * the Free Software Foundation, Inc., 51 Franklin Street, 19 | * Boston, MA 02110-1301, USA. 20 | */ 21 | #include 22 | #include 23 | #include "hal.h" 24 | 25 | // Use size optimization (UI not need fast speed, better have smallest size) 26 | #pragma GCC optimize ("Os") 27 | 28 | // Use macro, std isdigit more big 29 | #define _isdigit(c) (c >= '0' && c <= '9') 30 | // Rewrite universal standart str to value functions to more compact 31 | // 32 | // Convert string to int32 33 | int32_t my_atoi(const char *p) { 34 | int32_t value = 0; 35 | uint32_t c; 36 | bool neg = false; 37 | 38 | if (*p == '-') {neg = true; p++;} 39 | if (*p == '+') p++; 40 | while ((c = *p++ - '0') < 10) 41 | value = value * 10 + c; 42 | return neg ? -value : value; 43 | } 44 | 45 | // Convert string to uint32 46 | // 0x - for hex radix 47 | // 0o - for oct radix 48 | // 0b - for bin radix 49 | // default dec radix 50 | uint32_t my_atoui(const char *p) { 51 | uint32_t value = 0, radix = 10, c; 52 | if (*p == '+') p++; 53 | if (*p == '0') { 54 | switch (p[1]) { 55 | case 'x': radix = 16; break; 56 | case 'o': radix = 8; break; 57 | case 'b': radix = 2; break; 58 | default: goto calculate; 59 | } 60 | p+=2; 61 | } 62 | calculate: 63 | while (1) { 64 | c = *p++ - '0'; 65 | // c = to_upper(*p) - 'A' + 10 66 | if (c >= 'A' - '0') c = (c&(~0x20)) - ('A' - '0') + 10; 67 | if (c >= radix) return value; 68 | value = value * radix + c; 69 | } 70 | } 71 | 72 | float my_atof(const char *p) { 73 | int neg = false; 74 | if (*p == '-') 75 | neg = true; 76 | if (*p == '-' || *p == '+') 77 | p++; 78 | float x = my_atoi(p); 79 | while (_isdigit((int)*p)) 80 | p++; 81 | if (*p == '.' || *p == ',') { 82 | float d = 1.0f; 83 | p++; 84 | while (_isdigit((int)*p)) { 85 | d *= 1e-1f; 86 | x += d * (*p - '0'); 87 | p++; 88 | } 89 | } 90 | if (*p) { 91 | int exp = 0; 92 | if (*p == 'e' || *p == 'E') exp = my_atoi(&p[1]); 93 | else if (*p == 'G') exp = 9; // Giga 94 | else if (*p == 'M') exp = 6; // Mega 95 | else if (*p == 'k') exp = 3; // kilo 96 | else if (*p == 'm') exp = -3; // milli 97 | else if (*p == 'u') exp = -6; // micro 98 | else if (*p == 'n') exp = -9; // nano 99 | else if (*p == 'p') exp =-12; // pico 100 | if (exp > 0) do {x*= 1e+1f;} while (--exp); 101 | if (exp < 0) do {x*= 1e-1f;} while (++exp); 102 | } 103 | return neg ? -x : x; 104 | } 105 | 106 | static char to_lower(char c) {return (c >='A' && c <= 'Z') ? c - 'A' + 'a' : c;} 107 | bool strcmpi(const char *t1, const char *t2) { 108 | int i = 0; 109 | while (1) { 110 | char ch1 = to_lower(t1[i]), ch2 = to_lower(t2[i]); 111 | if (ch1 != ch2) return false; 112 | if (ch1 == 0) return true; 113 | i++; 114 | } 115 | } 116 | 117 | // 118 | // Function used for search substring v in list 119 | // Example need search parameter "center" in "start|stop|center|span|cw" getStringIndex return 2 120 | // If not found return -1 121 | // Used for easy parse command arguments 122 | int get_str_index(const char *v, const char *list) { 123 | int i = 0; 124 | while (1) { 125 | const char *p = v; 126 | while (1) { 127 | char c = *list; 128 | if (c == '|') c = 0; 129 | if (c == *p++) { 130 | // Found, return index 131 | if (c == 0) return i; 132 | list++; // Compare next symbol 133 | continue; 134 | } 135 | break; // Not equal, break 136 | } 137 | // Set new substring ptr 138 | while (1) { 139 | // End of string, not found 140 | if (*list == 0) return -1; 141 | if (*list++ == '|') break; 142 | } 143 | i++; 144 | } 145 | return -1; 146 | } 147 | 148 | /* 149 | * Search first symbols (s2) entry in string (s1) 150 | */ 151 | static inline char* _strpbrk(char *s1, const char *s2) { 152 | do { 153 | const char *s = s2; 154 | while(*s) if (*s++ == *s1) return s1; 155 | } while(*++s1); 156 | return s1; 157 | } 158 | 159 | /* 160 | * Split line by arguments, return arguments count 161 | */ 162 | int parse_line(char *line, char* args[], int max_cnt) { 163 | char *lp = line, c; 164 | const char *brk; 165 | uint16_t nargs = 0; 166 | while ((c = *lp) != 0) { // While not end 167 | if (c != ' ' && c != '\t') { // Skipping white space and tabs. 168 | if (c == '"') {lp++; brk = "\""; } // string end is next quote or end 169 | else { brk = " \t";} // string end is tab or space or end 170 | if (nargs < max_cnt) args[nargs] = lp; // Put pointer in args buffer (if possible) 171 | nargs++; // Substring count 172 | lp = _strpbrk(lp, brk); // search end 173 | if (*lp == 0) break; // Stop, end of input string 174 | *lp = 0; // Set zero at the end of substring 175 | } 176 | lp++; 177 | } 178 | return nargs; 179 | } 180 | 181 | /* 182 | * Swap byte order in uint16_t buffer 183 | */ 184 | void swap_bytes(uint16_t *buf, int size) { 185 | for (int i = 0; i < size; i++) 186 | buf[i] = __REVSH(buf[i]); // swap byte order (example 0x10FF to 0xFF10) 187 | } 188 | 189 | /* 190 | * RLE packbits compression algorithm 191 | */ 192 | int packbits(char *source, char *dest, int size) { 193 | int i = 0, rle, l, pk = 0, sz = 0; 194 | while ((l = size - i) > 0) { 195 | if (l > 128) l = 128; // Limit search RLE block size to 128 196 | char c = source[i++]; // Get next byte and write to block 197 | for (rle = 0; c == source[i + rle] && --l; rle++); // Calculate this byte RLE sequence size = rle + 1 198 | if (sz && rle < 2) rle = 0; // Ignore (rle + 1) < 3 sequence on run non RLE input 199 | else if (sz == 0 || rle > 0) sz = pk++; // Reset state or RLE sequence found -> start new block 200 | dest[pk++] = c; // Write char to block 201 | if (rle > 0) {i+= rle; dest[sz] = -rle;} // Write RLE sequence size and go to new block 202 | else if ((dest[sz] = pk - sz - 2) < 127) // Continue write non RLE data while 1 + (non_rle + 1) < 127 203 | continue; 204 | sz = 0; // Block complete 205 | } 206 | return pk; 207 | } 208 | 209 | /* 210 | * Delay 8 core tick function 211 | */ 212 | void _delay_8t(uint32_t cycles) { 213 | if(cycles < 1) return; 214 | __asm ( 215 | "1: \n" 216 | " subs %[cyc], %[cyc], #1 \n" // 1 cycle 217 | " nop \n" // 1 cycle 218 | " nop \n" // 1 cycle 219 | " nop \n" // 1 cycle 220 | " nop \n" // 1 cycle 221 | " nop \n" // 1 cycle 222 | " bne 1b \n" // 2 if taken, 1 otherwise 223 | : [cyc] "+l" (cycles) 224 | : // no inputs 225 | : // No memory 226 | ); 227 | } 228 | -------------------------------------------------------------------------------- /data_storage.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2020, Dmitry (DiSlord) dislordlive@gmail.com 3 | * Based on TAKAHASHI Tomohiro (TTRFTECH) edy555@gmail.com 4 | * All rights reserved. 5 | * 6 | * This is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3, or (at your option) 9 | * any later version. 10 | * 11 | * The software is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with GNU Radio; see the file COPYING. If not, write to 18 | * the Free Software Foundation, Inc., 51 Franklin Street, 19 | * Boston, MA 02110-1301, USA. 20 | */ 21 | #include "ch.h" 22 | #include "hal.h" 23 | #include "nanovna.h" 24 | #include 25 | 26 | uint16_t lastsaveid = 0; 27 | #if SAVEAREA_MAX >= 8 28 | #error "Increase checksum_ok type for save more cache slots" 29 | #endif 30 | 31 | // properties CRC check cache (max 8 slots) 32 | static uint8_t checksum_ok = 0; 33 | 34 | static uint32_t calibration_slot_area(int id) { 35 | return SAVE_PROP_CONFIG_ADDR + id * SAVE_PROP_CONFIG_SIZE; 36 | } 37 | 38 | static uint32_t checksum(const void *start, size_t len) { 39 | uint32_t *p = (uint32_t*)start; 40 | uint32_t value = 0; 41 | // align by sizeof(uint32_t) 42 | len = (len + sizeof(uint32_t)-1)/sizeof(uint32_t); 43 | while (len-- > 0) 44 | value = __ROR(value, 31) + *p++; 45 | return value; 46 | } 47 | 48 | int config_save(void) { 49 | // Apply magic word and calculate checksum 50 | config.magic = CONFIG_MAGIC; 51 | config.checksum = checksum(&config, sizeof config - sizeof config.checksum); 52 | 53 | // write to flash 54 | flash_program_half_word_buffer((uint16_t*)SAVE_CONFIG_ADDR, (uint16_t*)&config, sizeof(config_t)); 55 | return 0; 56 | } 57 | 58 | int config_recall(void) { 59 | const config_t *src = (const config_t*)SAVE_CONFIG_ADDR; 60 | 61 | if (src->magic != CONFIG_MAGIC || checksum(src, sizeof *src - sizeof src->checksum) != src->checksum) 62 | return -1; 63 | // duplicated saved data onto sram to be able to modify marker/trace 64 | memcpy(&config, src, sizeof(config_t)); 65 | return 0; 66 | } 67 | 68 | int caldata_save(uint32_t id) { 69 | if (id >= SAVEAREA_MAX) 70 | return -1; 71 | 72 | // Apply magic word and calculate checksum 73 | current_props.magic = PROPERTIES_MAGIC; 74 | current_props.checksum = checksum(¤t_props, sizeof current_props - sizeof current_props.checksum); 75 | 76 | // write to flash 77 | uint16_t *dst = (uint16_t*)calibration_slot_area(id); 78 | flash_program_half_word_buffer(dst, (uint16_t*)¤t_props, sizeof(properties_t)); 79 | 80 | lastsaveid = id; 81 | return 0; 82 | } 83 | 84 | const properties_t * get_properties(uint32_t id) { 85 | if (id >= SAVEAREA_MAX) 86 | return NULL; 87 | // point to saved area on the flash memory 88 | properties_t *src = (properties_t*)calibration_slot_area(id); 89 | // Check crc cache mask (made it only 1 time) 90 | if (checksum_ok&(1<magic != PROPERTIES_MAGIC || checksum(src, sizeof *src - sizeof src->checksum) != src->checksum) 93 | return NULL; 94 | checksum_ok|=1<>4); 205 | // acc_samp_c+= (int32_t)(samp_c>>4); 206 | // acc_ref_s += (int32_t)( ref_s>>4); 207 | // acc_ref_c += (int32_t)( ref_c>>4); 208 | } 209 | #endif 210 | 211 | void 212 | calculate_gamma(float *gamma) 213 | { 214 | // calculate reflection coeff. by samp divide by ref 215 | #if 0 216 | measure_t rs = acc_ref_s; 217 | measure_t rc = acc_ref_c; 218 | measure_t rr = rs * rs + rc * rc; 219 | measure_t ss = acc_samp_s; 220 | measure_t sc = acc_samp_c; 221 | gamma[0] = (sc * rc + ss * rs) / rr; 222 | gamma[1] = (ss * rc - sc * rs) / rr; 223 | #else 224 | measure_t rs_rc = (measure_t) acc_ref_s / acc_ref_c; 225 | measure_t sc_rc = (measure_t)acc_samp_c / acc_ref_c; 226 | measure_t ss_rc = (measure_t)acc_samp_s / acc_ref_c; 227 | measure_t rr = rs_rc * rs_rc + 1.0f; 228 | gamma[0] = (sc_rc + ss_rc * rs_rc) / rr; 229 | gamma[1] = (ss_rc - sc_rc * rs_rc) / rr; 230 | #endif 231 | } 232 | 233 | void 234 | fetch_amplitude(float *gamma) 235 | { 236 | gamma[0] = acc_samp_s * 1e-9; 237 | gamma[1] = acc_samp_c * 1e-9; 238 | } 239 | 240 | void 241 | fetch_amplitude_ref(float *gamma) 242 | { 243 | gamma[0] = acc_ref_s * 1e-9; 244 | gamma[1] = acc_ref_c * 1e-9; 245 | } 246 | 247 | void 248 | reset_dsp_accumerator(void) 249 | { 250 | acc_ref_s = 0; 251 | acc_ref_c = 0; 252 | acc_samp_s = 0; 253 | acc_samp_c = 0; 254 | } 255 | -------------------------------------------------------------------------------- /dsp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2020, Dmitry (DiSlord) dislordlive@gmail.com 3 | * All rights reserved. 4 | * 5 | * This is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 3, or (at your option) 8 | * any later version. 9 | * 10 | * The software is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with GNU Radio; see the file COPYING. If not, write to 17 | * the Free Software Foundation, Inc., 51 Franklin Street, 18 | * Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | // Cortex M4 DSP instructions assembly 22 | 23 | // __smlabb inserts a SMLABB instruction. __smlabb returns the equivalent of 24 | // int32_t res = x[0] * y[0] + acc 25 | // where [0] is the lower 16 bits and [1] is the upper 16 bits. This operation sets the Q flag if overflow occurs on the addition. 26 | __attribute__((always_inline)) __STATIC_INLINE int32_t __smlabb(int32_t x, int32_t y, int32_t acc) 27 | { 28 | register int32_t r; 29 | __asm__ ("smlabb %[r], %[x], %[y], %[a]" 30 | : [r] "=r" (r) : [x] "r" (x), [y] "r" (y), [a] "r" (acc) : ); 31 | return r; 32 | } 33 | 34 | // __smlabt inserts a SMLABT instruction. __smlabt returns the equivalent of 35 | // int32_t res = x[0] * y[1] + acc 36 | // where [0] is the lower 16 bits and [1] is the upper 16 bits. This operation sets the Q flag if overflow occurs on the addition. 37 | __attribute__((always_inline)) __STATIC_INLINE int32_t __smlabt(int32_t x, int32_t y, int32_t acc) 38 | { 39 | register int32_t r; 40 | __asm__ ("smlabt %[r], %[x], %[y], %[a]" 41 | : [r] "=r" (r) : [x] "r" (x), [y] "r" (y), [a] "r" (acc) : ); 42 | return r; 43 | } 44 | 45 | // __smlatb inserts a SMLATB instruction. __smlatb returns the equivalent of 46 | // int32_t res = x[1] * y[0] + acc 47 | // where [0] is the lower 16 bits and [1] is the upper 16 bits. This operation sets the Q flag if overflow occurs on the addition. 48 | __attribute__((always_inline)) __STATIC_INLINE int32_t __smlatb(int32_t x, int32_t y, int32_t acc) 49 | { 50 | register int32_t r; 51 | __asm__ ("smlatb %[r], %[x], %[y], %[a]" 52 | : [r] "=r" (r) : [x] "r" (x), [y] "r" (y), [a] "r" (acc) : ); 53 | return r; 54 | } 55 | 56 | // __smlatt inserts a SMLATT instruction. __smlatt returns the equivalent of 57 | // int32_t res = x[1] * y[1] + acc 58 | // where [0] is the lower 16 bits and [1] is the upper 16 bits. This operation sets the Q flag if overflow occurs on the addition. 59 | __attribute__((always_inline)) __STATIC_INLINE int32_t __smlatt(int32_t x, int32_t y, int32_t acc) 60 | { 61 | register int32_t r; 62 | __asm__ ("smlatt %[r], %[x], %[y], %[a]" 63 | : [r] "=r" (r) : [x] "r" (x), [y] "r" (y), [a] "r" (acc) : ); 64 | return r; 65 | } 66 | 67 | // __smlalbb inserts a SMLALBB instruction. __smlalbb returns the equivalent of 68 | // int64_t res = x[0] * y[0] + acc 69 | // where [0] is the lower 16 bits and [1] is the upper 16 bits. 70 | __attribute__((always_inline)) __STATIC_INLINE int64_t __smlalbb(int64_t acc, int32_t x, int32_t y) 71 | { 72 | register union { 73 | struct { uint32_t lo; uint32_t hi; } s_rep; 74 | int64_t i_rep; 75 | } r; 76 | r.i_rep = acc; 77 | __asm__ ("smlalbb %[r_lo], %[r_hi], %[x], %[y]" 78 | : [r_lo] "+r" (r.s_rep.lo), [r_hi] "+r" (r.s_rep.hi) 79 | : [x] "r" (x), [y] "r" (y) : ); 80 | return r.i_rep; 81 | } 82 | 83 | // __smlalbt inserts a SMLALBT instruction. __smlalbt returns the equivalent of 84 | // int64_t res = x[0] * y[1] + acc 85 | // where [0] is the lower 16 bits and [1] is the upper 16 bits. 86 | __attribute__((always_inline)) __STATIC_INLINE int64_t __smlalbt(int64_t acc, int32_t x, int32_t y) 87 | { 88 | register union { 89 | struct { uint32_t lo; uint32_t hi; } s_rep; 90 | int64_t i_rep; 91 | } r; 92 | r.i_rep = acc; 93 | __asm__ ("smlalbt %[r_lo], %[r_hi], %[x], %[y]" 94 | : [r_lo] "+r" (r.s_rep.lo), [r_hi] "+r" (r.s_rep.hi) 95 | : [x] "r" (x), [y] "r" (y) : ); 96 | return r.i_rep; 97 | } 98 | 99 | // __smlaltb inserts a SMLALTB instruction. __smlaltb returns the equivalent of 100 | // int64_t res = x[1] * y[0] + acc 101 | // where [0] is the lower 16 bits and [1] is the upper 16 bits. 102 | __attribute__((always_inline)) __STATIC_INLINE int64_t __smlaltb(int64_t acc, int32_t x, int32_t y) 103 | { 104 | register union { 105 | struct { uint32_t lo; uint32_t hi; } s_rep; 106 | int64_t i_rep; 107 | } r; 108 | r.i_rep = acc; 109 | __asm__ ("smlaltb %[r_lo], %[r_hi], %[x], %[y]" 110 | : [r_lo] "+r" (r.s_rep.lo), [r_hi] "+r" (r.s_rep.hi) 111 | : [x] "r" (x), [y] "r" (y) : ); 112 | return r.i_rep; 113 | } 114 | 115 | // __smlaltt inserts a SMLALTT instruction. __smlaltt returns the equivalent of 116 | // int64_t res = x[1] * y[1] + acc 117 | // where [0] is the lower 16 bits and [1] is the upper 16 bits. 118 | __attribute__((always_inline)) __STATIC_INLINE int64_t __smlaltt(int64_t acc, int32_t x, int32_t y) 119 | { 120 | register union { 121 | struct { uint32_t lo; uint32_t hi; } s_rep; 122 | int64_t i_rep; 123 | } r; 124 | r.i_rep = acc; 125 | __asm__ ("smlaltt %[r_lo], %[r_hi], %[x], %[y]" 126 | : [r_lo] "+r" (r.s_rep.lo), [r_hi] "+r" (r.s_rep.hi) 127 | : [x] "r" (x), [y] "r" (y) : ); 128 | return r.i_rep; 129 | } 130 | -------------------------------------------------------------------------------- /hardware.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2020, Dmitry (DiSlord) dislordlive@gmail.com 3 | * Based on TAKAHASHI Tomohiro (TTRFTECH) edy555@gmail.com 4 | * All rights reserved. 5 | * 6 | * This is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3, or (at your option) 9 | * any later version. 10 | * 11 | * The software is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with GNU Radio; see the file COPYING. If not, write to 18 | * the Free Software Foundation, Inc., 51 Franklin Street, 19 | * Boston, MA 02110-1301, USA. 20 | */ 21 | #include "ch.h" 22 | #include "hal.h" 23 | #include "nanovna.h" 24 | 25 | // Compact STM32 ADC library 26 | #if HAL_USE_ADC == TRUE 27 | #error "Error VNA use self ADC lib, define HAL_USE_ADC = FALSE in halconf.h" 28 | #endif 29 | #ifdef NANOVNA_F303 30 | #include "NANOVNA_STM32_F303/adc_v3.c" 31 | #else 32 | #include "NANOVNA_STM32_F072/adc_v1.c" 33 | #endif 34 | 35 | // Compact STM32 I2C library 36 | #if HAL_USE_I2C == TRUE 37 | #error "Error VNA use self I2C lib, define HAL_USE_I2C = FALSE in halconf.h" 38 | #endif 39 | #ifdef NANOVNA_F303 40 | #include "NANOVNA_STM32_F303/i2c_v2.c" 41 | #else 42 | #include "NANOVNA_STM32_F072/i2c_v2.c" 43 | #endif 44 | 45 | #ifdef __USE_RTC__ 46 | // Compact STM32 RTC time library 47 | #if HAL_USE_RTC == TRUE 48 | #error "Error VNA use self RTC lib, define HAL_USE_RTC = FALSE in halconf.h" 49 | #endif 50 | #ifdef NANOVNA_F303 51 | #include "NANOVNA_STM32_F303/rtc_v2.c" 52 | #else 53 | #include "NANOVNA_STM32_F072/rtc_v2.c" 54 | #endif 55 | #endif 56 | 57 | // Compact STM32 DAC library 58 | #if HAL_USE_DAC == TRUE 59 | #error "Need disable HAL_USE_DAC in halconf.h for use VNA_DAC" 60 | #endif 61 | #ifdef NANOVNA_F303 62 | #include "NANOVNA_STM32_F303/dac_v1.c" 63 | #else 64 | #include "NANOVNA_STM32_F072/dac_v1.c" 65 | #endif 66 | 67 | // Compact STM32 I2S library 68 | #if HAL_USE_I2S == TRUE 69 | #error "Need disable HAL_USE_DAC in halconf.h for use VNA_DAC" 70 | #endif 71 | #ifdef NANOVNA_F303 72 | #include "NANOVNA_STM32_F303/i2s.c" 73 | #else 74 | #include "NANOVNA_STM32_F072/i2s.c" 75 | #endif 76 | 77 | // Compact STM32 flash library 78 | #ifdef NANOVNA_F303 79 | #include "NANOVNA_STM32_F303/flash.c" 80 | #else 81 | #include "NANOVNA_STM32_F072/flash.c" 82 | #endif 83 | 84 | // Compact STM32 GPIO library 85 | #if HAL_USE_PAL == FALSE 86 | #ifdef NANOVNA_F303 87 | #include "NANOVNA_STM32_F303/gpio_v2.c" 88 | #else 89 | #include "NANOVNA_STM32_F072/gpio_v2.c" 90 | #endif 91 | #endif 92 | 93 | // Compact STM32 DMA library 94 | #ifdef NANOVNA_F303 95 | #include "NANOVNA_STM32_F303/dma_v1.c" 96 | #else 97 | #include "NANOVNA_STM32_F072/dma_v1.c" 98 | #endif 99 | 100 | // Compact STM32 EXT library 101 | #if HAL_USE_EXT == FALSE 102 | #ifdef NANOVNA_F303 103 | #include "NANOVNA_STM32_F303/exti_v1.c" 104 | #else 105 | #include "NANOVNA_STM32_F072/exti_v1.c" 106 | #endif 107 | #endif 108 | 109 | #if HAL_USE_GPT == FALSE 110 | // Run TIM2 as us timer counter (used as STM32_ST_TIM timer in ChibiOS) 111 | // Run TIM3 as ms timer counter 112 | void initTimers(void) { 113 | // rccEnableTIM2(FALSE); 114 | rccEnableTIM3(FALSE); 115 | // TIM2 use AHB1 bus clock (32 bit timer), use STM32_TIMCLK1 clock source 116 | // TIM2->PSC = STM32_TIMCLK1 / (1000000U) - 1; // 1MHz tick 117 | // TIM3 use AHB1 bus clock (16 bit timer), used in touch period handler 118 | TIM3->PSC = STM32_TIMCLK1 / (1000U) - 1; // 1kHz tick 119 | TIM3->CR2 = 0x20; // Generate TRIGO event for ADC watchdog 120 | } 121 | 122 | // 123 | void startTimer(TIM_TypeDef *timer, uint32_t period) { 124 | timer->ARR = period - 1; 125 | timer->EGR = STM32_TIM_EGR_UG; 126 | timer->CNT = 0; 127 | timer->CR1 = STM32_TIM_CR1_URS | STM32_TIM_CR1_CEN; 128 | } 129 | #endif 130 | -------------------------------------------------------------------------------- /icons_menu.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2020, Dmitry (DiSlord) dislordlive@gmail.com 3 | * All rights reserved. 4 | * 5 | * This is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 3, or (at your option) 8 | * any later version. 9 | * 10 | * The software is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with GNU Radio; see the file COPYING. If not, write to 17 | * the Free Software Foundation, Inc., 51 Franklin Street, 18 | * Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | //**************************************************************** 22 | // Icons used in UI 23 | //**************************************************************** 24 | 25 | // Touch test icon on screen 26 | #if LCD_WIDTH < 800 27 | #define CALIBRATION_OFFSET 16 28 | #define TOUCH_MARK_W 9 29 | #define TOUCH_MARK_H 9 30 | #define TOUCH_MARK_X 4 31 | #define TOUCH_MARK_Y 4 32 | static const uint8_t touch_bitmap[]={ 33 | _BMP16(0b0000100000000000), 34 | _BMP16(0b0100100100000000), 35 | _BMP16(0b0010101000000000), 36 | _BMP16(0b0000100000000000), 37 | _BMP16(0b1111011110000000), 38 | _BMP16(0b0000100000000000), 39 | _BMP16(0b0010101000000000), 40 | _BMP16(0b0100100100000000), 41 | _BMP16(0b0000100000000000), 42 | }; 43 | #else 44 | #define CALIBRATION_OFFSET 16 45 | #define TOUCH_MARK_W 15 46 | #define TOUCH_MARK_H 15 47 | #define TOUCH_MARK_X 7 48 | #define TOUCH_MARK_Y 7 49 | static const uint8_t touch_bitmap[]={ 50 | _BMP16(0b0000000100000000), 51 | _BMP16(0b0100000100000100), 52 | _BMP16(0b0010000100001000), 53 | _BMP16(0b0001000100010000), 54 | _BMP16(0b0000100100100000), 55 | _BMP16(0b0000010101000000), 56 | _BMP16(0b0000000100000000), 57 | _BMP16(0b1111111011111110), 58 | _BMP16(0b0000000100000000), 59 | _BMP16(0b0000010101000000), 60 | _BMP16(0b0000100100100000), 61 | _BMP16(0b0001000100010000), 62 | _BMP16(0b0010000100001000), 63 | _BMP16(0b0100000100000100), 64 | _BMP16(0b0000000100000000), 65 | }; 66 | #endif 67 | 68 | // Icons for menus 69 | #if _USE_FONT_ < 3 70 | #define ICON_SIZE 14 71 | #define ICON_WIDTH 11 72 | #define ICON_HEIGHT 11 73 | #define ICON_GET_DATA(i) (&button_icons[2*ICON_HEIGHT*(i)]) 74 | static const uint8_t button_icons[] = { 75 | _BMP16(0b1111111111000000), 76 | _BMP16(0b1000000001000000), 77 | _BMP16(0b1000000001000000), 78 | _BMP16(0b1000000001000000), 79 | _BMP16(0b1000000001000000), 80 | _BMP16(0b1000000001000000), 81 | _BMP16(0b1000000001000000), 82 | _BMP16(0b1000000001000000), 83 | _BMP16(0b1000000001000000), 84 | _BMP16(0b1000000001000000), 85 | _BMP16(0b1111111111000000), 86 | 87 | _BMP16(0b1111111111000000), 88 | _BMP16(0b1000000000100000), 89 | _BMP16(0b1000000001100000), 90 | _BMP16(0b1000000011000000), 91 | _BMP16(0b1000000110000000), 92 | _BMP16(0b1010001101000000), 93 | _BMP16(0b1011011001000000), 94 | _BMP16(0b1001110001000000), 95 | _BMP16(0b1000100001000000), 96 | _BMP16(0b1000000001000000), 97 | _BMP16(0b1111111111000000), 98 | 99 | _BMP16(0b0000000000000000), 100 | _BMP16(0b0001111000000000), 101 | _BMP16(0b0010000100000000), 102 | _BMP16(0b0100000010000000), 103 | _BMP16(0b1000000001000000), 104 | _BMP16(0b1000000001000000), 105 | _BMP16(0b1000000001000000), 106 | _BMP16(0b1000000001000000), 107 | _BMP16(0b0100000010000000), 108 | _BMP16(0b0010000100000000), 109 | _BMP16(0b0001111000000000), 110 | 111 | _BMP16(0b0000000000000000), 112 | _BMP16(0b0001111000000000), 113 | _BMP16(0b0010000100000000), 114 | _BMP16(0b0100110010000000), 115 | _BMP16(0b1001111001000000), 116 | _BMP16(0b1011111101000000), 117 | _BMP16(0b1011111101000000), 118 | _BMP16(0b1001111001000000), 119 | _BMP16(0b0100110010000000), 120 | _BMP16(0b0010000100000000), 121 | _BMP16(0b0001111000000000), 122 | 123 | _BMP16(0b1111111111100000), 124 | _BMP16(0b1000000000100000), 125 | _BMP16(0b1000111110100000), 126 | _BMP16(0b1001100110100000), 127 | _BMP16(0b1011000110100000), 128 | _BMP16(0b1011000110100000), 129 | _BMP16(0b1011111110100000), 130 | _BMP16(0b1011000110100000), 131 | _BMP16(0b1011000110100000), 132 | _BMP16(0b1000000000100000), 133 | _BMP16(0b1111111111100000), 134 | 135 | _BMP16(0b1111111111100000), 136 | _BMP16(0b1000000000100000), 137 | _BMP16(0b1011000110100000), 138 | _BMP16(0b1011000110100000), 139 | _BMP16(0b1011101110100000), 140 | _BMP16(0b1011111110100000), 141 | _BMP16(0b1011010110100000), 142 | _BMP16(0b1011010110100000), 143 | _BMP16(0b1011000110100000), 144 | _BMP16(0b1000000000100000), 145 | _BMP16(0b1111111111100000), 146 | }; 147 | #else 148 | #define ICON_SIZE 18 149 | #define ICON_WIDTH 14 150 | #define ICON_HEIGHT 14 151 | #define ICON_GET_DATA(i) (&button_icons[2*ICON_HEIGHT*(i)]) 152 | static const uint8_t button_icons[] = { 153 | _BMP16(0b1111111111111000), 154 | _BMP16(0b1000000000001000), 155 | _BMP16(0b1000000000001000), 156 | _BMP16(0b1000000000001000), 157 | _BMP16(0b1000000000001000), 158 | _BMP16(0b1000000000001000), 159 | _BMP16(0b1000000000001000), 160 | _BMP16(0b1000000000001000), 161 | _BMP16(0b1000000000001000), 162 | _BMP16(0b1000000000001000), 163 | _BMP16(0b1000000000001000), 164 | _BMP16(0b1000000000001000), 165 | _BMP16(0b1000000000001000), 166 | _BMP16(0b1111111111111000), 167 | 168 | _BMP16(0b1111111111111000), 169 | _BMP16(0b1000000000001000), 170 | _BMP16(0b1000000000000100), 171 | _BMP16(0b1000000000001100), 172 | _BMP16(0b1000000000011100), 173 | _BMP16(0b1010000000111000), 174 | _BMP16(0b1011000001110000), 175 | _BMP16(0b1011100011101000), 176 | _BMP16(0b1001110111001000), 177 | _BMP16(0b1000111110001000), 178 | _BMP16(0b1000011100001000), 179 | _BMP16(0b1000001000001000), 180 | _BMP16(0b1000000000001000), 181 | _BMP16(0b1111111111111000), 182 | 183 | _BMP16(0b0000111110000000), 184 | _BMP16(0b0001000001000000), 185 | _BMP16(0b0010000000100000), 186 | _BMP16(0b0100000000010000), 187 | _BMP16(0b1000000000001000), 188 | _BMP16(0b1000000000001000), 189 | _BMP16(0b1000000000001000), 190 | _BMP16(0b1000000000001000), 191 | _BMP16(0b1000000000001000), 192 | _BMP16(0b1000000000001000), 193 | _BMP16(0b0100000000010000), 194 | _BMP16(0b0010000000100000), 195 | _BMP16(0b0001000001000000), 196 | _BMP16(0b0000111110000000), 197 | 198 | _BMP16(0b0000111110000000), 199 | _BMP16(0b0001000001000000), 200 | _BMP16(0b0010000000100000), 201 | _BMP16(0b0100011100010000), 202 | _BMP16(0b1000111110001000), 203 | _BMP16(0b1001111111001000), 204 | _BMP16(0b1001111111001000), 205 | _BMP16(0b1001111111001000), 206 | _BMP16(0b1001111111001000), 207 | _BMP16(0b1000111110001000), 208 | _BMP16(0b0100011100010000), 209 | _BMP16(0b0010000000100000), 210 | _BMP16(0b0001000001000000), 211 | _BMP16(0b0000111110000000), 212 | 213 | _BMP16(0b1111111111111000), 214 | _BMP16(0b1000000000001000), 215 | _BMP16(0b1000011111001000), 216 | _BMP16(0b1000110011001000), 217 | _BMP16(0b1001100011001000), 218 | _BMP16(0b1001100011001000), 219 | _BMP16(0b1001100011001000), 220 | _BMP16(0b1001111111001000), 221 | _BMP16(0b1001100011001000), 222 | _BMP16(0b1001100011001000), 223 | _BMP16(0b1001100011001000), 224 | _BMP16(0b1001100011001000), 225 | _BMP16(0b1000000000001000), 226 | _BMP16(0b1111111111111000), 227 | 228 | _BMP16(0b1111111111111000), 229 | _BMP16(0b1000000000001000), 230 | _BMP16(0b1011000001101000), 231 | _BMP16(0b1011100011101000), 232 | _BMP16(0b1011110111101000), 233 | _BMP16(0b1011111111101000), 234 | _BMP16(0b1011111111101000), 235 | _BMP16(0b1011011101101000), 236 | _BMP16(0b1011001001101000), 237 | _BMP16(0b1011001001101000), 238 | _BMP16(0b1011000001101000), 239 | _BMP16(0b1011000001101000), 240 | _BMP16(0b1000000000001000), 241 | _BMP16(0b1111111111111000), 242 | }; 243 | #endif -------------------------------------------------------------------------------- /mcuconf.h: -------------------------------------------------------------------------------- 1 | /* 2 | ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #ifdef NANOVNA_F303 18 | #include "NANOVNA_STM32_F303/mcuconf.h" 19 | #else 20 | #include "NANOVNA_STM32_F072/mcuconf.h" 21 | #endif 22 | -------------------------------------------------------------------------------- /prog.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | DFU_UTIL=../chibios-stm/dfu-util/src/dfu-util 3 | $DFU_UTIL -d 0483:df11 -a 0 -s 0x08000000:leave -D build/ch.bin 4 | -------------------------------------------------------------------------------- /si5351.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2020, Dmitry (DiSlord) dislordlive@gmail.com 3 | * Based on TAKAHASHI Tomohiro (TTRFTECH) edy555@gmail.com 4 | * All rights reserved. 5 | * 6 | * This is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3, or (at your option) 9 | * any later version. 10 | * 11 | * The software is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with GNU Radio; see the file COPYING. If not, write to 18 | * the Free Software Foundation, Inc., 51 Franklin Street, 19 | * Boston, MA 02110-1301, USA. 20 | */ 21 | 22 | #define SI5351_REG_3_OUTPUT_ENABLE_CONTROL 3 23 | #define SI5351_CLK0_EN (1<<0) 24 | #define SI5351_CLK1_EN (1<<1) 25 | #define SI5351_CLK2_EN (1<<2) 26 | 27 | // Reg 16-18 CLKX_CONTROL 28 | #define SI5351_REG_16_CLK0_CONTROL 16 29 | #define SI5351_REG_17_CLK1_CONTROL 17 30 | #define SI5351_REG_18_CLK2_CONTROL 18 31 | #define SI5351_CLK_POWERDOWN (1<<7) 32 | #define SI5351_CLK_INTEGER_MODE (1<<6) 33 | #define SI5351_CLK_PLL_SELECT_A (0<<5) 34 | #define SI5351_CLK_PLL_SELECT_B (1<<5) 35 | #define SI5351_CLK_INVERT (1<<4) 36 | #define SI5351_CLK_INPUT_MASK (3<<2) 37 | #define SI5351_CLK_INPUT_XTAL (0<<2) 38 | #define SI5351_CLK_INPUT_CLKIN (1<<2) 39 | #define SI5351_CLK_INPUT_MULTISYNTH_0_4 (2<<2) 40 | #define SI5351_CLK_INPUT_MULTISYNTH_N (3<<2) 41 | #define SI5351_CLK_DRIVE_STRENGTH_MASK (3<<0) 42 | #define SI5351_CLK_DRIVE_STRENGTH_2MA (0<<0) 43 | #define SI5351_CLK_DRIVE_STRENGTH_4MA (1<<0) 44 | #define SI5351_CLK_DRIVE_STRENGTH_6MA (2<<0) 45 | #define SI5351_CLK_DRIVE_STRENGTH_8MA (3<<0) 46 | #define SI5351_CLK_DRIVE_STRENGTH_AUTO 0xFF 47 | 48 | #define SI5351_REG_PLL_A 26 49 | #define SI5351_REG_PLL_B 34 50 | 51 | #define SI5351_REG_42_MULTISYNTH0 42 52 | #define SI5351_REG_50_MULTISYNTH1 50 53 | #define SI5351_REG_58_MULTISYNTH2 58 54 | #define SI5351_DIVBY4 (3<<2) 55 | #define SI5351_R_DIV_1 (0<<4) 56 | #define SI5351_R_DIV_2 (1<<4) 57 | #define SI5351_R_DIV_4 (2<<4) 58 | #define SI5351_R_DIV_8 (3<<4) 59 | #define SI5351_R_DIV_16 (4<<4) 60 | #define SI5351_R_DIV_32 (5<<4) 61 | #define SI5351_R_DIV_64 (6<<4) 62 | #define SI5351_R_DIV_128 (7<<4) 63 | #define SI5351_R_DIV(n) ((n)<<4) 64 | 65 | #define SI5351_REG_177_PLL_RESET 177 66 | #define SI5351_PLL_RESET_B (1<<7) 67 | #define SI5351_PLL_RESET_A (1<<5) 68 | 69 | #define SI5351_REG_183_CRYSTAL_LOAD 183 70 | #define SI5351_CRYSTAL_LOAD__PF (0<<6) 71 | #define SI5351_CRYSTAL_LOAD_6PF (1<<6) 72 | #define SI5351_CRYSTAL_LOAD_8PF (2<<6) 73 | #define SI5351_CRYSTAL_LOAD_10PF (3<<6) 74 | 75 | void si5351_init(void); 76 | void si5351_disable_output(void); 77 | void si5351_enable_output(void); 78 | 79 | void si5351_set_frequency_offset(int32_t offset); 80 | int si5351_set_frequency(uint32_t freq, uint8_t drive_strength); 81 | void si5351_set_power(uint8_t drive_strength); 82 | void si5351_set_band_mode(uint16_t t); 83 | 84 | // Defug use functions 85 | void si5351_bulk_write(const uint8_t *buf, int len); 86 | bool si5351_bulk_read(uint8_t reg, uint8_t* buf, int len); 87 | void si5351_set_timing(int i, int v); 88 | void si5351_update_band_config(int idx, uint32_t pidx, uint32_t v); 89 | void si5351_set_tcxo(uint32_t xtal); 90 | 91 | // Get info functions 92 | uint32_t si5351_get_frequency(void); 93 | uint32_t si5351_get_harmonic_lvl(uint32_t f); 94 | -------------------------------------------------------------------------------- /spi.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2020, Dmitry (DiSlord) dislordlive@gmail.com 3 | * All rights reserved. 4 | * 5 | * This is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 3, or (at your option) 8 | * any later version. 9 | * 10 | * The software is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with GNU Radio; see the file COPYING. If not, write to 17 | * the Free Software Foundation, Inc., 51 Franklin Street, 18 | * Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | //***************************************************************************** 22 | //********************************** SPI1 bus ********************************* 23 | //***************************************************************************** 24 | // STM32 SPI transfer mode: 25 | // in 8 bit mode: 26 | // if you write *(uint8_t*)(&SPI1->DR) = (uint8_t) data, then data send as << data 27 | // if you write *(uint16_t*)(&SPI1->DR) =(uint16_t) data, then data send as << dataLoByte, after send dataHiByte 28 | // in 16 bit mode 29 | // if you write *(uint16_t*)(&SPI1->DR) =(uint16_t) data, then data send as << data 30 | 31 | // SPI init in 8 bit mode 32 | #define SPI_CR2_8BIT 0x0700 33 | #define SPI_CR2_16BIT 0x0F00 34 | 35 | //***************************************************** 36 | // SPI bus baud rate (PPL/BR_DIV) 37 | //***************************************************** 38 | #define SPI_BR_DIV2 (0x00000000U) 39 | #define SPI_BR_DIV4 (SPI_CR1_BR_0) 40 | #define SPI_BR_DIV8 (SPI_CR1_BR_1) 41 | #define SPI_BR_DIV16 (SPI_CR1_BR_1|SPI_CR1_BR_0) 42 | #define SPI_BR_DIV32 (SPI_CR1_BR_2) 43 | #define SPI_BR_DIV64 (SPI_CR1_BR_2|SPI_CR1_BR_0) 44 | #define SPI_BR_DIV128 (SPI_CR1_BR_2|SPI_CR1_BR_1) 45 | #define SPI_BR_DIV256 (SPI_CR1_BR_2|SPI_CR1_BR_1|SPI_CR1_BR_0) 46 | 47 | #define SPI_BR_SET(spi, br) (spi->CR1 = (spi->CR1& ~(SPI_CR1_BR))|br) 48 | 49 | //***************************************************** 50 | // SPI bus activity macros 51 | //***************************************************** 52 | // The RXNE flag is set depending on the FRXTH bit value in the SPIx_CR2 register: 53 | // • If FRXTH is set, RXNE goes high and stays high until the RXFIFO level is greater or equal to 1/4 (8-bit). 54 | #define SPI_RX_IS_NOT_EMPTY(spi) (spi->SR&SPI_SR_RXNE) 55 | #define SPI_RX_IS_EMPTY(spi) (!(spi->SR&SPI_SR_RXNE)) 56 | 57 | // The TXE flag is set when transmission TXFIFO has enough space to store data to send. 58 | // 0: Tx buffer not empty, bit is cleared automatically when the TXFIFO level becomes greater than 1/2 59 | // 1: Tx buffer empty, flag goes high and stays high until the TXFIFO level is lower or equal to 1/2 of the FIFO depth 60 | #define SPI_TX_IS_NOT_EMPTY(spi) (!(spi->SR&SPI_SR_TXE)) 61 | #define SPI_TX_IS_EMPTY(spi) (spi->SR&SPI_SR_TXE) 62 | 63 | // When BSY is set, it indicates that a data transfer is in progress on the SPI (the SPI bus is busy). 64 | #define SPI_IS_BUSY(spi) (spi->SR & SPI_SR_BSY) 65 | 66 | // Tx or Rx in process 67 | #define SPI_IN_TX_RX(spi) ((spi->SR & (SPI_SR_TXE | SPI_SR_RXNE)) == 0 || SPI_IS_BUSY(spi)) 68 | 69 | //***************************************************** 70 | // SPI send data macros 71 | //***************************************************** 72 | #define SPI_WRITE_8BIT(spi, data) *(__IO uint8_t*)(&spi->DR) = (uint8_t) data 73 | #define SPI_WRITE_16BIT(spi, data) *(__IO uint16_t*)(&spi->DR) = (uint16_t) data 74 | 75 | //***************************************************** 76 | // SPI read data macros 77 | //***************************************************** 78 | #define SPI_READ_8BIT(spi) *(__IO uint8_t*)(&spi->DR) 79 | #define SPI_READ_16BIT(spi) *(__IO uint16_t*)(&spi->DR) 80 | 81 | -------------------------------------------------------------------------------- /usbcfg.h: -------------------------------------------------------------------------------- 1 | /* 2 | ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #ifndef _USBCFG_H_ 18 | #define _USBCFG_H_ 19 | 20 | extern const USBConfig usbcfg; 21 | extern SerialUSBConfig serusbcfg; 22 | extern SerialUSBDriver SDU1; 23 | 24 | #endif /* _USBCFG_H_ */ 25 | 26 | /** @} */ 27 | -------------------------------------------------------------------------------- /vna_math.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2021, Dmitry (DiSlord) dislordlive@gmail.com 3 | * All rights reserved. 4 | * 5 | * This is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 3, or (at your option) 8 | * any later version. 9 | * 10 | * The software is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with GNU Radio; see the file COPYING. If not, write to 17 | * the Free Software Foundation, Inc., 51 Franklin Street, 18 | * Boston, MA 02110-1301, USA. 19 | */ 20 | #ifndef __VNA_MATH_H 21 | #define __VNA_MATH_H 22 | // Use math.h functions if need 23 | #include 24 | 25 | #ifndef __FPU_PRESENT 26 | #define __FPU_PRESENT 0 27 | #endif 28 | #ifndef __FPU_USED 29 | #define __FPU_USED 0 30 | #endif 31 | 32 | // VNA math used library 33 | #ifdef __USE_VNA_MATH__ 34 | // Some functions implemented in hardware FPU 35 | #if (__FPU_PRESENT == 1) && (__FPU_USED == 1) 36 | __attribute__((always_inline)) __STATIC_INLINE float vna_fabsf(float x){__asm__ ("vabs.f32 %0, %1" : "=t"(x) : "t"(x)); return x;} 37 | __attribute__((always_inline)) __STATIC_INLINE float vna_sqrtf(float x){__asm__ ("vsqrt.f32 %0, %1" : "=t"(x) : "t"(x)); return x;} 38 | __attribute__((always_inline)) __STATIC_INLINE float vna_fmaf(float x, float y, float z){__asm__ ("vfma.f32 %0, %1, %2" : "+t"(z) : "t"(x), "t"(y)); return z;} 39 | 40 | #else 41 | // Define inline functions 42 | __attribute__((always_inline)) __STATIC_INLINE float vna_fabsf(float x){union {float f; uint32_t i;} u = {x}; u.i &= 0x7fffffff; return u.f;} 43 | __attribute__((always_inline)) __STATIC_INLINE float vna_fmaf(float x, float y, float z){return z+x*y;} 44 | // square root 45 | float vna_sqrtf(float x); 46 | #endif 47 | //================================ 48 | // log 49 | float vna_logf(float x); 50 | float vna_log10f_x_10(float x); 51 | float vna_expf(float x); 52 | // atan 53 | float vna_atanf(float x); 54 | float vna_atan2f(float x, float y); 55 | // modff 56 | float vna_modff(float x, float *iptr); 57 | #else 58 | // Use defaults math functions 59 | #define vna_fabsf fabsf 60 | #define vna_sqrtf sqrtf 61 | #define vna_logf logf 62 | #define vna_log10f_x_10 (logf(x) * (10.0f / logf(10.0f))) 63 | #define vna_expf expf 64 | #define vna_atanf atanf 65 | #define vna_atan2f atan2f 66 | #define vna_modff modff 67 | #endif 68 | 69 | // fft 70 | void fft(float array[][2], const uint8_t dir); 71 | #define fft_forward(array) fft(array, 0) 72 | #define fft_inverse(array) fft(array, 1) 73 | 74 | // cube root 75 | float vna_cbrtf(float x); 76 | 77 | // Return sin/cos value, angle have range 0.0 to 1.0 (0 is 0 degree, 1 is 360 degree) 78 | void vna_sincosf(float angle, float * pSinVal, float * pCosVal); 79 | 80 | #endif 81 | --------------------------------------------------------------------------------