.. index:: svd2db-v2,readdb,gema,make,xsltproc,getopt .. _svd2db-v2: .. All edits ONLY to: /home/tp/projects/programming-languages/forth/mecrisp-stellaris/svd2db-v2/doc/readme.rst .. Then run make in the above dir AND the mecrisp-stellaris/mecrisp-unofficial-doc to update the site ! Svd2db-v2 README ================ Author Copyright 2023,2023 by T.J.Porter https://mecrisp-stellaris-folkdoc.sourceforge.io/index.html license: MIT, please see COPYING Abstract -------- **Svd2db is made to assist designers who may use Gcc, Assembly, Forth, PicoLisp etc, or any new embedded language that does not come with ready made includes or header files containing specific hardware information necessary for embedded programming.** **In many cases this means the STMicro Technical Reference Manual PDF is the main designer resource.** **However using the Reference Manual for programming consumes a *great deal of time* and is error prone by way of typos. It also encourages the temptation to shorten CMSIS-SVD Peripheral_Register_Bitfield names making them non-standard.** **Non-standard CMSIS-SVD Peripheral_Register_Bitfield names decreases traceability, increases maintennance difficulty and prevents source sharing.** **Svd2db is a bit like a *Unix MAN Page* for embedded and is designed for fast searching and listing. Svd2db gets its data from the same place that the Technical Manual does, namely the mcu CMSIS-SVD file.** Programs ^^^^^^^^ **Svd2db**: Creates the Sqlite3 database file named **svd2db.db** given a SVD file as input, ie "make asm SVD=stm32f051.svd" **Readdb**: A Getopt CLI application that searches and reads the database, ie "./readdb -L". Readdb requires a database file named **"svd2db.db"** in the same directory. Download ^^^^^^^^ See https://mecrisp-stellaris-folkdoc.sourceforge.io/new-projects.html#new-projects to find the **svd2db-v2** link. This release contains a sample stm32f051.svd and svd2db.db database so you don't have to build any to test ./readdb Changelog for V2 ---------------- * Description field bug fixed; last two words were often joined together * Everything except style files has been reweitten * Makefile is totally new. Much better layout and more user error handling and messages. * Gemma now does all text processing, no more SED and shell scripts. Much cleaner source. * Makefile variable 'ARGS' changed to 'SVD', i.e. "make asm SVD=mcu-model.svd" Database Reader --------------- Readdb is a CLI based program and entering './readdb' will print instructions and help. Alternate DB Readers ^^^^^^^^^^^^^^^^^^^^ However the Svd2db database does not not require readdb because it is a Sqlite database and there are many other free alternatives such as: * the Sqlite CLI interface itself * GUI Sqlite readers and editors are available for all OS's including windows. * DB Browser for SQLite https://sqlitebrowser.org/ * SQLite Viewer Web App https://sqliteviewer.app/ * SQLite Reader for Chrome https://chrome.google.com/webstore/detail/sqlite-reader/ * And many more, just do web a search for 'Sqlite reader'. Readdb Example ^^^^^^^^^^^^^^ List all bitfields containg 'sleep' in the description field of the PWR peripheral. 'Ar' means Access Rights, 'bw' is BitWidth and 'bo' is BitOffset. 'Address' is the absolute memory location of the PWR_CR register. :: ./readdb -p pwr -b lpds -T name address ar bw bo description ------------------------------ ---------- -- -- -- -------------------------------------------------- PWR_CR_LPDS 0x40007000 rw 1 0 Low Power Deep Sleep Database Information ^^^^^^^^^^^^^^^^^^^^ * The MCU model the database was built for. * CMSIS-SVD compliant Peripheral_Register_Bitfield names. * Absolute Memory Register Addresses. Theae are not available in the Reference Manual. * Description Field. * Bitfield attributes: * BitOffset (bo) * BitWidth (bw) * Access type * read-only (ro) * write-only (wo) * read-wrote (rw) Database Creation ^^^^^^^^^^^^^^^^^ There are two types of database that can be created, the first uses '0x' as the hexadecimal prefix, and the second is '$'. * 0x is used when writing C and Assembly (asm) source. * $ is used when writing Forth source. Syntax ~~~~~~ The commands below are entered in the release directory. The *only* difference between the two database types is the hexadecimal prefix as above. These are supplied as a programmer convenience. 0x Prefix ~~~~~~~~~ :: make asm SVD=STM32F051.svd This will create a database named: :: svd2db.db $ Prefix ~~~~~~~~ :: make forth SVD=STM32F051.svd This will create a database named: :: svd2db.db .. note:: Yes, the database names are the same, but the old one is auto deleted before the new one is created. This way ./readdb will always have the right database name to use when invoked. Supported Mcu's ^^^^^^^^^^^^^^^ Any STM32 Cortex-M MCU with a SVD file. Dependencies ^^^^^^^^^^^^ Unix, Gema (http://gema.sourceforge.net/new/index.shtml), Make, xsltproc, getopt. These should all be available in any unix repo. SVD ~~~ The CMSIS System View Description format (CMSIS-SVD) formalizes the description of the system contained in Arm Cortex-M processor-based micro controllers, in particular, the memory mapped registers of peripherals. The detail contained in system view descriptions is comparable to the data in device reference manuals. The information ranges from high level functional descriptions of a peripheral all the way down to the definition and purpose of an individual bit field in a memory mapped register. * Are XML text files detailing all peripheral registers for ARM MCU families. * May be downloaded from https://github.com/posborne/cmsis-svd/archive/master.zip (39MB) and elsewhere. * Keil, now owned by ARM, have SVD PACKS for all the MCU’s which may be downloaded from their site. * Do not contain ARM specific information such as SYSTICK etc. License ^^^^^^^ MIT, please see COPYING Author ^^^^^^ Terry Porter Copyright 2023 Details and Usage ----------------- Number Bases ^^^^^^^^^^^^ =========== ============== Number Base Prefix =========== ============== Hexadecimal 0x or $ Decimal None =========== ============== Readdb switches ^^^^^^^^^^^^^^^ :: ./readdb **Search switches**, any combination :: -p peripheral name (required by all searches) -b bitfield name or part off -r register name or part off -d Description phrase **Listing switches**, only one :: -L List Peripherals (takes precedence over any other search switches) -T Technical listing, lists all the registers in a peripheral by name ascending. -M Tech Manual Listing, requires -r .. Note:: ./readdb isn't perfect, but it's stable and reliable. If your search returns nothing it usually means a incompatible use of switches. If you don't like it, change it, only shell, getopt and sqlite skills are needed. Please send me a copy of your improved version :) Examples ^^^^^^^^ SD Card Reader ~~~~~~~~~~~~~~ You're designing a SD card reader and need to set the SPI BAUD RATE bitfield, what is it ? Sure, you'll still *probably* need to consult the ref manual to find the three bit code for the Baudrate you need, but you can code the rest first using Svd2db. Enter ~~~~~ :: ./readdb -p spi1 -d baud -T Output ~~~~~~ :: name address ar bw bo description ------------------------------ ---------- -- -- -- -------------------------------------------------- SPI1_CR1_BR 0x40013000 rw 3 3 Baud rate control Display all the Peripherals ~~~~~~~~~~~~~~~~~~~~~~~~~~~ :: ./readdb -L Output ~~~~~~ :: ADC1 CRC EXTI GPIOC IWDG RTC TIM1 USART1 WWDG AFIO DBG FLASH GPIOD NVIC SDIO TIM2 USART2 BKP DMA1 GPIOA I2C1 PWR SPI1 TIM3 USART3 CAN DMA2 GPIOB I2C2 RCC SPI2 TIM4 USB Display all the Register Data ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ :: ./readdb -p pwr -T Output ~~~~~~ :: name address ar bw bo description ------------------------------ ---------- -- -- -- -------------------------------------------------- PWR NULL -- -- 99 STM32F103xx: Power control Peripheral PWR_CR 0x40007000 -- -- 98 Reset:0x00000000 Address: 0x40007000 PWR_CR_CSBF 0x40007000 rw 1 3 Clear STANDBY Flag PWR_CR_CWUF 0x40007000 rw 1 2 Clear Wake-up Flag PWR_CR_DBP 0x40007000 rw 1 8 Disable Backup Domain write protection PWR_CR_LPDS 0x40007000 rw 1 0 Low Power Deep Sleep PWR_CR_PDDS 0x40007000 rw 1 1 Power Down Deep Sleep PWR_CR_PLS 0x40007000 rw 3 5 PVD Level Selection PWR_CR_PVDE 0x40007000 rw 1 4 Power Voltage DetectorEnable PWR_CSR 0x40007004 -- -- 98 Reset:0x00000000 Address: 0x40007004 PWR_CSR_EWUP 0x40007004 rw 1 8 Enable WKUP pin PWR_CSR_PVDO 0x40007004 ro 1 2 PVD Output PWR_CSR_SBF 0x40007004 ro 1 1 STANDBY Flag PWR_CSR_WUF 0x40007004 ro 1 0 Wake-Up Flag Display All Register Names ~~~~~~~~~~~~~~~~~~~~~~~~~~ Ignore any "NULL" names :: ./readdb -p pwr -R register = CR register = CSR register = NULL Display Contents of named Register in a Peripheral, sorted by BitOffset ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Same as in the Reference Manual. :: ./readdb -p pwr -r cr -M name ar bw bo description ------------------------------ -- -- -- -------------------------------------------------- PWR -- -- 99 STM32F0xx: Power control Peripheral PWR_CR -- -- 98 Reset:0x00000000 Address: 0x40007000 PWR_CR_FPDS rw 1 9 Flash power down in Stop mode PWR_CR_DBP rw 1 8 Disable backup domain write protection PWR_CR_PLS rw 3 5 PVD level selection PWR_CR_PVDE rw 1 4 Power voltage detector enable PWR_CR_CSBF rw 1 3 Clear standby flag PWR_CR_CWUF rw 1 2 Clear wakeup flag PWR_CR_PDDS rw 1 1 Power down deepsleep PWR_CR_LPDS rw 1 0 Low-power deep sleep Forth Blinky ------------ :: \ *********************************************************** \ filename: main.fs \ For Mecrisp-Stellaris by Matthias Koch \ by: Terry Porter 2022, released under the GPL License \ Demo of SVD2DB and READDB https:\mecrisp-stellaris-folkdoc.sourceforge.io/readdb.html \ CPU: STM32F051 running at default 8MHz clock \ SVD: STM32F051.svd \ BLUE LED = PC8, blinks about once per second. \ *********************************************************** constant $40021000 RCC_CR constant $40021014 RCC_AHBENR constant $48000800 GPIOC_MODER constant $48000818 GPIOC_BSRR : init ( -- ) 1 19 lshift RCC_AHBENR bis! \ I/O port C clock enable %01 16 lshift GPIOC_MODER bis! \ set Port C, bit 8 Mode to 01: General purpose output mode : : delay ( -- ) 800000 0 do loop ; : main ( -- ) init begin 1 8 lshift GPIOC_BSRR ! \ SET PC8 high. led ON delay 1 25 lshift GPIOC_BSRR ! \ CLR PC8, led OF delay again : Forth Write-only Blinky ^^^^^^^^^^^^^^^^^^^^^^^ Kidding. A real write-only would be 'magic number' source only with no comments. :: : init ( -- ) 1 19 lshift $40021014 bis! \ I/O port C clock enable %01 16 lshift $48000800 bis! \ set Port C, bit 8 Mode to 01: General purpose output mode ; : delay ( -- ) 800000 0 do loop ; : main ( -- ) init begin 1 8 lshift $48000818 ! \ SET PC8 high. led ON delay 1 25 lshift $48000818 ! \ CLR PC8, led OF delay again ; How were the addresses and bitfields derived ? ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Comments show how: :: \ ./readdb -p rcc -r ahbenr -M \ ---> RCC_AHBENR -- -- 98 Reset:$00000014 Address: $40021014 constant $40021014 RCC_AHBENR \ ./readdb -p gpioc -r moder -M \ ---> GPIOC_MODER -- -- 98 Reset:$00000000 Address: $48000800 constant $48000800 GPIOC_MODER \ ./readdb -p gpioc -r bsrr -M \ ---> GPIOC_BSRR -- -- 98 Reset:$00000000 Address: $48000818 constant $48000818 GPIOC_BSRR : init ( -- ) \ ./readdb -p rcc -r ahbenr -T \ ---> RCC_AHBENR_IOPCEN $40021014 rw 1 19 I/O port C clock enable 1 19 lshift RCC_AHBENR bis! \ I/O port C clock enable \ ./readdb -p gpioc -r moder -T \ ---> GPIOC_MODER_MODER8 $48000800 rw 2 16 Port x configuration bits (y =0..15) %01 16 lshift GPIOC_MODER bis! \ set Port C, bit 8 Mode to 01: General purpose output mode : : delay ( -- ) 800000 0 do loop ; : main ( -- ) init begin \ ./readdb -p gpioc -R \ ---> register = BSRR \ ./readdb -p gpioc -r bsrr -M \ ---> GPIOC_BSRR_BS8 wo 1 8 Port x SET BIT y (y=0..15) 1 8 lshift GPIOC_BSRR ! \ SET PC8 high. led ON delay \ ---> GPIOC_BSRR_BR8 wo 1 24 Port x RESET BIT y (y =0..15) 1 25 lshift GPIOC_BSRR ! \ CLR PC8, led OF delay again : C Blinky -------- :: // *********************************************************** // filename: main.c // Original Author: Frank Duignan http://eleceng.dit.ie/frank/arm/BareMetalSTM32F0Discovery/ // Many changes by: Terry Porter 2022, released under the MIT License // Demo of SVD2DB and READDB https://mecrisp-stellaris-folkdoc.sourceforge.io/readdb.html // This demo uses no libraries or headers whilst creating a Blinky for a STM32F0 Discovery board // CPU: STM32F051 running at default 8MHz clock // SVD: STM32F051.svd // BLUE LED = PC8, blinks about once per second.https://dpaste.com/2BCNX3LZX // *********************************************************** volatile int count; #define REGISTER_32(ADDRESS) (*((volatile unsigned int *)(ADDRESS))) #define RCC_AHBENR REGISTER_32(0x40021014) #define GPIOC_MODER REGISTER_32(0x48000800) #define GPIOC_BSRR REGISTER_32(0x48000818) void init(void) { RCC_AHBENR |= 1 << 19; // I/O port C clock enable GPIOC_MODER |= 0x01 << 16; // set Port C, bit 8 Mode to 01: General purpose output mode } void delay(void) { count = 4; // large for visible blinking // count = 800000; while(count--); } int main() { init(); while(1) { GPIOC_BSRR = 1 << 8; // SET PC8 high. led ON delay(); GPIOC_BSRR = 1 << 24; // CLR PC8, led OFF delay(); } return 0; } How were the addresses and bitfields derived ? ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ :: volatile int count; #define REGISTER_32(ADDRESS) (*((volatile unsigned int *)(ADDRESS))) // ./readdb -p rcc -r ahbenr -M // ---> RCC_AHBENR -- -- 98 Reset:0x00000014 Address: 0x40021014 #define RCC_AHBENR REGISTER_32(0x40021014) // ./readdb -p gpioc -r moder -M // ---> GPIOC_MODER -- -- 98 Reset:0x00000000 Address: 0x48000800 #define GPIOC_MODER REGISTER_32(0x48000800) // ./readdb -p gpioc -r bsrr -M // ---> GPIOC_BSRR -- -- 98 Reset:0x00000000 Address: 0x48000818 #define GPIOC_BSRR REGISTER_32(0x48000818) void init(void) { // ./readdb -p rcc -r ahbenr -T // ---> RCC_AHBENR_IOPCEN 0x40021014 rw 1 19 I/O port C clock enable RCC_AHBENR |= 1 << 19; // I/O port C clock enable // ./readdb -p gpioc -r moder -T // ---> GPIOC_MODER_MODER8 0x48000800 rw 2 16 Port x configuration bits (y =0..15) GPIOC_MODER |= 0x01 << 16; // set Port C, bit 8 Mode to 01: General purpose output mode } void delay(void) { // small for gdb testing count = 4; // large for visible blinking // count = 800000; while(count--); } int main() { init(); while(1) { // ./readdb -p gpioc -R // ---> register = BSRR // ./readdb -p gpioc -r bsrr -M // ---> GPIOC_BSRR_BS8 wo 1 8 Port x SET BIT y (y=0..15) GPIOC_BSRR = 1 << 8; // SET PC8 high. led ON delay(); // ---> GPIOC_BSRR_BR8 wo 1 24 Port x RESET BIT y (y =0..15) GPIOC_BSRR = 1 << 24; // CLR PC8, led OFF delay(); } return 0; }