diff --git a/README.md b/README.md index a4836d2..c6d57af 100644 --- a/README.md +++ b/README.md @@ -1,26 +1,74 @@ # LoLRa -*Transmit 900MHz LoRa frames surprisingly far without a radio* +Transmit 900MHz LoRa frames surprisingly far without a radio (And other radio shenanigans using ADCs, PWMs and I2S/SPI busses) including sending other RF data, as well as receiving RF signals (Though admittedly not a LoRa receiver). - * [Introduction](#introduction) - * [Background](#background) - * [LoRaWAN](#lorawan) - * [Limitations](#limitations) - * [Future Work](#future-work) - * [Resources](#resources) - * [Special Thanks](#special-thanks) - * [Range Tests](#range-tests) +If you are looking for the Hackaday 2024 microcontroller radio talk, you can click here. -## Introduction +If you are looking for LoLRa Merch (Like t-shirts, etc.), click here. -Firmware-only LoRa transmission, for a variety of processors. Send LoRa packets, without any radio, chips, external hardware or built-in radios at all on a variety of common, inexpensive processors. While not truly bit banging, this repository shows how using either a shift register (i.e. I2S or SPI port) or an APLL, you can send LoRa packets that can be decoded by commercial off the shelf LoRa gateways and other chips. + * [Introduct and repo overview](#introduction-and-repo-overview) + * LoRa + * [Introduction (LoRa)](#introduction-lora) + * [Background](#background) + * [LoRaWAN](#lorawan) + * [Limitations](#limitations) + * [Future Work](#future-work) + * [Resources](#resources) + * [Special Thanks](#special-thanks) + * [Range Tests](#range-tests) > [!NOTE] -> This repo is designed for use with ITU Region 2 (The Americas) targeting 902-928MHz. Code changes are needed for use in Region 1 (EU, Russia, Africa) to target 863-870MHz or Region 3 (Australia, China, India) to target 920-923MHz. +> 1. Portions of code in this repo are under various licenses and cannot be trivially incorporated into other libraries, including some files containing a no-ai-training license for any of the RF-specific portions of the project. Be cautious when using code from this repo. See ![LICENSE](LICENSE) for more information. +> 2. The LoRa® and LoRaWAN® Mark and LoRa Logo are trademarks of Semtech Corporation. +> 3. LoLRa is not associated with Semtech in any way whatsoever. +> 4. This repo is designed for use with ITU Region 2 (The Americas) targeting 902-928MHz. Code changes are needed for use in Region 1 (EU, Russia, Africa) to target 863-870MHz or Region 3 (Australia, China, India) to target 920-923MHz. > [!CAUTION] > Because we rely on harmonics and aliasing, the primary frequency components emitted by your microcontroller are going to be in portions of the RF spectrum where RF transmissions are banned. Please filter your output or perform your tests in an area where you are unlikely to leak significant RF. The overall EIRP output is genreally ≪300uW across the whole spectrum spread out over hundreds of emission frequencies, but there is virtually no way a device deliberately transmitting on these frequencies could ever pass FCC part 15 compliance, even with filtering. + +## Introduction and Repo Overview + +I have always been fascinated with sending and receiving radio signals from microcontrollers that don't have dedicated radio hardware. This repo serves as a overview of many of the projects I've done to do this decoding, along with example code (Though some of it is restrictively licensed) + +In general the repo is split up in to many projects, but categoriezed by device type. + + * ch32v (Note, all examples require 8MHz (v203) or 24Mhz (v003) crystal oscillator) + * General Note: All OLED displays used here are 128x128 SPI-mode OLED displays. + * [ch32v003-adcrx](ch32v/ch32v003-adcrx) - prints quadrature values for receiving at 1/4 sample rate signals, or harmonics thereof. Specifically this is tuned to receiv CW on citizen band frequencies, specifically 27.000050 MHz + * [ch32v003-lora](ch32v/ch32v003-lora) - Successful (but very poor) transmission of LoRa messages with a ch32v003. + * [ch32v003-timer](ch32v/ch32v003-timer) - An attempt to use non-tabled dithering of PWM signals to send FM radio and/or 315MHz signals. *This does not work well* but it is included as a reference for dtrying to dither RF on the 003. + * [ch32v003-txrx](ch32v/ch32v003-txrx) - Trying to send from one 003 to another 003 receiving. This does not work well - only about 1'. + * [ch32v203-adcrx](ch32v203-adcrx) - Very basic quadrature decoding on a ch32v203. + * [ch32v203-fft](ch32v203-fft) - Perform an FFT on a small window of samples on a ch32v203. This outputs to an OLED display. It doesn't keep up in realtime though. It also relies on fix_fft.h (which cannot be distirbuted with this project because of a lack of license. + * [**ch32v203-goertzel**](ch32v/ch32v203-goertzel) - Perform a full goertzel's tuning on an incoming ADC signal so that it can listen to multiple AM and NBFM radio stations from an ADC pin. + * [lib/calculator.html](ch32v/lib/calculator.html) - webpage that can use webhid with ch32v203-goertzel. + * [**ch32v203-lora**](ch32v/ch32v203-lora) - Proper transmission of LoRaWAN packets (from the tests outlined below). + * [ch32v203-tx](ch32v/ch32v203-tx) - Very basic test, setup to just turn on a PWM on the ch32v203. + * esp32-s2 + * [**loratest**](esp32-s2/loratest) - Full stack protocol for sending LoRa messages from an esp32-s2. (From range test) + * [**narrow_fsk_test**](esp32-s2/narrow_fsk_test) - Very basic test using dithering and the PLL in the esp32-s2 to see how tight/narrow control is possible with the esp32-s2. This does not do a dithered closed loop, but would not be terribly hard to add. + * [**videoending**](esp32-s2/videoending) - Mechanism for allowing an ESP32-S2 to FSK, hopping around to draw a picture in a spectrogram. This was used for the video ending. + * esp8266 + * [example_125k_raw](esp8266/example_125k_raw) - Sending a raw 125kHz wide LoRa message. + * [example_500k_raw](esp8266/example_500k_raw) - Sending a raw 500kHz wide LoRa message. + * [**lorawan_example**](esp8266/lorawan_example) - Using the I2S bus on the ESP8266 to send a full-stack LoRaWAN message to the things network. + * [non_lora_310_transmit](esp8266/non_lora_310_transmit) - Exmaple of how to transmit 310MHz OOK with an ESP8266. + * lib + * [aes-cbc-cmac.h](lib/aes-cbc-cmac.h) - Public Domain RFC4493 AES-CMAC header only library. + * [LoRa-SDR-Code.h](lib/LoRa-SDR-Code.h) - MIT (unrestrictive) Licensed code to construct LoRa packets + * [lorawan_simple.h](lib/lorawan_simple.h) - MIT (unrestrictive) Licensed code to construct LoRaWAN packets. + * [rf_data_gen.h](lib/rf_data_gen.h) - Helper function for helping generate bit tables for I2S/SPI outpiut of carefully crafted signals. + * [tiny-AES-c.h](lib/rf_data_gen.h) - Public Domain AES encryption/decryption library. + * tools + * [60-rtlsdr.rules](tools/60-rtlsdr.rules) - Make it so you can use your airspy from Linux as a user. + * [complex_magsink_to_image.c](tools/complex_magsink_to_image.c) - Generate ultra high resolution (in time domain) waterfall views. + * [testloradec.grc](tools/testloradec.grc) - Using gr_lora exmaple to decode LoRa in GNURadio + +## Introduction (LoRa) + +Firmware-only LoRa transmission, for a variety of processors. Send LoRa packets, without any radio, chips, external hardware or built-in radios at all on a variety of common, inexpensive processors. While not truly bit banging, this repository shows how using either a shift register (i.e. I2S or SPI port) or an APLL, you can send LoRa packets that can be decoded by commercial off the shelf LoRa gateways and other chips. + There are two major modes that this repository works with. 1. Transmission using a tunable PLL, creating a square wave, then using a harmonic (the 13th harmonic in the case of the ESP32-S2) and then transmitting the signal out a clock out pin. @@ -31,9 +79,6 @@ Click Below for the Youtube Video version of this page: [![LoRa Without A Radio](https://i3.ytimg.com/vi/eIdHBDSQHyw/maxresdefault.jpg)](https://www.youtube.com/watch?v=eIdHBDSQHyw) -> [!NOTE] -> Portions of code in this repo are under various licenses and cannot be trivially incorporated into other libraries without a bit of a mess, including a no-ai-training license for any of the RF-specific portions of the project. Be cautious when using code from this repo. See ![LICENSE](LICENSE) for more information. - ## Background ### Square waves, and images @@ -93,11 +138,11 @@ While LoRa can be used with many different channel widths, 125kHz and 500kHz are ![Bitstream Analysis](resources/bitstreamdiagram.png) This diagram shows frequency on the X axis, and time on the Y axis (top to bottom)... You can see: - * **𝔸** our output on a platform like the CH32V203 is not perfect, that's because the SPI bus on the CH32V203 glitches by parts of a bit here and there. This causes other, weaker images in the output. But, largely we can produce totally valid and readable (at a long distance) LoRa packets. - * **𝔹** LoRa consists of several upchirps some in a preamble. + * **�** our output on a platform like the CH32V203 is not perfect, that's because the SPI bus on the CH32V203 glitches by parts of a bit here and there. This causes other, weaker images in the output. But, largely we can produce totally valid and readable (at a long distance) LoRa packets. + * **�** LoRa consists of several upchirps some in a preamble. * **ℂ** two more upchirps with a phase offset indicating a sync word if we select 0x43 (or 0x34 depending on endian) for the upchirps here, our packets will be decoded and potentially forwarded by commercial LoRa gateways. - * **𝔻** 2.25 down chrips in. That extra .25 causes some pain 😈 (the minimum logical unit is a quarter chirp, not a whole chirp). - * Then a payload where each upchirp is offset by a phase to convey information in **𝔼**. + * **�** 2.25 down chrips in. That extra .25 causes some pain � (the minimum logical unit is a quarter chirp, not a whole chirp). + * Then a payload where each upchirp is offset by a phase to convey information in **�**. Conveniently the window for a given chirp is stable depending on the spreading factor. For the above packet, with SF7, it works out to 1,024us per symbol, or for SF8, 2,048us per symbol. Each symbol/chirp can represent a number of bits, by a phase offset. @@ -260,3 +305,4 @@ Low Overhead Radios Using Side-Channels](https://dl.acm.org/doi/abs/10.1145/3583 * My girlfriend for testing help and auxiliary camera work * Everyone who helped out with my various open source projects + diff --git a/ch32v/ch32v003-adcrx/Makefile b/ch32v/ch32v003-adcrx/Makefile new file mode 100644 index 0000000..81d63e1 --- /dev/null +++ b/ch32v/ch32v003-adcrx/Makefile @@ -0,0 +1,15 @@ +all : flash + +TARGET:=adcrx +TARGET_MCU:=CH32V003 +CH32V003FUN:=../ch32v003fun/ch32v003fun + + +EXTRA_CFLAGS:=-Wno-unused-function -I../../lib + +include ../ch32v003fun/ch32v003fun/ch32v003fun.mk + +flash : cv_flash +clean : cv_clean + rm -rf rf_data_gen chirpbuff.dat chirpbuff.h chirpbuffinfo.h + diff --git a/ch32v/ch32v003-adcrx/adcrx.c b/ch32v/ch32v003-adcrx/adcrx.c new file mode 100644 index 0000000..9bc138a --- /dev/null +++ b/ch32v/ch32v003-adcrx/adcrx.c @@ -0,0 +1,360 @@ +/** + +MIT-like-non-ai-license + +Copyright (c) 2024 Charles Lohr "CNLohr" + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the two following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +In addition the following restrictions apply: + +1. The Software and any modifications made to it may not be used for the +purpose of training or improving machine learning algorithms, including but not +limited to artificial intelligence, natural language processing, or data +mining. This condition applies to any derivatives, modifications, or updates +based on the Software code. Any usage of the Software in an AI-training dataset +is considered a breach of this License. + +2. The Software may not be included in any dataset used for training or +improving machine learning algorithms, including but not limited to artificial +intelligence, natural language processing, or data mining. + + +3. Any person or organization found to be in violation of these restrictions +will be subject to legal action and may be held liable for any damages +resulting from such use. + +If any term is unenforcable, other terms remain in-force. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +**/ + +// NOT LORA!!! -- but experimenting with the possibility of rx. + +// SETUP INSTRUCTIONS: +// (1) `make` in the optionbytes folder to configure `RESET` correctly. +// (2) Create a tone (if using the funprog, ../ch32v003fun/minichlink/minichlink -X ECLK 1:235:189:9:3 for 27.48387097MHz +// (2) or, for 24.387096762MHz - ../ch32v003fun/minichlink/minichlink -X ECLK 1:150:49:8:3 + + + + +#include "ch32v003fun.h" +#include + +/* General note: + Max speed was found to be: + ADCclk = RCC / 2 + SAMPTR2 = 0 (3 cycles) + PWM period = 27 (48/28 = 1.714MHz) + + If you go a little slower... + ADCclk = RCC / 2 + SAMPTR2 = 1 (9 cycles) + PWM period = 39 (48/40 = 1.2MHz) + + Perform Quadrature Decoding + I = + + - - + Q = + - - + + + We want the target waveform to be exactly n * Fs - fs / 4 = FBrd + for a natural value of n. + 27 / (n-1/4) = Fs + + Oddly enough, after creating a table with various values of N and + possible divisors, a PERFECT divisor works out to the "max speed" listed above (1.714MHz) + but that makes me scared at this juncture. What if we intentionally just target 1.5MHz? + 1.5 = freq / (n-1/4) + arbitrarily select n to be 17 (for the 17th harmonic) + + TODO: Is it supposed to be n-1/4 or n+1/4 or does it not matter? + + + We will be targeting 48/35 MHz - (with PWM_PERIOD 34) + Calculated to use the 19.75th harmonic @ 27.08571429MHz, but ideal found at 27.08643MHz +*/ + +#define Q 1000 + +#define PWM_PERIOD (28-1) //For 27.000500MHz +//#define QUADRATURE +//#define TIGHT_OUT +//#define DUMPBUFF +#define PWM_OUTPUT 7 + +//#define PWM_PERIOD (32-1) +//#define QUADRATURE +//#define PWM_OUTPUT 3 + +#define ADC_BUFFSIZE 256 +volatile uint16_t adc_buffer[ADC_BUFFSIZE]; + +void SetupADC() +{ + + // Reset the ADC to init all regs + RCC->APB2PRSTR |= RCC_APB2Periph_ADC1; + RCC->APB2PRSTR &= ~RCC_APB2Periph_ADC1; + + // ADCCLK = 12 MHz => RCC_ADCPRE divide by 4 + RCC->CFGR0 &= ~RCC_ADCPRE; // Clear out the bis in case they were set + RCC->CFGR0 |= RCC_ADCPRE_DIV2; // Fastest possible (divide-by-2) NOTE: This is OUTSIDE the specified value in the datasheet. + + // Set up single conversion on chl 7 + ADC1->RSQR1 = 0; + ADC1->RSQR2 = 0; + ADC1->RSQR3 = 6; // 0-9 for 8 ext inputs and two internals /// 7 or 6 means one of the ADC inputs. + + // Not using injection group. + + // PD4 is analog input chl 7 + 6 + GPIOD->CFGLR &= ~(0xf<<(4*4)); // CNF = 00: Analog, MODE = 00: Input + GPIOD->CFGLR &= ~(0xf<<(4*6)); // CNF = 00: Analog, MODE = 00: Input + + // Sampling time for channels. Careful: This has PID tuning implications. + // Note that with 3 and 3,the full loop (and injection) runs at 138kHz. + ADC1->SAMPTR2 = (0<<(3*7)); + + // Turn on ADC and set rule group to sw trig + // 0 = Use TRGO event for Timer 1 to fire ADC rule. + ADC1->CTLR2 = ADC_ADON | ADC_EXTTRIG | ADC_DMA; + + // Reset calibration + ADC1->CTLR2 |= ADC_RSTCAL; + while(ADC1->CTLR2 & ADC_RSTCAL); + + // Calibrate ADC + ADC1->CTLR2 |= ADC_CAL; + while(ADC1->CTLR2 & ADC_CAL); + + // ADC_SCAN: Allow scanning. + ADC1->CTLR1 = ADC_SCAN; + + // Turn on DMA + RCC->AHBPCENR |= RCC_AHBPeriph_DMA1; + + //DMA1_Channel1 is for ADC + DMA1_Channel1->PADDR = (uint32_t)&ADC1->RDATAR; + DMA1_Channel1->MADDR = (uint32_t)adc_buffer; + DMA1_Channel1->CNTR = ADC_BUFFSIZE; + DMA1_Channel1->CFGR = + DMA_M2M_Disable | + DMA_Priority_VeryHigh | + DMA_MemoryDataSize_HalfWord | + DMA_PeripheralDataSize_HalfWord | + DMA_MemoryInc_Enable | + DMA_Mode_Circular | + DMA_DIR_PeripheralSRC; + + // Turn on DMA channel 1 + DMA1_Channel1->CFGR |= DMA_CFGR1_EN; + + // Enable continuous conversion and DMA + //ADC1->CTLR2 |= ADC_DMA | ADC_EXTSEL; //ADC_CONT + + // start conversion + ADC1->CTLR2 |= ADC_SWSTART; + +} + +static void SetupTimer1() +{ + // Enable Timer 1 + RCC->APB2PRSTR |= RCC_APB2Periph_TIM1; + RCC->APB2PRSTR &= ~RCC_APB2Periph_TIM1; + + TIM1->PSC = 0x0000; // Prescalar to 0x0000 (so, 48MHz base clock) + TIM1->ATRLR = PWM_PERIOD; + +#ifdef PWM_OUTPUT + GPIOC->CFGLR &= ~(0xf<<(4*4)); + GPIOC->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP_AF)<<(4*4); + + TIM1->CCER = TIM_CC4E | TIM_CC4P; + TIM1->CHCTLR2 = TIM_OC4M_2 | TIM_OC4M_1; + TIM1->CH4CVR = 5; // Actual duty cycle (Off to begin with) +#endif + + // Setup TRGO for ADC. This makes is to the ADC will trigger on timer + // reset, so we trigger at the same position every time relative to the + // FET turning on. + TIM1->CTLR2 = TIM_MMS_1; + + // Enable TIM1 outputs + TIM1->BDTR = TIM_MOE; + TIM1->CTLR1 = TIM_CEN; +} + + +void InnerLoop() __attribute__((noreturn)); + + +void InnerLoop() +{ + int i = 0; + int q = 0; + int tpl = 0; + + // Timer goes backwards when we are moving forwards. + volatile uint16_t * adc_buffer_end = 0; + volatile uint16_t * adc_buffer_top = adc_buffer + ADC_BUFFSIZE; + volatile uint16_t * adc = adc_buffer; + + int frcnt = 0; + + int tstart = 0; + +#ifdef DUMPBUFF + uint16_t shadowbuff[Q+16]; + int shadowplace = 0; + #define SHADOWSTORE(X) shadowbuff[frcnt+X] = t; +#else + #define SHADOWSTORE(X) +#endif + + while( 1 ) + { + tpl = ADC_BUFFSIZE - DMA1_Channel1->CNTR; // Warning, sometimes this is == to the base, or == 0 (i.e. might be 256, if top is 255) + if( tpl == ADC_BUFFSIZE ) tpl = 0; + + adc_buffer_end = adc_buffer + ( ( tpl / 4) * 4 ); +//printf( "%3d %4d %d %04x\n", DMA1_Channel1->CNTR, TIM1->CNT, ADC1->RDATAR, ADC1->STATR ); + while( adc != adc_buffer_end ) + { +#ifdef QUADRATURE + int32_t t = adc[0]; SHADOWSTORE(0); + i += t; q += t; + t = adc[1]; SHADOWSTORE(1); + i -= t; q += t; + t = adc[2]; SHADOWSTORE(2); + i -= t; q -= t; + t = adc[3]; SHADOWSTORE(3); + i += t; q -= t; + adc += 4; + frcnt += 4; +#else + i = i + adc[0] - adc[1]; + adc += 2; + frcnt += 2; +#endif + + if( adc == adc_buffer_top ) adc = adc_buffer; + if( frcnt >= Q ) break; + } + + + if( frcnt >= Q ) + { + +#ifdef DUMPBUFF + int j; + for( j = 0; j < Q; j++ ) + printf( "%d,%d\n", j, shadowbuff[j] ); +#endif +#ifdef QUADRATURE + int ti = i>>3; + int tq = q>>3; + int is = (ti*ti + tq*tq)>>8; +#else + int is = ((i<0)?-i:i)>>2; +#endif + int s = 1<<( ( 32 - __builtin_clz(is) )/2); + s = (s + is/s)/2; + +#ifdef TIGHT_OUT + printf( "%d\n", is ); +#elif defined( PWM_OUTPUT ) + + + int tv = (i>>PWM_OUTPUT) + (PWM_PERIOD/2); + if( tv < 0 ) tv = 0; + if( tv >= PWM_PERIOD ) tv = PWM_PERIOD-1; + + TIM1->CH4CVR = tv; +#else + + printf( "%8d I:%7d Q:%7d [%d %d %d %d] / %d\n",s, i ,q, adc_buffer[0], adc_buffer[1], adc_buffer[2], adc_buffer[3], (int)(SysTick->CNT - tstart) ); +#endif + //printf( "%d\n", s ); + frcnt = 0; + i = 0; + q = 0; + tpl = ADC_BUFFSIZE - DMA1_Channel1->CNTR; + adc = adc_buffer + ( ( tpl / 4) * 4 ); + tstart = SysTick->CNT; + } +/* + Delay_Us( 100 ); + int end = DMA1_Channel1->CNTR; + int v0 = adc_buffer[0]; + int v1 = adc_buffer[1]; + int v2 = adc_buffer[2]; + int v3 = adc_buffer[3]; + printf( "%d %d %d %d %d\n", (uint8_t)(start-end), v0, v1, v2, v3 ); +*/ + } + + +} + +int main() +{ + // REQUIRES External 24MHz oscillator + printf( "Initializing\n" ); + + SystemInit(); + + Delay_Ms(10); + + printf( "System On\n" ); + + // Enable Peripherals + RCC->APB2PCENR |= RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOC | + RCC_APB2Periph_GPIOA | RCC_APB2Periph_TIM1 | RCC_APB2Periph_ADC1 | + RCC_APB2Periph_AFIO; + + RCC->APB1PCENR = RCC_APB1Periph_TIM2; + + // Disable HSI + RCC->CTLR &= ~(RCC_HSION); + + printf( "CTLR: %08x CFGR0: %08x\n", RCC->CTLR, RCC->CFGR0 ); + + SetupADC(); + + +#if 0 + // turn on the op-amp + EXTEN->EXTEN_CTR |= EXTEN_OPA_EN; + + // select op-amp pos pin: 0 = PA2, 1 = PD7 + EXTEN->EXTEN_CTR |= EXTEN_OPA_PSEL; + + // select op-amp neg pin: 0 = PA1, 1 = PD0 + EXTEN->EXTEN_CTR |= EXTEN_OPA_NSEL; +#endif + + + printf( "ADC Setup\n" ); + + SetupTimer1(); + + printf( "Timer 1 setup\n" ); + + InnerLoop(); +} diff --git a/ch32v/ch32v003-adcrx/funconfig.h b/ch32v/ch32v003-adcrx/funconfig.h new file mode 100644 index 0000000..eb91275 --- /dev/null +++ b/ch32v/ch32v003-adcrx/funconfig.h @@ -0,0 +1,10 @@ +#ifndef _FUNCONFIG_H +#define _FUNCONFIG_H + +#define FUNCONF_USE_DEBUGPRINTF 1 +#define FUNCONF_USE_UARTPRINTF 0 +#define FUNCONF_USE_HSE 1 +#define FUNCONF_SYSTICK_USE_HCLK 1 + +#endif + diff --git a/ch32v/ch32v003/Makefile b/ch32v/ch32v003-lora/Makefile similarity index 100% rename from ch32v/ch32v003/Makefile rename to ch32v/ch32v003-lora/Makefile diff --git a/ch32v/ch32v003/README.md b/ch32v/ch32v003-lora/README.md similarity index 100% rename from ch32v/ch32v003/README.md rename to ch32v/ch32v003-lora/README.md diff --git a/ch32v/ch32v003/funconfig.h b/ch32v/ch32v003-lora/funconfig.h similarity index 100% rename from ch32v/ch32v003/funconfig.h rename to ch32v/ch32v003-lora/funconfig.h diff --git a/ch32v/ch32v003/loratest.c b/ch32v/ch32v003-lora/loratest.c similarity index 100% rename from ch32v/ch32v003/loratest.c rename to ch32v/ch32v003-lora/loratest.c diff --git a/ch32v/ch32v003/rf_data_gen.c b/ch32v/ch32v003-lora/rf_data_gen.c similarity index 100% rename from ch32v/ch32v003/rf_data_gen.c rename to ch32v/ch32v003-lora/rf_data_gen.c diff --git a/ch32v/ch32v003-timer/Makefile b/ch32v/ch32v003-timer/Makefile new file mode 100644 index 0000000..55946f9 --- /dev/null +++ b/ch32v/ch32v003-timer/Makefile @@ -0,0 +1,15 @@ +all : flash + +TARGET:=nonlora +TARGET_MCU:=CH32V003 +CH32V003FUN:=../ch32v003fun/ch32v003fun + + +EXTRA_CFLAGS:=-Wno-unused-function -I../../lib + +include ../ch32v003fun/ch32v003fun/ch32v003fun.mk + +flash : cv_flash +clean : cv_clean + rm -rf rf_data_gen chirpbuff.dat chirpbuff.h chirpbuffinfo.h + diff --git a/ch32v/ch32v003-timer/README.md b/ch32v/ch32v003-timer/README.md new file mode 100644 index 0000000..f899063 --- /dev/null +++ b/ch32v/ch32v003-timer/README.md @@ -0,0 +1,9 @@ +# DMA Timer CH32V003 Firmware-Only 315MHz / 97.7 FM Transmitting code + +THIS IS A DRAFT + +Be sure to provide a 24MHz clock (not crystal unless you disable the bypass) on PA1. + +Output will be on PC3 (T1C3) + +Generally you cannot use the built-in oscillator circuit becuase it's too spread-y. diff --git a/ch32v/ch32v003-timer/backup-interesting-stars/Makefile b/ch32v/ch32v003-timer/backup-interesting-stars/Makefile new file mode 100644 index 0000000..7854584 --- /dev/null +++ b/ch32v/ch32v003-timer/backup-interesting-stars/Makefile @@ -0,0 +1,14 @@ +all : flash + +TARGET:=loratest +TARGET_MCU:=CH32V003 +CH32V003FUN:=../../ch32v003fun/ch32v003fun + +EXTRA_CFLAGS:=-Wno-unused-function -I../../../lib + +include ../../ch32v003fun/ch32v003fun/ch32v003fun.mk + +flash : cv_flash +clean : cv_clean + rm -rf rf_data_gen chirpbuff.dat chirpbuff.h chirpbuffinfo.h + diff --git a/ch32v/ch32v003-timer/backup-interesting-stars/funconfig.h b/ch32v/ch32v003-timer/backup-interesting-stars/funconfig.h new file mode 100644 index 0000000..50db3cf --- /dev/null +++ b/ch32v/ch32v003-timer/backup-interesting-stars/funconfig.h @@ -0,0 +1,9 @@ +#ifndef _FUNCONFIG_H +#define _FUNCONFIG_H + +#define FUNCONF_USE_DEBUGPRINTF 1 +#define FUNCONF_USE_UARTPRINTF 0 +#define FUNCONF_SYSTICK_USE_HCLK 1 + +#endif + diff --git a/ch32v/ch32v003-timer/backup-interesting-stars/loratest.c b/ch32v/ch32v003-timer/backup-interesting-stars/loratest.c new file mode 100644 index 0000000..2713d29 --- /dev/null +++ b/ch32v/ch32v003-timer/backup-interesting-stars/loratest.c @@ -0,0 +1,585 @@ +/** + +MIT-like-non-ai-license + +Copyright (c) 2024 Charles Lohr "CNLohr" + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the two following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +In addition the following restrictions apply: + +1. The Software and any modifications made to it may not be used for the +purpose of training or improving machine learning algorithms, including but not +limited to artificial intelligence, natural language processing, or data +mining. This condition applies to any derivatives, modifications, or updates +based on the Software code. Any usage of the Software in an AI-training dataset +is considered a breach of this License. + +2. The Software may not be included in any dataset used for training or +improving machine learning algorithms, including but not limited to artificial +intelligence, natural language processing, or data mining. + + +3. Any person or organization found to be in violation of these restrictions +will be subject to legal action and may be held liable for any damages +resulting from such use. + +If any term is unenforcable, other terms remain in-force. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +**/ + +// XXX WARNING: Something is wrong with this - +// The output isn't perfectly time aligned +// And as such there are extra images in weird places. +// TODO: Investigate the DMA+SPI Port jankyness. +#include "ch32v003fun.h" +#include +#include + +#include "LoRa-SDR-Code.h" + +#define DMA_SIZE_WORDS 128 + +#define SENDBUFF_WORDS (DMA_SIZE_WORDS*2) +uint8_t sendbuff[SENDBUFF_WORDS]; + + +// Bits are shifted out MSBit first, then to LSBit + + +#define MAX_BYTES 25 +#define MAX_SYMBOLS (MAX_BYTES*2+16) + +// Our table is bespoke for the specific SF. +#define CHIPSSPREAD CHIRPLENGTH_WORDS// QUARTER_CHIRP_LENGTH_WORDS (TODO: Use the quater value elsewhere in the code) +#define MARK_FROM_SF0 (1<BSHR = 1; // Turn on GPIOD0 for profiling + + // Backup flags. + volatile int intfr = DMA1->INTFR; + do + { + // Clear all possible flags. + DMA1->INTFCR = DMA1_IT_GL3; + + + //int place = DMA1_Channel3->CNTR; + // CNTR says that there are THIS MANY bytes left in the transfer. + // So a high CNTR value indicates a very early place in the buffer. + + uint16_t * sb = 0; + + temp++; + + if( intfr & DMA1_IT_HT3 ) + { + sb = sendbuff; + } + else if( intfr & DMA1_IT_TC3 ) + { + sb = sendbuff + SENDBUFF_WORDS/2; + } + + if( sb ) + { + if( quadsetplace < 0 ) + { + // Abort Send + memset( sb, 0, SENDBUFF_WORDS*2/2 ); + DMA1_Channel3->CFGR &= ~DMA_CFGR1_EN; + goto complete; + } + + fxcycle += DMA_SIZE_WORDS; + if( fxcycle == NUM_DMAS_PER_QUARTER_CHIRP*DMA_SIZE_WORDS ) + { + fxcycle = 0; + // Advance to next quarter word. + quadsetplace++; + + if( quadsetplace > quadsetcount ) + { +#ifdef TEST_TONE + quadsetplace = 0; +#else + quadsetplace = -1; +#endif + memset( sb, 0, SENDBUFF_WORDS*2/2 ); + goto complete; + } + } + + int symbol = quadsets[quadsetplace]; // Actually 0...CHIRPLENGTHWORDS + + const uint16_t * tsb = 0; + + // Select down- or up-chirp. + if( symbol < 0 ) + { + int word = fxcycle - symbol - 1; + if( word >= CHIRPLENGTH_WORDS ) word -= CHIRPLENGTH_WORDS; + word++; + tsb = (&chirpbuff[word+REVERSE_START_OFFSET_BYTES/4]); + } + else + { + int word = fxcycle + symbol; + if( word >= CHIRPLENGTH_WORDS ) word -= CHIRPLENGTH_WORDS; + tsb = (&chirpbuff[word]); + } + + // I tried using the DMA to do the copy - but that didn't work for some reason. + //while( DMA1_Channel2->CFGR & 1 ); +// DMA1_Channel2->CNTR = DMA_SIZE_WORDS/2; +// DMA1_Channel2->MADDR = (uint32_t)tsb; +// DMA1_Channel2->PADDR = (uint32_t)sb; +// DMA1_Channel2->CFGR |= DMA_CFGR1_EN; + + int cpy = DMA_SIZE_WORDS/2; +#ifdef TEST_TONE + // Test tone + memset( sb, 0xaa, cpy*2 ); +#else +#if DMA_SIZE_WORDS_DIVISIBLE_BY_FOUR == 0 + #error need divisibiltiy by 2. +#else + //while( cpy-- ) { *(sb++) = wordo; } + // Guarantee aligned access. + uint32_t * sbw = (uint32_t*)(((uint32_t)sb)&~3); + uint32_t * tsbw = (uint32_t*)(((uint32_t)tsb)&~3); + //while( cpy-- ) { *(sbw++) = *(tsbw++); } + + // Align the data copy if needed + if( cpy & 1 ) + { + *(sbw++) = *(tsbw++); + } + cpy /= 2; // Doubled up per loop + asm volatile("\ +1:\ +c.lw a3, 0(%[from])\n\ +c.lw a4, 4(%[from])\n\ +c.addi %[from], 8\n\ +c.addi %[cpy], -1\n\ +c.sw a3, 0(%[to])\n\ +c.sw a4, 4(%[to])\n\ +c.addi %[to], 8\n\ +c.bnez %[cpy], 1b\n\ +" : [cpy]"+r"(cpy), [from]"+r"(tsbw), [to]"+r"(sbw) : : "a3", "a4", "memory"); +#endif +#endif + } + +complete: + intfr = DMA1->INTFR; + } while( intfr ); + + //GPIOD->BSHR = 1<<16; // Turn off GPIOD0 for profiling +} +#endif + + + +void LoopFunction() __attribute__((section(".srodata"))); +void LoopFunction() +{ + uint8_t * start = (uint8_t*)DMA1_Channel2->MADDR; + uint8_t * end = (uint8_t*)((uint32_t)DMA1_Channel2->MADDR + SENDBUFF_WORDS); + uint8_t * here = start+ 8; + uint32_t targ = 2000; + uint32_t running = 0; + uint8_t * tail = end - DMA1_Channel2->CNTR; + uint32_t * cntr = DMA1_Channel2->CNTR; + uint32_t temp = 0; + uint32_t temp2 = 0; + + asm volatile("\n\ + li %[targ], 2000\n\ +genloop:\n\ + lw %[temp], 0(%[cntr])\n\ + sub %[tail], %[end], %[temp]\n\ + beq %[here], %[tail], genloop\n\ +innerloop:\ + li %[temp], 17\n\ + blt %[running], %[targ], noskip\n\ + li %[temp], 18\n\ + sub %[running], %[running], %[targ]\n\ +noskip:\n\ + sb %[temp], 0(%[here])\n\ + addi %[here], %[here], 1\n\ + bne %[here], %[end], skipreset\n\ + add %[here], x0, %[start]\n\ +skipreset:\n\ + bne %[here], %[tail], innerloop\n\ + j genloop\n\ +" : [here]"+r"(here) : + [start]"r"(start), + [end]"r"(end), + [targ]"r"(targ), + [running]"r"(running), + [tail]"r"(tail), + [cntr]"r"(cntr), + [temp]"r"(temp), + [temp2]"r"(temp2) ); + +/* + while(1) + { + int targ_f = 2000; //(frameno & 511)*9 + 1700; + int run_f = 0; + uint8_t * tail = end - DMA1_Channel2->CNTR; + + while( here != tail ) + { + int setf = 17; + if( run_f > targ_f ) + { + setf = 18; + run_f -= targ_f; + } + run_f += setf*32; + + *here = setf; + + here++; + } +*/ +/* + for( j = 0; j < sizeof( sendbuff ); j++ ) + { + int setf = 10; + if( run_f > targ_f ) + { + setf = 9; + run_f -= targ_f; + } + run_f += setf*32; + + sendbuff[j] = setf; + } +*/ +} +void LoopFunction2() __attribute__((aligned(256))) __attribute__((section(".srodata"))) __attribute__ ((noinline)); + +__attribute__((section(".sdata"))) __attribute__((aligned(256))) const uint32_t tablef[] = { + 0x09090909, + 0x0909090a, + 0x090a090a, + 0x0a0a0a09, + 0x0a0a0a0a, + 0x0a0a0a0b, + 0x0a0b0a0b, + 0x0b0b0b0a, + 0x0b0b0b0b, + 0x0b0b0b0c, + 0x0b0c0b0c, + 0x0c0c0c0b, + 0x0c0c0c0c, + 0x0c0c0c0d, + 0x0c0d0c0d, + 0x0d0d0d0c, + 0x0d0d0d0d, + }; + +void LoopFunction2() +{ + + uint32_t * start = (uint8_t*)DMA1_Channel2->MADDR; + uint32_t * end = (uint8_t*)((uint32_t)DMA1_Channel2->MADDR + SENDBUFF_WORDS); + uint32_t * here = start; + + int run_f = 0; + + volatile uint32_t * cntrptr = &DMA1_Channel2->CNTR; + + while(1) + { + //uint32_t * tail = 0xfffffffc & (uintptr_t)(((uint8_t*)end) - *cntrptr); + //if( tail == end ) tail--; + uint32_t * tail = ((SENDBUFF_WORDS-1) & (0xfffffffc)) & (uintptr_t)(((uint8_t*)start) + SENDBUFF_WORDS - *cntrptr); + + while( here != tail ) + { + uint32_t cp = ((SysTick->CNT>>14)&0xfff)+0x4000; + *(here++) = tablef[run_f>>12]; + run_f &= 4095; + run_f += cp; + if( here == end ) + here = start; + } + } + +} + + +int main() +{ + SystemInit(); + + funGpioInitAll(); + + // Set a wait state (1 = normal <= 48MHz) + FLASH->ACTLR = 1; + +// MCO for testing. +// funPinMode( PA8, GPIO_CFGLR_OUT_50Mhz_AF_PP ); RCC->CFGR0 |= RCC_CFGR0_MCO_PLL; + +// printf( "Switching to HSE\n" ); + Delay_Ms( 10 ); + + // Disable clock security system. + RCC->CTLR &= ~RCC_CSSON; + + // Enable external crystal + RCC->CTLR |= RCC_HSEON; + + // XXX NOTE: This is only used if you have a clock, not an oscillator. +// RCC->CTLR |= RCC_HSEBYP; + + // Set System Clock Source to be 0. + RCC->CFGR0 = (RCC->CFGR0 & ~RCC_SW) | 0; + + // Disable PLL + RCC->CTLR &= ~RCC_PLLON; + + // Switch to HSE + RCC->CFGR0 |= RCC_PLLSRC; + + // Enable PLL + RCC->CTLR |= RCC_PLLON; + + // Wait for HSE to become ready. + while( !( RCC->CTLR & RCC_HSERDY) ); + while( !( RCC->CTLR & RCC_PLLRDY) ); + + RCC->CFGR0 |= RCC_SW_1; // Switch system clock to PLL +// printf( "HSE Switched\n" ); + Delay_Ms( 10 ); + RCC->CTLR &= ~RCC_HSION; + Delay_Ms( 10 ); + //printf( "HSI Off [%08lx %08lx]\n", RCC->CTLR, RCC->CFGR0 ); HSI Off [03035180 0001000a] + + RCC->APB2PCENR |= RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOC | + RCC_APB2Periph_TIM1; + + RCC->AHBPCENR |= RCC_AHBPeriph_DMA1; + + funPinMode( PC3, GPIO_CFGLR_OUT_50Mhz_AF_PP ); // T1C3 on PC3 + + RCC->APB2PRSTR |= RCC_APB2Periph_TIM1; + RCC->APB2PRSTR &= ~RCC_APB2Periph_TIM1; + + + // Prescaler + TIM1->PSC = 0x0000; + + // Auto Reload - sets period + TIM1->ATRLR = 20; + + // Reload immediately + TIM1->SWEVGR |= TIM_UG; + + // Enable CH1N output, positive pol + TIM1->CCER |= TIM_CC3E; + TIM1->CCER |= TIM_CC1E; + + // Compare 3 = for output + TIM1->CHCTLR2 = + TIM_OC3M_0 | TIM_OC3M_1; + + // Compare 1 = for triggering + TIM1->CHCTLR1 = TIM_OC1M_2 | TIM_OC1M_1; + + // Set the Capture Compare Register value to 50% initially + TIM1->CH3CVR = 4; + TIM1->CH1CVR = 0; // This triggers DMA. + + // Enable TIM1 outputs + TIM1->BDTR |= TIM_MOE; + + // Enable TIM1 + TIM1->CTLR1 |= TIM_CEN; + + TIM1->DMAINTENR = TIM_TDE | TIM_COMDE | TIM_CC1DE | TIM_UDE; + + + //DMA1_Channel3 is for SPI1TX + DMA1_Channel2->PADDR = (uint32_t)&TIM1->ATRLR; + DMA1_Channel2->MADDR = (uint32_t)sendbuff; + DMA1_Channel2->CNTR = 0;// sizeof( bufferset )/2; // Number of unique copies. (Don't start, yet!) + DMA1_Channel2->CFGR = + DMA_M2M_Disable | + DMA_Priority_VeryHigh | + DMA_PeripheralDataSize_HalfWord | + DMA_MemoryDataSize_Byte | + DMA_MemoryInc_Enable | + DMA_Mode_Circular | // OR DMA_Mode_Circular or DMA_Mode_Normal + DMA_DIR_PeripheralDST | + 0; + //DMA_IT_TC | DMA_IT_HT; // Transmission Complete + Half Empty Interrupts. + +// NVIC_EnableIRQ( DMA1_Channel3_IRQn ); + + int j; + for( j = 0; j < sizeof( sendbuff ); j++ ) + { + sendbuff[j] = 12; + } + + + // Enter critical section. + DMA1_Channel2->MADDR = (uint32_t)sendbuff; + DMA1_Channel2->CNTR = SENDBUFF_WORDS; // Number of unique uint16_t entries. + DMA1_Channel2->CFGR |= DMA_CFGR1_EN; + + int frameno = 0; +// LoopFunction(); + + LoopFunction2(); + + +#if 0 + uint32_t frame = 0; + while(1) + { + Delay_Ms( 1000 ); + +#ifdef LORAWAN + // Optionally generate a LoRaWAN Packet. + const static uint8_t raw_pl[4] = { 0xaa, 0xaa, 0xaa, 0xaa, }; + // Just some random data. + static uint8_t raw_payload_with_b0[MAX_BYTES+8] = { 0 }; + uint8_t * payload_in = raw_payload_with_b0 + 16; + int payload_in_size; + + // Be sure to provide your appropriate keys and address here. + static const uint8_t payload_key[AES_BLOCKLEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; // AppSKey Big Endian + static const uint8_t network_skey[AES_BLOCKLEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; // NwkSKey Big Endian + static const uint8_t devaddress[4] = { 0x00, 0x00, 0x00, 0x00 }; // Device address Little Endian LSB (Written backwards from Device address default view) + + payload_in_size = GenerateLoRaWANPacket( raw_payload_with_b0, raw_pl, sizeof(raw_pl), payload_key, network_skey, devaddress, frame ); +#else + uint8_t payload_in[15] = { 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; + int payload_in_size = 15; + +#endif + + lora_symbols_count = 0; + int r = CreateMessageFromPayload( lora_symbols, &lora_symbols_count, MAX_SYMBOLS, SF_NUMBER, 4, payload_in, payload_in_size ); + + if( r < 0 ) + { + printf( "Failed to generate message (%d)\n", r ); + // Failed + continue; + } + + frame++; + + int j; + + quadsetcount = 0; + int16_t * qso = quadsets; + for( j = 0; j < PREAMBLE_CHIRPS; j++ ) + { + qso = AddChirp( qso, 0, 0 ); + } + + uint8_t syncword = 0x43; + + #if SF_NUMBER == 6 + #define CODEWORD_SHIFT 2 + #else + #define CODEWORD_SHIFT 3 + #endif + + if( CODEWORD_LENGTH > 0 ) + qso = AddChirp( qso, ( ( syncword & 0xf ) << CODEWORD_SHIFT ), 0 ); + if( CODEWORD_LENGTH > 1 ) + qso = AddChirp( qso, ( ( ( syncword & 0xf0 ) >> 4 ) << CODEWORD_SHIFT ), 0); + + *(qso++) = -(CHIPSSPREAD * 0 / 4 )-1; + *(qso++) = -(CHIPSSPREAD * 1 / 4 )-1; + *(qso++) = -(CHIPSSPREAD * 2 / 4 )-1; + *(qso++) = -(CHIPSSPREAD * 3 / 4 )-1; + *(qso++) = -(CHIPSSPREAD * 0 / 4 )-1; + *(qso++) = -(CHIPSSPREAD * 1 / 4 )-1; + *(qso++) = -(CHIPSSPREAD * 2 / 4 )-1; + *(qso++) = -(CHIPSSPREAD * 3 / 4 )-1; + *(qso++) = -(CHIPSSPREAD * 0 / 4 )-1; + + if( SF_NUMBER <= 6 ) + { + // Two additional upchirps with SF6 https://github.com/tapparelj/gr-lora_sdr/issues/74#issuecomment-1891569580 + for( j = 0; j < 2; j++ ) + qso = AddChirp( qso, 0, 0 ); + } + + for( j = 0; j < lora_symbols_count; j++ ) + { + int ofs = lora_symbols[j]; + qso = AddChirp( qso, ofs, 0 ); + } + + runningcount_bits = 0; + + // This tells the interrupt we have data. + quadsetcount = qso - quadsets + 0; + printf( "- %d -- %d [%d] %d; %d\n", (int)temp, (int)lora_symbols_count, (int)quadsetcount, CHIPSSPREAD/4, sendbuff[0] ); + quadsetplace = 0; + + DMA1_Channel3->CFGR |= DMA_CFGR1_EN; + + while( quadsetplace >= 0 ); + } +#endif +} + diff --git a/ch32v/ch32v003-timer/funconfig.h b/ch32v/ch32v003-timer/funconfig.h new file mode 100644 index 0000000..50db3cf --- /dev/null +++ b/ch32v/ch32v003-timer/funconfig.h @@ -0,0 +1,9 @@ +#ifndef _FUNCONFIG_H +#define _FUNCONFIG_H + +#define FUNCONF_USE_DEBUGPRINTF 1 +#define FUNCONF_USE_UARTPRINTF 0 +#define FUNCONF_SYSTICK_USE_HCLK 1 + +#endif + diff --git a/ch32v/ch32v003-timer/nonlora.c b/ch32v/ch32v003-timer/nonlora.c new file mode 100644 index 0000000..451847c --- /dev/null +++ b/ch32v/ch32v003-timer/nonlora.c @@ -0,0 +1,551 @@ +/** + +MIT-like-non-ai-license + +Copyright (c) 2024 Charles Lohr "CNLohr" + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the two following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +In addition the following restrictions apply: + +1. The Software and any modifications made to it may not be used for the +purpose of training or improving machine learning algorithms, including but not +limited to artificial intelligence, natural language processing, or data +mining. This condition applies to any derivatives, modifications, or updates +based on the Software code. Any usage of the Software in an AI-training dataset +is considered a breach of this License. + +2. The Software may not be included in any dataset used for training or +improving machine learning algorithms, including but not limited to artificial +intelligence, natural language processing, or data mining. + + +3. Any person or organization found to be in violation of these restrictions +will be subject to legal action and may be held liable for any damages +resulting from such use. + +If any term is unenforcable, other terms remain in-force. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +**/ + + +// NOT LORA!!! + +// Transmit a sweep on 97.7MHz +#define FM_TRANSMITTER_SWEEP + +// Nothing = Transmit a 315MHz signal. + +// XXX WARNING: Something is wrong with this - +// The output isn't perfectly time aligned +// And as such there are extra images in weird places. +// TODO: Investigate the DMA+SPI Port jankyness. +#include "ch32v003fun.h" +#include +#include + +#include "LoRa-SDR-Code.h" + +#ifdef LORAWAN +#include "lorawan_simple.h" +#endif + +#define DMA_SIZE_WORDS 128 + +#define SENDBUFF_WORDS (DMA_SIZE_WORDS*2) +uint8_t sendbuff[SENDBUFF_WORDS]; + +// Bits are shifted out MSBit first, then to LSBit + + +#define MAX_BYTES 25 +#define MAX_SYMBOLS (MAX_BYTES*2+16) + +// Our table is bespoke for the specific SF. +#define CHIPSSPREAD CHIRPLENGTH_WORDS// QUARTER_CHIRP_LENGTH_WORDS (TODO: Use the quater value elsewhere in the code) +#define MARK_FROM_SF0 (1<BSHR = 1; // Turn on GPIOD0 for profiling + + // Backup flags. + volatile int intfr = DMA1->INTFR; + do + { + // Clear all possible flags. + DMA1->INTFCR = DMA1_IT_GL3; + + + //int place = DMA1_Channel3->CNTR; + // CNTR says that there are THIS MANY bytes left in the transfer. + // So a high CNTR value indicates a very early place in the buffer. + + uint16_t * sb = 0; + + temp++; + + if( intfr & DMA1_IT_HT3 ) + { + sb = sendbuff; + } + else if( intfr & DMA1_IT_TC3 ) + { + sb = sendbuff + SENDBUFF_WORDS/2; + } + + if( sb ) + { + if( quadsetplace < 0 ) + { + // Abort Send + memset( sb, 0, SENDBUFF_WORDS*2/2 ); + DMA1_Channel3->CFGR &= ~DMA_CFGR1_EN; + goto complete; + } + + fxcycle += DMA_SIZE_WORDS; + if( fxcycle == NUM_DMAS_PER_QUARTER_CHIRP*DMA_SIZE_WORDS ) + { + fxcycle = 0; + // Advance to next quarter word. + quadsetplace++; + + if( quadsetplace > quadsetcount ) + { +#ifdef TEST_TONE + quadsetplace = 0; +#else + quadsetplace = -1; +#endif + memset( sb, 0, SENDBUFF_WORDS*2/2 ); + goto complete; + } + } + + int symbol = quadsets[quadsetplace]; // Actually 0...CHIRPLENGTHWORDS + + const uint16_t * tsb = 0; + + // Select down- or up-chirp. + if( symbol < 0 ) + { + int word = fxcycle - symbol - 1; + if( word >= CHIRPLENGTH_WORDS ) word -= CHIRPLENGTH_WORDS; + word++; + tsb = (&chirpbuff[word+REVERSE_START_OFFSET_BYTES/4]); + } + else + { + int word = fxcycle + symbol; + if( word >= CHIRPLENGTH_WORDS ) word -= CHIRPLENGTH_WORDS; + tsb = (&chirpbuff[word]); + } + + // I tried using the DMA to do the copy - but that didn't work for some reason. + //while( DMA1_Channel5->CFGR & 1 ); +// DMA1_Channel5->CNTR = DMA_SIZE_WORDS/2; +// DMA1_Channel5->MADDR = (uint32_t)tsb; +// DMA1_Channel5->PADDR = (uint32_t)sb; +// DMA1_Channel5->CFGR |= DMA_CFGR1_EN; + + int cpy = DMA_SIZE_WORDS/2; +#ifdef TEST_TONE + // Test tone + memset( sb, 0xaa, cpy*2 ); +#else +#if DMA_SIZE_WORDS_DIVISIBLE_BY_FOUR == 0 + #error need divisibiltiy by 2. +#else + //while( cpy-- ) { *(sb++) = wordo; } + // Guarantee aligned access. + uint32_t * sbw = (uint32_t*)(((uint32_t)sb)&~3); + uint32_t * tsbw = (uint32_t*)(((uint32_t)tsb)&~3); + //while( cpy-- ) { *(sbw++) = *(tsbw++); } + + // Align the data copy if needed + if( cpy & 1 ) + { + *(sbw++) = *(tsbw++); + } + cpy /= 2; // Doubled up per loop + asm volatile("\ +1:\ +c.lw a3, 0(%[from])\n\ +c.lw a4, 4(%[from])\n\ +c.addi %[from], 8\n\ +c.addi %[cpy], -1\n\ +c.sw a3, 0(%[to])\n\ +c.sw a4, 4(%[to])\n\ +c.addi %[to], 8\n\ +c.bnez %[cpy], 1b\n\ +" : [cpy]"+r"(cpy), [from]"+r"(tsbw), [to]"+r"(sbw) : : "a3", "a4", "memory"); +#endif +#endif + } + +complete: + intfr = DMA1->INTFR; + } while( intfr ); + + //GPIOD->BSHR = 1<<16; // Turn off GPIOD0 for profiling +} +#endif + + + +void LoopFunction() __attribute__((section(".srodata"))); +void LoopFunction() +{ + uint8_t * start = (uint8_t*)DMA1_Channel5->MADDR; + uint8_t * end = (uint8_t*)((uint32_t)DMA1_Channel5->MADDR + SENDBUFF_WORDS); + uint8_t * here = start+ 8; + uint32_t targ = 2000; + uint32_t running = 0; + uint8_t * tail = end - DMA1_Channel5->CNTR; + uint32_t * cntr = DMA1_Channel5->CNTR; + uint32_t temp = 0; + uint32_t temp2 = 0; + + asm volatile("\n\ + li %[targ], 2000\n\ +genloop:\n\ + lw %[temp], 0(%[cntr])\n\ + sub %[tail], %[end], %[temp]\n\ + beq %[here], %[tail], genloop\n\ +innerloop:\ + li %[temp], 17\n\ + blt %[running], %[targ], noskip\n\ + li %[temp], 18\n\ + sub %[running], %[running], %[targ]\n\ +noskip:\n\ + sb %[temp], 0(%[here])\n\ + addi %[here], %[here], 1\n\ + bne %[here], %[end], skipreset\n\ + add %[here], x0, %[start]\n\ +skipreset:\n\ + bne %[here], %[tail], innerloop\n\ + j genloop\n\ +" : [here]"+r"(here) : + [start]"r"(start), + [end]"r"(end), + [targ]"r"(targ), + [running]"r"(running), + [tail]"r"(tail), + [cntr]"r"(cntr), + [temp]"r"(temp), + [temp2]"r"(temp2) ); + +/* + while(1) + { + int targ_f = 2000; //(frameno & 511)*9 + 1700; + int run_f = 0; + uint8_t * tail = end - DMA1_Channel5->CNTR; + + while( here != tail ) + { + int setf = 17; + if( run_f > targ_f ) + { + setf = 18; + run_f -= targ_f; + } + run_f += setf*32; + + *here = setf; + + here++; + } +*/ +/* + for( j = 0; j < sizeof( sendbuff ); j++ ) + { + int setf = 10; + if( run_f > targ_f ) + { + setf = 9; + run_f -= targ_f; + } + run_f += setf*32; + + sendbuff[j] = setf; + } +*/ +} +void LoopFunction2() __attribute__((aligned(256))) __attribute__((section(".srodata"))) __attribute__ ((noinline)); + +__attribute__((section(".sdata"))) __attribute__((aligned(256))) const uint32_t tablef[] = { + 0x06060606, + 0x06060607, + 0x06070607, + 0x07070706, + 0x07070707, + 0x07070708, + 0x07080708, + 0x08080807, + 0x08080808, + 0x08080809, + 0x08090809, + 0x09090908, + 0x09090909, + 0x0909090a, + 0x090a090a, + 0x0a0a0a09, + 0x0a0a0a0a, // Below this line is unstable - i.e. sometimes there are missing DMA transfers. + 0x0a0a0a0b, + 0x0a0b0a0b, + 0x0b0b0b0a, + 0x0b0b0b0b, + 0x0b0b0b0c, + 0x0b0c0b0c, + 0x0c0c0c0b, + 0x0c0c0c0c, + 0x0c0c0c0d, + 0x0c0d0c0d, + 0x0d0d0d0c, + 0x0d0d0d0d, + 0x0d0d0d0e, + 0x0d0e0d0e, + 0x0e0e0e0d, + 0x0e0e0e0e, + 0x0e0e0e0f, + 0x0e0f0e0f, + 0x0f0f0f0e, + 0x0f0f0f0f, + 0x0f0f0f10, + 0x0f100f10, + 0x1010100f, + 0x10101010, + 0x10101011, + 0x10111011, + 0x11111110, + }; + +void LoopFunction2() +{ + + uint32_t * start = (uint8_t*)DMA1_Channel5->MADDR; + uint32_t * end = (uint8_t*)((uint32_t)DMA1_Channel5->MADDR + SENDBUFF_WORDS); + uint32_t * here = start; + + int run_f = 0; + + volatile uint32_t * cntrptr = &DMA1_Channel5->CNTR; + + while(1) + { + //uint32_t * tail = 0xfffffffc & (uintptr_t)(((uint8_t*)end) - *cntrptr); + //if( tail == end ) tail--; + uint32_t * tail = ((SENDBUFF_WORDS-1) & (0xfffffffc)) & (uintptr_t)(((uint8_t*)start) + SENDBUFF_WORDS - *cntrptr); + + while( here != tail ) + { +#ifdef FM_TRANSMITTER_SWEEP + // 97.7MHz FM Station + int notein = (SysTick->CNT>>3)&0x1fff; + if( notein > 0xfff ) notein = 0x2000-notein; + uint32_t cp = (notein)+0x20000; +#else + // 315MHz + uint32_t cp = 0x1bfc3; +#endif + *(here++) = tablef[run_f>>12]; + run_f &= (1<<12)-1; + run_f += cp; + if( here == end ) + here = start; + } + } + +} + + +int main() +{ + SystemInit(); + + funGpioInitAll(); + + // Set a wait state (1 = normal <= 48MHz) + FLASH->ACTLR = 1; + +// MCO for testing. +// funPinMode( PA8, GPIO_CFGLR_OUT_50Mhz_AF_PP ); RCC->CFGR0 |= RCC_CFGR0_MCO_PLL; + +// printf( "Switching to HSE\n" ); + Delay_Ms( 10 ); + + // Disable clock security system. + RCC->CTLR &= ~RCC_CSSON; + + // Enable external crystal + RCC->CTLR |= RCC_HSEON; + + // XXX NOTE: This is only used if you have a clock, not an oscillator. +// RCC->CTLR |= RCC_HSEBYP; + + // Set System Clock Source to be 0. + RCC->CFGR0 = (RCC->CFGR0 & ~RCC_SW) | 0; + + // Disable PLL + RCC->CTLR &= ~RCC_PLLON; + + // Switch to HSE + RCC->CFGR0 |= RCC_PLLSRC; + + // Enable PLL + RCC->CTLR |= RCC_PLLON; + + // Wait for HSE to become ready. + while( !( RCC->CTLR & RCC_HSERDY) ); + while( !( RCC->CTLR & RCC_PLLRDY) ); + + RCC->CFGR0 |= RCC_SW_1; // Switch system clock to PLL +// printf( "HSE Switched\n" ); + Delay_Ms( 10 ); + RCC->CTLR &= ~RCC_HSION; + Delay_Ms( 10 ); + //printf( "HSI Off [%08lx %08lx]\n", RCC->CTLR, RCC->CFGR0 ); HSI Off [03035180 0001000a] + + RCC->APB2PCENR |= RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOC | + RCC_APB2Periph_TIM1; + + RCC->AHBPCENR |= RCC_AHBPeriph_DMA1; + + funPinMode( PC3, GPIO_CFGLR_OUT_50Mhz_AF_PP ); // T1C3 on PC3 + + RCC->APB2PRSTR |= RCC_APB2Periph_TIM1; + RCC->APB2PRSTR &= ~RCC_APB2Periph_TIM1; + + + // Prescaler + TIM1->PSC = 0x0000; + + // Auto Reload - sets period + TIM1->ATRLR = 17; + + // Reload immediately + TIM1->SWEVGR |= TIM_UG; + + // Enable CH1N output, positive pol + TIM1->CCER |= TIM_CC3E; + TIM1->CCER |= TIM_CC1E; + + // Compare 3 = for output + // Modes: + // 0, 1, 2: Nothing + // 3: Flip + // 4, 5: Nothing + // 6: "Fast PWM mode 1" + // 7: Flipping (Further out) +#ifdef FM_TRANSMITTER_SWEEP + TIM1->CHCTLR2 = TIM_OC3M_0 | TIM_OC3M_1 | TIM_OC3PE | TIM_OC3FE; +#else + TIM1->CHCTLR2 = TIM_OC3M_2 | TIM_OC3M_1 | TIM_OC3PE | TIM_OC3FE; +#endif + + // Compare 1 = for triggering + TIM1->CHCTLR1 = TIM_OC1M_2 | TIM_OC1M_1 | TIM_OC1FE; + + // Set the Capture Compare Register value to 50% initially + TIM1->CH3CVR = 4; // ACTUALLY Ignored typically it seems. + TIM1->CH1CVR = 0; // This triggers DMA. + + // Enable TIM1 outputs + TIM1->BDTR |= TIM_MOE; + + // Enable TIM1 + TIM1->CTLR1 |= TIM_CEN; + + TIM1->DMAINTENR = TIM_TDE | TIM_UDE; // Outputs DMA1_Channel5 + +#if 0 + // Another try - use TIM2 to trigger DMA? + RCC->APB1PCENR |= RCC_APB1Periph_TIM2; + RCC->APB1PRSTR |= RCC_APB1Periph_TIM2; + RCC->APB1PRSTR &= ~RCC_APB1Periph_TIM2; + + TIM2->PSC = 0x0000; + TIM2->ATRLR = 37; + TIM2->SWEVGR |= TIM_UG; + TIM2->BDTR |= TIM_MOE; + TIM2->CHCTLR1 = TIM_OC1M_2 | TIM_OC1M_1 | TIM_OC1FE; + TIM2->DMAINTENR |= TIM_UDE | TIM_TDE | TIM_TDE | TIM_CC1DE; + TIM2->CTLR1 |= TIM_CEN; + // TIM2_UP = DMA Channel 2. +#endif + + DMA1_Channel5->PADDR = (uint32_t)&TIM1->CH3CVR; + DMA1_Channel5->MADDR = (uint32_t)sendbuff; + DMA1_Channel5->CNTR = 0;// sizeof( bufferset )/2; // Number of unique copies. (Don't start, yet!) + DMA1_Channel5->CFGR = + DMA_M2M_Disable | + DMA_Priority_VeryHigh | + DMA_PeripheralDataSize_HalfWord | + DMA_MemoryDataSize_Byte | + DMA_MemoryInc_Enable | + DMA_Mode_Circular | // OR DMA_Mode_Circular or DMA_Mode_Normal + DMA_DIR_PeripheralDST | + 0; + //DMA_IT_TC | DMA_IT_HT; // Transmission Complete + Half Empty Interrupts. + +// NVIC_EnableIRQ( DMA1_Channel3_IRQn ); + + int j; + for( j = 0; j < sizeof( sendbuff ); j++ ) + { + sendbuff[j] = 12; + } + + + // Enter critical section. + DMA1_Channel5->MADDR = (uint32_t)sendbuff; + DMA1_Channel5->CNTR = SENDBUFF_WORDS; // Number of unique uint16_t entries. + DMA1_Channel5->CFGR |= DMA_CFGR1_EN; + + + LoopFunction2(); +} + diff --git a/ch32v/ch32v003-txrx/README.md b/ch32v/ch32v003-txrx/README.md new file mode 100644 index 0000000..4d22c46 --- /dev/null +++ b/ch32v/ch32v003-txrx/README.md @@ -0,0 +1,9 @@ +Trying to use a plain 003 to send and receive (one for each). + +One generates a 12MHz tone. + +The other samples at 48/47MHz. + +This doesn't particularly work well. + +It only goes about 1' diff --git a/ch32v/ch32v003-txrx/ch32v003rx/Makefile b/ch32v/ch32v003-txrx/ch32v003rx/Makefile new file mode 100644 index 0000000..2afcae6 --- /dev/null +++ b/ch32v/ch32v003-txrx/ch32v003rx/Makefile @@ -0,0 +1,13 @@ +all : flash + +TARGET:=ch32v003rx +TARGET_MCU:=CH32V003 +CH32V003FUN:=../../ch32v003fun/ch32v003fun + +EXTRA_CFLAGS:=-Wno-unused-function -I../../lib + +include $(CH32V003FUN)/ch32v003fun.mk + +flash : cv_flash +clean : cv_clean + diff --git a/ch32v/ch32v003-txrx/ch32v003rx/ch32v003rx.c b/ch32v/ch32v003-txrx/ch32v003rx/ch32v003rx.c new file mode 100644 index 0000000..dfef1d8 --- /dev/null +++ b/ch32v/ch32v003-txrx/ch32v003rx/ch32v003rx.c @@ -0,0 +1,257 @@ +/** + +MIT-like-non-ai-license + +Copyright (c) 2024 Charles Lohr "CNLohr" + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the two following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +In addition the following restrictions apply: + +1. The Software and any modifications made to it may not be used for the +purpose of training or improving machine learning algorithms, including but not +limited to artificial intelligence, natural language processing, or data +mining. This condition applies to any derivatives, modifications, or updates +based on the Software code. Any usage of the Software in an AI-training dataset +is considered a breach of this License. + +2. The Software may not be included in any dataset used for training or +improving machine learning algorithms, including but not limited to artificial +intelligence, natural language processing, or data mining. + + +3. Any person or organization found to be in violation of these restrictions +will be subject to legal action and may be held liable for any damages +resulting from such use. + +If any term is unenforcable, other terms remain in-force. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +**/ + +#include "ch32v003fun.h" +#include + +#define ADC_NUMCHLS 1 +#define DMA_SIZE 512 + +#define ADC_PIN PC4 +#define ADCNO 2 + +#define LEDPIN PD6 + +#define USE_TIMER + +uint32_t dmadata[DMA_SIZE/2] __attribute__((aligned(64))); + + +uint32_t ercnt = 0; + +#define IQDLEN 32 +int32_t lastintenR[IQDLEN], lastintenI[IQDLEN]; +uint32_t intenhead; +uint32_t intentail; + +uint32_t wordouts; + +void DMA1_Channel1_IRQHandler( void ) __attribute__((interrupt)); +void DMA1_Channel1_IRQHandler( void ) +{ + DMA1_Channel1->CFGR |= DMA_CFGR1_EN; + + // Clear all possible flags. + DMA1->INTFCR = DMA1_IT_GL1; + uint32_t * head = dmadata; + uint32_t * end = dmadata + DMA_SIZE/2; + static uint32_t * here = dmadata; + static uint32_t thisintenR; + static uint32_t thisintenI; + static uint32_t rcnt; + + // We have a pointer to the next data we want to analyize. + // We have a pointer to where the tail of the new data is. + // We want to process data from where we are to where the + // data ends. + // So, we set and end point, which could be either the end + // of where the data is or the end of the array with the + // data. + // Then we plow through the data until we get to one of those + // two. And we either reset the pointer to the beginning of + // the array, OR, we stop because we ran out of data. + + uint32_t cnt = DMA1_Channel1->CNTR; + if( cnt == 0 ) cnt = 1; + uint32_t tail_offset = DMA_SIZE - cnt; + uint32_t * tail = dmadata + tail_offset/2; // Tuncate down to quads if a pair has not been fully written. + uint32_t * stopat = (here < tail) ? tail : end; + + do + { + do + { + int32_t vA = *(here++); + int32_t vB = *(here++); + thisintenR += (vA&0xfff) - (vB&0xfff); + thisintenI += (vA >> 16) - (vB >> 16); +rcnt++; + } while( here != stopat ); + + + if( here == end ) + { + lastintenR[intenhead] = thisintenR; // Fixup (because when we were subtracting, it should be -1) + lastintenI[intenhead] = thisintenI; // Fixup (because when we were subtracting, it should be -1) + + intenhead = (intenhead+1) & (IQDLEN-1); + + thisintenR = 0; + thisintenI = 0; + here = head; +ercnt = rcnt; +rcnt = 0; + wordouts++; + } + + if( here == tail ) break; + } + while( 1 ); +} + + + +int main() +{ + SystemInit(); + + Delay_Ms( 100 ); + + EXTEND->CTR = 1<<10; // LDO trim + + funGpioInitAll(); + + RCC->APB1PCENR |= RCC_APB1Periph_TIM2; + RCC->APB2PCENR |= RCC_APB2Periph_ADC1; + + // Reset the ADC to init all regs + RCC->APB2PRSTR |= RCC_APB2Periph_ADC1; + RCC->APB2PRSTR &= ~RCC_APB2Periph_ADC1; + + ADC1->RSQR1 = (1-1) << 20; // One channel. + ADC1->RSQR2 = 0; + ADC1->RSQR3 = (ADCNO<<(5*0)); + + // set sampling time for chl 7, 4, 3, 2 + // 0:7 => 3/9/15/30/43/57/73/241 cycles +#ifdef USE_TIMER + ADC1->SAMPTR2 = (1<<(3*ADCNO)); +#else + ADC1->SAMPTR2 = (3<<(3*ADCNO)); +#endif + + // turn on ADC + ADC1->CTLR2 = ADC_ADON; + + // Reset calibration + ADC1->CTLR2 = ADC_ADON | ADC_RSTCAL; + while(ADC1->CTLR2 & ADC_RSTCAL); + + // Calibrate + ADC1->CTLR2 = ADC_ADON | ADC_CAL; + while(ADC1->CTLR2 & ADC_CAL); + + // Turn on DMA + RCC->AHBPCENR |= RCC_AHBPeriph_DMA1; + + //DMA1_Channel1 is for ADC + DMA1_Channel1->PADDR = (uint32_t)&ADC1->RDATAR; + DMA1_Channel1->MADDR = (uint32_t)dmadata; + DMA1_Channel1->CNTR = DMA_SIZE; + DMA1_Channel1->CFGR = + DMA_M2M_Disable | + DMA_Priority_VeryHigh | + DMA_MemoryDataSize_HalfWord | + DMA_PeripheralDataSize_HalfWord | + DMA_MemoryInc_Enable | + DMA_Mode_Circular | + DMA_DIR_PeripheralSRC | + DMA_IT_TC | DMA_IT_HT; // Transmission Complete + Half Empty Interrupts. + +// NVIC_SetPriority( DMA1_Channel3_IRQn, 0<<4 ); //We don't need to tweak priority. + NVIC_EnableIRQ( DMA1_Channel1_IRQn ); + DMA1_Channel1->CFGR |= DMA_CFGR1_EN; // Turn on DMA channel 1 + + ADC1->CTLR1 = ADC_SCAN; // enable scanning + // Enable continuous conversion and DMA, selected by TIM2CC1 +#ifdef USE_TIMER + ADC1->CTLR2 = ADC_ADON | ADC_DMA | ADC_EXTSEL_2 | ADC_EXTTRIG; +#else + ADC1->CTLR2 = ADC_ADON | ADC_DMA | ADC_EXTSEL | ADC_SWSTART | ADC_CONT; +#endif + + // Reset TIM2 to init all regs + RCC->APB1PRSTR |= RCC_APB1Periph_TIM2; + RCC->APB1PRSTR &= ~RCC_APB1Periph_TIM2; + +#ifdef USE_TIMER + + TIM2->PSC = 0x0000; // Prescalar + TIM2->ATRLR = 46; // TIM2 max before reset. 48 = Period of 49 cycles. + TIM2->CHCTLR1 = TIM_OC1M_2 | TIM_OC1M_1 | TIM_OC1PE; + TIM2->CTLR1 = TIM_ARPE; + TIM2->CCER = TIM_CC1E | TIM_CC1P | TIM_CC1NP; + TIM2->SWEVGR = TIM_UG; + + // Enable TIM2 (T2C1 = Trigger ADC) + TIM2->CTLR1 |= TIM_CEN; + TIM2->CH1CVR = 1; + +#endif + + // PD4 = T2C1 + funPinMode( LEDPIN, GPIO_CFGLR_OUT_50Mhz_PP ); + //funPinMode( PD4, GPIO_CFGLR_OUT_50Mhz_AF_PP ); + + funPinMode( ADC_PIN, + //GPIO_CFGLR_IN_PUPD + GPIO_CFGLR_IN_ANALOG + ); + + while(1) + { + printf( "%5d %5d %ld %ld %ld %ld\n", (int)lastintenR[intenhead], (int)lastintenI[intenhead], dmadata[0]&0xfff, dmadata[0]>>16, dmadata[1]&0xfff, dmadata[1]>>16 ); + + int i; + int32_t lR[8], lI[8]; + int head = (intenhead - 8) & (IQDLEN-1); + for( i = 0; i < 8; i++ ) + { + lR[i] = lastintenR[head]; + lI[i] = lastintenI[head]; + head = (head+1)&(IQDLEN-1); + } + + for( i = 0; i < 8; i++ ) + { + printf( "%6ld%6ld\n", lR[i], lI[i] ); + } + + printf( "%08lx %ld ** %d\n", dmadata[0], wordouts, ercnt ); + Delay_Ms( 1000 ); + + } +} diff --git a/ch32v/ch32v003-txrx/ch32v003rx/funconfig.h b/ch32v/ch32v003-txrx/ch32v003rx/funconfig.h new file mode 100644 index 0000000..046451f --- /dev/null +++ b/ch32v/ch32v003-txrx/ch32v003rx/funconfig.h @@ -0,0 +1,9 @@ +#ifndef _FUNCONFIG_H +#define _FUNCONFIG_H + +#define FUNCONF_USE_DEBUGPRINTF 1 +#define FUNCONF_USE_UARTPRINTF 0 +#define FUNCONF_USE_HSE 1 + +#endif + diff --git a/ch32v/ch32v003-txrx/ch32v003tx/Makefile b/ch32v/ch32v003-txrx/ch32v003tx/Makefile new file mode 100644 index 0000000..85e6362 --- /dev/null +++ b/ch32v/ch32v003-txrx/ch32v003tx/Makefile @@ -0,0 +1,13 @@ +all : flash + +TARGET:=ch32v003tx +TARGET_MCU:=CH32V003 +CH32V003FUN:=../../ch32v003fun/ch32v003fun + +EXTRA_CFLAGS:=-Wno-unused-function -I../../lib + +include $(CH32V003FUN)/ch32v003fun.mk + +flash : cv_flash +clean : cv_clean + diff --git a/ch32v/ch32v003-txrx/ch32v003tx/ch32v003tx.c b/ch32v/ch32v003-txrx/ch32v003tx/ch32v003tx.c new file mode 100644 index 0000000..ba672ad --- /dev/null +++ b/ch32v/ch32v003-txrx/ch32v003tx/ch32v003tx.c @@ -0,0 +1,92 @@ +/** + +MIT-like-non-ai-license + +Copyright (c) 2024 Charles Lohr "CNLohr" + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the two following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +In addition the following restrictions apply: + +1. The Software and any modifications made to it may not be used for the +purpose of training or improving machine learning algorithms, including but not +limited to artificial intelligence, natural language processing, or data +mining. This condition applies to any derivatives, modifications, or updates +based on the Software code. Any usage of the Software in an AI-training dataset +is considered a breach of this License. + +2. The Software may not be included in any dataset used for training or +improving machine learning algorithms, including but not limited to artificial +intelligence, natural language processing, or data mining. + + +3. Any person or organization found to be in violation of these restrictions +will be subject to legal action and may be held liable for any damages +resulting from such use. + +If any term is unenforcable, other terms remain in-force. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +**/ + +#include "ch32v003fun.h" +#include + +#define LEDPIN PD6 + +int main() +{ + SystemInit(); + + Delay_Ms( 100 ); + + funGpioInitAll(); + RCC->APB1PCENR |= RCC_APB1Periph_TIM2; + // PD4 = T2C1 + funPinMode( PD4, GPIO_CFGLR_OUT_50Mhz_AF_PP ); + funPinMode( LEDPIN, GPIO_CFGLR_OUT_50Mhz_PP ); + + // Reset TIM2 to init all regs + RCC->APB1PRSTR |= RCC_APB1Periph_TIM2; + RCC->APB1PRSTR &= ~RCC_APB1Periph_TIM2; + + TIM2->PSC = 0x0000; // Prescalar + TIM2->ATRLR = 3; // Max + TIM2->CHCTLR1 = TIM_OC1M_2 | TIM_OC1M_1 | TIM_OC1PE | TIM_OC1FE; + TIM2->CTLR1 = TIM_ARPE; + TIM2->CCER = TIM_CC1E | TIM_CC1P | TIM_CC1NP; + TIM2->SWEVGR = TIM_UG; + + // Enable TIM2 + TIM2->CTLR1 |= TIM_CEN; + TIM2->CH1CVR = TIM2->ATRLR/2; + + while(1); + + while(1) + { + TIM2->CH1CVR = 2; + TIM2->CCER = TIM_CC1E | TIM_CC1P; + funDigitalWrite( LEDPIN, 1 ); + Delay_Us( 1500 ); + TIM2->CCER = TIM_CC1E; + TIM2->CH1CVR = 2; + funDigitalWrite( LEDPIN, 0 ); + Delay_Us( 1500 ); + } +} diff --git a/ch32v/ch32v003-txrx/ch32v003tx/funconfig.h b/ch32v/ch32v003-txrx/ch32v003tx/funconfig.h new file mode 100644 index 0000000..046451f --- /dev/null +++ b/ch32v/ch32v003-txrx/ch32v003tx/funconfig.h @@ -0,0 +1,9 @@ +#ifndef _FUNCONFIG_H +#define _FUNCONFIG_H + +#define FUNCONF_USE_DEBUGPRINTF 1 +#define FUNCONF_USE_UARTPRINTF 0 +#define FUNCONF_USE_HSE 1 + +#endif + diff --git a/ch32v/ch32v003fun b/ch32v/ch32v003fun index 87e4ee5..f41db0d 160000 --- a/ch32v/ch32v003fun +++ b/ch32v/ch32v003fun @@ -1 +1 @@ -Subproject commit 87e4ee59d9f63e1c126c728adcbc68133361e57e +Subproject commit f41db0dc304fd855e8e806282a9a250661708a72 diff --git a/ch32v/ch32v203-adcrx/Makefile b/ch32v/ch32v203-adcrx/Makefile new file mode 100644 index 0000000..50397be --- /dev/null +++ b/ch32v/ch32v203-adcrx/Makefile @@ -0,0 +1,15 @@ +all : flash + +TARGET:=adcrx +TARGET_MCU:=CH32V203G6U6 +TARGET_MCU_PACKAGE:=CH32V203G6U6 +CH32V003FUN:=../ch32v003fun/ch32v003fun + +EXTRA_CFLAGS:=-Wno-unused-function -I../../lib + +include ../ch32v003fun/ch32v003fun/ch32v003fun.mk + +flash : cv_flash +clean : cv_clean + rm -rf rf_data_gen chirpbuff.dat chirpbuff.h chirpbuffinfo.h + diff --git a/ch32v/ch32v203-adcrx/adcrx.c b/ch32v/ch32v203-adcrx/adcrx.c new file mode 100644 index 0000000..e2230eb --- /dev/null +++ b/ch32v/ch32v203-adcrx/adcrx.c @@ -0,0 +1,339 @@ +/** + +MIT-like-non-ai-license + +Copyright (c) 2024 Charles Lohr "CNLohr" + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the two following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +In addition the following restrictions apply: + +1. The Software and any modifications made to it may not be used for the +purpose of training or improving machine learning algorithms, including but not +limited to artificial intelligence, natural language processing, or data +mining. This condition applies to any derivatives, modifications, or updates +based on the Software code. Any usage of the Software in an AI-training dataset +is considered a breach of this License. + +2. The Software may not be included in any dataset used for training or +improving machine learning algorithms, including but not limited to artificial +intelligence, natural language processing, or data mining. + + +3. Any person or organization found to be in violation of these restrictions +will be subject to legal action and may be held liable for any damages +resulting from such use. + +If any term is unenforcable, other terms remain in-force. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +**/ + +// NOT LORA!!! -- but experimenting with the possibility of rx. + +// SETUP INSTRUCTIONS: +// (1) `make` in the optionbytes folder to configure `RESET` correctly. +// (2) Create a tone (if using the funprog, ../ch32v003fun/minichlink/minichlink -X ECLK 1:235:189:9:3 for 27.48387097MHz +// (2) or, for 24.387096762MHz - ../ch32v003fun/minichlink/minichlink -X ECLK 1:150:49:8:3 + +/* More notes + + * Minimum sample time with DMA = fCPU / 28 (5.14MHz) + +*/ + + +#include "ch32v003fun.h" +#include + +/* General note: +*/ + +#define Q 1024 + +#define PWM_PERIOD (36-1) //For 27.0MHz -- It appears to be good for *244 in the table? WHY 26MHz???!?!!? +#define TIGHT_OUT 1 +#define QUADRATURE +//#define DUMPBUFF + +//#define PWM_PERIOD (32-1) +//#define QUADRATURE +//#define PWM_OUTPUT 3 + +#define ADC_BUFFSIZE 256 +volatile uint16_t adc_buffer[ADC_BUFFSIZE]; + +void SetupADC() +{ + // XXX TODO -look into PGA + // XXX TODO - look into BUFEN and TKITUNE + // XXX TODO - Look into tag-teaming the ADCs + + // PDA is analog input chl 7 + GPIOA->CFGLR &= ~(0xf<<(4*7)); // CNF = 00: Analog, MODE = 00: Input + + // ADC CLK is chained off of APB2. + + // Reset the ADC to init all regs + RCC->APB2PRSTR |= RCC_APB2Periph_ADC1; + RCC->APB2PRSTR &= ~RCC_APB2Periph_ADC1; + + // ADCCLK = 12 MHz => RCC_ADCPRE divide by 4 + RCC->CFGR0 &= ~RCC_ADCPRE; // Clear out the bis in case they were set + RCC->CFGR0 |= RCC_ADCPRE_DIV2; // Fastest possible (divide-by-2) NOTE: This is OUTSIDE the specified value in the datasheet. + + // Set up single conversion on chl 7 + ADC1->RSQR1 = 0; + ADC1->RSQR2 = 0; + ADC1->RSQR3 = 7; // 0-9 for 8 ext inputs and two internals + + // Not using injection group. + + // Sampling time for channels. Careful: This has PID tuning implications. + // Note that with 3 and 3,the full loop (and injection) runs at 138kHz. + ADC1->SAMPTR2 = (0<<(3*7)); + + // Turn on ADC and set rule group to sw trig + // 0 = Use TRGO event for Timer 1 to fire ADC rule. + ADC1->CTLR2 = ADC_ADON | ADC_EXTTRIG | ADC_DMA; + + // Reset calibration + ADC1->CTLR2 |= ADC_RSTCAL; + while(ADC1->CTLR2 & ADC_RSTCAL); + + // Calibrate ADC + ADC1->CTLR2 |= ADC_CAL; + while(ADC1->CTLR2 & ADC_CAL); + + // ADC_SCAN: Allow scanning. + ADC1->CTLR1 = /*ADC_Pga_64 | */ADC_SCAN; + + + // Turn on DMA + RCC->AHBPCENR |= RCC_AHBPeriph_DMA1; + + //DMA1_Channel1 is for ADC + DMA1_Channel1->PADDR = (uint32_t)&ADC1->RDATAR; + DMA1_Channel1->MADDR = (uint32_t)adc_buffer; + DMA1_Channel1->CNTR = ADC_BUFFSIZE; + DMA1_Channel1->CFGR = + DMA_M2M_Disable | + DMA_Priority_VeryHigh | + DMA_MemoryDataSize_HalfWord | + DMA_PeripheralDataSize_HalfWord | + DMA_MemoryInc_Enable | + DMA_Mode_Circular | + DMA_DIR_PeripheralSRC; + + // Turn on DMA channel 1 + DMA1_Channel1->CFGR |= DMA_CFGR1_EN; + + // Enable continuous conversion and DMA + ADC1->CTLR2 |= ADC_DMA; // | ADC_CONT; + + // start conversion + ADC1->CTLR2 |= ADC_SWSTART;// | ADC_CONT; + +} + +static void SetupTimer1() +{ + // Enable Timer 1 + RCC->APB2PRSTR |= RCC_APB2Periph_TIM1; + RCC->APB2PRSTR &= ~RCC_APB2Periph_TIM1; + + TIM1->PSC = 0; // Prescalar to 0x0000 (so, 48MHz base clock) + TIM1->ATRLR = PWM_PERIOD; + +#ifdef PWM_OUTPUT + // PA10 = T1CH3. + GPIOA->CFGHR &= ~(0xf<<(4*2)); + GPIOA->CFGHR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP_AF)<<(4*2); + + TIM1->CCER = TIM_CC3E | TIM_CC3P; + TIM1->CHCTLR2 = TIM_OC3M_2 | TIM_OC3M_1; + TIM1->CH3CVR = 5; // Actual duty cycle (Off to begin with) +#endif + + TIM1->CCER = TIM_CC1E; + TIM1->CHCTLR1 = TIM_OC1M_2 | TIM_OC1M_1; + TIM1->CH1CVR = 1; + + // Setup TRGO to trigger for ADC (NOTE: Not on the 203! TIM1_TRGO is only connected to injection) + //TIM1->CTLR2 = TIM_MMS_1; + + // Enable TIM1 outputs + TIM1->BDTR = TIM_MOE; + TIM1->CTLR1 = TIM_CEN; +} + + +void InnerLoop() __attribute__((noreturn)); + + +void InnerLoop() +{ + int i = 0; + int q = 0; + int tpl = 0; + + // Timer goes backwards when we are moving forwards. + volatile uint16_t * adc_buffer_end = 0; + volatile uint16_t * adc_buffer_top = adc_buffer + ADC_BUFFSIZE; + volatile uint16_t * adc = adc_buffer; + + int frcnt = 0; + + int tstart = 0; + +#ifdef DUMPBUFF + uint16_t shadowbuff[Q+16]; + int shadowplace = 0; + #define SHADOWSTORE(X) shadowbuff[frcnt+X] = t; +#else + #define SHADOWSTORE(X) +#endif + + while( 1 ) + { + tpl = ADC_BUFFSIZE - DMA1_Channel1->CNTR; // Warning, sometimes this is == to the base, or == 0 (i.e. might be 256, if top is 255) + if( tpl == ADC_BUFFSIZE ) tpl = 0; + + adc_buffer_end = adc_buffer + ( ( tpl / 4) * 4 ); +//printf( "%3d %4d %d %04x\n", DMA1_Channel1->CNTR, TIM1->CNT, ADC1->RDATAR, ADC1->STATR ); + while( adc != adc_buffer_end ) + { +#ifdef QUADRATURE + int32_t t = adc[0]; SHADOWSTORE(0); + i += t; q += t; + t = adc[1]; SHADOWSTORE(1); + i -= t; q += t; + t = adc[2]; SHADOWSTORE(2); + i -= t; q -= t; + t = adc[3]; SHADOWSTORE(3); + i += t; q -= t; + adc += 4; + frcnt += 4; +#else + i = i + adc[0] - adc[1]; + adc += 2; + frcnt += 2; +#endif + + if( adc == adc_buffer_top ) adc = adc_buffer; + if( frcnt >= Q ) break; + } + + + if( frcnt >= Q ) + { + +#ifdef DUMPBUFF + int j; + for( j = 0; j < Q; j++ ) + printf( "%d,%d\n", j, shadowbuff[j] ); +#endif +#ifdef QUADRATURE + int ti = i>>3; + int tq = q>>3; + int is = (ti*ti + tq*tq)>>8; +#else + int is = i>>2; +#endif + int s = 1<<( ( 32 - __builtin_clz(is) )/2); + s = (s + is/s)/2; + + +#ifdef TIGHT_OUT + printf( "%d\n", s ); +#elif defined( PWM_OUTPUT ) + int tv = (s>>PWM_OUTPUT) + (PWM_PERIOD/2); + if( tv < 0 ) tv = 0; + if( tv >= PWM_PERIOD ) tv = PWM_PERIOD-1; + TIM1->CH3CVR = tv; +#else + + printf( "%8d I:%7d Q:%7d [%d %d %d %d] / %d\n",s, i ,q, adc_buffer[0], adc_buffer[1], adc_buffer[2], adc_buffer[3], (int)(SysTick->CNT - tstart) ); +#endif + //printf( "%d\n", s ); + frcnt = 0; + i = 0; + q = 0; + tpl = ADC_BUFFSIZE - DMA1_Channel1->CNTR; + adc = adc_buffer + ( ( tpl / 4) * 4 ); + tstart = SysTick->CNT; + } +/* + Delay_Us( 100 ); + int end = DMA1_Channel1->CNTR; + int v0 = adc_buffer[0]; + int v1 = adc_buffer[1]; + int v2 = adc_buffer[2]; + int v3 = adc_buffer[3]; + printf( "%d %d %d %d %d\n", (uint8_t)(start-end), v0, v1, v2, v3 ); +*/ + } + +} + +int main() +{ + SystemInit(); + + SysTick->CTLR = (1<<2) | 1; // HCLK + Delay_Ms(100); + + printf( "System On\n" ); + + // x18; 8MHz x 18 = 144 MHz + RCC->CFGR0 &= ~RCC_PPRE2; // No divisor on APB1/2 + RCC->CFGR0 &= ~RCC_PPRE1; + RCC->CFGR0 |= RCC_PLLMULL_0 | RCC_PLLMULL_1 | RCC_PLLMULL_2 | RCC_PLLMULL_3; + + Delay_Ms(50); + + // Disable HSI + RCC->CTLR &= ~(RCC_HSION); + +// printf( "RCC: %08x\n", (RCC->CFGR0) ); + RCC->AHBPCENR |= 3; //DMA2EN | DMA1EN + RCC->APB2PCENR |= RCC_APB2Periph_TIM1 | RCC_APB2Periph_ADC1 | RCC_APB2Periph_ADC2 | 0x07; // Enable all GPIO + RCC->APB1PCENR |= RCC_APB1Periph_TIM2; + + SetupADC(); + +#if 0 + // turn on the op-amp + EXTEN->EXTEN_CTR |= EXTEN_OPA_EN; + + // select op-amp pos pin: 0 = PA2, 1 = PD7 + EXTEN->EXTEN_CTR |= EXTEN_OPA_PSEL; + + // select op-amp neg pin: 0 = PA1, 1 = PD0 + EXTEN->EXTEN_CTR |= EXTEN_OPA_NSEL; +#endif + + + printf( "ADC Setup\n" ); + + SetupTimer1(); + + printf( "Timer 1 setup\n" ); + + InnerLoop(); +} diff --git a/ch32v/ch32v203-adcrx/funconfig.h b/ch32v/ch32v203-adcrx/funconfig.h new file mode 100644 index 0000000..eb91275 --- /dev/null +++ b/ch32v/ch32v203-adcrx/funconfig.h @@ -0,0 +1,10 @@ +#ifndef _FUNCONFIG_H +#define _FUNCONFIG_H + +#define FUNCONF_USE_DEBUGPRINTF 1 +#define FUNCONF_USE_UARTPRINTF 0 +#define FUNCONF_USE_HSE 1 +#define FUNCONF_SYSTICK_USE_HCLK 1 + +#endif + diff --git a/ch32v/ch32v203-fft/Makefile b/ch32v/ch32v203-fft/Makefile new file mode 100644 index 0000000..356722c --- /dev/null +++ b/ch32v/ch32v203-fft/Makefile @@ -0,0 +1,15 @@ +all : flash + +TARGET:=adcfft +TARGET_MCU:=CH32V203G6U6 +TARGET_MCU_PACKAGE:=CH32V203G6U6 +CH32V003FUN:=../ch32v003fun/ch32v003fun + +EXTRA_CFLAGS:=-Wno-unused-function -I../../lib -I../lib + +include ../ch32v003fun/ch32v003fun/ch32v003fun.mk + +flash : cv_flash +clean : cv_clean + rm -rf rf_data_gen chirpbuff.dat chirpbuff.h chirpbuffinfo.h + diff --git a/ch32v/ch32v203-fft/README.md b/ch32v/ch32v203-fft/README.md new file mode 100644 index 0000000..23b672e --- /dev/null +++ b/ch32v/ch32v203-fft/README.md @@ -0,0 +1,4 @@ +# Example with an FFT for quickly figuring out where on the spectrum to look. + + * Display on PB8/PB9 for SCL/SDA + * Analog is on PA7 diff --git a/ch32v/ch32v203-fft/adcfft.c b/ch32v/ch32v203-fft/adcfft.c new file mode 100644 index 0000000..b45bed9 --- /dev/null +++ b/ch32v/ch32v203-fft/adcfft.c @@ -0,0 +1,491 @@ +/** + +MIT-like-non-ai-license + +Copyright (c) 2024 Charles Lohr "CNLohr" + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the two following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +In addition the following restrictions apply: + +1. The Software and any modifications made to it may not be used for the +purpose of training or improving machine learning algorithms, including but not +limited to artificial intelligence, natural language processing, or data +mining. This condition applies to any derivatives, modifications, or updates +based on the Software code. Any usage of the Software in an AI-training dataset +is considered a breach of this License. + +2. The Software may not be included in any dataset used for training or +improving machine learning algorithms, including but not limited to artificial +intelligence, natural language processing, or data mining. + + +3. Any person or organization found to be in violation of these restrictions +will be subject to legal action and may be held liable for any damages +resulting from such use. + +If any term is unenforcable, other terms remain in-force. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +**/ + +// NOT LORA!!! -- but experimenting with the possibility of rx. + +// SETUP INSTRUCTIONS: +// (1) `make` in the optionbytes folder to configure `RESET` correctly. +// (2) Create a tone (if using the funprog, ../ch32v003fun/minichlink/minichlink -X ECLK 1:235:189:9:3 for 27.48387097MHz +// (2) or, for 24.387096762MHz - ../ch32v003fun/minichlink/minichlink -X ECLK 1:150:49:8:3 + +/* More notes + + * Minimum sample time with DMA = fCPU / 28 (5.14MHz) + +*/ + + +#include "ch32v003fun.h" +#include + +#define SH1107_128x128 +#define SSD1306_RST_PIN PA3 +#define SSD1306_CS_PIN PA4 +#define SSD1306_DC_PIN PA6 +#define SSD1306_MOSI_PIN PA7 +#define SSD1306_SCK_PIN PA5 +#define SSD1306_BAUD_RATE_PRESCALER SPI_BaudRatePrescaler_4 +#include "ssd1306_spi.h" +#include "ssd1306.h" + +#define FIX_FFT_IMPLEMENTATION +#include "fix_fft.h" + +/* General note: +*/ + +#define Q 256 + +#define TARGET_BIN 51 + +#define PWM_PERIOD (31-1) //For 27.0MHz, use 36MHz if quadrature -- It appears to be good for *244 in the table? WHY 26MHz???!?!!? + +#define ADC_BUFFSIZE 512 +volatile uint16_t adc_buffer[ADC_BUFFSIZE]; + +void SetupADC() +{ + // XXX TODO -look into PGA + // XXX TODO - Look into tag-teaming the ADCs + + // PA7 is analog input chl 7 + GPIOA->CFGLR &= ~(0xf<<(4*7)); // CNF = 00: Analog, MODE = 00: Input + + // ADC CLK is chained off of APB2. + + // Reset the ADC to init all regs + RCC->APB2PRSTR |= RCC_APB2Periph_ADC1; + RCC->APB2PRSTR &= ~RCC_APB2Periph_ADC1; + + // ADCCLK = 12 MHz => RCC_ADCPRE divide by 4 + RCC->CFGR0 &= ~RCC_ADCPRE; // Clear out the bis in case they were set + RCC->CFGR0 |= RCC_ADCPRE_DIV2; // Fastest possible (divide-by-2) NOTE: This is OUTSIDE the specified value in the datasheet. + + // Set up single conversion on chl 7 + ADC1->RSQR1 = 0; + ADC1->RSQR2 = 0; + ADC1->RSQR3 = 7; // 0-9 for 8 ext inputs and two internals + + // Not using injection group. + + // Sampling time for channels. Careful: This has PID tuning implications. + // Note that with 3 and 3,the full loop (and injection) runs at 138kHz. + ADC1->SAMPTR2 = (0<<(3*7)); + + // Turn on ADC and set rule group to sw trig + // 0 = Use TRGO event for Timer 1 to fire ADC rule. + ADC1->CTLR2 = ADC_ADON | ADC_EXTTRIG | ADC_DMA; + + // Reset calibration + ADC1->CTLR2 |= ADC_RSTCAL; + while(ADC1->CTLR2 & ADC_RSTCAL); + + // Calibrate ADC + ADC1->CTLR2 |= ADC_CAL; + while(ADC1->CTLR2 & ADC_CAL); + + // ADC_SCAN: Allow scanning. + ADC1->CTLR1 = /*ADC_Pga_64 | */ADC_SCAN; + + + // Turn on DMA + RCC->AHBPCENR |= RCC_AHBPeriph_DMA1; + + //DMA1_Channel1 is for ADC + DMA1_Channel1->PADDR = (uint32_t)&ADC1->RDATAR; + DMA1_Channel1->MADDR = (uint32_t)adc_buffer; + DMA1_Channel1->CNTR = ADC_BUFFSIZE; + DMA1_Channel1->CFGR = + DMA_M2M_Disable | + DMA_Priority_VeryHigh | + DMA_MemoryDataSize_HalfWord | + DMA_PeripheralDataSize_HalfWord | + DMA_MemoryInc_Enable | + DMA_Mode_Circular | + DMA_DIR_PeripheralSRC; + + // Turn on DMA channel 1 + DMA1_Channel1->CFGR |= DMA_CFGR1_EN; + + // Enable continuous conversion and DMA + ADC1->CTLR2 |= ADC_DMA; // | ADC_CONT; + + // start conversion + ADC1->CTLR2 |= ADC_SWSTART;// | ADC_CONT; + +} + +static void SetupTimer1() +{ + // Enable Timer 1 + RCC->APB2PRSTR |= RCC_APB2Periph_TIM1; + RCC->APB2PRSTR &= ~RCC_APB2Periph_TIM1; + + TIM1->PSC = 0; // Prescalar to 0x0000 (so, 48MHz base clock) + TIM1->ATRLR = PWM_PERIOD; + +#ifdef PWM_OUTPUT + // PA10 = T1CH3. + GPIOA->CFGHR &= ~(0xf<<(4*2)); + GPIOA->CFGHR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP_AF)<<(4*2); + + TIM1->CCER = TIM_CC3E | TIM_CC3P; + TIM1->CHCTLR2 = TIM_OC3M_2 | TIM_OC3M_1; + TIM1->CH3CVR = 5; // Actual duty cycle (Off to begin with) +#endif + + TIM1->CCER = TIM_CC1E; + TIM1->CHCTLR1 = TIM_OC1M_2 | TIM_OC1M_1; + TIM1->CH1CVR = 1; + + // Setup TRGO to trigger for ADC (NOTE: Not on the 203! TIM1_TRGO is only connected to injection) + //TIM1->CTLR2 = TIM_MMS_1; + + // Enable TIM1 outputs + TIM1->BDTR = TIM_MOE; + TIM1->CTLR1 = TIM_CEN; +} + + +void InnerLoop() __attribute__((noreturn)); + + +void InnerLoop() +{ + //int i = 0; + //int q = 0; + int tpl = 0; + + // Timer goes backwards when we are moving forwards. + volatile uint16_t * adc_buffer_end = 0; + volatile uint16_t * adc_buffer_top = adc_buffer + ADC_BUFFSIZE; + volatile uint16_t * adc = adc_buffer; + + int frcnt = 0; + + int tstart = 0; + + int16_t shadowbuff[Q+16]; + + int shadowplace = 0; + #define SCALEUP 6 + #define SHADOWSTORE(X) shadowbuff[frcnt+X] = t; + + while( 1 ) + { + tpl = ADC_BUFFSIZE - DMA1_Channel1->CNTR; // Warning, sometimes this is == to the base, or == 0 (i.e. might be 256, if top is 255) + + tpl += ADC_BUFFSIZE; + tpl = (tpl & (ADC_BUFFSIZE-1)); + if( tpl == ADC_BUFFSIZE ) tpl = 0; + + adc_buffer_end = adc_buffer + ( ( tpl / 4) * 4 ); +//printf( "%3d %4d %d %04x\n", DMA1_Channel1->CNTR, TIM1->CNT, ADC1->RDATAR, ADC1->STATR ); + while( adc != adc_buffer_end ) + { + + int32_t t = adc[0]; SHADOWSTORE(0); + //i += t; q += t; + t = adc[1]; SHADOWSTORE(1); + //i -= t; q += t; + t = adc[2]; SHADOWSTORE(2); + //i -= t; q -= t; + t = adc[3]; SHADOWSTORE(3); + //i += t; q -= t; + adc += 4; + frcnt += 4; + + if( adc == adc_buffer_top ) adc = adc_buffer; + if( frcnt >= Q ) break; + } + + + if( frcnt >= Q ) + { + +#if 0 + +#ifdef DUMPBUFF + int j; + for( j = 0; j < Q; j++ ) + printf( "%d,%d\n", j, shadowbuff[j] ); +#endif +#ifdef QUADRATURE + int ti = i>>3; + int tq = q>>3; + int is = (ti*ti + tq*tq)>>8; +#else + int is = i>>2; +#endif + int s = 1<<( ( 32 - __builtin_clz(is) )/2); + s = (s + is/s)/2; + + +#ifdef TIGHT_OUT + printf( "%d\n", s ); +#elif defined( PWM_OUTPUT ) + int tv = (s>>PWM_OUTPUT) + (PWM_PERIOD/2); + if( tv < 0 ) tv = 0; + if( tv >= PWM_PERIOD ) tv = PWM_PERIOD-1; + TIM1->CH3CVR = tv; +#else + + printf( "%8d I:%7d Q:%7d [%d %d %d %d] / %d\n",s, i ,q, adc_buffer[0], adc_buffer[1], adc_buffer[2], adc_buffer[3], (int)(SysTick->CNT - tstart) ); +#endif + //printf( "%d\n", s ); +#endif + int k; + + // printf( "Data: " ); + for( k = 0; k < Q; k++ ) + { + // printf( "%d, ",shadowbuff[k] ); + shadowbuff[k] = (shadowbuff[k]<>(SCALEUP+1))+40, 1 ); + } + + int16_t imag[Q] = { 0 }; + + int r = + fix_fft(shadowbuff, imag, 8, 0); + + //fix_fftr(shadowbuff, 7 /*1<<7 = 128 bins wide*/, 0); + //fix_fft(shadowbuff, FSQ, 8 /*1<<7 = 128 bins wide*/, 0); + +// printf( "FFT: +// for( k = 0; k < 128; k++ ) +// { +// } + + int targbin = TARGET_BIN; + int targv = 0; + int maxbin = 0; + int maxbinv = 0; + + + for( k = 0; k < 128; k++ ) + { +/* + int s = shadowbuff[k] * shadowbuff[k] + FSQ[k]*FSQ[k]; + //if( s == 0 ) continue; + int x = 1<<( ( 32 - __builtin_clz(s) )/2); + x = (x + i/x)/2; + x = (x + i/x)/2; //Not really needed. +*/ + + // for real + // int x = shadowbuff[(k>>1) | ((k&64)>>6)]; + // For faked imag + +#if 0 + int s = shadowbuff[k] * shadowbuff[k] + shadowbuff[255-k]*shadowbuff[255-k]; + //if( s == 0 ) continue; + int x = 1<<( ( 32 - __builtin_clz(s) )/2); + x = (x + s/x)/2; + x = (x + s/x)/2; //Not really needed. + x = (x + s/x)/2; //Not really needed. + + //x = shadowbuff[ k ]; + //x = s >> 8; + + x = x >> 2; +#endif + + int s = shadowbuff[k] * shadowbuff[k] + imag[k]*imag[k]; + //if( s == 0 ) continue; + int x = 1<<( ( 32 - __builtin_clz(s) )/2); + x = (x + s/x)/2; + x = (x + s/x)/2; //Not really needed. + x = (x + s/x)/2; //Not really needed. + + //x = shadowbuff[ k ]; + //x = s >> 8; + + //x = x >> 2; + if( x > maxbinv && k != 0) { maxbinv = x; maxbin = k; } + if( k == targbin ) targv = x; + + x++; + if( x < 0 ) x = 0; + if( x > 127 ) x = 127; + if( x != 0 ) + ssd1306_drawFastVLine( k, 127-x, x, 1 ); + + } + + static int tbhist[128]; + static int tbhead = 0; + tbhist[tbhead++] = targv; + if( tbhead == 128 ) tbhead = 0; + + char cts[32]; + snprintf( cts, sizeof(cts), "%5d%5d@%d", osb, targv, targbin ); + ssd1306_drawstr( 0, 0, cts, 1 ); + snprintf( cts, sizeof(cts), "P:%d B%3d/%4d", PWM_PERIOD, maxbin, maxbinv ); + ssd1306_drawstr( 0, 8, cts, 1 ); + + for( k = 0; k < 128; k++ ) + { + ssd1306_drawPixel( k, 105-tbhist[(tbhead-k+256)%128]/2, 1); + } + + memset( shadowbuff, 0, sizeof( shadowbuff ) ); + + ssd1306_refresh(); + ssd1306_setbuf(0); + + frcnt = 0; +// i = 0; +// q = 0; + tpl = ADC_BUFFSIZE - DMA1_Channel1->CNTR; + adc = adc_buffer + ( ( tpl / 4) * 4 ); + tstart = SysTick->CNT; + } +/* + Delay_Us( 100 ); + int end = DMA1_Channel1->CNTR; + int v0 = adc_buffer[0]; + int v1 = adc_buffer[1]; + int v2 = adc_buffer[2]; + int v3 = adc_buffer[3]; + printf( "%d %d %d %d %d\n", (uint8_t)(start-end), v0, v1, v2, v3 ); +*/ + } + +} + +int main() +{ + SystemInit(); + + SysTick->CTLR = (1<<2) | 1; // HCLK + Delay_Ms(100); + + printf( "System On\n" ); + + RCC->CTLR |= RCC_HSEON; + while( ! ( RCC->CTLR & RCC_HSERDY ) ); + + RCC->CFGR0 = (RCC->CFGR0 & ~RCC_SW) | RCC_SW_HSE; + + RCC->CTLR &= ~RCC_PLLON; + + // Switch PLL to HSE. + RCC->CFGR0 |= RCC_PLLSRC; + + // x18; 8MHz x 18 = 144 MHz + RCC->CFGR0 &= ~RCC_PPRE2; // No divisor on APB1/2 + RCC->CFGR0 &= ~RCC_PPRE1; + RCC->CFGR0 |= RCC_PLLMULL_0 | RCC_PLLMULL_1 | RCC_PLLMULL_2 | RCC_PLLMULL_3; + + RCC->CTLR |= RCC_PLLON; + + // Switch to PLL + RCC->CFGR0 = (RCC->CFGR0 & ~RCC_SW) | RCC_SW_PLL; + + // Disable HSI + RCC->CTLR &= ~(RCC_HSION); + + Delay_Ms(10); + + + printf( "CTLR: %08x / CFGR0: %08x\n", (RCC->CTLR), (RCC->CFGR0) ); + RCC->AHBPCENR |= 3; //DMA2EN | DMA1EN + RCC->APB2PCENR |= RCC_APB2Periph_TIM1 | RCC_APB2Periph_ADC1 | RCC_APB2Periph_ADC2 | 0x07; // Enable all GPIO + RCC->APB1PCENR |= RCC_APB1Periph_TIM2; + + SetupADC(); + + printf( "Setting up OLED.\n" ); + //ssd1306_spi_setup(); + uint8_t ret = ssd1306_spi_init(); + ssd1306_init(); + ssd1306_setbuf(0); + +#if 0 + int i = 0; + int k = 0; + int frame = 0; + while( 1) + { +// ssd1306_drawLine( (frame)%128, (0)%128, (0)%128, (127-frame)%128, 1 ); + ssd1306_drawstr( frame%128, frame%128, "hello", 1 ); + + ssd1306_refresh(); + ssd1306_setbuf(0); + frame++; + } + + while(1); +#endif + +#if 0 + // turn on the op-amp + EXTEN->EXTEN_CTR |= EXTEN_OPA_EN; + + // select op-amp pos pin: 0 = PA2, 1 = PD7 + EXTEN->EXTEN_CTR |= EXTEN_OPA_PSEL; + + // select op-amp neg pin: 0 = PA1, 1 = PD0 + EXTEN->EXTEN_CTR |= EXTEN_OPA_NSEL; +#endif + + + printf( "ADC Setup\n" ); + + SetupTimer1(); + + printf( "Timer 1 setup\n" ); + + InnerLoop(); +} diff --git a/ch32v/ch32v203-fft/funconfig.h b/ch32v/ch32v203-fft/funconfig.h new file mode 100644 index 0000000..eb91275 --- /dev/null +++ b/ch32v/ch32v203-fft/funconfig.h @@ -0,0 +1,10 @@ +#ifndef _FUNCONFIG_H +#define _FUNCONFIG_H + +#define FUNCONF_USE_DEBUGPRINTF 1 +#define FUNCONF_USE_UARTPRINTF 0 +#define FUNCONF_USE_HSE 1 +#define FUNCONF_SYSTICK_USE_HCLK 1 + +#endif + diff --git a/ch32v/ch32v203-goertzel/Makefile b/ch32v/ch32v203-goertzel/Makefile new file mode 100644 index 0000000..f47f937 --- /dev/null +++ b/ch32v/ch32v203-goertzel/Makefile @@ -0,0 +1,15 @@ +all : flash + +TARGET:=adcgoertzel +TARGET_MCU:=CH32V203G6U6 +TARGET_MCU_PACKAGE:=CH32V203G6U6 +CH32V003FUN:=../ch32v003fun/ch32v003fun + +EXTRA_CFLAGS:=-Wno-unused-function -I../../lib -I../lib -I../ch32v003fun/examples_v20x/otg_device -I. + +include ../ch32v003fun/ch32v003fun/ch32v003fun.mk + +flash : cv_flash +clean : cv_clean + rm -rf rf_data_gen chirpbuff.dat chirpbuff.h chirpbuffinfo.h + diff --git a/ch32v/ch32v203-goertzel/README.md b/ch32v/ch32v203-goertzel/README.md new file mode 100644 index 0000000..a26f283 --- /dev/null +++ b/ch32v/ch32v203-goertzel/README.md @@ -0,0 +1,32 @@ +# How to use this + + * Display on PB8/PB9 for SCL/SDA + * Analog is on PA7 + +First, use FFT, then look in the middle for the highest bin @. This is the # of pixels from the left side of the screen you are. + +Then edit ttest.c, + +``` + g_goertzel_omega_per_sample = (47.0/256) * 3.1415926535*2.0*65536; +``` + +where 47.0 in this case is the bin # from the FFT. + +Change this, `make test` + +Then copy the values: +const int32_t g_goertzel_omega_per_sample = 75599; +const int32_t g_goertzel_coefficient = 870257651; +const int32_t g_goertzel_coefficient_s = 1963246708; + +into the top of adcgoertzel.c + + +TODO: TODO: Test HTML values. + +TODO: TODO: g_goertzel_omega_per_sample lokos WRONG. + + +Extra notes: + .87996033 = 880 AM, why? diff --git a/ch32v/ch32v203-goertzel/adcgoertzel.c b/ch32v/ch32v203-goertzel/adcgoertzel.c new file mode 100644 index 0000000..db5d2cd --- /dev/null +++ b/ch32v/ch32v203-goertzel/adcgoertzel.c @@ -0,0 +1,863 @@ +/** + +MIT-like-non-ai-license + +Copyright (c) 2024 Charles Lohr "CNLohr" + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the two following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +In addition the following restrictions apply: + +1. The Software and any modifications made to it may not be used for the +purpose of training or improving machine learning algorithms, including but not +limited to artificial intelligence, natural language processing, or data +mining. This condition applies to any derivatives, modifications, or updates +based on the Software code. Any usage of the Software in an AI-training dataset +is considered a breach of this License. + +2. The Software may not be included in any dataset used for training or +improving machine learning algorithms, including but not limited to artificial +intelligence, natural language processing, or data mining. + + +3. Any person or organization found to be in violation of these restrictions +will be subject to legal action and may be held liable for any damages +resulting from such use. + +If any term is unenforcable, other terms remain in-force. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +**/ + +// SETUP INSTRUCTIONS: +// (1) `make` in the optionbytes folder to configure `RESET` correctly. +// (2) Create a tone (if using the funprog, ../ch32v003fun/minichlink/minichlink -X ECLK 1:235:189:9:3 for 27.48387097MHz +// (2) or, for 24.387096762MHz - ../ch32v003fun/minichlink/minichlink -X ECLK 1:150:49:8:3 +/* More notes + * Minimum sample time with DMA = fCPU / 28 (5.14MHz) +*/ + +// TODO: +// 1: Cleanup some code. +// 2: Leverage other ADC. +// 3: + + +#include "ch32v003fun.h" +#include +#include +#include + + +// Channel for ADC +#define CHANNEL 0 + +// For I2C, output will be on PB8/PB9 SCL/SDA +//#define ENABLE_OLED +//#define PWM_OUTPUT +int g_volume_pwm = 127; // 0 - 127 (100%) (but you can go over 100) (For when using PWM) +#define ENABLE_OLED_SCOPE +//#define PROFILING_PIN PC8 + +#define SAMPLETIME 1 // 0: 1.5 cycles; 1: 7.5 cycles; 2: 13.5 cycles; (0 would go fastest and is important in single-ADC mode, but 1 seems slightly better in 2-ADC mode) + +#ifdef ENABLE_OLED_SCOPE +#define SH1107_128x128 +#define SSD1306_RST_PIN PA3 +#define SSD1306_CS_PIN PA4 +#define SSD1306_DC_PIN PA6 +#define SSD1306_MOSI_PIN PA7 +#define SSD1306_SCK_PIN PA5 +#define SSD1306_BAUD_RATE_PRESCALER SPI_BaudRatePrescaler_4 +#include "ssd1306_spi.h" +#include "ssd1306.h" +#endif + +#ifdef ENABLE_OLED +#define SH1107_128x128 +#define SSD1306_REMAP_I2C +//#define SSD1306_I2C_IRQ +#include "ssd1306_i2c.h" +#include "ssd1306.h" +#endif + +#if defined( ENABLE_OLED ) && defined( ENABLE_OLED_SCOPE ) +#error Cant be SPI and I2C OLED +#endif + + +#include "./usb_config.h" +#include "../ch32v003fun/examples_v20x/otg_device/otgusb.h" + +// Bigger buffer decreases chance of fall-through, but increases the size of each operation. +#define ADC_BUFFSIZE 512 + +volatile uint16_t adc_buffer[ADC_BUFFSIZE]; + +int32_t g_goertzel_phasor_r = 32768; +int32_t g_goertzel_phasor_i = 0; +int32_t g_attenuation_pow2 = 4; + +#if 1 +// Very basic setup, for tuning to 880AM +int g_pwm_period = (60-1); +int g_exactcompute = (1); +int g_goertzel_buffer = (1024); +int32_t g_goertzel_omega_per_sample = 873460290; // 0.183333 of whole per step / -8.720000MHz +int32_t g_goertzel_coefficient = 873460290; +int32_t g_goertzel_coefficient_s = 1961823932; +int32_t g_goertzel_advance_r = -3425; +int32_t g_goertzel_advance_i = 32588; +#endif + +int intensity_average = 1; + +#define LOG_GOERTZEL_LIST 512 +int32_t qibaselogs[LOG_GOERTZEL_LIST]; +volatile int qibaselogs_head; + +void SetupADC() +{ + // XXX TODO -look into PGA + // XXX TODO - Look into tag-teaming the ADCs + + // PDA is analog input chl CHANNEL + GPIOA->CFGLR &= ~(0xf<<(4*CHANNEL)); // CNF = 00: Analog, MODE = 00: Input + + // ADC CLK is chained off of APB2. + + // Reset the ADC to init all regs + RCC->APB2PRSTR |= RCC_APB2Periph_ADC1 | RCC_APB2Periph_ADC2; + RCC->APB2PRSTR &= ~( RCC_APB2Periph_ADC1 | RCC_APB2Periph_ADC2 ); + + // ADCCLK = 12 MHz => RCC_ADCPRE divide by 4 + RCC->CFGR0 &= ~RCC_ADCPRE; // Clear out the bis in case they were set + RCC->CFGR0 |= RCC_ADCPRE_DIV2; // Fastest possible (divide-by-2) NOTE: This is OUTSIDE the specified value in the datasheet. + + // Set up single conversion on chl 7 + ADC1->RSQR3 = CHANNEL; // 0-9 for 8 ext inputs and two internals Set to 7 for PA7 + ADC2->RSQR3 = CHANNEL; // 0-9 for 8 ext inputs and two internals Set to 7 for PA7 + + ADC1->ISQR = CHANNEL; // Mirror in case we switch to injection mode. + ADC2->ISQR = CHANNEL; + + // Not using injection group. + + // Sampling time for channels. Careful: This has PID tuning implications. + // Note that with 3 and 3,the full loop (and injection) runs at 138kHz. + ADC1->SAMPTR2 = (SAMPLETIME<<(3*CHANNEL)); // (3*channel) + ADC2->SAMPTR2 = (SAMPLETIME<<(3*CHANNEL)); // (3*channel) + + // Turn on ADC and set rule group to sw trig + // 0 = Use TRGO event for Timer 1 to fire ADC rule. + ADC1->CTLR2 = ADC_ADON | ADC_EXTTRIG | ADC_DMA; + ADC2->CTLR2 = ADC_ADON | ADC_EXTTRIG | ADC_EXTSEL_1;// | ADC_DMA; + // For EXTTRIG, EXTSEL (none) = 0 = TIM1CC1 / + // For JEXTTRIG, EXTSEL = 0 = TIM1 TRGO (Or ADC_JEXTSEL_0 => CH4) + + // Reset calibration + ADC1->CTLR2 |= ADC_RSTCAL; + ADC2->CTLR2 |= ADC_RSTCAL; + while(ADC1->CTLR2 & ADC_RSTCAL); + while(ADC2->CTLR2 & ADC_RSTCAL); + + // Calibrate ADC + ADC1->CTLR2 |= ADC_CAL; + ADC2->CTLR2 |= ADC_CAL; + while(ADC1->CTLR2 & ADC_CAL); + while(ADC2->CTLR2 & ADC_CAL); + + // ADC_SCAN: Allow scanning. + ADC2->CTLR1 = ADC_SCAN; + ADC1->CTLR1 = + //ADC_DUALMOD_0 | ADC_DUALMOD_3 | // Alternate Trigger Mode (Can't use with DMA) + ADC_SCAN; + //ADC_Pga_16 | ADC_BUFEN ; + //ADC_Pga_64 | ADC_BUFEN; + + // Turn on DMA + RCC->AHBPCENR |= RCC_AHBPeriph_DMA1; + + //DMA1_Channel1 is for ADC + DMA1_Channel1->PADDR = (uint32_t)&ADC1->RDATAR; + DMA1_Channel1->MADDR = (uint32_t)adc_buffer; + DMA1_Channel1->CNTR = ADC_BUFFSIZE/2; + DMA1_Channel1->CFGR = + DMA_M2M_Disable | + DMA_Priority_VeryHigh | + DMA_MemoryDataSize_Word | + DMA_PeripheralDataSize_Word | + DMA_MemoryInc_Enable | + DMA_Mode_Circular | + DMA_DIR_PeripheralSRC; + + NVIC_EnableIRQ( DMA1_Channel1_IRQn ); + DMA1_Channel1->CFGR |= DMA_CFGR1_EN | DMA_IT_TC | DMA_IT_HT; // Transmission Complete + Half Empty Interrupts. + + // Enable continuous conversion and DMA + ADC1->CTLR2 |= ADC_DMA; // | ADC_CONT; +} + +static void SetupTimer1() +{ + // Enable Timer 1 + RCC->APB2PRSTR |= RCC_APB2Periph_TIM1; + RCC->APB2PRSTR &= ~RCC_APB2Periph_TIM1; + + TIM1->PSC = 0; // Prescalar to 0x0000 (so, 48MHz base clock) + TIM1->ATRLR = g_pwm_period; + +#ifdef PWM_OUTPUT + // PA9 = T1CH2. + funPinMode( PA9, GPIO_CFGLR_OUT_2Mhz_AF_PP ); + + TIM1->CCER = TIM_CC2E | TIM_CC2P; + TIM1->CHCTLR1 |= TIM_OC2M_2 | TIM_OC2M_1 | TIM_OC2FE; + TIM1->CH2CVR = 5; // Set duty cycle somewhere random. + + // Enable TIM1 outputs + TIM1->BDTR |= 0xc000;//TIM_MOE; +#endif + + TIM1->CCER |= TIM_CC1E | TIM_CC4E | TIM_CC3E; + TIM1->CHCTLR1 |= TIM_OC1M_2 | TIM_OC1M_1; + TIM1->CHCTLR2 |= TIM_OC3M_2 | TIM_OC3M_1 | TIM_OC4M_2 | TIM_OC4M_1; + TIM1->CH1CVR = 1; // In case we are using rule triggering + TIM1->CH3CVR = 1; // In case we are using rule (alternate) triggering + TIM1->CH4CVR = 1; // In case we are using injection triggering + + // Setup TRGO to trigger for ADC injection group + TIM1->CTLR2 = TIM_MMS_1; + + // Enable TIM1 outputs + TIM1->BDTR = TIM_MOE; + TIM1->CTLR1 = TIM_CEN; +} + +#ifdef ENABLE_OLED_SCOPE + +#ifdef PLOTGUARD +// Command-mode, Set X, Disable Timer, Set Y, Enable Timer +// There doesn't seem to be a way of truly pausing the scanout. +// GENERAL NOTE: This doesn't actually seem to help reduce streaking. +uint8_t cmdxy[] = { 0x00, 0xd3, 0x30, 0xd5, 0xff, 0xdc, 0x30, 0xd5, 0xf0 }; +#else +// Only set xy plot, and make sure clock is cranked. +uint8_t cmdxy[] = { 0x00, 0xd3, 0x30, 0xdc, 0x30, 0xd5, 0xf0 }; +#endif + +void config_turbo_scope() +{ + DMA1_Channel3->PADDR = (uint32_t)&SPI1->DATAR; + DMA1_Channel3->MADDR = (uint32_t)cmdxy; + DMA1_Channel3->CNTR = sizeof(cmdxy); + DMA1_Channel3->CFGR = + DMA_M2M_Disable | + DMA_Priority_Low | + DMA_MemoryDataSize_Byte | + DMA_PeripheralDataSize_Byte | + DMA_MemoryInc_Enable | + DMA_Mode_Normal | + DMA_DIR_PeripheralDST; + + // Turn on DMA channel 3 (For SPI output) + DMA1_Channel3->CFGR |= DMA_CFGR1_EN; + + // All display controls from here on out are made using DC = 0. + funDigitalWrite( SSD1306_DC_PIN, FUN_LOW ); + + SPI1->CTLR2 |= SPI_CTLR2_TXDMAEN; +} + +static void PlotPoint( int x, int y ) +{ + funDigitalWrite( SSD1306_CS_PIN, FUN_HIGH ); +#ifdef PLOTGUARD + cmdxy[2] = x; cmdxy[6] = y; +#else + cmdxy[2] = x; cmdxy[4] = y; +#endif + DMA1_Channel3->CNTR = sizeof(cmdxy); + funDigitalWrite( SSD1306_CS_PIN, FUN_LOW ); + DMA1_Channel3->CFGR |= DMA_CFGR1_EN; +} +#endif + +void InnerLoop() __attribute__((noreturn)); + + +uint32_t tc; + + +volatile uint16_t * adc_tail = adc_buffer; + +uint32_t g_goertzel_samples; +uint32_t g_goertzel_outs; +int32_t g_goertzel, g_goertzelp, g_goertzelp2; +int32_t g_goertzelp_store, g_goertzelp2_store; + +int32_t g_laststart = 0; +int32_t g_lastper; +int32_t g_lastlen; +uint32_t g_accumulate_over_window; + +void DMA1_Channel1_IRQHandler( void ) __attribute__((interrupt)); +void DMA1_Channel1_IRQHandler( void ) +{ + int32_t start = SysTick->CNT; +#ifdef PROFILING_PIN + funDigitalWrite( PROFILING_PIN, 1 ); +#endif + + // Timer goes backwards when we are moving forwards. + volatile uint16_t * adc_buffer_end = 0; + volatile uint16_t * adc_buffer_top = adc_buffer + ADC_BUFFSIZE; + + int32_t goertzel_coefficient = g_goertzel_coefficient; + int32_t goertzelp2 = g_goertzelp2; + int32_t goertzelp = g_goertzelp; + int32_t goertzel = g_goertzel; + int32_t accumulate_over_window = g_accumulate_over_window; + + uint32_t goertzel_samples = g_goertzel_samples; + // Backup flags. + volatile int intfr = DMA1->INTFR; + + do + { + // Clear all possible flags. + DMA1->INTFCR = DMA1_IT_GL1; + + int tpl = ADC_BUFFSIZE - DMA1_Channel1->CNTR*2; + // Warning, sometimes this is DMA1_Channel1->CNTR == to the base, or == 0 (i.e. might be 256, if top is 255) + + tpl += ADC_BUFFSIZE; + tpl = (tpl & (ADC_BUFFSIZE-1)); + if( tpl == ADC_BUFFSIZE ) tpl = 0; + + adc_buffer_end = adc_buffer + ( ( tpl / 4) * 4 ); + + #define INFADC 2 + // Add a tiny bias to the ADC to help keep goertz in range. + static int adc_offset = (-2048) << INFADC; + + while( adc_tail != adc_buffer_end ) + { + + uint32_t t; // 1/2 of 4096, to try to keep our numbers reasonable. + + // Here is where the magic happens. + +#if 1 + // Also, this is the current limiting factor for the maximum samplerate. + // We can't go above 7.2MSPS and keep up here when main CPU is @ 144MHz. + + #define XSTR(x) #x + #define GOERTZELLOOP(idx) \ + asm volatile("\n\ + lhu %[adcin]," XSTR(idx) "(%[adc_tail]) \n\ + slli %[adcin],%[adcin],%[iadc] /*INFADC = 2*/ \n\ + add %[adcin],%[adcin],%[adcoffset] /*adcin += adcoffset*/ \n\ + add %[accumulate_over_window], %[adcin], %[accumulate_over_window]\n \ + addi %[goertzelp2],%[goertzelp],0 /*goertzelp2 = goertzelp*/ \n\ + addi %[goertzelp], %[goertzel],0 /*goertzelp = goertzel*/ \n\ + slli %[goertzel], %[goertzelp], 2 /*prescaling up goertzelp*/\n\ + mulh %[goertzel], %[goertzel_coefficient], %[goertzel]\n\ + sub %[adcin],%[adcin],%[goertzelp2] /*adcin -= goertzelp2*/ \n\ + add %[goertzel], %[goertzel], %[adcin] /* mulh = signed * signed + adc */ \n"\ + : [goertzel]"+r"(goertzel), [goertzelp]"+r"(goertzelp), [goertzelp2]"+r"(goertzelp2), [adcin]"+r"(t), [accumulate_over_window]"+r"(accumulate_over_window) : \ + [adc_tail]"r"(adc_tail), [adcoffset]"r"(adc_offset), [goertzel_coefficient]"r"(goertzel_coefficient), [iadc]"i"(INFADC) ); + + GOERTZELLOOP(0); + GOERTZELLOOP(2); + GOERTZELLOOP(4); + GOERTZELLOOP(6); +#else + t = ((adc_tail[0])<> 32 ) - goertzelp2; + + t = ((adc_tail[1])<> 32 ) - goertzelp2; + + t = ((adc_tail[2])<> 32 ) - goertzelp2; + + t = ((adc_tail[3])<> 32 ) - goertzelp2; +#endif + + adc_tail+=4; + goertzel_samples+=4; + if( adc_tail == adc_buffer_top ) adc_tail = adc_buffer; + if( goertzel_samples == g_goertzel_buffer ) + { +#ifdef PROFILING_PIN + funDigitalWrite( PROFILING_PIN, 0 ); +#endif + + g_goertzelp_store = goertzel; + g_goertzelp2_store = goertzelp; + + int32_t zp = g_goertzelp_store; + int32_t zp2 = g_goertzelp2_store; + int32_t rr = (((int64_t)(g_goertzel_coefficient ) * (int64_t)zp<<1)>>(32+g_attenuation_pow2)) - (zp2>>g_attenuation_pow2); + int32_t ri = (((int64_t)(g_goertzel_coefficient_s) * (int64_t)zp<<1)>>(32+g_attenuation_pow2)); + + // Advanced the current goertzel advance + // phasor = phasor * advance; + // real = real * real - imag * imag; + // imag = real * imag + real * imag; + // Sometimes you would bias the output here so that when truncating down you don't perpetually decay. + // But experimentally, it didn't make a difference. + int32_t temp = (g_goertzel_phasor_r * g_goertzel_advance_i + g_goertzel_phasor_i * g_goertzel_advance_r) >> 15; + g_goertzel_phasor_r = (g_goertzel_phasor_r * g_goertzel_advance_r - g_goertzel_phasor_i * g_goertzel_advance_i) >> 15; + g_goertzel_phasor_i = temp; + + // Fixup phasor over time to prevent it from dacaying. + #define ABS(x) (((x)<0)?-(x):(x)) + int s_phasor = g_goertzel_phasor_r * g_goertzel_phasor_r + g_goertzel_phasor_i * g_goertzel_phasor_i; + int intensity_phasor = (ABS(g_goertzel_phasor_r) + ABS(g_goertzel_phasor_i)) * 26100 / 32768 + 1; // Found experimentally (Also try to avoid divide-by-zero. + intensity_phasor = (intensity_phasor + s_phasor/intensity_phasor)/2; + intensity_phasor = (intensity_phasor + s_phasor/intensity_phasor)/2; + if( intensity_phasor < 32760 ) + { + // It is decaying, this is equivelent to f = f * 1.000244141 + g_goertzel_phasor_r += g_goertzel_phasor_r >> 12; + g_goertzel_phasor_i += g_goertzel_phasor_i >> 12; + } + + // Now, rotate rr, ri by that phasor. + // To get it in line >> 15, but we also want to divide by 8 (>>3) because that makes the rest of the math easier. + temp = (g_goertzel_phasor_r * ri + g_goertzel_phasor_i * rr) >> (15); + rr = (g_goertzel_phasor_r * rr - g_goertzel_phasor_i * ri) >> (15); + ri = temp; + + // rr, ri are now in the correct frame of reference. Continue computing. + + qibaselogs[qibaselogs_head] = ((uint16_t)rr) | (((uint16_t)ri)<<16); + qibaselogs_head = ( qibaselogs_head + 1 ) & ((LOG_GOERTZEL_LIST)-1); + + int s = rr * rr + ri * ri; + //int intensity = 1<<( ( 32 - __builtin_clz(s) )/2); + #define ABS(x) (((x)<0)?-(x):(x)) + int intensity = (ABS(rr) + ABS(ri)) * 26100 / 32768; // Found experimentally (Also try to avoid divide-by-zero. + //if( intensity == 0 ) + // intensity = 1; + intensity++; + intensity = (intensity + s/intensity)/2; + intensity = (intensity + s/intensity)/2; + + // intensity = rr * rr + ri * ri + + // This performs a low-pass IIR without exploding intensity_average. + intensity_average = intensity_average - (intensity_average>>12) + (intensity>>6); + if( ((int32_t)intensity_average) >= 1<<23 ) intensity_average = (1<<23)-1; + if( ((int32_t)intensity_average) < 2048 ) intensity_average = 2048; + + #ifdef PWM_OUTPUT + intensity = intensity * g_volume_pwm * g_pwm_period / (intensity_average>>(10-12)); + if( intensity >= g_pwm_period-1 ) intensity = g_pwm_period-2; + if( intensity < 1 ) intensity = 1; + TIM1->CH2CVR = intensity; // Actual duty cycle (Off to begin with) + #endif + + g_goertzel_outs++; + goertzel = 0; + goertzelp = 0; + goertzel_samples = 0; + + // Try to improve bias. + adc_offset -= accumulate_over_window / g_goertzel_buffer; + accumulate_over_window = 0; + +#ifdef ENABLE_OLED_SCOPE + int rrplot = rr * 1536 / (intensity_average); + int riplot = ri * 1536 / (intensity_average); + rrplot += 64; + riplot += 64; + if( rrplot < 1 ) rrplot = 1; + if( riplot < 1 ) riplot = 1; + if( rrplot > 126 ) rrplot = 126; + if( riplot > 126 ) riplot = 126; + PlotPoint( rrplot, riplot ); +#endif + +#ifdef PROFILING_PIN + funDigitalWrite( PROFILING_PIN, 1 ); +#endif + + } + } + + intfr = DMA1->INTFR; + } while( intfr & DMA1_IT_GL1 ); + + g_goertzelp2 = goertzelp2; + g_goertzelp = goertzelp; + g_goertzel = goertzel; + g_goertzel_samples = goertzel_samples; + g_accumulate_over_window = accumulate_over_window; + +#ifdef PROFILING_PIN + funDigitalWrite( PROFILING_PIN, 0 ); // For profiling +#endif + int32_t end = SysTick->CNT; + g_lastper = start - g_laststart; + g_laststart = start; + g_lastlen = end - start; +} + +static inline uint32_t gets2() +{ + uint32_t ret; + asm volatile( "mv %[ret], s2" : [ret]"=&r"(ret) ); + return ret; +} + +uint8_t i2c_send_buffer[16]; +void setup_i2c_dma(void) +{ + // Turn on DMA + RCC->AHBPCENR |= RCC_AHBPeriph_DMA1; + + //DMA1_Channel6 is for I2C1TX + DMA1_Channel6->PADDR = (uint32_t)&I2C1->DATAR; + DMA1_Channel6->MADDR = (uint32_t)&i2c_send_buffer; + DMA1_Channel6->CNTR = 0; + DMA1_Channel6->CFGR = + DMA_M2M_Disable | + DMA_Priority_Low | + DMA_MemoryDataSize_Byte | + DMA_PeripheralDataSize_Byte | + DMA_MemoryInc_Enable | + DMA_Mode_Normal | + DMA_DIR_PeripheralDST | + 0; + I2C1->CTLR2 = I2C_CTLR2_DMAEN | 0b111100; + + DMA1_Channel6->CFGR |= DMA_CFGR1_EN; + + NVIC_DisableIRQ(I2C1_EV_IRQn); +} + + +int main() +{ + SystemInit(); + + SysTick->CTLR = (1<<2) | 1; // HCLK + Delay_Ms(100); + + RCC->CTLR |= RCC_HSEON; + while( ! ( RCC->CTLR & RCC_HSERDY ) ); + + RCC->CFGR0 = (RCC->CFGR0 & ~RCC_SW) | RCC_SW_HSE; + + RCC->CTLR &= ~RCC_PLLON; + + // Switch PLL to HSE. + RCC->CFGR0 |= RCC_PLLSRC; + + // x18; 8MHz x 18 = 144 MHz + RCC->CFGR0 &= ~RCC_PPRE2; // No divisor on APB1/2 + RCC->CFGR0 &= ~RCC_PPRE1; + RCC->CFGR0 |= RCC_PLLMULL_0 | RCC_PLLMULL_1 | RCC_PLLMULL_2 | RCC_PLLMULL_3; + + RCC->CTLR |= RCC_PLLON; + + // Switch to PLL + RCC->CFGR0 = (RCC->CFGR0 & ~RCC_SW) | RCC_SW_PLL; + + // Disable HSI + RCC->CTLR &= ~(RCC_HSION); + + Delay_Ms(10); + + + //printf( "CTLR: %08x / CFGR0: %08x\n", (RCC->CTLR), (RCC->CFGR0) ); + RCC->AHBPCENR |= 3; //DMA2EN | DMA1EN + RCC->APB2PCENR |= RCC_APB2Periph_TIM1 | RCC_APB2Periph_ADC1 | RCC_APB2Periph_ADC2 | 0x07 | RCC_APB2Periph_GPIOA; // Enable all GPIO + RCC->APB1PCENR |= RCC_APB1Periph_TIM2; + + SetupADC(); + +#if defined( ENABLE_OLED ) + ssd1306_i2c_setup(); + ssd1306_i2c_init(); + + if( ssd1306_init() ) + printf( "Failed to initialize OLED\n" ); + else + printf( "Initialized OLED\n" ); + + ssd1306_setbuf(1); + ssd1306_refresh(); +#endif + +#ifdef ENABLE_OLED_SCOPE + int i; + + ssd1306_spi_init(); + ssd1306_rst(); + + if( ssd1306_init() ) + printf( "Failed to initialize OLED\n" ); + else + printf( "Initialized OLED\n" ); + + ssd1306_setbuf(0); + + // Setup a diagonal to allow for vector mode. + for( i = 0; i < 128; i++ ) + { + ssd1306_drawPixel( i, i, 1 ); + //ssd1306_drawPixel( i+1, i, 1 ); + } + + // Not sure why, need to do it a few times to make it stick? + ssd1306_refresh(); + ssd1306_refresh(); + + + uint8_t force_two_row_mode[] = { + 0xa8, 0, // Set MUX ratio (Actually # of lines to scan) (But it's this + 1) You can make this 1 for wider. + }; + ssd1306_pkt_send(force_two_row_mode, sizeof( force_two_row_mode ) , 1); + + uint8_t force_max_speed[] = { + 0xd5, 0xf0 + }; + ssd1306_pkt_send(force_max_speed, sizeof( force_max_speed ) , 1); + + config_turbo_scope(); +#if 0 // Test streaking + int rframe = 0; + while(1) + { + PlotPoint( rframe & 0xff, rframe>>8 ); + rframe++; + //Delay_Ms(1); + } +#endif + +#endif + +#ifdef PROFILING_PIN + funPinMode( PROFILING_PIN, GPIO_CFGLR_OUT_50Mhz_PP ); +#endif + + SetupTimer1(); + + USBOTGSetup(); + + + while(1){ +#if 0 + // To draw a sinewave... + int adcz = adc_buffer[0]; + for( k = 0; k < 128; k++ ) + { + int y = adc_buffer[k]-adcz + 64; + if( y < 0 ) y = 0; + if( y > 127 ) y = 127; + ssd1306_drawPixel( k, y, 1 ); + } +#endif + + // Only display half of the list so the other half could + // be updated by the ISR. + +#ifdef ENABLE_OLED + int pxa = 0; + int glread = qibaselogs_head; + + for( pxa = 0; pxa < LOG_GOERTZEL_LIST; pxa++ ) + { + uint32_t combiq = qibaselogs[glread]; + glread = ( glread + 1 ) & ( LOG_GOERTZEL_LIST -1 ); + + int16_t rr = combiq & 0xffff; + int16_t ri = combiq >> 16; + + rr = rr * 512 / (intensity_average); + ri = ri * 512 / (intensity_average); + + rr += 64; + ri += 64; + + if( rr < 0 ) rr = 0; + if( ri < 0 ) ri = 0; + if( rr > 127 ) rr = 127; + if( ri > 127 ) ri = 127; + + ssd1306_drawPixel( rr, ri, 1 ); + } + + ssd1306_refresh(); + + ssd1306_setbuf(0); +#endif + + // Do nothing. + Delay_Ms(17); + } +} + + + + + +uint8_t scratchpad[512]; +int g_isConfigurePacket = 0; + +int HandleHidUserSetReportSetup( struct _USBState * ctx, tusb_control_request_t * req ) +{ + int id = req->wValue & 0xff; + g_isConfigurePacket = 0; + if( id == 0xaa && req->wLength <= sizeof( scratchpad ) ) + { + ctx->pCtrlPayloadPtr = scratchpad; + return req->wLength; + } + else if( id == 0xac && req->wLength <= sizeof( scratchpad ) ) + { + g_isConfigurePacket = 1; + ctx->pCtrlPayloadPtr = scratchpad; + return req->wLength; + } + return 0; +} + +int HandleHidUserGetReportSetup( struct _USBState * ctx, tusb_control_request_t * req ) +{ + int id = req->wValue & 0xff; + if( id == 0xaa ) + { + ctx->pCtrlPayloadPtr = scratchpad; + return 255; + } + else if( id == 0xac ) + { + g_isConfigurePacket = 1; + ctx->pCtrlPayloadPtr = scratchpad; + return 63; + } + else if( id == 0xad ) + { + static int last_baselog; + + int samps_to_send = (qibaselogs_head - last_baselog + LOG_GOERTZEL_LIST * 2 - 1) & (LOG_GOERTZEL_LIST-1); + if( samps_to_send > 120 ) samps_to_send = 120; + + int intensity_send = intensity_average; + + if( intensity_send >= (1<<24) ) + intensity_send = (1<<24)-1; + ((uint32_t*)scratchpad)[0] = (((uint32_t)intensity_send)<<8) | samps_to_send; + ((uint32_t*)scratchpad)[1] = (g_lastper<<16) | g_lastlen; + ((uint32_t*)scratchpad)[2] = (0<<16) | (((g_pwm_period+1)*g_goertzel_buffer)); //LSW = 144MHz / X + + ((uint32_t*)scratchpad)[3] = SysTick->CNT; + ((uint32_t*)scratchpad)[4] = *((uint32_t*)adc_buffer); + + int i; + for( i = 5; i < samps_to_send + 5; i++ ) + { + last_baselog = (last_baselog+1)&(LOG_GOERTZEL_LIST-1); + ((uint32_t*)(scratchpad))[i] = ((int32_t*)qibaselogs)[last_baselog]; + } + + for( ; i < 128; i++ ) + ((uint32_t*)(scratchpad))[i] = 0; + + + ctx->pCtrlPayloadPtr = scratchpad; + return 510; + } + return 0; +} + +void HandleHidUserReportDataOut( struct _USBState * ctx, uint8_t * data, int len ) +{ +} + +int HandleHidUserReportDataIn( struct _USBState * ctx, uint8_t * data, int len ) +{ +// printf( "IN %d %d %08x %08x\n", len, ctx->USBFS_SetupReqLen, data, FSUSBCTX.ENDPOINTS[0] ); +// memset( data, 0xcc, len ); + return len; +} + +void HandleHidUserReportOutComplete( struct _USBState * ctx ) +{ + if( g_isConfigurePacket ) + { + + uint32_t * configs = (uint32_t*)scratchpad; + // Note: configs[0] == 0xac (command type) + + //printf( "Is Configure Packet %08x\n", configs[1] ); + + int numconfigs = configs[1]; + if( numconfigs > 0) g_pwm_period = configs[2]; + if( numconfigs > 1) g_goertzel_buffer = configs[3]; + if( numconfigs > 2) g_goertzel_omega_per_sample = configs[4]; // 0.816667 of whole per step / 0.880000MHz + if( numconfigs > 3) g_goertzel_coefficient = configs[5]; + if( numconfigs > 4) g_goertzel_coefficient_s = configs[6]; + if( numconfigs > 5) g_exactcompute = configs[7]; + if( numconfigs > 6) g_goertzel_advance_r = configs[8]; + if( numconfigs > 7) g_goertzel_advance_i = configs[9]; + if( numconfigs > 8) + { + int adc_buffer = configs[10]; + if( adc_buffer ) + { + // Consider using PGA. + //ADC_Pga_16 | ADC_SCAN | ADC_BUFEN ; + //ADC_Pga_64 | ADC_SCAN; + ADC1->CTLR1 |= ADC_BUFEN;// | ADC_Pga_4; // Adding PGA causes wild oscillation. + ADC1->CTLR2 |= ADC_BUFEN;// | ADC_Pga_4; + } + else + { + ADC1->CTLR1 &= (~ADC_BUFEN); + ADC2->CTLR1 &= (~ADC_BUFEN); + } + } + if( numconfigs > 9) g_attenuation_pow2 = configs[11]; + + // Need to reset so we don't blast by. + g_goertzel_samples = 0; + TIM1->ATRLR = g_pwm_period; + + TIM1->CH1CVR = 1; + TIM1->CH3CVR = TIM1->ATRLR/2+1; + + + g_isConfigurePacket = 0; + } + return; +} + diff --git a/ch32v/ch32v203-goertzel/funconfig.h b/ch32v/ch32v203-goertzel/funconfig.h new file mode 100644 index 0000000..8edd6b5 --- /dev/null +++ b/ch32v/ch32v203-goertzel/funconfig.h @@ -0,0 +1,11 @@ +#ifndef _FUNCONFIG_H +#define _FUNCONFIG_H + +#define FUNCONF_USE_DEBUGPRINTF 1 +#define FUNCONF_USE_UARTPRINTF 0 +#define FUNCONF_USE_HSE 1 +#define FUNCONF_SYSTICK_USE_HCLK 1 +#define FUNCONF_ENABLE_HPE 0 + +#endif + diff --git a/ch32v/ch32v203-goertzel/ttest/Makefile b/ch32v/ch32v203-goertzel/ttest/Makefile new file mode 100644 index 0000000..feb3730 --- /dev/null +++ b/ch32v/ch32v203-goertzel/ttest/Makefile @@ -0,0 +1,23 @@ +all : test floattest phasor_rotation_test + +phasor_rotation_testt : phasor_rotation_test.c + gcc -o $@ $^ -lm -g + +phasor_rotation_test : phasor_rotation_testt + ./phasor_rotation_testt + +floattest : floattestt + ./floattestt + +floattestt : floattestt.c + gcc -o $@ $^ -lm -g + + +test : ttest + ./ttest + +ttest : ttest.c + gcc -o $@ $^ -lm -g + +clean : + rm -rf *.o ttest *~ floattestt diff --git a/ch32v/ch32v203-goertzel/ttest/demo_run.ods b/ch32v/ch32v203-goertzel/ttest/demo_run.ods new file mode 100644 index 0000000..38834bf Binary files /dev/null and b/ch32v/ch32v203-goertzel/ttest/demo_run.ods differ diff --git a/ch32v/ch32v203-goertzel/ttest/floattestt.c b/ch32v/ch32v203-goertzel/ttest/floattestt.c new file mode 100644 index 0000000..191750e --- /dev/null +++ b/ch32v/ch32v203-goertzel/ttest/floattestt.c @@ -0,0 +1,44 @@ +#include +#include + +int main() +{ + const float omegaPerSample = 3.1415926*2.0 / 128; // pi / 200 + + // Only divide by 128 to show two cycles. + + const int numSamples = 256; // enough to go from 0 to 2pi + + float phase = 0; + //for( float phase = 0; phase < 3.1415926*2.0; phase += 0.01 ) + { + float coeff = 2 * cos( omegaPerSample ); + int i; + + // TRICKY: When you want a sinewave, initialize with omegaPerSample. This + // is crucial. The initial state will have massive consequences. + float sprev = omegaPerSample; + float sprev2 = 0; + for( i = 0; i < numSamples; i++ ) + { + // If you wanted to do a DFT, set SAMPLE to your incoming sample. + float SAMPLE = 65536 * sin( phase + i * omegaPerSample ); + + // Here is where the magic happens. + float s = SAMPLE + coeff * sprev - sprev2; + sprev2 = sprev; + sprev = s; + + // For DFT, your power will be: + float power = sprev*sprev + sprev2*sprev2 - (coeff * sprev * sprev2); + //printf( "Power: %f\n", power ); + + float coeff_s = 2 * sin( omegaPerSample ); + double rR = 0.5 * coeff * sprev - sprev2; + double rI = 0.5 * coeff_s * sprev; + printf( "%d,%f,%f\n", i, rR, rI); + + } + + } +} diff --git a/ch32v/ch32v203-goertzel/ttest/iir_goertzel_not_in_use.ods b/ch32v/ch32v203-goertzel/ttest/iir_goertzel_not_in_use.ods new file mode 100644 index 0000000..b1b13b3 Binary files /dev/null and b/ch32v/ch32v203-goertzel/ttest/iir_goertzel_not_in_use.ods differ diff --git a/ch32v/ch32v203-goertzel/ttest/phasor_rotation_test.c b/ch32v/ch32v203-goertzel/ttest/phasor_rotation_test.c new file mode 100644 index 0000000..bbdf615 --- /dev/null +++ b/ch32v/ch32v203-goertzel/ttest/phasor_rotation_test.c @@ -0,0 +1,43 @@ +#include +#include +#include + +int main() +{ + int phasor_r = 32768; + int phasor_i = 0; + double phasor = 0; + + double omega = 0.1; + int omega_r = cos( omega ) * 32768; + int omega_i = sin( omega ) * 32768; + + int i; + for( i = 0; i < 10000; i++ ) + { + + int32_t temp = (phasor_r * omega_i + phasor_i * omega_r ) >> 15; + phasor_r = (phasor_r * omega_r - phasor_i * omega_i ) >> 15; + phasor_i = temp; + phasor += omega; + + + // Approximate sqrt(x*x+y*y) + #define ABS(x) (((x)<0)?-(x):(x)) + int s = phasor_r * phasor_r + phasor_i * phasor_i; + int intensity = (ABS(phasor_r) + ABS(phasor_i)) * 26100 / 32768 + 1; // Found experimentally (Also try to avoid divide-by-zero. + intensity = (intensity + s/intensity)/2; + intensity = (intensity + s/intensity)/2; + + if( intensity < 32763 ) + { + phasor_r += phasor_r >> 12; + phasor_i += phasor_i >> 12; + } + + double fA = atan2( phasor_i, phasor_r ); + printf( "%6d %6d / %6d %6d / %d / %f %f %f\n", omega_r, omega_i, phasor_r, phasor_i, intensity, fA, phasor, fA-phasor ); + if( phasor >= 3.141592653589 ) phasor -= 3.141592653589*2; + } + +} diff --git a/ch32v/ch32v203-goertzel/ttest/ttest.c b/ch32v/ch32v203-goertzel/ttest/ttest.c new file mode 100644 index 0000000..2bb6086 --- /dev/null +++ b/ch32v/ch32v203-goertzel/ttest/ttest.c @@ -0,0 +1,112 @@ +#include +#include +#include + +uint32_t g_goertzel_omega_per_sample; +int32_t g_goertzel_coefficient; +int32_t g_goertzel_coefficient_s; +uint32_t g_goertzel_samples; +uint32_t g_goertzel_outs; +int32_t g_goertzelp, g_goertzelp2; +int32_t g_goertzelp_store, g_goertzelp2_store; + +int main() +{ + //XXX XXX NOTE If you are computing the coefficients, you can plug the value in here. + // You can get this number from calculator.html. I've had better luck with "inverse goertzel" numbers. + g_goertzel_omega_per_sample = (47.0/256) * 3.1415926535*2.0*(1<<29); + g_goertzel_coefficient = 2 * cos( g_goertzel_omega_per_sample / (double)(1<<29) ) * (1<<30); + g_goertzel_coefficient_s = 2 * sin( g_goertzel_omega_per_sample / (double)(1<<29) ) * (1<<30); + + + const double AomegaPerSample = g_goertzel_omega_per_sample/(double)(1<<29); + const int AnumSamples = 256; // enough to go from 0 to 2pi + double Acoeff = 2 * cos( AomegaPerSample ) * 65536; + double Acoeff_s = 2 * sin( AomegaPerSample ) * 65536; + double Asprev = AomegaPerSample * 65536; + double Asprev2 = 0; + + printf( "%d / %d / %d %f / %f / %f\n", g_goertzel_omega_per_sample, g_goertzel_coefficient, g_goertzel_coefficient_s, Acoeff, Acoeff_s, AomegaPerSample ); + + + g_goertzelp = g_goertzel_omega_per_sample>>(29-16); + + int32_t goertzel_coefficient = g_goertzel_coefficient; + int32_t goertzelp2 = g_goertzelp2; + int32_t goertzelp = g_goertzelp; + uint32_t goertzel_samples = g_goertzel_samples; + + uint32_t adc_tail; + + double As; + + int js = 0; + for( js = 0; js < 260/4; js++ ) + { + int32_t t; // 1/2 of 4096, to try to keep our numbers reasonable. + + // Here is where the magic happens. + int32_t goertzel; + + #define ITERATION(x) \ + t = sin( AomegaPerSample * (x+js*4) ) * 16384*0; \ +\ + /* Fixed */ \ + goertzelp2 = goertzelp; \ + goertzelp = goertzel; \ + goertzel = t + ( ( (((int32_t)(goertzel_coefficient))) * ((((int64_t)goertzelp)<<2)) ) >> 32 ) - goertzelp2; \ +\ + /* Float */ \ + Asprev2 = Asprev; \ + Asprev = As; \ + As = t + ( Acoeff * Asprev ) / 65536.0 - Asprev2; \ +\ +/*printf( "%d,%d,%d,%d\n", ( ( (int64_t)(goertzel_coefficient) * (int64_t)goertzelp ) >> 32 ) , goertzel_coefficient, goertzelp, goertzelp2 ); */ \ +\ + {\ + int32_t rr = (((int64_t)(g_goertzel_coefficient ) * (int64_t)goertzelp<<1)>>32) - (goertzelp2); \ + int32_t ri = (((int64_t)(g_goertzel_coefficient_s) * (int64_t)goertzelp<<1)>>32); \ + /*printf( "%3d %10d %10d %10d %10d / %9d %9d %9d * ", js*4+x, rr, ri, goertzelp, goertzelp2, goertzel_coefficient, g_goertzel_omega_per_sample, t );*/ \ + /*printf( "%4d %10d %10d (%10d %10d) ", js*4+x, goertzelp, goertzelp2, goertzel_coefficient, g_goertzel_coefficient_s );*/ \ + printf( "%4d %10d %10d (%10d %10d) ", js*4+x, goertzelp, goertzelp2, rr, ri ); \ +\ + float Apower = Asprev*Asprev + Asprev2*Asprev2 - (Acoeff * Asprev * Asprev2); \ + double ArR = 0.5 * Acoeff * Asprev / 65536 - Asprev2; \ + double ArI = 0.5 * Acoeff_s * Asprev / 65536; \ + /*printf( "%14.3f, %14.3f (%14.3f %14.3f)\n", Asprev, Asprev2, Acoeff,Acoeff_s );*/ \ + printf( "%14.3f, %14.3f (%14.3f %14.3f %f)\n", Asprev, Asprev2, ArR, ArI, sqrt( ArR*ArR +ArI*ArI ) ); \ + } + + + ITERATION( 0 ); + ITERATION( 1 ); + ITERATION( 2 ); + ITERATION( 3 ); + + adc_tail+=4; + goertzel_samples+=4; +// if( adc_tail == adc_buffer_top ) adc_tail = adc_buffer; + +/* if( goertzel_samples == 128 ) + { + g_goertzelp_store = goertzelp; + g_goertzelp2_store = goertzelp2; + + goertzelp = 0; + goertzelp2 = 0; + + g_goertzel_outs++; + goertzel_samples = 0; + } +*/ + } + + + g_goertzelp2 = goertzelp2; + g_goertzelp = goertzelp; + g_goertzel_samples = goertzel_samples; + + printf( "Constants:\nconst int32_t g_goertzel_omega_per_sample = %d;\nconst int32_t g_goertzel_coefficient = %d;\nconst int32_t g_goertzel_coefficient_s = %d;\n", g_goertzel_omega_per_sample, g_goertzel_coefficient, g_goertzel_coefficient_s ); + +} + diff --git a/ch32v/ch32v203-goertzel/usb_config.h b/ch32v/ch32v203-goertzel/usb_config.h new file mode 100644 index 0000000..5ca870c --- /dev/null +++ b/ch32v/ch32v203-goertzel/usb_config.h @@ -0,0 +1,157 @@ +#ifndef _USB_CONFIG_H +#define _USB_CONFIG_H + +#include "funconfig.h" +#include "ch32v003fun.h" + +#define FUSB_CONFIG_EPS 2 // Include EP0 in this count +#define FUSB_SUPPORTS_SLEEP 0 +#define FUSB_HID_INTERFACES 1 +#define FUSB_CURSED_TURBO_DMA 0 // Hacky, but seems fine, shaves 2.5us off filling 64-byte buffers. +#define FUSB_HID_USER_REPORTS 1 +#define FUSB_IO_PROFILE 1 +#define FUSB_USE_HPE FUNCONF_ENABLE_HPE + +#include "usb_defines.h" + +//Taken from http://www.usbmadesimple.co.uk/ums_ms_desc_dev.htm +static const uint8_t device_descriptor[] = { + 18, //Length + 1, //Type (Device) + 0x00, 0x02, //Spec + 0x0, //Device Class + 0x0, //Device Subclass + 0x0, //Device Protocol (000 = use config descriptor) + 64, //Max packet size for EP0 (This has to be 8 because of the USB Low-Speed Standard) + 0x09, 0x12, //ID Vendor + 0x35, 0xd0, //ID Product + 0x03, 0x00, //ID Rev + 1, //Manufacturer string + 2, //Product string + 3, //Serial string + 1, //Max number of configurations +}; + +static const uint8_t HIDAPIRepDesc[ ] = +{ + HID_USAGE_PAGE ( 0xff ), // Vendor-defined page. + HID_USAGE ( 0x00 ), + HID_REPORT_SIZE ( 8 ), + HID_COLLECTION ( HID_COLLECTION_LOGICAL ), + HID_REPORT_COUNT ( 254 ), + HID_REPORT_ID ( 0xaa ) + HID_USAGE ( 0x01 ), + HID_FEATURE ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) , + HID_REPORT_COUNT ( 63 ), // For use with `hidapitester --vidpid 1209/D003 --open --read-feature 171` + HID_REPORT_ID ( 0xab ) + HID_USAGE ( 0x01 ), + HID_FEATURE ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) , + HID_REPORT_COUNT ( 63 ), // For configuring the setup. + HID_REPORT_ID ( 0xac ) + HID_USAGE ( 0x01 ), + HID_FEATURE ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) , + HID_REPORT_COUNT_N ( 510,2 ), // For receiving IQ data on host. + HID_REPORT_ID ( 0xad ) + HID_USAGE ( 0x01 ), + HID_FEATURE ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) , + HID_COLLECTION_END, +}; + +/* Configuration Descriptor Set */ +static const uint8_t config_descriptor[ ] = +{ + /* Configuration Descriptor */ + 0x09, // bLength + 0x02, // bDescriptorType + 0x22, 0x00, // wTotalLength + 0x01, // bNumInterfaces (3) + 0x01, // bConfigurationValue + 0x00, // iConfiguration + 0xA0, // bmAttributes: Bus Powered; Remote Wakeup + 0x32, // MaxPower: 100mA + + /* Interface Descriptor (Special) */ + 0x09, // bLength + 0x04, // bDescriptorType + 0x00, // bInterfaceNumber + 0x01, // bAlternateSetting + 0x01, // bNumEndpoints + 0x03, // bInterfaceClass + 0x00, // bInterfaceSubClass + 0xff, // bInterfaceProtocol: OTher + 0x00, // iInterface + + /* HID Descriptor (Special) */ + 0x09, // bLength + 0x21, // bDescriptorType + 0x10, 0x01, // bcdHID + 0x00, // bCountryCode + 0x01, // bNumDescriptors + 0x22, // bDescriptorType + sizeof(HIDAPIRepDesc), 0x00, // wDescriptorLength + + /* Endpoint Descriptor (Special) */ + 0x07, // bLength + 0x05, // bDescriptorType + 0x81, // bEndpointAddress: IN Endpoint 1 + 0x03, // bmAttributes + 0x08, 0x00, // wMaxPacketSize + 0xff, // bInterval: slow. +}; + + + +#define STR_MANUFACTURER u"CNLohr" +#define STR_PRODUCT u"lolra ch32v203 goertzel test" +#define STR_SERIAL u"CUSTOMDEVICE000" + +struct usb_string_descriptor_struct { + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t wString[]; +}; +const static struct usb_string_descriptor_struct string0 __attribute__((section(".rodata"))) = { + 4, + 3, + {0x0409} +}; +const static struct usb_string_descriptor_struct string1 __attribute__((section(".rodata"))) = { + sizeof(STR_MANUFACTURER), + 3, + STR_MANUFACTURER +}; +const static struct usb_string_descriptor_struct string2 __attribute__((section(".rodata"))) = { + sizeof(STR_PRODUCT), + 3, + STR_PRODUCT +}; +const static struct usb_string_descriptor_struct string3 __attribute__((section(".rodata"))) = { + sizeof(STR_SERIAL), + 3, + STR_SERIAL +}; + +// This table defines which descriptor data is sent for each specific +// request from the host (in wValue and wIndex). +const static struct descriptor_list_struct { + uint32_t lIndexValue; + const uint8_t *addr; + uint8_t length; +} descriptor_list[] = { + {0x00000100, device_descriptor, sizeof(device_descriptor)}, + {0x00000200, config_descriptor, sizeof(config_descriptor)}, + // interface number // 2200 for hid descriptors. + {0x00002200, HIDAPIRepDesc, sizeof(HIDAPIRepDesc)}, + + {0x00002100, config_descriptor + 18, 9 }, // Not sure why, this seems to be useful for Windows + Android. + + {0x00000300, (const uint8_t *)&string0, 4}, + {0x04090301, (const uint8_t *)&string1, sizeof(STR_MANUFACTURER)}, + {0x04090302, (const uint8_t *)&string2, sizeof(STR_PRODUCT)}, + {0x04090303, (const uint8_t *)&string3, sizeof(STR_SERIAL)} +}; +#define DESCRIPTOR_LIST_ENTRIES ((sizeof(descriptor_list))/(sizeof(struct descriptor_list_struct)) ) + + +#endif + diff --git a/ch32v/ch32v203/Makefile b/ch32v/ch32v203-lora/Makefile similarity index 100% rename from ch32v/ch32v203/Makefile rename to ch32v/ch32v203-lora/Makefile diff --git a/ch32v/ch32v203/README.md b/ch32v/ch32v203-lora/README.md similarity index 100% rename from ch32v/ch32v203/README.md rename to ch32v/ch32v203-lora/README.md diff --git a/ch32v/ch32v203/funconfig.h b/ch32v/ch32v203-lora/funconfig.h similarity index 100% rename from ch32v/ch32v203/funconfig.h rename to ch32v/ch32v203-lora/funconfig.h diff --git a/ch32v/ch32v203/loratest.c b/ch32v/ch32v203-lora/loratest.c similarity index 100% rename from ch32v/ch32v203/loratest.c rename to ch32v/ch32v203-lora/loratest.c diff --git a/ch32v/ch32v203/rf_data_gen.c b/ch32v/ch32v203-lora/rf_data_gen.c similarity index 100% rename from ch32v/ch32v203/rf_data_gen.c rename to ch32v/ch32v203-lora/rf_data_gen.c diff --git a/ch32v/ch32v203tx/Makefile b/ch32v/ch32v203tx/Makefile new file mode 100644 index 0000000..201a38b --- /dev/null +++ b/ch32v/ch32v203tx/Makefile @@ -0,0 +1,13 @@ +all : flash + +TARGET:=ch32v203tx +TARGET_MCU:=CH32V203 +CH32V003FUN:=../ch32v003fun/ch32v003fun + +EXTRA_CFLAGS:=-Wno-unused-function -I../../lib + +include $(CH32V003FUN)/ch32v003fun.mk + +flash : cv_flash +clean : cv_clean + diff --git a/ch32v/ch32v203tx/ch32v203tx.c b/ch32v/ch32v203tx/ch32v203tx.c new file mode 100644 index 0000000..5fddaba --- /dev/null +++ b/ch32v/ch32v203tx/ch32v203tx.c @@ -0,0 +1,51 @@ +// This file is under the standard MIT license, CC0 or Public domain. you choose. +// CNLohr <>< 2024 +// It just does a normal PWM output from a ch32v203 + +#include "ch32v003fun.h" +#include + +#define LEDPIN PD6 + +int main() +{ + SystemInit(); + + Delay_Ms( 100 ); + + + funGpioInitAll(); + RCC->APB1PCENR |= RCC_APB1Periph_TIM2; + // PD4 = T2C1 on 003, PA0 on the 203. + funPinMode( PA0, GPIO_CFGLR_OUT_50Mhz_AF_PP ); + funPinMode( PA1, GPIO_CFGLR_OUT_50Mhz_AF_PP ); + funPinMode( LEDPIN, GPIO_CFGLR_OUT_50Mhz_PP ); + + // Reset TIM2 to init all regs + RCC->APB1PRSTR |= RCC_APB1Periph_TIM2; + RCC->APB1PRSTR &= ~RCC_APB1Periph_TIM2; + + TIM2->PSC = 0x0000; // Prescalar + TIM2->ATRLR = 4; // loop = fclk / (atrlr+1) + TIM2->CHCTLR1 = TIM_OC1M_2 | TIM_OC1M_1 | TIM_OC1PE | TIM_OC1FE; + TIM2->CTLR1 = TIM_ARPE; + TIM2->CCER = TIM_CC1E | TIM_CC1P | TIM_CC1NE; + TIM2->SWEVGR = TIM_UG; + + // Enable TIM2 + TIM2->CTLR1 |= TIM_CEN; + TIM2->CH1CVR = TIM2->ATRLR/2+1; + + printf( "Setup\n" ); + while(1) + { + TIM2->CH1CVR = 2; + TIM2->CCER = TIM_CC1E | TIM_CC1P; + funDigitalWrite( LEDPIN, 1 ); + Delay_Us( 20000 ); + TIM2->CCER = TIM_CC1E; + TIM2->CH1CVR = 2; + funDigitalWrite( LEDPIN, 0 ); + Delay_Us( 20000 ); + } +} diff --git a/ch32v/ch32v203tx/funconfig.h b/ch32v/ch32v203tx/funconfig.h new file mode 100644 index 0000000..046451f --- /dev/null +++ b/ch32v/ch32v203tx/funconfig.h @@ -0,0 +1,9 @@ +#ifndef _FUNCONFIG_H +#define _FUNCONFIG_H + +#define FUNCONF_USE_DEBUGPRINTF 1 +#define FUNCONF_USE_UARTPRINTF 0 +#define FUNCONF_USE_HSE 1 + +#endif + diff --git a/ch32v/lib/AudioLinkMono-Bold.ttf b/ch32v/lib/AudioLinkMono-Bold.ttf new file mode 100644 index 0000000..1331d4e Binary files /dev/null and b/ch32v/lib/AudioLinkMono-Bold.ttf differ diff --git a/ch32v/lib/README.md b/ch32v/lib/README.md new file mode 100644 index 0000000..df6316d --- /dev/null +++ b/ch32v/lib/README.md @@ -0,0 +1,6 @@ +# The "calculator" tools + +Including the host side code for the ch32v203 goertzel tuner. + +The font used, AudioLink is from https://audiolink.dev/ by Llealloo and are "(PUBLIC DOMAIN / free to use)" (as of 6/22/2024) + diff --git a/ch32v/lib/calculator.css b/ch32v/lib/calculator.css new file mode 100644 index 0000000..6a937b8 --- /dev/null +++ b/ch32v/lib/calculator.css @@ -0,0 +1,305 @@ +/* +Copyright (c) 2024 by Brett Schwickerath (https://codepen.io/schwiiiii/pen/wvVqLmX) +Modified +Copyright (c) 2024 by cnlohr + +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the +Software without restriction, including without limitation the rights to use, copy, +modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, +and to permit persons to whom the Software is furnished to do so, subject to the +following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +@font-face { + font-family: 'AudioLink'; + src: url('AudioLinkMono-Bold.ttf') format('truetype') +} + +:root { + color-scheme: dark; + --gl: radial-gradient(circle 1px at 0px 0px, var(--light) 1px, transparent 0); + --gd: radial-gradient(circle 1px at 0px 0px, var(--dark) 1px, transparent 0); + --dark: #111; + --light: #eee; + --bg-0: var(--dark); + --bg-1: var(--gl) 0px 0px / 4px 4px, var(--dark); + --bg-2: var(--gl) 0px 0px / 4px 4px, var(--gl) 2px 2px / 4px 4px, var(--dark); + --bg-3: var(--gl) 0px 0px / 2px 2px, var(--dark); + --bg-4: var(--gl) 0px 0px / 2px 2px, var(--gl) 1px 1px / 2px 2px, var(--dark); + --bg-5: var(--gd) 0px 0px / 2px 2px, var(--light); + --bg-6: var(--gd) 0px 0px / 4px 4px, var(--gd) 2px 2px / 4px 4px, var(--light); + --bg-7: var(--gd) 0px 0px / 4px 4px, var(--light); + --bg-8: var(--light); + + --l-shadow: + -1px -1px 0 var(--dark), + 0 -1px 0 var(--dark), + 1px -1px 0 var(--dark), + 1px 0 0 var(--dark), + 1px 1px 0 var(--dark), + 0 1px 0 var(--dark), + -1px 1px 0 var(--dark), + -1px 0 0 var(--dark); + + --d-shadow: + -1px -1px 0 var(--light), + 0 -1px 0 var(--light), + 1px -1px 0 var(--light), + 1px 0 0 var(--light), + 1px 1px 0 var(--light), + 0 1px 0 var(--light), + -1px 1px 0 var(--light), + -1px 0 0 var(--light); + + --drop-shadow: + drop-shadow(-1px -1px 0 var(--light)) + drop-shadow(0 -1px 0 var(--light)) + drop-shadow(1px -1px 0 var(--light)) + drop-shadow(1px 0 0 var(--light)) + drop-shadow(1px 1px 0 var(--light)) + drop-shadow(0 1px 0 var(--light)) + drop-shadow(-1px 1px 0 var(--light)) + drop-shadow(-1px 0 0 var(--light)); +} + +* { + box-sizing: border-box; + font-family: "AudioLink", monospace; + text-rendering: optimizeSpeed; + font-size: inherit; + color: light-dark(var(--dark), var(--light)); +} + +html { + /*font-size: 1vmin;*/ + /* animation: + adjust-light 17s linear infinite both, + adjust-dark 11s linear infinite both; */ +} + +body { + margin: 0; + min-height: 100vh; + display: flex; + flex-direction: column; + /* + justify-content: center; + align-items: center; + */ + gap: 4rem; + background: var(--dark); +} + +.shades { + display: inline-flex; + gap: 1rem; +} + +.shade { + height: calc(80rem / 9); + width: calc(80rem / 9); + border-radius: 50%; + border: 3px solid var(--light); + + &:nth-child(1) { background: var(--bg-0); } + &:nth-child(2) { background: var(--bg-1); } + &:nth-child(3) { background: var(--bg-2); } + &:nth-child(4) { background: var(--bg-3); } + &:nth-child(5) { background: var(--bg-4); } + &:nth-child(6) { background: var(--bg-5); } + &:nth-child(7) { background: var(--bg-6); } + &:nth-child(8) { background: var(--bg-7); } + &:nth-child(9) { background: var(--bg-8); } +} + +form { + font-size: 2rem; + background: var(--bg-4); + padding: 2rem; + border-radius: 2rem; + display: flex; + flex-direction: column; + gap: 1rem; + border: 3px var(--light) solid; +} + +label { + background: var(--bg-1); + display: flex; + flex-direction: column; + gap: .5rem; + padding: 1rem; + border-radius: 1rem; + text-shadow: var(--l-shadow); + border: 1px var(--light) solid; + color: var(--light); +} + + +input::-webkit-outer-spin-button, +input::-webkit-inner-spin-button { + -webkit-appearance: none; +} + +/*.scrollwheel_tune{*/ +input[type=number] { + background: var(--bg-0); + outline: 0; + -moz-appearance:textfield; /* Firefox */ + padding-top: 1rem; + padding-bottom: 1rem; + padding-left: 1.1rem; + padding-right: 1.0rem; + text-shadow: var(--l-shadow); + border: 1px var(--light) solid; + animation: dark-to-light 200ms ease-out forwards; + transition: 200ms ease-out; + border-radius: 1.5rem; + &:hover { + animation: light-to-dark 200ms linear forwards; + color: var(--dark); + text-shadow: var(--d-shadow); + } +} + +textarea,input:not([type='number']) { + background: var(--bg-0); + border: 0; + overflow:hidden; + outline: 0; + border-radius: .8rem; + padding: .5rem; + padding-bottom:.3rem; + text-shadow: var(--l-shadow); + border: 1px var(--light) solid; + animation: dark-to-light 200ms ease-out forwards; + transition: 200ms ease-out; + + &:hover { + animation: light-to-dark 200ms linear forwards; + color: var(--dark); + text-shadow: var(--d-shadow); + } +} + +button,input[type=submit] { + background: var(--bg-0); + border: 0; + outline: 0; + border-radius: 2rem; + padding: .7rem; + font-weight: bold; + text-shadow: var(--l-shadow); + cursor: pointer; + border: 1px var(--light) solid; + color: var(--light); + animation: dark-to-light 200ms ease-out forwards; + transition: 200ms ease-out; + + &:hover { + animation: light-to-dark 200ms linear forwards; + color: var(--dark); + text-shadow: var(--d-shadow); + } +} + +.cube-wrapper { + --size: 8rem; + margin-top: 2rem; + perspective: 200px; + perspective-origin: 50% 0%; + filter: var(--drop-shadow); +} + +.cube { + height: var(--size); + width: var(--size); + position: relative; + transform-style: preserve-3d; + transform-origin: 50% 50% calc(var(--size) * .5); + animation: rotate 10s linear infinite; +} + +.face { + position: absolute; + height: var(--size); + width: var(--size); + transform-style: preserve-3d; + transform-origin: 50% 50% calc(var(--size) * .5); + + &:nth-child(1) { transform: rotateY(90deg); background: var(--bg-2); } + &:nth-child(2) { transform: rotateY(180deg); background: var(--bg-3) } + &:nth-child(3) { transform: rotateY(-90deg); background: var(--bg-4) } + &:nth-child(4) { transform: rotateX(90deg); background: var(--bg-5) } + &:nth-child(5) { transform: rotateX(-90deg); background: var(--bg-6) } + &:nth-child(6) { background: var(--bg-7) } +} + +@keyframes light-to-dark { + 0% { background: var(--bg-0); } + 12.5% { background: var(--bg-1); } + 25% { background: var(--bg-2); } + 37.5% { background: var(--bg-3); } + 50% { background: var(--bg-4); } + 62.5% { background: var(--bg-5); } + 75% { background: var(--bg-6); } + 87.5% { background: var(--bg-7); } + 100% { background: var(--bg-8); } +} + +@keyframes dark-to-light { + 0% { background: var(--bg-8); } + 12.5% { background: var(--bg-7); } + 25% { background: var(--bg-6); } + 37.5% { background: var(--bg-5); } + 50% { background: var(--bg-4); } + 62.5% { background: var(--bg-3); } + 75% { background: var(--bg-2); } + 87.5% { background: var(--bg-1); } + 100% { background: var(--bg-0); } +} + +@keyframes rotate { + from { transform: rotateY(0) rotateX(1turn) rotateZ(0) } + to { transform: rotateY(1turn) rotateX(0) rotateZ(1turn) } +} + +@keyframes adjust-dark { + 0% { --dark: hsl(0turn, 100%, 80%); } + 10% { --dark: hsl(.1turn, 100%, 80%); } + 20% { --dark: hsl(.2turn, 100%, 80%); } + 30% { --dark: hsl(.3turn, 100%, 80%); } + 40% { --dark: hsl(.4turn, 100%, 80%); } + 50% { --dark: hsl(.5turn, 100%, 80%); } + 60% { --dark: hsl(.6turn, 100%, 80%); } + 70% { --dark: hsl(.7turn, 100%, 80%); } + 80% { --dark: hsl(.8turn, 100%, 80%); } + 90% { --dark: hsl(.9turn, 100%, 80%); } + 100% { --dark: hsl(1turn, 100%, 80%); } +} + +@keyframes adjust-light { + 0% { --light: hsl(0turn, 100%, 20%); } + 10% { --light: hsl(.1turn, 100%, 20%); } + 20% { --light: hsl(.2turn, 100%, 20%); } + 30% { --light: hsl(.3turn, 100%, 20%); } + 40% { --light: hsl(.4turn, 100%, 20%); } + 50% { --light: hsl(.5turn, 100%, 20%); } + 60% { --light: hsl(.6turn, 100%, 20%); } + 70% { --light: hsl(.7turn, 100%, 20%); } + 80% { --light: hsl(.8turn, 100%, 20%); } + 90% { --light: hsl(.9turn, 100%, 20%); } + 100% { --light: hsl(1turn, 100%, 20%); } +} + diff --git a/ch32v/lib/calculator.html b/ch32v/lib/calculator.html new file mode 100644 index 0000000..c9225fb --- /dev/null +++ b/ch32v/lib/calculator.html @@ -0,0 +1,534 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Tool for computing tuning to specific frequencies by use of direct ADC reading at specific timer-controlled rate to "tune" to specific frequencies either by quadrature or differential.

+
+ + +
+ + + + + + + +
System Rate MHz
Target MHz
Quanta
Quanta Search Range
Table Type + Quadrature
+ Goertzels
+ Goertzel (unalign) +
+
+Live Control:
+ + +
+ + +
+
+
+
+
+ADC Buffer Enable +
Pow2 Attenuation: +
+
+
+
+
+
+ + diff --git a/ch32v/lib/font_8x8.h b/ch32v/lib/font_8x8.h new file mode 100644 index 0000000..815d5b2 --- /dev/null +++ b/ch32v/lib/font_8x8.h @@ -0,0 +1,2569 @@ +/**********************************************/ +/* */ +/* Font file generated by cpi2fnt */ +/* */ +/**********************************************/ + +const static unsigned char fontdata[] = { + + /* 0 0x00 '^@' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 1 0x01 '^A' */ + 0x7e, /* 01111110 */ + 0x81, /* 10000001 */ + 0xa5, /* 10100101 */ + 0x81, /* 10000001 */ + 0xbd, /* 10111101 */ + 0x99, /* 10011001 */ + 0x81, /* 10000001 */ + 0x7e, /* 01111110 */ + + /* 2 0x02 '^B' */ + 0x7e, /* 01111110 */ + 0xff, /* 11111111 */ + 0xdb, /* 11011011 */ + 0xff, /* 11111111 */ + 0xc3, /* 11000011 */ + 0xe7, /* 11100111 */ + 0xff, /* 11111111 */ + 0x7e, /* 01111110 */ + + /* 3 0x03 '^C' */ + 0x6c, /* 01101100 */ + 0xfe, /* 11111110 */ + 0xfe, /* 11111110 */ + 0xfe, /* 11111110 */ + 0x7c, /* 01111100 */ + 0x38, /* 00111000 */ + 0x10, /* 00010000 */ + 0x00, /* 00000000 */ + + /* 4 0x04 '^D' */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + 0x7c, /* 01111100 */ + 0xfe, /* 11111110 */ + 0x7c, /* 01111100 */ + 0x38, /* 00111000 */ + 0x10, /* 00010000 */ + 0x00, /* 00000000 */ + + /* 5 0x05 '^E' */ + 0x38, /* 00111000 */ + 0x7c, /* 01111100 */ + 0x38, /* 00111000 */ + 0xfe, /* 11111110 */ + 0xfe, /* 11111110 */ + 0xd6, /* 11010110 */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + + /* 6 0x06 '^F' */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + 0x7c, /* 01111100 */ + 0xfe, /* 11111110 */ + 0xfe, /* 11111110 */ + 0x7c, /* 01111100 */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + + /* 7 0x07 '^G' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 8 0x08 '^H' */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xe7, /* 11100111 */ + 0xc3, /* 11000011 */ + 0xc3, /* 11000011 */ + 0xe7, /* 11100111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + + /* 9 0x09 '^I' */ + 0x00, /* 00000000 */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x42, /* 01000010 */ + 0x42, /* 01000010 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* 10 0x0a '^J' */ + 0xff, /* 11111111 */ + 0xc3, /* 11000011 */ + 0x99, /* 10011001 */ + 0xbd, /* 10111101 */ + 0xbd, /* 10111101 */ + 0x99, /* 10011001 */ + 0xc3, /* 11000011 */ + 0xff, /* 11111111 */ + + /* 11 0x0b '^K' */ + 0x0f, /* 00001111 */ + 0x07, /* 00000111 */ + 0x0f, /* 00001111 */ + 0x7d, /* 01111101 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x78, /* 01111000 */ + + /* 12 0x0c '^L' */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + + /* 13 0x0d '^M' */ + 0x3f, /* 00111111 */ + 0x33, /* 00110011 */ + 0x3f, /* 00111111 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x70, /* 01110000 */ + 0xf0, /* 11110000 */ + 0xe0, /* 11100000 */ + + /* 14 0x0e '^N' */ + 0x7f, /* 01111111 */ + 0x63, /* 01100011 */ + 0x7f, /* 01111111 */ + 0x63, /* 01100011 */ + 0x63, /* 01100011 */ + 0x67, /* 01100111 */ + 0xe6, /* 11100110 */ + 0xc0, /* 11000000 */ + + /* 15 0x0f '^O' */ + 0x18, /* 00011000 */ + 0xdb, /* 11011011 */ + 0x3c, /* 00111100 */ + 0xe7, /* 11100111 */ + 0xe7, /* 11100111 */ + 0x3c, /* 00111100 */ + 0xdb, /* 11011011 */ + 0x18, /* 00011000 */ + + /* 16 0x10 '^P' */ + 0x80, /* 10000000 */ + 0xe0, /* 11100000 */ + 0xf8, /* 11111000 */ + 0xfe, /* 11111110 */ + 0xf8, /* 11111000 */ + 0xe0, /* 11100000 */ + 0x80, /* 10000000 */ + 0x00, /* 00000000 */ + + /* 17 0x11 '^Q' */ + 0x02, /* 00000010 */ + 0x0e, /* 00001110 */ + 0x3e, /* 00111110 */ + 0xfe, /* 11111110 */ + 0x3e, /* 00111110 */ + 0x0e, /* 00001110 */ + 0x02, /* 00000010 */ + 0x00, /* 00000000 */ + + /* 18 0x12 '^R' */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + + /* 19 0x13 '^S' */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x00, /* 00000000 */ + 0x66, /* 01100110 */ + 0x00, /* 00000000 */ + + /* 20 0x14 '^T' */ + 0x7f, /* 01111111 */ + 0xdb, /* 11011011 */ + 0xdb, /* 11011011 */ + 0x7b, /* 01111011 */ + 0x1b, /* 00011011 */ + 0x1b, /* 00011011 */ + 0x1b, /* 00011011 */ + 0x00, /* 00000000 */ + + /* 21 0x15 '^U' */ + 0x3e, /* 00111110 */ + 0x61, /* 01100001 */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x86, /* 10000110 */ + 0x7c, /* 01111100 */ + + /* 22 0x16 '^V' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x7e, /* 01111110 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + + /* 23 0x17 '^W' */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0xff, /* 11111111 */ + + /* 24 0x18 '^X' */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* 25 0x19 '^Y' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* 26 0x1a '^Z' */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0xfe, /* 11111110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 27 0x1b '^[' */ + 0x00, /* 00000000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0xfe, /* 11111110 */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 28 0x1c '^\' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 29 0x1d '^]' */ + 0x00, /* 00000000 */ + 0x24, /* 00100100 */ + 0x66, /* 01100110 */ + 0xff, /* 11111111 */ + 0x66, /* 01100110 */ + 0x24, /* 00100100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 30 0x1e '^^' */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x7e, /* 01111110 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 31 0x1f '^_' */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0x7e, /* 01111110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 32 0x20 ' ' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 33 0x21 '!' */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* 34 0x22 '"' */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x24, /* 00100100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 35 0x23 '#' */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0xfe, /* 11111110 */ + 0x6c, /* 01101100 */ + 0xfe, /* 11111110 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x00, /* 00000000 */ + + /* 36 0x24 '$' */ + 0x18, /* 00011000 */ + 0x3e, /* 00111110 */ + 0x60, /* 01100000 */ + 0x3c, /* 00111100 */ + 0x06, /* 00000110 */ + 0x7c, /* 01111100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* 37 0x25 '%' */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xcc, /* 11001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x66, /* 01100110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + + /* 38 0x26 '&' */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + + /* 39 0x27 ''' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 40 0x28 '(' */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x00, /* 00000000 */ + + /* 41 0x29 ')' */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x00, /* 00000000 */ + + /* 42 0x2a '*' */ + 0x00, /* 00000000 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0xff, /* 11111111 */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 43 0x2b '+' */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 44 0x2c ',' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + + /* 45 0x2d '-' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 46 0x2e '.' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* 47 0x2f '/' */ + 0x06, /* 00000110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0xc0, /* 11000000 */ + 0x80, /* 10000000 */ + 0x00, /* 00000000 */ + + /* 48 0x30 '0' */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xd6, /* 11010110 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x00, /* 00000000 */ + + /* 49 0x31 '1' */ + 0x18, /* 00011000 */ + 0x38, /* 00111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + + /* 50 0x32 '2' */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0x06, /* 00000110 */ + 0x1c, /* 00011100 */ + 0x30, /* 00110000 */ + 0x66, /* 01100110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + + /* 51 0x33 '3' */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0x06, /* 00000110 */ + 0x3c, /* 00111100 */ + 0x06, /* 00000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 52 0x34 '4' */ + 0x1c, /* 00011100 */ + 0x3c, /* 00111100 */ + 0x6c, /* 01101100 */ + 0xcc, /* 11001100 */ + 0xfe, /* 11111110 */ + 0x0c, /* 00001100 */ + 0x1e, /* 00011110 */ + 0x00, /* 00000000 */ + + /* 53 0x35 '5' */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xfc, /* 11111100 */ + 0x06, /* 00000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 54 0x36 '6' */ + 0x38, /* 00111000 */ + 0x60, /* 01100000 */ + 0xc0, /* 11000000 */ + 0xfc, /* 11111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 55 0x37 '7' */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x00, /* 00000000 */ + + /* 56 0x38 '8' */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 57 0x39 '9' */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7e, /* 01111110 */ + 0x06, /* 00000110 */ + 0x0c, /* 00001100 */ + 0x78, /* 01111000 */ + 0x00, /* 00000000 */ + + /* 58 0x3a ':' */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* 59 0x3b ';' */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + + /* 60 0x3c '<' */ + 0x06, /* 00000110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x06, /* 00000110 */ + 0x00, /* 00000000 */ + + /* 61 0x3d '=' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 62 0x3e '>' */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0x00, /* 00000000 */ + + /* 63 0x3f '?' */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* 64 0x40 '@' */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xde, /* 11011110 */ + 0xde, /* 11011110 */ + 0xde, /* 11011110 */ + 0xc0, /* 11000000 */ + 0x78, /* 01111000 */ + 0x00, /* 00000000 */ + + /* 65 0x41 'A' */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + + /* 66 0x42 'B' */ + 0xfc, /* 11111100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x7c, /* 01111100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0xfc, /* 11111100 */ + 0x00, /* 00000000 */ + + /* 67 0x43 'C' */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* 68 0x44 'D' */ + 0xf8, /* 11111000 */ + 0x6c, /* 01101100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x6c, /* 01101100 */ + 0xf8, /* 11111000 */ + 0x00, /* 00000000 */ + + /* 69 0x45 'E' */ + 0xfe, /* 11111110 */ + 0x62, /* 01100010 */ + 0x68, /* 01101000 */ + 0x78, /* 01111000 */ + 0x68, /* 01101000 */ + 0x62, /* 01100010 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + + /* 70 0x46 'F' */ + 0xfe, /* 11111110 */ + 0x62, /* 01100010 */ + 0x68, /* 01101000 */ + 0x78, /* 01111000 */ + 0x68, /* 01101000 */ + 0x60, /* 01100000 */ + 0xf0, /* 11110000 */ + 0x00, /* 00000000 */ + + /* 71 0x47 'G' */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xce, /* 11001110 */ + 0x66, /* 01100110 */ + 0x3a, /* 00111010 */ + 0x00, /* 00000000 */ + + /* 72 0x48 'H' */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + + /* 73 0x49 'I' */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* 74 0x4a 'J' */ + 0x1e, /* 00011110 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x78, /* 01111000 */ + 0x00, /* 00000000 */ + + /* 75 0x4b 'K' */ + 0xe6, /* 11100110 */ + 0x66, /* 01100110 */ + 0x6c, /* 01101100 */ + 0x78, /* 01111000 */ + 0x6c, /* 01101100 */ + 0x66, /* 01100110 */ + 0xe6, /* 11100110 */ + 0x00, /* 00000000 */ + + /* 76 0x4c 'L' */ + 0xf0, /* 11110000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x62, /* 01100010 */ + 0x66, /* 01100110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + + /* 77 0x4d 'M' */ + 0xc6, /* 11000110 */ + 0xee, /* 11101110 */ + 0xfe, /* 11111110 */ + 0xfe, /* 11111110 */ + 0xd6, /* 11010110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + + /* 78 0x4e 'N' */ + 0xc6, /* 11000110 */ + 0xe6, /* 11100110 */ + 0xf6, /* 11110110 */ + 0xde, /* 11011110 */ + 0xce, /* 11001110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + + /* 79 0x4f 'O' */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 80 0x50 'P' */ + 0xfc, /* 11111100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x7c, /* 01111100 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0xf0, /* 11110000 */ + 0x00, /* 00000000 */ + + /* 81 0x51 'Q' */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xce, /* 11001110 */ + 0x7c, /* 01111100 */ + 0x0e, /* 00001110 */ + + /* 82 0x52 'R' */ + 0xfc, /* 11111100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x7c, /* 01111100 */ + 0x6c, /* 01101100 */ + 0x66, /* 01100110 */ + 0xe6, /* 11100110 */ + 0x00, /* 00000000 */ + + /* 83 0x53 'S' */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* 84 0x54 'T' */ + 0x7e, /* 01111110 */ + 0x7e, /* 01111110 */ + 0x5a, /* 01011010 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* 85 0x55 'U' */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 86 0x56 'V' */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x00, /* 00000000 */ + + /* 87 0x57 'W' */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xd6, /* 11010110 */ + 0xd6, /* 11010110 */ + 0xfe, /* 11111110 */ + 0x6c, /* 01101100 */ + 0x00, /* 00000000 */ + + /* 88 0x58 'X' */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + + /* 89 0x59 'Y' */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* 90 0x5a 'Z' */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0x8c, /* 10001100 */ + 0x18, /* 00011000 */ + 0x32, /* 00110010 */ + 0x66, /* 01100110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + + /* 91 0x5b '[' */ + 0x3c, /* 00111100 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* 92 0x5c '\' */ + 0xc0, /* 11000000 */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x06, /* 00000110 */ + 0x02, /* 00000010 */ + 0x00, /* 00000000 */ + + /* 93 0x5d ']' */ + 0x3c, /* 00111100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* 94 0x5e '^' */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 95 0x5f '_' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + + /* 96 0x60 '`' */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 97 0x61 'a' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x78, /* 01111000 */ + 0x0c, /* 00001100 */ + 0x7c, /* 01111100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + + /* 98 0x62 'b' */ + 0xe0, /* 11100000 */ + 0x60, /* 01100000 */ + 0x7c, /* 01111100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0xdc, /* 11011100 */ + 0x00, /* 00000000 */ + + /* 99 0x63 'c' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc0, /* 11000000 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 100 0x64 'd' */ + 0x1c, /* 00011100 */ + 0x0c, /* 00001100 */ + 0x7c, /* 01111100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + + /* 101 0x65 'e' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 102 0x66 'f' */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x60, /* 01100000 */ + 0xf8, /* 11111000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0xf0, /* 11110000 */ + 0x00, /* 00000000 */ + + /* 103 0x67 'g' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x76, /* 01110110 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x7c, /* 01111100 */ + 0x0c, /* 00001100 */ + 0xf8, /* 11111000 */ + + /* 104 0x68 'h' */ + 0xe0, /* 11100000 */ + 0x60, /* 01100000 */ + 0x6c, /* 01101100 */ + 0x76, /* 01110110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0xe6, /* 11100110 */ + 0x00, /* 00000000 */ + + /* 105 0x69 'i' */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* 106 0x6a 'j' */ + 0x06, /* 00000110 */ + 0x00, /* 00000000 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + + /* 107 0x6b 'k' */ + 0xe0, /* 11100000 */ + 0x60, /* 01100000 */ + 0x66, /* 01100110 */ + 0x6c, /* 01101100 */ + 0x78, /* 01111000 */ + 0x6c, /* 01101100 */ + 0xe6, /* 11100110 */ + 0x00, /* 00000000 */ + + /* 108 0x6c 'l' */ + 0x38, /* 00111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* 109 0x6d 'm' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xec, /* 11101100 */ + 0xfe, /* 11111110 */ + 0xd6, /* 11010110 */ + 0xd6, /* 11010110 */ + 0xd6, /* 11010110 */ + 0x00, /* 00000000 */ + + /* 110 0x6e 'n' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xdc, /* 11011100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x00, /* 00000000 */ + + /* 111 0x6f 'o' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 112 0x70 'p' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xdc, /* 11011100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x7c, /* 01111100 */ + 0x60, /* 01100000 */ + 0xf0, /* 11110000 */ + + /* 113 0x71 'q' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x76, /* 01110110 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x7c, /* 01111100 */ + 0x0c, /* 00001100 */ + 0x1e, /* 00011110 */ + + /* 114 0x72 'r' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xdc, /* 11011100 */ + 0x76, /* 01110110 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0xf0, /* 11110000 */ + 0x00, /* 00000000 */ + + /* 115 0x73 's' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0xc0, /* 11000000 */ + 0x7c, /* 01111100 */ + 0x06, /* 00000110 */ + 0xfc, /* 11111100 */ + 0x00, /* 00000000 */ + + /* 116 0x74 't' */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0xfc, /* 11111100 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x36, /* 00110110 */ + 0x1c, /* 00011100 */ + 0x00, /* 00000000 */ + + /* 117 0x75 'u' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + + /* 118 0x76 'v' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x00, /* 00000000 */ + + /* 119 0x77 'w' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xd6, /* 11010110 */ + 0xd6, /* 11010110 */ + 0xfe, /* 11111110 */ + 0x6c, /* 01101100 */ + 0x00, /* 00000000 */ + + /* 120 0x78 'x' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + + /* 121 0x79 'y' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7e, /* 01111110 */ + 0x06, /* 00000110 */ + 0xfc, /* 11111100 */ + + /* 122 0x7a 'z' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x4c, /* 01001100 */ + 0x18, /* 00011000 */ + 0x32, /* 00110010 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + + /* 123 0x7b '{' */ + 0x0e, /* 00001110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x70, /* 01110000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x0e, /* 00001110 */ + 0x00, /* 00000000 */ + + /* 124 0x7c '|' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* 125 0x7d '}' */ + 0x70, /* 01110000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x0e, /* 00001110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x70, /* 01110000 */ + 0x00, /* 00000000 */ + + /* 126 0x7e '~' */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 127 0x7f '' */ + 0x00, /* 00000000 */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + + /* 128 0x80 '' */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x0c, /* 00001100 */ + 0x78, /* 01111000 */ + + /* 129 0x81 '' */ + 0xcc, /* 11001100 */ + 0x00, /* 00000000 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + + /* 130 0x82 '' */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 131 0x83 '' */ + 0x7c, /* 01111100 */ + 0x82, /* 10000010 */ + 0x78, /* 01111000 */ + 0x0c, /* 00001100 */ + 0x7c, /* 01111100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + + /* 132 0x84 '' */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x78, /* 01111000 */ + 0x0c, /* 00001100 */ + 0x7c, /* 01111100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + + /* 133 0x85 '' */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x78, /* 01111000 */ + 0x0c, /* 00001100 */ + 0x7c, /* 01111100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + + /* 134 0x86 '' */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x78, /* 01111000 */ + 0x0c, /* 00001100 */ + 0x7c, /* 01111100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + + /* 135 0x87 '' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0x7e, /* 01111110 */ + 0x0c, /* 00001100 */ + 0x38, /* 00111000 */ + + /* 136 0x88 '' */ + 0x7c, /* 01111100 */ + 0x82, /* 10000010 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 137 0x89 '' */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 138 0x8a '' */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 139 0x8b '' */ + 0x66, /* 01100110 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* 140 0x8c '' */ + 0x7c, /* 01111100 */ + 0x82, /* 10000010 */ + 0x38, /* 00111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* 141 0x8d '' */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* 142 0x8e '' */ + 0xc6, /* 11000110 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + + /* 143 0x8f '' */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + + /* 144 0x90 '' */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0xf8, /* 11111000 */ + 0xc0, /* 11000000 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + + /* 145 0x91 '' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0xd8, /* 11011000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + + /* 146 0x92 '' */ + 0x3e, /* 00111110 */ + 0x6c, /* 01101100 */ + 0xcc, /* 11001100 */ + 0xfe, /* 11111110 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xce, /* 11001110 */ + 0x00, /* 00000000 */ + + /* 147 0x93 '' */ + 0x7c, /* 01111100 */ + 0x82, /* 10000010 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 148 0x94 '' */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 149 0x95 '' */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 150 0x96 '' */ + 0x78, /* 01111000 */ + 0x84, /* 10000100 */ + 0x00, /* 00000000 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + + /* 151 0x97 '' */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + + /* 152 0x98 '' */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7e, /* 01111110 */ + 0x06, /* 00000110 */ + 0xfc, /* 11111100 */ + + /* 153 0x99 '' */ + 0xc6, /* 11000110 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x00, /* 00000000 */ + + /* 154 0x9a '' */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 155 0x9b '' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 156 0x9c '' */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0x64, /* 01100100 */ + 0xf0, /* 11110000 */ + 0x60, /* 01100000 */ + 0x66, /* 01100110 */ + 0xfc, /* 11111100 */ + 0x00, /* 00000000 */ + + /* 157 0x9d '' */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 158 0x9e '' */ + 0xf8, /* 11111000 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xfa, /* 11111010 */ + 0xc6, /* 11000110 */ + 0xcf, /* 11001111 */ + 0xc6, /* 11000110 */ + 0xc7, /* 11000111 */ + + /* 159 0x9f '' */ + 0x0e, /* 00001110 */ + 0x1b, /* 00011011 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0xd8, /* 11011000 */ + 0x70, /* 01110000 */ + 0x00, /* 00000000 */ + + /* 160 0xa0 '' */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x78, /* 01111000 */ + 0x0c, /* 00001100 */ + 0x7c, /* 01111100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + + /* 161 0xa1 '' */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* 162 0xa2 '' */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 163 0xa3 '' */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + + /* 164 0xa4 '' */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0x00, /* 00000000 */ + 0xdc, /* 11011100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x00, /* 00000000 */ + + /* 165 0xa5 '' */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0x00, /* 00000000 */ + 0xe6, /* 11100110 */ + 0xf6, /* 11110110 */ + 0xde, /* 11011110 */ + 0xce, /* 11001110 */ + 0x00, /* 00000000 */ + + /* 166 0xa6 '' */ + 0x3c, /* 00111100 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x3e, /* 00111110 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 167 0xa7 '' */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 168 0xa8 '' */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x63, /* 01100011 */ + 0x3e, /* 00111110 */ + 0x00, /* 00000000 */ + + /* 169 0xa9 '' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 170 0xaa '' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 171 0xab '' */ + 0x63, /* 01100011 */ + 0xe6, /* 11100110 */ + 0x6c, /* 01101100 */ + 0x7e, /* 01111110 */ + 0x33, /* 00110011 */ + 0x66, /* 01100110 */ + 0xcc, /* 11001100 */ + 0x0f, /* 00001111 */ + + /* 172 0xac '' */ + 0x63, /* 01100011 */ + 0xe6, /* 11100110 */ + 0x6c, /* 01101100 */ + 0x7a, /* 01111010 */ + 0x36, /* 00110110 */ + 0x6a, /* 01101010 */ + 0xdf, /* 11011111 */ + 0x06, /* 00000110 */ + + /* 173 0xad '' */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* 174 0xae '' */ + 0x00, /* 00000000 */ + 0x33, /* 00110011 */ + 0x66, /* 01100110 */ + 0xcc, /* 11001100 */ + 0x66, /* 01100110 */ + 0x33, /* 00110011 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 175 0xaf '' */ + 0x00, /* 00000000 */ + 0xcc, /* 11001100 */ + 0x66, /* 01100110 */ + 0x33, /* 00110011 */ + 0x66, /* 01100110 */ + 0xcc, /* 11001100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 176 0xb0 '' */ + 0x22, /* 00100010 */ + 0x88, /* 10001000 */ + 0x22, /* 00100010 */ + 0x88, /* 10001000 */ + 0x22, /* 00100010 */ + 0x88, /* 10001000 */ + 0x22, /* 00100010 */ + 0x88, /* 10001000 */ + + /* 177 0xb1 '' */ + 0x55, /* 01010101 */ + 0xaa, /* 10101010 */ + 0x55, /* 01010101 */ + 0xaa, /* 10101010 */ + 0x55, /* 01010101 */ + 0xaa, /* 10101010 */ + 0x55, /* 01010101 */ + 0xaa, /* 10101010 */ + + /* 178 0xb2 '' */ + 0x77, /* 01110111 */ + 0xdd, /* 11011101 */ + 0x77, /* 01110111 */ + 0xdd, /* 11011101 */ + 0x77, /* 01110111 */ + 0xdd, /* 11011101 */ + 0x77, /* 01110111 */ + 0xdd, /* 11011101 */ + + /* 179 0xb3 '' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 180 0xb4 '' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xf8, /* 11111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 181 0xb5 '' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xf8, /* 11111000 */ + 0x18, /* 00011000 */ + 0xf8, /* 11111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 182 0xb6 '' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xf6, /* 11110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 183 0xb7 '' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 184 0xb8 '' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xf8, /* 11111000 */ + 0x18, /* 00011000 */ + 0xf8, /* 11111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 185 0xb9 '' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xf6, /* 11110110 */ + 0x06, /* 00000110 */ + 0xf6, /* 11110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 186 0xba '' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 187 0xbb '' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x06, /* 00000110 */ + 0xf6, /* 11110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 188 0xbc '' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xf6, /* 11110110 */ + 0x06, /* 00000110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 189 0xbd '' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 190 0xbe '' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xf8, /* 11111000 */ + 0x18, /* 00011000 */ + 0xf8, /* 11111000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 191 0xbf '' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xf8, /* 11111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 192 0xc0 '' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x1f, /* 00011111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 193 0xc1 '' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 194 0xc2 '' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 195 0xc3 '' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x1f, /* 00011111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 196 0xc4 '' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 197 0xc5 '' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xff, /* 11111111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 198 0xc6 '' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x1f, /* 00011111 */ + 0x18, /* 00011000 */ + 0x1f, /* 00011111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 199 0xc7 '' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x37, /* 00110111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 200 0xc8 '' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x37, /* 00110111 */ + 0x30, /* 00110000 */ + 0x3f, /* 00111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 201 0xc9 '' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3f, /* 00111111 */ + 0x30, /* 00110000 */ + 0x37, /* 00110111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 202 0xca '' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xf7, /* 11110111 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 203 0xcb '' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0xf7, /* 11110111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 204 0xcc '' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x37, /* 00110111 */ + 0x30, /* 00110000 */ + 0x37, /* 00110111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 205 0xcd '' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 206 0xce '' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xf7, /* 11110111 */ + 0x00, /* 00000000 */ + 0xf7, /* 11110111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 207 0xcf '' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 208 0xd0 '' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 209 0xd1 '' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 210 0xd2 '' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 211 0xd3 '' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x3f, /* 00111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 212 0xd4 '' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x1f, /* 00011111 */ + 0x18, /* 00011000 */ + 0x1f, /* 00011111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 213 0xd5 '' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x1f, /* 00011111 */ + 0x18, /* 00011000 */ + 0x1f, /* 00011111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 214 0xd6 '' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3f, /* 00111111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 215 0xd7 '' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xff, /* 11111111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 216 0xd8 '' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xff, /* 11111111 */ + 0x18, /* 00011000 */ + 0xff, /* 11111111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 217 0xd9 '' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xf8, /* 11111000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 218 0xda '' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x1f, /* 00011111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 219 0xdb '' */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + + /* 220 0xdc '' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + + /* 221 0xdd '' */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + + /* 222 0xde '' */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + + /* 223 0xdf '' */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 224 0xe0 '' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0xc8, /* 11001000 */ + 0xdc, /* 11011100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + + /* 225 0xe1 '' */ + 0x78, /* 01111000 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xd8, /* 11011000 */ + 0xcc, /* 11001100 */ + 0xc6, /* 11000110 */ + 0xcc, /* 11001100 */ + 0x00, /* 00000000 */ + + /* 226 0xe2 '' */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0x00, /* 00000000 */ + + /* 227 0xe3 '' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x00, /* 00000000 */ + + /* 228 0xe4 '' */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + + /* 229 0xe5 '' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0xd8, /* 11011000 */ + 0xd8, /* 11011000 */ + 0xd8, /* 11011000 */ + 0x70, /* 01110000 */ + 0x00, /* 00000000 */ + + /* 230 0xe6 '' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x7c, /* 01111100 */ + 0xc0, /* 11000000 */ + + /* 231 0xe7 '' */ + 0x00, /* 00000000 */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* 232 0xe8 '' */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + + /* 233 0xe9 '' */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x00, /* 00000000 */ + + /* 234 0xea '' */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0xee, /* 11101110 */ + 0x00, /* 00000000 */ + + /* 235 0xeb '' */ + 0x0e, /* 00001110 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x3e, /* 00111110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* 236 0xec '' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0xdb, /* 11011011 */ + 0xdb, /* 11011011 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 237 0xed '' */ + 0x06, /* 00000110 */ + 0x0c, /* 00001100 */ + 0x7e, /* 01111110 */ + 0xdb, /* 11011011 */ + 0xdb, /* 11011011 */ + 0x7e, /* 01111110 */ + 0x60, /* 01100000 */ + 0xc0, /* 11000000 */ + + /* 238 0xee '' */ + 0x1e, /* 00011110 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0x7e, /* 01111110 */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x1e, /* 00011110 */ + 0x00, /* 00000000 */ + + /* 239 0xef '' */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + + /* 240 0xf0 '' */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 241 0xf1 '' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + + /* 242 0xf2 '' */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + + /* 243 0xf3 '' */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + + /* 244 0xf4 '' */ + 0x0e, /* 00001110 */ + 0x1b, /* 00011011 */ + 0x1b, /* 00011011 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 245 0xf5 '' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xd8, /* 11011000 */ + 0xd8, /* 11011000 */ + 0x70, /* 01110000 */ + + /* 246 0xf6 '' */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 247 0xf7 '' */ + 0x00, /* 00000000 */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0x00, /* 00000000 */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 248 0xf8 '' */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 249 0xf9 '' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 250 0xfa '' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 251 0xfb '' */ + 0x0f, /* 00001111 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0xec, /* 11101100 */ + 0x6c, /* 01101100 */ + 0x3c, /* 00111100 */ + 0x1c, /* 00011100 */ + + /* 252 0xfc '' */ + 0x6c, /* 01101100 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 253 0xfd '' */ + 0x78, /* 01111000 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 254 0xfe '' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3c, /* 00111100 */ + 0x3c, /* 00111100 */ + 0x3c, /* 00111100 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 255 0xff '' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + +}; diff --git a/ch32v/lib/webhidcontrol.js b/ch32v/lib/webhidcontrol.js new file mode 100644 index 0000000..0ed3e0e --- /dev/null +++ b/ch32v/lib/webhidcontrol.js @@ -0,0 +1,583 @@ +/* This file is under the regular MIT license. + +Copyright 2024 Charles Lohr (cnlohr) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +*/ + +const expectedProductName = "CNLohr lolra ch32v203 goertzel test"; +const filter = { vendorId : 0x1209, productId : 0xd035 }; +let dev = null; +let loopAbort = false; + +const IQHistoryLen = 4096; +var IQHistoryArray = new Uint32Array(IQHistoryLen); +var MPHistoryArray = new Float32Array(IQHistoryLen*2); +var IQHistoryHead = 0|0; +var lastIntensity = 1.0; +var lastNumQ = 0; +var lastTotalTime = 1; +var lastTimeUsed = 1; +var didSetupGeneralData = false; +var graphIsClicked = false; + +function graphClick( e ) +{ + if( e.type == "mousedown" ) graphIsClicked = true; + if( e.type == "mouseup" ) graphIsClicked = false; + return true; +} + +function setStatus( msg ) +{ + document.getElementById( "STATUS" ).innerHTML = msg; + console.log( msg ); +} + +function setStatusError( msg ) +{ + setStatus( "" + msg + "" ); + console.log( msg ); + console.trace(); +} + +function tryConnect() +{ + if( !navigator.hid ) + { + return; + } + + if( !dev ) + { + navigator.hid.getDevices().then( (devices) => + { + if( devices.length == 0 ) + setStatusError( "No devices found. Open a device." ); + else + devices.forEach( tryOpen ); + }); + } +} + +async function closeDeviceTool() +{ + loopAbort = false; + setStatusError( "Disconnected" ); + dev = null; +} + +var playingAudioProcessor = null; +var audioContext = null; + +var targetModulation = 0; +var targetGain = 0.0; + +function UpdateButtonNames() +{ + document.getElementById( "ToggleAudioButton" ).value = ( targetGain > 0.0 ) ? "Stop Audio" : "Start Audio"; + document.getElementById( "ToggleAudioModulationButton" ).value = ( targetModulation > 0.5 ) ? "FM" : "AM"; +} + +async function toggleAudioModulation() +{ + if( playingAudioProcessor != null ) + { + var newVal = 1 - targetModulation; + targetModulation = newVal; + } + UpdateButtonNames(); +} + +async function toggleAudio() +{ + if( playingAudioProcessor == null ) + { + var bypass = '\ + class PlayingAudioProcessor extends AudioWorkletProcessor {\ + static get parameterDescriptors() {\ + return [\ + { name: "gain", defaultValue: 0, },\ + { name: "sampleAdvance", defaultValue: 0.5, },\ + ]\ + };\ + constructor() {\ + super();\ + this.rbuffer = new Float32Array(8192); \ + this.rbufferhead = 0|0; \ + this.rbuffertail = 0|0; \ + this.sampleplace = 0.0; \ + this.dcoffset = 0.0; \ + this.totalsampcount = 0|0; \ + \ + this.port.onmessage = (e) => { \ + for( var i = 0|0; i < e.data.length|0; i++ ) \ + { \ + let n = (this.rbufferhead + (1|0))%(8192|0); \ + if( n == this.rbuffertail ) \ + { \ + this.rbuffertail = (this.rbuffertail + (1|0))%(8192|0); \ + /*console.log( `Overflow` ); */ \ + } \ + var vv = e.data[i]; \ + this.dcoffset = this.dcoffset * 0.995 + vv * 0.005; \ + this.rbuffer[this.rbufferhead] = vv - this.dcoffset; \ + this.rbufferhead = n; \ + } \ + }; \ + }\ + \ + process(inputs, outputs, parameters) {\ + /*console.log( parameters.gain[0] );*/ \ + /*console.log( this.ingestData );*/ \ + let len = outputs[0][0].length; \ + const sa = Math.fround( parameters.sampleAdvance[0] ); /*float*/ \ + var s = Math.fround( this.sampleplace ); /*float*/ \ + var tail = this.rbuffertail | 0; /* int*/ \ + var tailnext = this.rbuffertail | 0; /* int*/ \ + if( tail == this.rbufferhead ) { /*console.log( "Underflow " );*/ return true; }\ + var tsamp = Math.fround( this.rbuffer[tail] ); \ + var nsamp = Math.fround( this.rbuffer[tailnext] ); \ + this.totalsampcount += len|0; \ + for (let b = 0|0; b < len|0; b++) { \ + s += sa; \ + var excess = Math.floor( s ) | 0; \ + if( excess > 0 ) \ + { \ + s -= excess; \ + tail = ( tail + (excess|0) ) % (8192|0); \ + tailnext = ( tail + (1|0) ) % (8192|0); \ + if( tail == this.rbufferhead ) { /* console.log( "Underflow" ); */ break; } \ + tsamp = Math.fround( this.rbuffer[tail] ); \ + nsamp = Math.fround( this.rbuffer[tailnext] ); \ + } \ + var valv = tsamp * (1.0-s) + nsamp * s; \ + outputs[0][0][b] = valv*parameters.gain[0]; \ + } \ + /*console.log( tail + " " + this.rbuffertail + " " + tsamp + " " + nsamp );*/ \ + this.rbuffertail = tail; \ + this.sampleplace = s; \ + return true; \ + } \ + } \ + \ + registerProcessor("playing-audio-processor", PlayingAudioProcessor);'; + + // The following mechanism does not work on Chrome. + // const dataURI = URL.createObjectURL( new Blob([bypass], { type: 'text/javascript', } ) ); + + + // Extremely tricky trick to side-step local file:// CORS issues. + // https://stackoverflow.com/a/67125196/2926815 + // https://stackoverflow.com/a/72180421/2926815 + let blob = new Blob([bypass], {type: 'application/javascript'}); + let reader = new FileReader(); + await reader.readAsDataURL(blob); + let dataURI = await new Promise((res) => { + reader.onloadend = function () { + res(reader.result); + } + }); + + audioContext = new AudioContext(); + + await audioContext.audioWorklet.addModule(dataURI); + + playingAudioProcessor = new AudioWorkletNode( + audioContext, + "playing-audio-processor" + ); + playingAudioProcessor.connect(audioContext.destination); + audioContext.resume(); + + let gainParam = playingAudioProcessor.parameters.get( "gain" ); + gainParam.setValueAtTime( 0, audioContext.currentTime ); + } + + var newVal = 1.0 - targetGain; + console.log( "Setting gain to: " + newVal ); + let gainParam = playingAudioProcessor.parameters.get("gain"); + gainParam.setValueAtTime( newVal, audioContext.currentTime); + targetGain = newVal; + document.getElementById( "ToggleAudioButton" ).value = ( newVal > 0.5 ) ? "Stop Audio" : "Start Audio"; + UpdateButtonNames(); +} + +function onLoadWebHidControl() +{ + liveGraph = document.getElementById( "LiveGraph" ); + liveGraph.addEventListener( "mousedown", graphClick ); + liveGraph.addEventListener( "mouseup", graphClick ); + + UpdateButtonNames(); + setTimeout( sendLoop, 1 ); + + if( !navigator.hid ) + { + setStatusError( "Browser does not support HID." ); + document.getElementById( "connectButton" ).hidden = true; + } + else + { + navigator.hid.addEventListener("disconnect", (event) => { if( event.device.productName == expectedProductName ) closeDeviceTool(); } ); + } + + setTimeout( () => { elapsedOK = true; }, 3000 ); + +} + +function reqConnect() +{ + loopAbort = true; + const initialization = navigator.hid.requestDevice( { filters: [ filter ] } ); + initialization.then( gotUSBDevice ); + initialization.catch( setStatusError ); +} + +function gotUSBDevice(result) +{ + if( result.length < 1 ) + { + setStatusError( "Error: No devices found" ); + return; + } + + if( result[0].productName != expectedProductName ) + { + setStatusError( "Error: Wrong device name. Got " + result[0].productName + " Expected " + expectedProductName ); + return; + } + + const thisDev = result[0]; + + tryOpen( thisDev ); +} + +function tryOpen( thisDev ) +{ + thisDev.open().then( ( result ) => { + if( result === undefined ) + { + if( dev ) dev.close(); + loopAbort = false; + dev = thisDev; + setStatus( "Connected." ); + } + else + { + setStatusError( "Error: Could not open; " + result ); + } + } ).catch( (e) => setStatusError( "Error: Could not open; " + e ) ); +} + +let sendReport = null; +let receiveReport = null; + +async function sendLoopError( e ) +{ +console.log( "SEND LOOP ERROR" ); + sendReport = null; + receiveReport = null; + if( dev ) await dev.close(); + dev = null; + setStatusError( e ); +} + +function updateWebHidDeviceWithParameters( paramlist ) +{ + var i = 0|0; + var arraySend = new Uint8Array(63); + for( var i = 0|0; i < paramlist.length|0; i++ ) + { + var vv = paramlist[i] | 0; + arraySend[i*4+7] = (vv>>0)&0xff; + arraySend[i*4+8] = (vv>>8)&0xff; + arraySend[i*4+9] = (vv>>16)&0xff; + arraySend[i*4+10] = (vv>>24)&0xff; + } + arraySend[3] = paramlist.length | 0; + sendReport = dev.sendFeatureReport( 0xAC, arraySend ).catch( sendLoopError ); + if( !sendReport ) sendLoopError( "error creating sendFeatureReport" ); +} + +FMiirphase = 0.0; /* for FM */ +FMlastphase = 0.0; /* for FM */ +FMphaseout = 0.0; /* for FM */ + +lastadc = 0|0; + + +remote_clock_mhz = 0; +remote_clock_last_timestamp = 0|0; +remote_clock_last_timems = 0.0; +remote_clock_initted = false; +remote_clock_refinement = 1.0; +remote_clock_total_s = 0; +remote_clock_total_ticks = 0.0; + +function ComputeRemoteClock( remote_time_ticks, now_ms ) +{ + if( !remote_clock_initted ) + { + remote_clock_last_timestamp = remote_time_ticks; + remote_clock_last_timems = now_ms; + remote_clock_refinement = 1.0; + remote_clock_initted = true; + remote_clock_total_ms = 0; + remote_clock_total_ticks = 0|0; + return; + } + + var delta_s = (now_ms - remote_clock_last_timems)/1000.0; + var delta_clock = ((remote_time_ticks - remote_clock_last_timestamp)|0)*2; // convert 144MHz to 288MHz + var this_mhz = delta_clock / delta_s; + + remote_clock_total_s += delta_s; + remote_clock_total_ticks += delta_clock * 1.0; + + remote_clock_mhz = remote_clock_total_ticks / remote_clock_total_s; + + remote_clock_total_s *= 0.99999; + remote_clock_total_ticks *= 0.99999; + + remote_clock_last_timestamp = remote_time_ticks; + remote_clock_last_timems = now_ms; +} + +function updateCrystalWithMHz() +{ + document.getElementById('crystalmhz').value = remote_clock_mhz/1000000.0; +} + +async function sendLoop() +{ + const sleep = ms => new Promise(r => setTimeout(r, ms)); + var frameNo = 0|0; + var lastTime = performance.now(); + let goodCount = 0; + let badCount = 0; + let kBsecAvg = 0; + let xActionSecAvg = 0; + + while( true ) + { + if( dev && dev !== null && !loopAbort ) + { + receiveReport = dev.receiveFeatureReport( 0xAD ).catch( sendLoopError ); + if( !receiveReport ) sendLoopError( "error creating receiveReport" ); + + frameNo++ + + const updateStatsPerfPer = 4; + if( frameNo % updateStatsPerfPer == 0 ) + { + let thisTime = performance.now(); + let deltaTime = thisTime - lastTime; + let kBsec = (255*1000/1024*updateStatsPerfPer)/(deltaTime); + let xActionSec = (2*updateStatsPerfPer*1000)/(deltaTime); + kBsecAvg = kBsecAvg * 0.9 + kBsec * 0.1; + xActionSecAvg = xActionSecAvg * 0.9 + xActionSec * 0.1; + + document.getElementById( "StatusPerf" ).innerHTML = + (kBsecAvg).toFixed(2) + " kB/s
" + + (xActionSecAvg).toFixed(2) + "x/s
"; + + if( !didSetupGeneralData ) + { + document.getElementById( "GeneralData" ).innerHTML = + "" + + "" + + "" + + "" + + "" + + "
Count: " + goodCount + " / " + badCount + "Inten: " + ((Math.log( lastIntensity * lastIntensity )/Math.log(10)) * 10-120).toFixed(2) + "db (" + lastIntensity + ")ADCs: " + (lastadc>>16).toFixed(0) + " / " + (lastadc&0xffff).toFixed(0) + " MHz ` + "" + ((remote_clock_mhz-288000000)/288).toFixed(3) + " PPM
"; + didSetupGeneralData = true; + } + else + { + + document.getElementById( "gdCount" ).innerHTML = "Count: " + goodCount + " / " + badCount; + document.getElementById( "gdInten" ).innerHTML = "Inten: " + ((Math.log( lastIntensity * lastIntensity )/Math.log(10)) * 10-120).toFixed(2) + "db (" + lastIntensity + ")"; + document.getElementById( "gdADCs" ).innerHTML = "ADC:" + (lastadc>>16).toFixed(0) + " / " + (lastadc&0xffff).toFixed(0); + document.getElementById( "gdButton" ).value = "" + (remote_clock_mhz/1000000.0).toFixed(6); + document.getElementById( "gdPPM" ).innerHTML = "" + ((remote_clock_mhz-288000000)/288).toFixed(3) + " PPM"; + didSetupGeneralData = true; + } + + lastTime = thisTime; + } + else if( frameNo % updateStatsPerfPer == 2 ) + { + const ctx = liveGraph.getContext("2d"); + + if( !graphIsClicked ) + { + let liveGraphContainer = document.getElementById( "LiveGraphContainer" ); + liveGraph.width = liveGraphContainer.clientWidth; + liveGraph.style.position = 'absolute'; + + ctx.clearRect(0, 0, liveGraph.width, liveGraph.height); + + let grey = darkmode?"rgb( 240 240 240 )":"rgb(16 16 16)"; + let mark = darkmode?"rgb( 255 255 255 )":"rgb(0 0 0)"; + + var filledness = lastNumQ * 198 / 120; + ctx.fillStyle = grey; + ctx.fillRect( 2, 2 + 198 - filledness, 18, filledness - 2); + + filledness = ( lastTimeUsed * 1.0 / lastTotalTime ) * 198; + ctx.fillStyle = grey; + ctx.fillRect( 26, 2 + 198 - filledness, 18, filledness - 2 ); + + ctx.fillStyle = mark; + + let mulcoeff = 2500.0 / lastIntensity; + var lot = 1.2; + var x = 253; + for( var i = (IQHistoryHead-1) & (IQHistoryLen-1); i != IQHistoryHead|0; i = (i - 1 + IQHistoryLen) & (IQHistoryLen-1) ) + { + let power = MPHistoryArray[i*2+0]; //Math.sqrt( real * real + imag * imag ) * mulcoeff; + let phase = MPHistoryArray[i*2+1]; //Math.atan2( real, imag ) * 0.159155078*0.5; + ctx.fillRect(x,power*120+10,2,2); + ctx.fillRect(x,phase*80+110,2,2); + + let v = IQHistoryArray[i]; + let real = (v >> 16); + let imag = (v & 0xffff); + if( real > 32767 ) real -= 65536; + if( imag > 32767 ) imag -= 65536; + real = real * mulcoeff + 100; + imag = imag * mulcoeff + 100; + if( real < 0 ) real = 0; if( real > 255 ) real = 255; + if( imag < 0 ) imag = 0; if( imag > 255 ) imag = 255; + x++; + if( lot > 0 ) + { + ctx.globalAlpha = lot; + ctx.fillRect(real+50,imag,2,2); + } + ctx.globalAlpha = 1.0; + lot -= 0.0015; + } + + ctx.strokeStyle = "rgb( 128 128 128 )"; + ctx.fillStyle = "rgb( 128 0 0 )"; + ctx.strokeRect( 1, 1, 20, 198 ); + ctx.strokeRect( 25, 1, 20, 198 ); + ctx.strokeRect( 49, 1, 200, 198 ); + ctx.strokeRect( 253, 1, liveGraph.width, 198 ); + } + } + + + if( sendReport ) + { + await sendReport; + } + if( receiveReport ) + { + let receiveData = await receiveReport; + if( receiveData && receiveData.buffer ) + { + // Receive data from USB (from HandleHidUserGetReportSetup) + let data = new Uint32Array( receiveData.buffer.slice( 0, 508 ) ); + let intensity = data[0]>>8; + let numq = data[0] & 0xff; + let time_total = data[1]>>16; + let time_used = data[1]&0xffff; + let sample_divisor = data[2]&0xffff; + let remote_time = data[3]; + ComputeRemoteClock( remote_time, performance.now() ); + lastadc = data[4]; + let demodbuffer = new Float32Array(numq); + let mulcoeff = 16.0 / lastIntensity; + for( var i = 0|0; i < numq; i++ ) + { + let vv = IQHistoryArray[IQHistoryHead] = data[i+5]; + let vi = vv >> 16; + let vq = vv & 0xffff; + if( vi >= 32768 ) vi = vi-65535; + if( vq >= 32768 ) vq = vq-65535; + let power = Math.sqrt( vi * vi + vq * vq ) * mulcoeff; + let phase = Math.atan2( vi, vq ) * 0.159155078 + 0.5; + MPHistoryArray[IQHistoryHead*2+0] = power; //Math.sqrt( real * real + imag * imag ) * mulcoeff; + MPHistoryArray[IQHistoryHead*2+1] = phase; //Math.atan2( real, imag ) * 0.159155078*0.5; + if( targetModulation == 0 ) + { /* AM */ + demodbuffer[i] = power; + } + else if( targetModulation == 1 ) + { /* FM */ + var diffphase = phase - FMlastphase; + FMlastphase = phase; + if( diffphase - FMiirphase < 0.0 ) diffphase += 1.0; + if( diffphase - FMiirphase > 1.0 ) diffphase -= 1.0; + FMiirphase = FMiirphase * 0.999 + diffphase * 0.001; + diffphase -= FMiirphase; + if( diffphase > 0.5 ) diffphase -= 1; + if( diffphase <-0.5 ) diffphase += 1; + var po = FMphaseout = FMphaseout * 0.993 + diffphase; + if( po < 0.0 ) po += 1.0; + if( po > 1.0 ) po -= 1.0; + demodbuffer[i] = po * .3; // Turn down FM it's really loud. + } + + IQHistoryHead = (IQHistoryHead+1)%IQHistoryLen; + } + lastIntensity = intensity; + lastNumQ = numq; + lastTotalTime = time_total; + lastTimeUsed = time_used; + + if( audioContext != null && playingAudioProcessor != null ) + { + let sampleAdvance = (system_rate/sample_divisor) / audioContext.sampleRate; + let sampleAdvanceParam = playingAudioProcessor.parameters.get("sampleAdvance"); + sampleAdvanceParam.setValueAtTime( sampleAdvance, audioContext.currentTime); + playingAudioProcessor.port.postMessage( demodbuffer ); + } + goodCount++; + } + else + { + badCount++; + } + } + } + else if( loopAbort ) + { + if( dev ) + { + console.log( "Loop Aborting, Dev Closing" ); + await dev.close(); + console.log( "Loop Aborting, Dev Closed." ); + dev = null; + } + await sleep(100); + } + else + { + // Try opening dev. + console.log( "Attempting reconnect." ); + tryConnect(); + goodCount = 0; + badCount = 0; + let i = 0|0; + for( i = 0; i < 10; i++ ) + { + await sleep(100); + if( dev ) + { + //break; + } + } + } + } + console.log( "ABORT\n" ); +} + diff --git a/esp32s2/narrow_fsk_test/.gitignore b/esp32s2/narrow_fsk_test/.gitignore new file mode 100644 index 0000000..af96791 --- /dev/null +++ b/esp32s2/narrow_fsk_test/.gitignore @@ -0,0 +1,2 @@ +.vscode +build diff --git a/esp32s2/narrow_fsk_test/CMakeLists.txt b/esp32s2/narrow_fsk_test/CMakeLists.txt new file mode 100644 index 0000000..b0a72d1 --- /dev/null +++ b/esp32s2/narrow_fsk_test/CMakeLists.txt @@ -0,0 +1,23 @@ +# The following lines of boilerplate have to be in your project's +# CMakeLists in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.5) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) + + +add_custom_target(stub_bootload + # If the swadge is running reboot it into the bootloader. + COMMAND make -C ../tools/reboot_into_bootloader reboot + COMMAND sleep 0.5 +) +#add_dependencies(flash before_flash) +add_custom_target(stub_run + #Sometimes the swadge needs a kick to get rebooted + COMMAND sleep 0.5 + COMMAND esptool.py --before no_reset --after no_reset load_ram ../tools/bootload_reboot_stub/bootload_reboot_stub.bin +) + + +project(usb_sandbox) + + diff --git a/esp32s2/narrow_fsk_test/main/CMakeLists.txt b/esp32s2/narrow_fsk_test/main/CMakeLists.txt new file mode 100644 index 0000000..9387585 --- /dev/null +++ b/esp32s2/narrow_fsk_test/main/CMakeLists.txt @@ -0,0 +1,4 @@ +idf_component_register(SRCS "main.c" "app.c" + INCLUDE_DIRS "" ) + + diff --git a/esp32s2/narrow_fsk_test/main/app.c b/esp32s2/narrow_fsk_test/main/app.c new file mode 100644 index 0000000..a7aff2c --- /dev/null +++ b/esp32s2/narrow_fsk_test/main/app.c @@ -0,0 +1,378 @@ +/** + +MIT-like-non-ai-license + +Copyright (c) 2024 Charles Lohr "CNLohr" + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the two following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +In addition the following restrictions apply: + +1. The Software and any modifications made to it may not be used for the +purpose of training or improving machine learning algorithms, including but not +limited to artificial intelligence, natural language processing, or data +mining. This condition applies to any derivatives, modifications, or updates +based on the Software code. Any usage of the Software in an AI-training dataset +is considered a breach of this License. + +2. The Software may not be included in any dataset used for training or +improving machine learning algorithms, including but not limited to artificial +intelligence, natural language processing, or data mining. + +3. Any person or organization found to be in violation of these restrictions +will be subject to legal action and may be held liable for any damages +resulting from such use. + +If any term is unenforcable, other terms remain in-force. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +*/ + +#include +#include +#include "esp_system.h" +#include "hal/gpio_types.h" +#include "esp_log.h" +#include "soc/efuse_reg.h" +#include "soc/soc.h" +#include "soc/system_reg.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "soc/gpio_sig_map.h" + + +#include "soc/io_mux_reg.h" +#include "soc/dedic_gpio_reg.h" + +// Funtenna will output on GPIO1 and 14. Otherwise it will be 17 and 18 +//#define FUNTENNA + +int global_i = 100; + + +static inline uint32_t getCycleCount() +{ + uint32_t ccount; + asm volatile("rsr %0,ccount":"=a" (ccount)); + return ccount; +} + + +#define IO_MUX_REG(x) XIO_MUX_REG(x) +#define XIO_MUX_REG(x) IO_MUX_GPIO##x##_REG + +#define GPIO_NUM(x) XGPIO_NUM(x) +#define XGPIO_NUM(x) GPIO_NUM_##x + + +#ifdef FUNTENNA + +#define RF1_PIN 1 +#define RF2_PIN 14 +#else +#define RF1_PIN 17 +#define RF2_PIN 18 +#endif + + + +#include "hal/gpio_types.h" +#include "driver/gpio.h" +#include "rom/gpio.h" +#include "soc/i2s_reg.h" +#include "soc/periph_defs.h" +#include "rom/lldesc.h" +#include "soc/rtc_cntl_reg.h" +#include "soc/rtc.h" +#include "soc/regi2c_apll.h" +//#include "components/hal/esp32s2/include/hal/regi2c_ctrl_ll.h +#include "hal/regi2c_ctrl_ll.h" +#include "esp_private/periph_ctrl.h" +#include "esp_private/regi2c_ctrl.h" +#include "hal/clk_tree_ll.h" + + + + +#define I2C_RTC_WIFI_CLK_EN (SYSCON_WIFI_CLK_EN_REG) + +#define I2C_RTC_CLK_GATE_EN (BIT(18)) +#define I2C_RTC_CLK_GATE_EN_M (BIT(18)) +#define I2C_RTC_CLK_GATE_EN_V 0x1 +#define I2C_RTC_CLK_GATE_EN_S 18 + +#define I2C_RTC_CONFIG0 0x6000e048 + +#define I2C_RTC_MAGIC_CTRL 0x00001FFF +#define I2C_RTC_MAGIC_CTRL_M ((I2C_RTC_MAGIC_CTRL_V)<<(I2C_RTC_MAGIC_CTRL_S)) +#define I2C_RTC_MAGIC_CTRL_V 0x1FFF +#define I2C_RTC_MAGIC_CTRL_S 4 + +#define I2C_RTC_CONFIG1 0x6000e044 + +#define I2C_RTC_BOD_MASK (BIT(22)) +#define I2C_RTC_BOD_MASK_M (BIT(22)) +#define I2C_RTC_BOD_MASK_V 0x1 +#define I2C_RTC_BOD_MASK_S 22 + +#define I2C_RTC_SAR_MASK (BIT(18)) +#define I2C_RTC_SAR_MASK_M (BIT(18)) +#define I2C_RTC_SAR_MASK_V 0x1 +#define I2C_RTC_SAR_MASK_S 18 + +#define I2C_RTC_BBPLL_MASK (BIT(17)) +#define I2C_RTC_BBPLL_MASK_M (BIT(17)) +#define I2C_RTC_BBPLL_MASK_V 0x1 +#define I2C_RTC_BBPLL_MASK_S 17 + +#define I2C_RTC_APLL_MASK (BIT(14)) +#define I2C_RTC_APLL_MASK_M (BIT(14)) +#define I2C_RTC_APLL_MASK_V 0x1 +#define I2C_RTC_APLL_MASK_S 14 + +#define I2C_RTC_ALL_MASK 0x00007FFF +#define I2C_RTC_ALL_MASK_M ((I2C_RTC_ALL_MASK_V)<<(I2C_RTC_ALL_MASK_S)) +#define I2C_RTC_ALL_MASK_V 0x7FFF +#define I2C_RTC_ALL_MASK_S 8 + +#define I2C_RTC_CONFIG2 0x6000e000 + +#define I2C_RTC_BUSY (BIT(25)) +#define I2C_RTC_BUSY_M (BIT(25)) +#define I2C_RTC_BUSY_V 0x1 +#define I2C_RTC_BUSY_S 25 + +#define I2C_RTC_WR_CNTL (BIT(24)) +#define I2C_RTC_WR_CNTL_M (BIT(24)) +#define I2C_RTC_WR_CNTL_V 0x1 +#define I2C_RTC_WR_CNTL_S 24 + +#define I2C_RTC_DATA 0x000000FF +#define I2C_RTC_DATA_M ((I2C_RTC_DATA_V)<<(I2C_RTC_DATA_S)) +#define I2C_RTC_DATA_V 0xFF +#define I2C_RTC_DATA_S 16 + +#define I2C_RTC_ADDR 0x000000FF +#define I2C_RTC_ADDR_M ((I2C_RTC_ADDR_V)<<(I2C_RTC_ADDR_S)) +#define I2C_RTC_ADDR_V 0xFF +#define I2C_RTC_ADDR_S 8 + +#define I2C_RTC_SLAVE_ID 0x000000FF +#define I2C_RTC_SLAVE_ID_M ((I2C_RTC_SLAVE_ID_V)<<(I2C_RTC_SLAVE_ID_S)) +#define I2C_RTC_SLAVE_ID_V 0xFF +#define I2C_RTC_SLAVE_ID_S 0 + +#define I2C_RTC_MAGIC_DEFAULT (0x1c40) + +#define I2C_BOD 0x61 +#define I2C_BBPLL 0x66 +#define I2C_SAR_ADC 0X69 +#define I2C_APLL 0X6D + + +int lastend = 0; + +// This generates a slow sweep over 17.8 seconds of exactly one full SDM0 iteration +// this is to measure how good dithering can be. + +const float fRadiator = 28.08; // In MHz 28.08MHz = in RTTY section of 10 Meters HAM band. +const float fHarmonic = 1.0; +const float fXTAL = 40; + +// Set to 2 for highest possible frequencies (up to 69MHz) Lower to get more control at lower frequencies. This is the part in parenthesis (ODIV+2) +// Higher numbers will give you more control. But, there is a limit. 350<40 * (SDM2 + SDM1/(2^8) + SDM0/(2^16) + 4)<500 +// Set to 3 for up to 46MHz +// Set to 4 for up to 34MHz +// set to 5 for up to 27MHz (well 27MHzish, you can go a tad higher) +const float nPLLDivisorD2 = 5; + + + + +// Configures APLL = 480 / 4 = 120 +// 40 * (SDM2 + SDM1/(2^8) + SDM0/(2^16) + 4) / ( 2 * (ODIV+2) ); +// Datasheet recommends that numerator does not exceed 500MHz. +void IRAM_ATTR local_rtc_clk_apll_enable(bool enable, uint32_t sdm0, uint32_t sdm1, uint32_t sdm2, uint32_t o_div) +{ + REG_SET_FIELD(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_PLLA_FORCE_PD, enable ? 0 : 1); + REG_SET_FIELD(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_PLLA_FORCE_PU, enable ? 1 : 0); + + if (enable) { + REGI2C_WRITE_MASK(I2C_APLL, I2C_APLL_DSDM2, sdm2); + REGI2C_WRITE_MASK(I2C_APLL, I2C_APLL_DSDM0, sdm0); + REGI2C_WRITE_MASK(I2C_APLL, I2C_APLL_DSDM1, sdm1); + REGI2C_WRITE(I2C_APLL, I2C_APLL_SDM_STOP, CLK_LL_APLL_SDM_STOP_VAL_1); + REGI2C_WRITE(I2C_APLL, I2C_APLL_SDM_STOP, CLK_LL_APLL_SDM_STOP_VAL_2_REV1); + REGI2C_WRITE_MASK(I2C_APLL, I2C_APLL_OR_OUTPUT_DIV, o_div ); + } + + + // Settings determined experimentally. + REGI2C_WRITE_MASK(I2C_APLL, I2C_APLL_OC_TSCHGP, 0 ); // 0 or 1 + REGI2C_WRITE_MASK(I2C_APLL, I2C_APLL_EN_FAST_CAL, 1 ); // 0 or 1 + REGI2C_WRITE_MASK(I2C_APLL, I2C_APLL_OC_DHREF_SEL, 3 ); // 0..3 + REGI2C_WRITE_MASK(I2C_APLL, I2C_APLL_OC_DLREF_SEL, 2 ); // 0..3 + REGI2C_WRITE_MASK(I2C_APLL, I2C_APLL_SDM_DITHER, 1 ); // 0 or 1 + REGI2C_WRITE_MASK(I2C_APLL, I2C_APLL_OC_DVDD, 25 ); // 0 .. 31 + +} + + +void IRAM_ATTR regi2c_write_reg_raw_local(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t data) +{ + uint32_t temp = ((block & I2C_RTC_SLAVE_ID_V) << I2C_RTC_SLAVE_ID_S) + | ((reg_add & I2C_RTC_ADDR_V) << I2C_RTC_ADDR_S) + | ((0x1 & I2C_RTC_WR_CNTL_V) << I2C_RTC_WR_CNTL_S) + | (((uint32_t)data & I2C_RTC_DATA_V) << I2C_RTC_DATA_S); + while (REG_GET_BIT(I2C_RTC_CONFIG2, I2C_RTC_BUSY)); + REG_WRITE(I2C_RTC_CONFIG2, temp); +} + + +void apll_quick_update( uint32_t sdm ) +{ + uint8_t sdm2 = sdm>>16; + uint8_t sdm1 = (sdm>>8)&0xff; + uint8_t sdm0 = (sdm>>0)&0xff; + static int last_sdm_0 = -1; + static int last_sdm_1 = -1; + static int last_sdm_2 = -1; + + if( sdm2 != last_sdm_2 ) + regi2c_write_reg_raw_local(I2C_APLL, I2C_APLL_HOSTID, I2C_APLL_DSDM2, sdm2); + if( sdm0 != last_sdm_0 ) + regi2c_write_reg_raw_local(I2C_APLL, I2C_APLL_HOSTID, I2C_APLL_DSDM0, sdm0); + if( sdm1 != last_sdm_1 ) + regi2c_write_reg_raw_local(I2C_APLL, I2C_APLL_HOSTID, I2C_APLL_DSDM1, sdm1); + + last_sdm_2 = sdm2; + last_sdm_1 = sdm1; + last_sdm_0 = sdm0; +} + + + +void sandbox_main() +{ + printf( "sandbox_main()\n" ); + + + + DPORT_SET_PERI_REG_MASK( DPORT_CPU_PERI_CLK_EN_REG, DPORT_CLK_EN_DEDICATED_GPIO ); + DPORT_CLEAR_PERI_REG_MASK( DPORT_CPU_PERI_RST_EN_REG, DPORT_RST_EN_DEDICATED_GPIO); + + // Setup GPIO39 to be the PRO ALONE output (For LEDs) + REG_WRITE( GPIO_OUT1_W1TC_REG, 1<<(39-32) ); + REG_WRITE( GPIO_ENABLE1_W1TS_REG, 1<<(39-32) ); + REG_WRITE( IO_MUX_GPIO39_REG, 2<> 20); + dither = (((iterct)&0xffff) +#include "sdkconfig.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "esp_system.h" +#include "spi_flash_mmap.h" +#include "esp_efuse.h" +#include "esp_efuse_table.h" // or "esp_efuse_custom_table.h" +#include "esp_task_wdt.h" +#include "esp_log.h" +#include "soc/dedic_gpio_reg.h" +#include "driver/gpio.h" +#include "soc/soc.h" +#include "soc/system_reg.h" +#include "soc/usb_reg.h" +#include "ulp_riscv.h" +#include "driver/rtc_io.h" +#include "driver/gpio.h" +#include "rom/gpio.h" +#include "soc/rtc.h" + +#define SOC_DPORT_USB_BASE 0x60080000 + +struct SandboxStruct +{ + void (*fnIdle)(); +}; + + +struct SandboxStruct * g_SandboxStruct; + + +void esp_sleep_enable_timer_wakeup(); + +volatile void * keep_symbols[] = { 0, vTaskDelay, ulp_riscv_halt, + ulp_riscv_timer_resume, ulp_riscv_timer_stop, ulp_riscv_load_binary, + ulp_riscv_run, ulp_riscv_config_and_run, esp_sleep_enable_timer_wakeup, + ulp_set_wakeup_period, rtc_gpio_init, rtc_gpio_set_direction, + rtc_gpio_set_level, gpio_config, gpio_matrix_out, gpio_matrix_in, + rtc_clk_cpu_freq_get_config, rtc_clk_cpu_freq_set_config_fast, + rtc_clk_apb_freq_get }; + +extern struct SandboxStruct sandbox_mode; + +void app_main(void) +{ + printf("Hello world! Keep table at %p\n", &keep_symbols ); + + g_SandboxStruct = &sandbox_mode; + + // esp_efuse_set_rom_log_scheme(ESP_EFUSE_ROM_LOG_ALWAYS_OFF); + esp_efuse_set_rom_log_scheme(ESP_EFUSE_ROM_LOG_ALWAYS_ON); + + printf("Minimum free heap size: %d bytes\n", (int)esp_get_minimum_free_heap_size()); + + void sandbox_main(); + + sandbox_main(); + + do + { + if( g_SandboxStruct && g_SandboxStruct->fnIdle ) { g_SandboxStruct->fnIdle(); } + esp_task_wdt_reset(); + taskYIELD(); + } while( 1 ); + +// printf("Restarting now.\n"); +// fflush(stdout); +// esp_restart(); +} diff --git a/esp32s2/narrow_fsk_test/partitions.csv b/esp32s2/narrow_fsk_test/partitions.csv new file mode 100644 index 0000000..209e1e3 --- /dev/null +++ b/esp32s2/narrow_fsk_test/partitions.csv @@ -0,0 +1,7 @@ +# Name, Type, SubType, Offset, Size, Flags +# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap +# Note: if you change the size of the nvs partition, make sure to update NVS_PARTITION_SIZE in `components/hdw-nvs/nvs_manager.h` +nvs, data, nvs, 0x9000, 0x6000, +phy_init, data, phy, 0xf000, 0x1000, +factory, app, factory, 0x10000, 1M, +storage, data, spiffs, , 0xF0000, diff --git a/esp32s2/narrow_fsk_test/sdkconfig b/esp32s2/narrow_fsk_test/sdkconfig new file mode 100644 index 0000000..2645b80 --- /dev/null +++ b/esp32s2/narrow_fsk_test/sdkconfig @@ -0,0 +1,1810 @@ +# +# Automatically generated file. DO NOT EDIT. +# Espressif IoT Development Framework (ESP-IDF) 5.1.1 Project Configuration +# +CONFIG_SOC_ADC_SUPPORTED=y +CONFIG_SOC_DAC_SUPPORTED=y +CONFIG_SOC_UART_SUPPORTED=y +CONFIG_SOC_TWAI_SUPPORTED=y +CONFIG_SOC_CP_DMA_SUPPORTED=y +CONFIG_SOC_DEDICATED_GPIO_SUPPORTED=y +CONFIG_SOC_GPTIMER_SUPPORTED=y +CONFIG_SOC_SUPPORTS_SECURE_DL_MODE=y +CONFIG_SOC_ULP_FSM_SUPPORTED=y +CONFIG_SOC_RISCV_COPROC_SUPPORTED=y +CONFIG_SOC_USB_OTG_SUPPORTED=y +CONFIG_SOC_PCNT_SUPPORTED=y +CONFIG_SOC_WIFI_SUPPORTED=y +CONFIG_SOC_ULP_SUPPORTED=y +CONFIG_SOC_CCOMP_TIMER_SUPPORTED=y +CONFIG_SOC_ASYNC_MEMCPY_SUPPORTED=y +CONFIG_SOC_EFUSE_KEY_PURPOSE_FIELD=y +CONFIG_SOC_TEMP_SENSOR_SUPPORTED=y +CONFIG_SOC_CACHE_SUPPORT_WRAP=y +CONFIG_SOC_RTC_FAST_MEM_SUPPORTED=y +CONFIG_SOC_RTC_SLOW_MEM_SUPPORTED=y +CONFIG_SOC_RTC_MEM_SUPPORTED=y +CONFIG_SOC_PSRAM_DMA_CAPABLE=y +CONFIG_SOC_XT_WDT_SUPPORTED=y +CONFIG_SOC_I2S_SUPPORTED=y +CONFIG_SOC_RMT_SUPPORTED=y +CONFIG_SOC_SDM_SUPPORTED=y +CONFIG_SOC_GPSPI_SUPPORTED=y +CONFIG_SOC_LEDC_SUPPORTED=y +CONFIG_SOC_I2C_SUPPORTED=y +CONFIG_SOC_SYSTIMER_SUPPORTED=y +CONFIG_SOC_AES_SUPPORTED=y +CONFIG_SOC_MPI_SUPPORTED=y +CONFIG_SOC_SHA_SUPPORTED=y +CONFIG_SOC_HMAC_SUPPORTED=y +CONFIG_SOC_DIG_SIGN_SUPPORTED=y +CONFIG_SOC_FLASH_ENC_SUPPORTED=y +CONFIG_SOC_SECURE_BOOT_SUPPORTED=y +CONFIG_SOC_MEMPROT_SUPPORTED=y +CONFIG_SOC_TOUCH_SENSOR_SUPPORTED=y +CONFIG_SOC_BOD_SUPPORTED=y +CONFIG_SOC_XTAL_SUPPORT_40M=y +CONFIG_SOC_ADC_RTC_CTRL_SUPPORTED=y +CONFIG_SOC_ADC_DIG_CTRL_SUPPORTED=y +CONFIG_SOC_ADC_ARBITER_SUPPORTED=y +CONFIG_SOC_ADC_DIG_IIR_FILTER_SUPPORTED=y +CONFIG_SOC_ADC_DIG_IIR_FILTER_UNIT_BINDED=y +CONFIG_SOC_ADC_MONITOR_SUPPORTED=y +CONFIG_SOC_ADC_DMA_SUPPORTED=y +CONFIG_SOC_ADC_PERIPH_NUM=2 +CONFIG_SOC_ADC_MAX_CHANNEL_NUM=10 +CONFIG_SOC_ADC_ATTEN_NUM=4 +CONFIG_SOC_ADC_DIGI_CONTROLLER_NUM=2 +CONFIG_SOC_ADC_PATT_LEN_MAX=32 +CONFIG_SOC_ADC_DIGI_MIN_BITWIDTH=12 +CONFIG_SOC_ADC_DIGI_MAX_BITWIDTH=12 +CONFIG_SOC_ADC_DIGI_IIR_FILTER_NUM=2 +CONFIG_SOC_ADC_DIGI_RESULT_BYTES=2 +CONFIG_SOC_ADC_DIGI_DATA_BYTES_PER_CONV=2 +CONFIG_SOC_ADC_SAMPLE_FREQ_THRES_HIGH=83333 +CONFIG_SOC_ADC_SAMPLE_FREQ_THRES_LOW=611 +CONFIG_SOC_ADC_RTC_MIN_BITWIDTH=13 +CONFIG_SOC_ADC_RTC_MAX_BITWIDTH=13 +CONFIG_SOC_ADC_CALIBRATION_V1_SUPPORTED=y +CONFIG_SOC_ADC_SELF_HW_CALI_SUPPORTED=y +CONFIG_SOC_BROWNOUT_RESET_SUPPORTED=y +CONFIG_SOC_CACHE_WRITEBACK_SUPPORTED=y +CONFIG_SOC_CP_DMA_MAX_BUFFER_SIZE=4095 +CONFIG_SOC_CPU_CORES_NUM=1 +CONFIG_SOC_CPU_INTR_NUM=32 +CONFIG_SOC_CPU_BREAKPOINTS_NUM=2 +CONFIG_SOC_CPU_WATCHPOINTS_NUM=2 +CONFIG_SOC_CPU_WATCHPOINT_SIZE=64 +CONFIG_SOC_DAC_CHAN_NUM=2 +CONFIG_SOC_DAC_RESOLUTION=8 +CONFIG_SOC_GPIO_PORT=1 +CONFIG_SOC_GPIO_PIN_COUNT=47 +CONFIG_SOC_GPIO_SUPPORT_PIN_GLITCH_FILTER=y +CONFIG_SOC_GPIO_FILTER_CLK_SUPPORT_APB=y +CONFIG_SOC_GPIO_SUPPORT_RTC_INDEPENDENT=y +CONFIG_SOC_GPIO_SUPPORT_FORCE_HOLD=y +CONFIG_SOC_GPIO_VALID_GPIO_MASK=0x7FFFFFFFFFFF +CONFIG_SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK=0x00007FFFFC000000 +CONFIG_SOC_DEDIC_GPIO_OUT_CHANNELS_NUM=8 +CONFIG_SOC_DEDIC_GPIO_IN_CHANNELS_NUM=8 +CONFIG_SOC_DEDIC_GPIO_ALLOW_REG_ACCESS=y +CONFIG_SOC_DEDIC_GPIO_HAS_INTERRUPT=y +CONFIG_SOC_DEDIC_GPIO_OUT_AUTO_ENABLE=y +CONFIG_SOC_I2C_NUM=2 +CONFIG_SOC_I2C_FIFO_LEN=32 +CONFIG_SOC_I2C_CMD_REG_NUM=16 +CONFIG_SOC_I2C_SUPPORT_SLAVE=y +CONFIG_SOC_I2C_SUPPORT_HW_CLR_BUS=y +CONFIG_SOC_I2C_SUPPORT_REF_TICK=y +CONFIG_SOC_I2C_SUPPORT_APB=y +CONFIG_SOC_I2S_NUM=1 +CONFIG_SOC_I2S_HW_VERSION_1=y +CONFIG_SOC_I2S_SUPPORTS_APLL=y +CONFIG_SOC_I2S_SUPPORTS_PLL_F160M=y +CONFIG_SOC_I2S_SUPPORTS_DMA_EQUAL=y +CONFIG_SOC_I2S_SUPPORTS_LCD_CAMERA=y +CONFIG_SOC_I2S_APLL_MIN_FREQ=250000000 +CONFIG_SOC_I2S_APLL_MAX_FREQ=500000000 +CONFIG_SOC_I2S_APLL_MIN_RATE=10675 +CONFIG_SOC_I2S_LCD_I80_VARIANT=y +CONFIG_SOC_LCD_I80_SUPPORTED=y +CONFIG_SOC_LCD_I80_BUSES=1 +CONFIG_SOC_LCD_I80_BUS_WIDTH=24 +CONFIG_SOC_LEDC_HAS_TIMER_SPECIFIC_MUX=y +CONFIG_SOC_LEDC_SUPPORT_APB_CLOCK=y +CONFIG_SOC_LEDC_SUPPORT_REF_TICK=y +CONFIG_SOC_LEDC_SUPPORT_XTAL_CLOCK=y +CONFIG_SOC_LEDC_CHANNEL_NUM=8 +CONFIG_SOC_LEDC_TIMER_BIT_WIDTH=14 +CONFIG_SOC_LEDC_SUPPORT_FADE_STOP=y +CONFIG_SOC_MMU_LINEAR_ADDRESS_REGION_NUM=5 +CONFIG_SOC_MMU_PERIPH_NUM=1 +CONFIG_SOC_MPU_MIN_REGION_SIZE=0x20000000 +CONFIG_SOC_MPU_REGIONS_MAX_NUM=8 +CONFIG_SOC_PCNT_GROUPS=1 +CONFIG_SOC_PCNT_UNITS_PER_GROUP=4 +CONFIG_SOC_PCNT_CHANNELS_PER_UNIT=2 +CONFIG_SOC_PCNT_THRES_POINT_PER_UNIT=2 +CONFIG_SOC_RMT_GROUPS=1 +CONFIG_SOC_RMT_TX_CANDIDATES_PER_GROUP=4 +CONFIG_SOC_RMT_RX_CANDIDATES_PER_GROUP=4 +CONFIG_SOC_RMT_CHANNELS_PER_GROUP=4 +CONFIG_SOC_RMT_MEM_WORDS_PER_CHANNEL=64 +CONFIG_SOC_RMT_SUPPORT_RX_DEMODULATION=y +CONFIG_SOC_RMT_SUPPORT_TX_ASYNC_STOP=y +CONFIG_SOC_RMT_SUPPORT_TX_LOOP_COUNT=y +CONFIG_SOC_RMT_SUPPORT_TX_SYNCHRO=y +CONFIG_SOC_RMT_SUPPORT_TX_CARRIER_DATA_ONLY=y +CONFIG_SOC_RMT_SUPPORT_REF_TICK=y +CONFIG_SOC_RMT_SUPPORT_APB=y +CONFIG_SOC_RMT_CHANNEL_CLK_INDEPENDENT=y +CONFIG_SOC_RTCIO_PIN_COUNT=22 +CONFIG_SOC_RTCIO_INPUT_OUTPUT_SUPPORTED=y +CONFIG_SOC_RTCIO_HOLD_SUPPORTED=y +CONFIG_SOC_RTCIO_WAKE_SUPPORTED=y +CONFIG_SOC_SDM_GROUPS=1 +CONFIG_SOC_SDM_CHANNELS_PER_GROUP=8 +CONFIG_SOC_SDM_CLK_SUPPORT_APB=y +CONFIG_SOC_SPI_HD_BOTH_INOUT_SUPPORTED=y +CONFIG_SOC_SPI_PERIPH_NUM=3 +CONFIG_SOC_SPI_DMA_CHAN_NUM=3 +CONFIG_SOC_SPI_MAX_CS_NUM=6 +CONFIG_SOC_SPI_MAXIMUM_BUFFER_SIZE=72 +CONFIG_SOC_SPI_MAX_PRE_DIVIDER=8192 +CONFIG_SOC_SPI_SUPPORT_DDRCLK=y +CONFIG_SOC_SPI_SLAVE_SUPPORT_SEG_TRANS=y +CONFIG_SOC_SPI_SUPPORT_CD_SIG=y +CONFIG_SOC_SPI_SUPPORT_CONTINUOUS_TRANS=y +CONFIG_SOC_SPI_SUPPORT_CLK_APB=y +CONFIG_SOC_SPI_SUPPORT_SLAVE_HD_VER2=y +CONFIG_SOC_SPI_PERIPH_SUPPORT_CONTROL_DUMMY_OUT=y +CONFIG_SOC_MEMSPI_IS_INDEPENDENT=y +CONFIG_SOC_SPI_SUPPORT_OCT=y +CONFIG_SOC_MEMSPI_SRC_FREQ_80M_SUPPORTED=y +CONFIG_SOC_MEMSPI_SRC_FREQ_40M_SUPPORTED=y +CONFIG_SOC_MEMSPI_SRC_FREQ_26M_SUPPORTED=y +CONFIG_SOC_MEMSPI_SRC_FREQ_20M_SUPPORTED=y +CONFIG_SOC_SYSTIMER_COUNTER_NUM=y +CONFIG_SOC_SYSTIMER_ALARM_NUM=3 +CONFIG_SOC_SYSTIMER_BIT_WIDTH_LO=32 +CONFIG_SOC_SYSTIMER_BIT_WIDTH_HI=32 +CONFIG_SOC_TIMER_GROUPS=2 +CONFIG_SOC_TIMER_GROUP_TIMERS_PER_GROUP=2 +CONFIG_SOC_TIMER_GROUP_COUNTER_BIT_WIDTH=64 +CONFIG_SOC_TIMER_GROUP_SUPPORT_XTAL=y +CONFIG_SOC_TIMER_GROUP_SUPPORT_APB=y +CONFIG_SOC_TIMER_GROUP_TOTAL_TIMERS=4 +CONFIG_SOC_TOUCH_VERSION_2=y +CONFIG_SOC_TOUCH_SENSOR_NUM=15 +CONFIG_SOC_TOUCH_PROXIMITY_CHANNEL_NUM=3 +CONFIG_SOC_TOUCH_PAD_THRESHOLD_MAX=0x1FFFFF +CONFIG_SOC_TOUCH_PAD_MEASURE_WAIT_MAX=0xFF +CONFIG_SOC_TWAI_CONTROLLER_NUM=1 +CONFIG_SOC_TWAI_CLK_SUPPORT_APB=y +CONFIG_SOC_TWAI_BRP_MIN=2 +CONFIG_SOC_TWAI_BRP_MAX=32768 +CONFIG_SOC_TWAI_SUPPORTS_RX_STATUS=y +CONFIG_SOC_UART_NUM=2 +CONFIG_SOC_UART_SUPPORT_WAKEUP_INT=y +CONFIG_SOC_UART_SUPPORT_APB_CLK=y +CONFIG_SOC_UART_SUPPORT_REF_TICK=y +CONFIG_SOC_UART_FIFO_LEN=128 +CONFIG_SOC_UART_BITRATE_MAX=5000000 +CONFIG_SOC_SPIRAM_SUPPORTED=y +CONFIG_SOC_SPIRAM_XIP_SUPPORTED=y +CONFIG_SOC_USB_PERIPH_NUM=y +CONFIG_SOC_SHA_DMA_MAX_BUFFER_SIZE=3968 +CONFIG_SOC_SHA_SUPPORT_DMA=y +CONFIG_SOC_SHA_SUPPORT_RESUME=y +CONFIG_SOC_SHA_CRYPTO_DMA=y +CONFIG_SOC_SHA_SUPPORT_SHA1=y +CONFIG_SOC_SHA_SUPPORT_SHA224=y +CONFIG_SOC_SHA_SUPPORT_SHA256=y +CONFIG_SOC_SHA_SUPPORT_SHA384=y +CONFIG_SOC_SHA_SUPPORT_SHA512=y +CONFIG_SOC_SHA_SUPPORT_SHA512_224=y +CONFIG_SOC_SHA_SUPPORT_SHA512_256=y +CONFIG_SOC_SHA_SUPPORT_SHA512_T=y +CONFIG_SOC_RSA_MAX_BIT_LEN=4096 +CONFIG_SOC_AES_SUPPORT_DMA=y +CONFIG_SOC_AES_SUPPORT_GCM=y +CONFIG_SOC_EFUSE_DIS_DOWNLOAD_ICACHE=y +CONFIG_SOC_EFUSE_DIS_DOWNLOAD_DCACHE=y +CONFIG_SOC_EFUSE_HARD_DIS_JTAG=y +CONFIG_SOC_EFUSE_SOFT_DIS_JTAG=y +CONFIG_SOC_EFUSE_DIS_BOOT_REMAP=y +CONFIG_SOC_EFUSE_DIS_LEGACY_SPI_BOOT=y +CONFIG_SOC_EFUSE_DIS_ICACHE=y +CONFIG_SOC_SECURE_BOOT_V2_RSA=y +CONFIG_SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS=3 +CONFIG_SOC_EFUSE_REVOKE_BOOT_KEY_DIGESTS=y +CONFIG_SOC_SUPPORT_SECURE_BOOT_REVOKE_KEY=y +CONFIG_SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX=64 +CONFIG_SOC_FLASH_ENCRYPTION_XTS_AES=y +CONFIG_SOC_FLASH_ENCRYPTION_XTS_AES_OPTIONS=y +CONFIG_SOC_FLASH_ENCRYPTION_XTS_AES_128=y +CONFIG_SOC_FLASH_ENCRYPTION_XTS_AES_256=y +CONFIG_SOC_MEMPROT_CPU_PREFETCH_PAD_SIZE=16 +CONFIG_SOC_MEMPROT_MEM_ALIGN_SIZE=4 +CONFIG_SOC_AES_CRYPTO_DMA=y +CONFIG_SOC_AES_SUPPORT_AES_128=y +CONFIG_SOC_AES_SUPPORT_AES_192=y +CONFIG_SOC_AES_SUPPORT_AES_256=y +CONFIG_SOC_PHY_DIG_REGS_MEM_SIZE=21 +CONFIG_SOC_WIFI_LIGHT_SLEEP_CLK_WIDTH=12 +CONFIG_SOC_SPI_MEM_SUPPORT_AUTO_WAIT_IDLE=y +CONFIG_SOC_SPI_MEM_SUPPORT_AUTO_SUSPEND=y +CONFIG_SOC_SPI_MEM_SUPPORT_SW_SUSPEND=y +CONFIG_SOC_SPI_MEM_SUPPORT_CONFIG_GPIO_BY_EFUSE=y +CONFIG_SOC_SPI_MEM_SUPPORT_WRAP=y +CONFIG_SOC_PM_SUPPORT_EXT0_WAKEUP=y +CONFIG_SOC_PM_SUPPORT_EXT1_WAKEUP=y +CONFIG_SOC_PM_SUPPORT_EXT_WAKEUP=y +CONFIG_SOC_PM_SUPPORT_WIFI_WAKEUP=y +CONFIG_SOC_PM_SUPPORT_TOUCH_SENSOR_WAKEUP=y +CONFIG_SOC_PM_SUPPORT_WIFI_PD=y +CONFIG_SOC_PM_SUPPORT_RTC_PERIPH_PD=y +CONFIG_SOC_PM_SUPPORT_RTC_FAST_MEM_PD=y +CONFIG_SOC_PM_SUPPORT_RTC_SLOW_MEM_PD=y +CONFIG_SOC_PM_SUPPORT_RC_FAST_PD=y +CONFIG_SOC_PM_SUPPORT_VDDSDIO_PD=y +CONFIG_SOC_CONFIGURABLE_VDDSDIO_SUPPORTED=y +CONFIG_SOC_CLK_APLL_SUPPORTED=y +CONFIG_SOC_APLL_MULTIPLIER_OUT_MIN_HZ=350000000 +CONFIG_SOC_APLL_MULTIPLIER_OUT_MAX_HZ=500000000 +CONFIG_SOC_APLL_MIN_HZ=5303031 +CONFIG_SOC_APLL_MAX_HZ=125000000 +CONFIG_SOC_CLK_RC_FAST_D256_SUPPORTED=y +CONFIG_SOC_RTC_SLOW_CLK_SUPPORT_RC_FAST_D256=y +CONFIG_SOC_CLK_RC_FAST_SUPPORT_CALIBRATION=y +CONFIG_SOC_CLK_XTAL32K_SUPPORTED=y +CONFIG_SOC_COEX_HW_PTI=y +CONFIG_SOC_EXTERNAL_COEX_LEADER_TX_LINE=y +CONFIG_SOC_TEMPERATURE_SENSOR_SUPPORT_FAST_RC=y +CONFIG_SOC_WIFI_HW_TSF=y +CONFIG_SOC_WIFI_FTM_SUPPORT=y +CONFIG_SOC_WIFI_WAPI_SUPPORT=y +CONFIG_SOC_WIFI_CSI_SUPPORT=y +CONFIG_SOC_WIFI_MESH_SUPPORT=y +CONFIG_SOC_WIFI_SUPPORT_VARIABLE_BEACON_WINDOW=y +CONFIG_SOC_WIFI_NAN_SUPPORT=y +CONFIG_SOC_ULP_HAS_ADC=y +CONFIG_IDF_CMAKE=y +CONFIG_IDF_TARGET_ARCH_XTENSA=y +CONFIG_IDF_TARGET_ARCH="xtensa" +CONFIG_IDF_TARGET="esp32s2" +CONFIG_IDF_TARGET_ESP32S2=y +CONFIG_IDF_FIRMWARE_CHIP_ID=0x0002 + +# +# Build type +# +CONFIG_APP_BUILD_TYPE_APP_2NDBOOT=y +# CONFIG_APP_BUILD_TYPE_RAM is not set +CONFIG_APP_BUILD_GENERATE_BINARIES=y +CONFIG_APP_BUILD_BOOTLOADER=y +CONFIG_APP_BUILD_USE_FLASH_SECTIONS=y +# CONFIG_APP_REPRODUCIBLE_BUILD is not set +# CONFIG_APP_NO_BLOBS is not set +# end of Build type + +# +# Bootloader config +# +CONFIG_BOOTLOADER_OFFSET_IN_FLASH=0x1000 +CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y +# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_DEBUG is not set +# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_PERF is not set +# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_NONE is not set +CONFIG_BOOTLOADER_LOG_LEVEL_NONE=y +# CONFIG_BOOTLOADER_LOG_LEVEL_ERROR is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_WARN is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_INFO is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_DEBUG is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_VERBOSE is not set +CONFIG_BOOTLOADER_LOG_LEVEL=0 +CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V=y +# CONFIG_BOOTLOADER_FACTORY_RESET is not set +# CONFIG_BOOTLOADER_APP_TEST is not set +CONFIG_BOOTLOADER_REGION_PROTECTION_ENABLE=y +# CONFIG_BOOTLOADER_WDT_ENABLE is not set +# CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE is not set +# CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP is not set +# CONFIG_BOOTLOADER_SKIP_VALIDATE_ON_POWER_ON is not set +# CONFIG_BOOTLOADER_SKIP_VALIDATE_ALWAYS is not set +CONFIG_BOOTLOADER_RESERVE_RTC_SIZE=0 +# CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC is not set +CONFIG_BOOTLOADER_FLASH_XMC_SUPPORT=y +# end of Bootloader config + +# +# Security features +# +CONFIG_SECURE_BOOT_V2_RSA_SUPPORTED=y +CONFIG_SECURE_BOOT_V2_PREFERRED=y +# CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT is not set +# CONFIG_SECURE_BOOT is not set +# CONFIG_SECURE_FLASH_ENC_ENABLED is not set +CONFIG_SECURE_ROM_DL_MODE_ENABLED=y +# end of Security features + +# +# Application manager +# +CONFIG_APP_COMPILE_TIME_DATE=y +# CONFIG_APP_EXCLUDE_PROJECT_VER_VAR is not set +# CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR is not set +# CONFIG_APP_PROJECT_VER_FROM_CONFIG is not set +CONFIG_APP_RETRIEVE_LEN_ELF_SHA=16 +# end of Application manager + +CONFIG_ESP_ROM_HAS_CRC_LE=y +CONFIG_ESP_ROM_HAS_MZ_CRC32=y +CONFIG_ESP_ROM_HAS_UART_BUF_SWITCH=y +CONFIG_ESP_ROM_NEEDS_SWSETUP_WORKAROUND=y +CONFIG_ESP_ROM_HAS_REGI2C_BUG=y +CONFIG_ESP_ROM_HAS_NEWLIB_NANO_FORMAT=y +CONFIG_ESP_ROM_HAS_FLASH_COUNT_PAGES_BUG=y + +# +# Boot ROM Behavior +# +CONFIG_BOOT_ROM_LOG_ALWAYS_ON=y +# CONFIG_BOOT_ROM_LOG_ALWAYS_OFF is not set +# CONFIG_BOOT_ROM_LOG_ON_GPIO_HIGH is not set +# CONFIG_BOOT_ROM_LOG_ON_GPIO_LOW is not set +# end of Boot ROM Behavior + +# +# Serial flasher config +# +# CONFIG_ESPTOOLPY_NO_STUB is not set +# CONFIG_ESPTOOLPY_FLASHMODE_QIO is not set +# CONFIG_ESPTOOLPY_FLASHMODE_QOUT is not set +CONFIG_ESPTOOLPY_FLASHMODE_DIO=y +# CONFIG_ESPTOOLPY_FLASHMODE_DOUT is not set +CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_STR=y +CONFIG_ESPTOOLPY_FLASHMODE="dio" +CONFIG_ESPTOOLPY_FLASHFREQ_80M=y +# CONFIG_ESPTOOLPY_FLASHFREQ_40M is not set +# CONFIG_ESPTOOLPY_FLASHFREQ_26M is not set +# CONFIG_ESPTOOLPY_FLASHFREQ_20M is not set +CONFIG_ESPTOOLPY_FLASHFREQ_80M_DEFAULT=y +CONFIG_ESPTOOLPY_FLASHFREQ="80m" +# CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_2MB is not set +CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y +# CONFIG_ESPTOOLPY_FLASHSIZE_8MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_32MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_64MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_128MB is not set +CONFIG_ESPTOOLPY_FLASHSIZE="4MB" +# CONFIG_ESPTOOLPY_HEADER_FLASHSIZE_UPDATE is not set +# CONFIG_ESPTOOLPY_BEFORE_RESET is not set +CONFIG_ESPTOOLPY_BEFORE_NORESET=y +CONFIG_ESPTOOLPY_BEFORE="no_reset" +# CONFIG_ESPTOOLPY_AFTER_RESET is not set +CONFIG_ESPTOOLPY_AFTER_NORESET=y +CONFIG_ESPTOOLPY_AFTER="no_reset" +CONFIG_ESPTOOLPY_MONITOR_BAUD=115200 +# end of Serial flasher config + +# +# Partition Table +# +# CONFIG_PARTITION_TABLE_SINGLE_APP is not set +# CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE is not set +# CONFIG_PARTITION_TABLE_TWO_OTA is not set +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" +CONFIG_PARTITION_TABLE_FILENAME="partitions.csv" +CONFIG_PARTITION_TABLE_OFFSET=0x8000 +CONFIG_PARTITION_TABLE_MD5=y +# end of Partition Table + +# +# Compiler options +# +# CONFIG_COMPILER_OPTIMIZATION_DEFAULT is not set +# CONFIG_COMPILER_OPTIMIZATION_SIZE is not set +CONFIG_COMPILER_OPTIMIZATION_PERF=y +# CONFIG_COMPILER_OPTIMIZATION_NONE is not set +CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y +# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT is not set +# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE is not set +CONFIG_COMPILER_FLOAT_LIB_FROM_GCCLIB=y +CONFIG_COMPILER_OPTIMIZATION_ASSERTION_LEVEL=2 +# CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT is not set +CONFIG_COMPILER_HIDE_PATHS_MACROS=y +# CONFIG_COMPILER_CXX_EXCEPTIONS is not set +# CONFIG_COMPILER_CXX_RTTI is not set +CONFIG_COMPILER_STACK_CHECK_MODE_NONE=y +# CONFIG_COMPILER_STACK_CHECK_MODE_NORM is not set +# CONFIG_COMPILER_STACK_CHECK_MODE_STRONG is not set +# CONFIG_COMPILER_STACK_CHECK_MODE_ALL is not set +# CONFIG_COMPILER_WARN_WRITE_STRINGS is not set +# CONFIG_COMPILER_DISABLE_GCC12_WARNINGS is not set +# CONFIG_COMPILER_DUMP_RTL_FILES is not set +# end of Compiler options + +# +# Component config +# + +# +# Application Level Tracing +# +# CONFIG_APPTRACE_DEST_JTAG is not set +CONFIG_APPTRACE_DEST_NONE=y +# CONFIG_APPTRACE_DEST_UART1 is not set +CONFIG_APPTRACE_DEST_UART_NONE=y +CONFIG_APPTRACE_UART_TASK_PRIO=1 +CONFIG_APPTRACE_LOCK_ENABLE=y +# end of Application Level Tracing + +# +# Driver Configurations +# + +# +# Legacy ADC Configuration +# +CONFIG_ADC_DISABLE_DAC=y +# CONFIG_ADC_SUPPRESS_DEPRECATE_WARN is not set + +# +# Legacy ADC Calibration Configuration +# +# CONFIG_ADC_CALI_SUPPRESS_DEPRECATE_WARN is not set +# end of Legacy ADC Calibration Configuration +# end of Legacy ADC Configuration + +# +# SPI Configuration +# +# CONFIG_SPI_MASTER_IN_IRAM is not set +CONFIG_SPI_MASTER_ISR_IN_IRAM=y +# CONFIG_SPI_SLAVE_IN_IRAM is not set +CONFIG_SPI_SLAVE_ISR_IN_IRAM=y +# end of SPI Configuration + +# +# TWAI Configuration +# +# CONFIG_TWAI_ISR_IN_IRAM is not set +CONFIG_TWAI_ERRATA_FIX_LISTEN_ONLY_DOM=y +# end of TWAI Configuration + +# +# Temperature sensor Configuration +# +# CONFIG_TEMP_SENSOR_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_TEMP_SENSOR_ENABLE_DEBUG_LOG is not set +# end of Temperature sensor Configuration + +# +# UART Configuration +# +# CONFIG_UART_ISR_IN_IRAM is not set +# end of UART Configuration + +# +# GPIO Configuration +# +# CONFIG_GPIO_CTRL_FUNC_IN_IRAM is not set +# end of GPIO Configuration + +# +# Sigma Delta Modulator Configuration +# +# CONFIG_SDM_CTRL_FUNC_IN_IRAM is not set +# CONFIG_SDM_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_SDM_ENABLE_DEBUG_LOG is not set +# end of Sigma Delta Modulator Configuration + +# +# GPTimer Configuration +# +# CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM is not set +# CONFIG_GPTIMER_ISR_IRAM_SAFE is not set +# CONFIG_GPTIMER_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_GPTIMER_ENABLE_DEBUG_LOG is not set +# end of GPTimer Configuration + +# +# PCNT Configuration +# +# CONFIG_PCNT_CTRL_FUNC_IN_IRAM is not set +# CONFIG_PCNT_ISR_IRAM_SAFE is not set +# CONFIG_PCNT_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_PCNT_ENABLE_DEBUG_LOG is not set +# end of PCNT Configuration + +# +# RMT Configuration +# +# CONFIG_RMT_ISR_IRAM_SAFE is not set +# CONFIG_RMT_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_RMT_ENABLE_DEBUG_LOG is not set +# end of RMT Configuration + +# +# I2S Configuration +# +# CONFIG_I2S_ISR_IRAM_SAFE is not set +# CONFIG_I2S_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_I2S_ENABLE_DEBUG_LOG is not set +# end of I2S Configuration + +# +# DAC Configuration +# +# CONFIG_DAC_CTRL_FUNC_IN_IRAM is not set +# CONFIG_DAC_ISR_IRAM_SAFE is not set +# CONFIG_DAC_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_DAC_ENABLE_DEBUG_LOG is not set +# end of DAC Configuration +# end of Driver Configurations + +# +# eFuse Bit Manager +# +# CONFIG_EFUSE_CUSTOM_TABLE is not set +# CONFIG_EFUSE_VIRTUAL is not set +CONFIG_EFUSE_MAX_BLK_LEN=256 +# end of eFuse Bit Manager + +# +# ESP-TLS +# +CONFIG_ESP_TLS_USING_MBEDTLS=y +CONFIG_ESP_TLS_USE_DS_PERIPHERAL=y +# CONFIG_ESP_TLS_CLIENT_SESSION_TICKETS is not set +# CONFIG_ESP_TLS_PSK_VERIFICATION is not set +# CONFIG_ESP_TLS_INSECURE is not set +# end of ESP-TLS + +# +# ADC and ADC Calibration +# +# CONFIG_ADC_ONESHOT_CTRL_FUNC_IN_IRAM is not set +# CONFIG_ADC_CONTINUOUS_ISR_IRAM_SAFE is not set +CONFIG_ADC_DISABLE_DAC_OUTPUT=y +# end of ADC and ADC Calibration + +# +# Wireless Coexistence +# +# CONFIG_ESP_COEX_EXTERNAL_COEXIST_ENABLE is not set +# end of Wireless Coexistence + +# +# Common ESP-related +# +CONFIG_ESP_ERR_TO_NAME_LOOKUP=y +# end of Common ESP-related + +# +# Ethernet +# +# CONFIG_ETH_USE_SPI_ETHERNET is not set +# CONFIG_ETH_USE_OPENETH is not set +# end of Ethernet + +# +# Event Loop Library +# +# CONFIG_ESP_EVENT_LOOP_PROFILING is not set +CONFIG_ESP_EVENT_POST_FROM_ISR=y +CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR=y +# end of Event Loop Library + +# +# GDB Stub +# +# end of GDB Stub + +# +# ESP HTTP client +# +# CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS is not set +# CONFIG_ESP_HTTP_CLIENT_ENABLE_BASIC_AUTH is not set +# CONFIG_ESP_HTTP_CLIENT_ENABLE_DIGEST_AUTH is not set +# end of ESP HTTP client + +# +# HTTP Server +# +CONFIG_HTTPD_MAX_REQ_HDR_LEN=512 +CONFIG_HTTPD_MAX_URI_LEN=512 +CONFIG_HTTPD_ERR_RESP_NO_DELAY=y +CONFIG_HTTPD_PURGE_BUF_LEN=32 +# CONFIG_HTTPD_LOG_PURGE_DATA is not set +# CONFIG_HTTPD_WS_SUPPORT is not set +# CONFIG_HTTPD_QUEUE_WORK_BLOCKING is not set +# end of HTTP Server + +# +# ESP HTTPS OTA +# +# CONFIG_ESP_HTTPS_OTA_DECRYPT_CB is not set +# CONFIG_ESP_HTTPS_OTA_ALLOW_HTTP is not set +# end of ESP HTTPS OTA + +# +# ESP HTTPS server +# +# end of ESP HTTPS server + +# +# Hardware Settings +# + +# +# Chip revision +# +CONFIG_ESP32S2_REV_MIN_0=y +# CONFIG_ESP32S2_REV_MIN_1 is not set +CONFIG_ESP32S2_REV_MIN_FULL=0 +CONFIG_ESP_REV_MIN_FULL=0 + +# +# Maximum Supported ESP32-S2 Revision (Rev v1.99) +# +CONFIG_ESP32S2_REV_MAX_FULL=199 +CONFIG_ESP_REV_MAX_FULL=199 +# end of Chip revision + +# +# MAC Config +# +CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_STA=y +CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_AP=y +CONFIG_ESP_MAC_UNIVERSAL_MAC_ADDRESSES_TWO=y +# CONFIG_ESP32S2_UNIVERSAL_MAC_ADDRESSES_ONE is not set +CONFIG_ESP32S2_UNIVERSAL_MAC_ADDRESSES_TWO=y +CONFIG_ESP32S2_UNIVERSAL_MAC_ADDRESSES=2 +# end of MAC Config + +# +# Sleep Config +# +# CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND is not set +# CONFIG_ESP_SLEEP_PSRAM_LEAKAGE_WORKAROUND is not set +CONFIG_ESP_SLEEP_RTC_BUS_ISO_WORKAROUND=y +# CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND is not set +# end of Sleep Config + +# +# RTC Clock Config +# +CONFIG_RTC_CLK_SRC_INT_RC=y +# CONFIG_RTC_CLK_SRC_EXT_CRYS is not set +# CONFIG_RTC_CLK_SRC_EXT_OSC is not set +# CONFIG_RTC_CLK_SRC_INT_8MD256 is not set +CONFIG_RTC_CLK_CAL_CYCLES=576 +# end of RTC Clock Config + +# +# Peripheral Control +# +CONFIG_PERIPH_CTRL_FUNC_IN_IRAM=y +# end of Peripheral Control + +# +# Main XTAL Config +# +CONFIG_XTAL_FREQ_40=y +CONFIG_XTAL_FREQ=40 +# end of Main XTAL Config +# end of Hardware Settings + +# +# LCD and Touch Panel +# + +# +# LCD Touch Drivers are maintained in the IDF Component Registry +# + +# +# LCD Peripheral Configuration +# +CONFIG_LCD_PANEL_IO_FORMAT_BUF_SIZE=32 +# CONFIG_LCD_ENABLE_DEBUG_LOG is not set +# end of LCD Peripheral Configuration +# end of LCD and Touch Panel + +# +# ESP NETIF Adapter +# +CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL=120 +CONFIG_ESP_NETIF_TCPIP_LWIP=y +# CONFIG_ESP_NETIF_LOOPBACK is not set +CONFIG_ESP_NETIF_USES_TCPIP_WITH_BSD_API=y +# CONFIG_ESP_NETIF_RECEIVE_REPORT_ERRORS is not set +# CONFIG_ESP_NETIF_L2_TAP is not set +# CONFIG_ESP_NETIF_BRIDGE_EN is not set +# end of ESP NETIF Adapter + +# +# Partition API Configuration +# +# end of Partition API Configuration + +# +# PHY +# +CONFIG_ESP_PHY_CALIBRATION_AND_DATA_STORAGE=y +# CONFIG_ESP_PHY_INIT_DATA_IN_PARTITION is not set +CONFIG_ESP_PHY_MAX_WIFI_TX_POWER=15 +CONFIG_ESP_PHY_MAX_TX_POWER=15 +CONFIG_ESP_PHY_REDUCE_TX_POWER=y +# CONFIG_ESP_PHY_ENABLE_USB is not set +CONFIG_ESP_PHY_RF_CAL_PARTIAL=y +# CONFIG_ESP_PHY_RF_CAL_NONE is not set +# CONFIG_ESP_PHY_RF_CAL_FULL is not set +CONFIG_ESP_PHY_CALIBRATION_MODE=0 +# end of PHY + +# +# Power Management +# +# CONFIG_PM_ENABLE is not set +# end of Power Management + +# +# ESP PSRAM +# +CONFIG_SPIRAM=y + +# +# SPI RAM config +# +CONFIG_SPIRAM_MODE_QUAD=y +CONFIG_SPIRAM_TYPE_AUTO=y +# CONFIG_SPIRAM_TYPE_ESPPSRAM16 is not set +# CONFIG_SPIRAM_TYPE_ESPPSRAM32 is not set +# CONFIG_SPIRAM_TYPE_ESPPSRAM64 is not set +CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY=y +CONFIG_SPIRAM_CLK_IO=30 +CONFIG_SPIRAM_CS_IO=26 +# CONFIG_SPIRAM_FETCH_INSTRUCTIONS is not set +# CONFIG_SPIRAM_RODATA is not set +CONFIG_SPIRAM_SPEED_80M=y +# CONFIG_SPIRAM_SPEED_40M is not set +# CONFIG_SPIRAM_SPEED_26M is not set +# CONFIG_SPIRAM_SPEED_20M is not set +CONFIG_SPIRAM_SPEED=80 +CONFIG_SPIRAM_BOOT_INIT=y +CONFIG_SPIRAM_IGNORE_NOTFOUND=y +# CONFIG_SPIRAM_USE_MEMMAP is not set +CONFIG_SPIRAM_USE_CAPS_ALLOC=y +# CONFIG_SPIRAM_USE_MALLOC is not set +CONFIG_SPIRAM_MEMTEST=y +CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP=y +# CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY is not set +# end of SPI RAM config +# end of ESP PSRAM + +# +# ESP Ringbuf +# +# CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH is not set +# end of ESP Ringbuf + +# +# ESP System Settings +# +# CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_80 is not set +# CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_160 is not set +CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y +CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ=240 + +# +# Cache config +# +CONFIG_ESP32S2_INSTRUCTION_CACHE_8KB=y +# CONFIG_ESP32S2_INSTRUCTION_CACHE_16KB is not set +# CONFIG_ESP32S2_INSTRUCTION_CACHE_LINE_16B is not set +CONFIG_ESP32S2_INSTRUCTION_CACHE_LINE_32B=y +CONFIG_ESP32S2_DATA_CACHE_8KB=y +# CONFIG_ESP32S2_DATA_CACHE_16KB is not set +# CONFIG_ESP32S2_DATA_CACHE_LINE_16B is not set +CONFIG_ESP32S2_DATA_CACHE_LINE_32B=y +# CONFIG_ESP32S2_INSTRUCTION_CACHE_WRAP is not set +# CONFIG_ESP32S2_DATA_CACHE_WRAP is not set +# end of Cache config + +# +# Memory +# +# CONFIG_ESP32S2_RTCDATA_IN_FAST_MEM is not set +# CONFIG_ESP32S2_USE_FIXED_STATIC_RAM_SIZE is not set +# end of Memory + +# +# Trace memory +# +# CONFIG_ESP32S2_TRAX is not set +CONFIG_ESP32S2_TRACEMEM_RESERVE_DRAM=0x0 +# end of Trace memory + +# CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT is not set +CONFIG_ESP_SYSTEM_PANIC_PRINT_REBOOT=y +# CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT is not set +# CONFIG_ESP_SYSTEM_PANIC_GDBSTUB is not set +# CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME is not set +CONFIG_ESP_SYSTEM_PANIC_REBOOT_DELAY_SECONDS=0 +CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE=y +CONFIG_ESP_SYSTEM_RTC_FAST_MEM_AS_HEAP_DEPCHECK=y +CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP=y + +# +# Memory protection +# +# CONFIG_ESP_SYSTEM_MEMPROT_FEATURE is not set +# end of Memory protection + +CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE=32 +CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=2304 +CONFIG_ESP_MAIN_TASK_STACK_SIZE=8192 +CONFIG_ESP_MAIN_TASK_AFFINITY_CPU0=y +# CONFIG_ESP_MAIN_TASK_AFFINITY_NO_AFFINITY is not set +CONFIG_ESP_MAIN_TASK_AFFINITY=0x0 +CONFIG_ESP_MINIMAL_SHARED_STACK_SIZE=2048 +CONFIG_ESP_CONSOLE_UART_DEFAULT=y +# CONFIG_ESP_CONSOLE_USB_CDC is not set +# CONFIG_ESP_CONSOLE_UART_CUSTOM is not set +# CONFIG_ESP_CONSOLE_NONE is not set +CONFIG_ESP_CONSOLE_UART=y +CONFIG_ESP_CONSOLE_MULTIPLE_UART=y +CONFIG_ESP_CONSOLE_UART_NUM=0 +CONFIG_ESP_CONSOLE_UART_BAUDRATE=115200 +CONFIG_ESP_INT_WDT=y +CONFIG_ESP_INT_WDT_TIMEOUT_MS=300 +CONFIG_ESP_TASK_WDT_EN=y +# CONFIG_ESP_TASK_WDT_INIT is not set +# CONFIG_ESP_PANIC_HANDLER_IRAM is not set +# CONFIG_ESP_DEBUG_STUBS_ENABLE is not set +CONFIG_ESP_DEBUG_OCDAWARE=y +CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_4=y + +# +# Brownout Detector +# +CONFIG_ESP_BROWNOUT_DET=y +CONFIG_ESP_BROWNOUT_DET_LVL_SEL_7=y +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_6 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_5 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_4 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_3 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_2 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_1 is not set +CONFIG_ESP_BROWNOUT_DET_LVL=7 +# end of Brownout Detector + +# CONFIG_ESP32S2_KEEP_USB_ALIVE is not set +CONFIG_ESP_SYSTEM_BROWNOUT_INTR=y +# end of ESP System Settings + +# +# IPC (Inter-Processor Call) +# +CONFIG_ESP_IPC_TASK_STACK_SIZE=1536 +# end of IPC (Inter-Processor Call) + +# +# High resolution timer (esp_timer) +# +# CONFIG_ESP_TIMER_PROFILING is not set +CONFIG_ESP_TIME_FUNCS_USE_RTC_TIMER=y +CONFIG_ESP_TIME_FUNCS_USE_ESP_TIMER=y +CONFIG_ESP_TIMER_TASK_STACK_SIZE=3584 +CONFIG_ESP_TIMER_INTERRUPT_LEVEL=1 +# CONFIG_ESP_TIMER_SHOW_EXPERIMENTAL is not set +CONFIG_ESP_TIMER_TASK_AFFINITY=0x0 +CONFIG_ESP_TIMER_TASK_AFFINITY_CPU0=y +CONFIG_ESP_TIMER_ISR_AFFINITY=0x1 +CONFIG_ESP_TIMER_ISR_AFFINITY_CPU0=y +# CONFIG_ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD is not set +CONFIG_ESP_TIMER_IMPL_SYSTIMER=y +# end of High resolution timer (esp_timer) + +# +# Wi-Fi +# +CONFIG_ESP_WIFI_ENABLED=y +CONFIG_ESP_WIFI_STATIC_RX_BUFFER_NUM=10 +CONFIG_ESP_WIFI_DYNAMIC_RX_BUFFER_NUM=32 +# CONFIG_ESP_WIFI_STATIC_TX_BUFFER is not set +CONFIG_ESP_WIFI_DYNAMIC_TX_BUFFER=y +CONFIG_ESP_WIFI_TX_BUFFER_TYPE=1 +CONFIG_ESP_WIFI_CACHE_TX_BUFFER_NUM=32 +CONFIG_ESP_WIFI_DYNAMIC_TX_BUFFER_NUM=32 +# CONFIG_ESP_WIFI_CSI_ENABLED is not set +# CONFIG_ESP_WIFI_AMPDU_TX_ENABLED is not set +# CONFIG_ESP_WIFI_AMPDU_RX_ENABLED is not set +# CONFIG_ESP_WIFI_AMSDU_TX_ENABLED is not set +CONFIG_ESP_WIFI_NVS_ENABLED=y +CONFIG_ESP_WIFI_SOFTAP_BEACON_MAX_LEN=752 +CONFIG_ESP_WIFI_MGMT_SBUF_NUM=32 +CONFIG_ESP_WIFI_IRAM_OPT=y +CONFIG_ESP_WIFI_RX_IRAM_OPT=y +CONFIG_ESP_WIFI_ENABLE_WPA3_SAE=y +CONFIG_ESP_WIFI_ENABLE_SAE_PK=y +CONFIG_ESP_WIFI_ENABLE_WPA3_OWE_STA=y +# CONFIG_ESP_WIFI_SLP_IRAM_OPT is not set +# CONFIG_ESP_WIFI_FTM_ENABLE is not set +# CONFIG_ESP_WIFI_STA_DISCONNECTED_PM_ENABLE is not set +# CONFIG_ESP_WIFI_GMAC_SUPPORT is not set +# CONFIG_ESP_WIFI_SOFTAP_SUPPORT is not set +# CONFIG_ESP_WIFI_SLP_BEACON_LOST_OPT is not set +CONFIG_ESP_WIFI_ESPNOW_MAX_ENCRYPT_NUM=7 +# CONFIG_ESP_WIFI_NAN_ENABLE is not set +CONFIG_ESP_WIFI_MBEDTLS_CRYPTO=y +CONFIG_ESP_WIFI_MBEDTLS_TLS_CLIENT=y +# CONFIG_ESP_WIFI_WAPI_PSK is not set +# CONFIG_ESP_WIFI_SUITE_B_192 is not set +# CONFIG_ESP_WIFI_11KV_SUPPORT is not set +# CONFIG_ESP_WIFI_MBO_SUPPORT is not set +# CONFIG_ESP_WIFI_DPP_SUPPORT is not set +# CONFIG_ESP_WIFI_11R_SUPPORT is not set + +# +# WPS Configuration Options +# +# CONFIG_ESP_WIFI_WPS_STRICT is not set +# CONFIG_ESP_WIFI_WPS_PASSPHRASE is not set +# end of WPS Configuration Options + +# CONFIG_ESP_WIFI_DEBUG_PRINT is not set +# CONFIG_ESP_WIFI_TESTING_OPTIONS is not set +# end of Wi-Fi + +# +# Core dump +# +# CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH is not set +# CONFIG_ESP_COREDUMP_ENABLE_TO_UART is not set +CONFIG_ESP_COREDUMP_ENABLE_TO_NONE=y +# end of Core dump + +# +# FAT Filesystem support +# +CONFIG_FATFS_VOLUME_COUNT=2 +CONFIG_FATFS_LFN_NONE=y +# CONFIG_FATFS_LFN_HEAP is not set +# CONFIG_FATFS_LFN_STACK is not set +# CONFIG_FATFS_SECTOR_512 is not set +CONFIG_FATFS_SECTOR_4096=y +# CONFIG_FATFS_CODEPAGE_DYNAMIC is not set +CONFIG_FATFS_CODEPAGE_437=y +# CONFIG_FATFS_CODEPAGE_720 is not set +# CONFIG_FATFS_CODEPAGE_737 is not set +# CONFIG_FATFS_CODEPAGE_771 is not set +# CONFIG_FATFS_CODEPAGE_775 is not set +# CONFIG_FATFS_CODEPAGE_850 is not set +# CONFIG_FATFS_CODEPAGE_852 is not set +# CONFIG_FATFS_CODEPAGE_855 is not set +# CONFIG_FATFS_CODEPAGE_857 is not set +# CONFIG_FATFS_CODEPAGE_860 is not set +# CONFIG_FATFS_CODEPAGE_861 is not set +# CONFIG_FATFS_CODEPAGE_862 is not set +# CONFIG_FATFS_CODEPAGE_863 is not set +# CONFIG_FATFS_CODEPAGE_864 is not set +# CONFIG_FATFS_CODEPAGE_865 is not set +# CONFIG_FATFS_CODEPAGE_866 is not set +# CONFIG_FATFS_CODEPAGE_869 is not set +# CONFIG_FATFS_CODEPAGE_932 is not set +# CONFIG_FATFS_CODEPAGE_936 is not set +# CONFIG_FATFS_CODEPAGE_949 is not set +# CONFIG_FATFS_CODEPAGE_950 is not set +CONFIG_FATFS_CODEPAGE=437 +CONFIG_FATFS_FS_LOCK=0 +CONFIG_FATFS_TIMEOUT_MS=10000 +CONFIG_FATFS_PER_FILE_CACHE=y +CONFIG_FATFS_ALLOC_PREFER_EXTRAM=y +# CONFIG_FATFS_USE_FASTSEEK is not set +CONFIG_FATFS_VFS_FSTAT_BLKSIZE=0 +# end of FAT Filesystem support + +# +# FreeRTOS +# + +# +# Kernel +# +# CONFIG_FREERTOS_SMP is not set +CONFIG_FREERTOS_UNICORE=y +CONFIG_FREERTOS_HZ=100 +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE is not set +# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_PTRVAL is not set +CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY=y +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=1536 +# CONFIG_FREERTOS_USE_IDLE_HOOK is not set +# CONFIG_FREERTOS_USE_TICK_HOOK is not set +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=16 +# CONFIG_FREERTOS_ENABLE_BACKWARD_COMPATIBILITY is not set +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_TASK_NOTIFICATION_ARRAY_ENTRIES=1 +# CONFIG_FREERTOS_USE_TRACE_FACILITY is not set +# CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS is not set +# end of Kernel + +# +# Port +# +# CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK is not set +CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS=y +# CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP is not set +CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER=y +CONFIG_FREERTOS_ISR_STACKSIZE=1536 +CONFIG_FREERTOS_INTERRUPT_BACKTRACE=y +CONFIG_FREERTOS_TICK_SUPPORT_CORETIMER=y +CONFIG_FREERTOS_CORETIMER_0=y +# CONFIG_FREERTOS_CORETIMER_1 is not set +CONFIG_FREERTOS_SYSTICK_USES_CCOUNT=y +# CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH is not set +CONFIG_FREERTOS_PLACE_SNAPSHOT_FUNS_INTO_FLASH=y +# CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE is not set +CONFIG_FREERTOS_ENABLE_TASK_SNAPSHOT=y +# end of Port + +CONFIG_FREERTOS_NO_AFFINITY=0x7FFFFFFF +CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION=y +CONFIG_FREERTOS_DEBUG_OCDAWARE=y +# end of FreeRTOS + +# +# Hardware Abstraction Layer (HAL) and Low Level (LL) +# +CONFIG_HAL_ASSERTION_EQUALS_SYSTEM=y +# CONFIG_HAL_ASSERTION_DISABLE is not set +# CONFIG_HAL_ASSERTION_SILENT is not set +# CONFIG_HAL_ASSERTION_ENABLE is not set +CONFIG_HAL_DEFAULT_ASSERTION_LEVEL=2 +CONFIG_HAL_SPI_MASTER_FUNC_IN_IRAM=y +CONFIG_HAL_SPI_SLAVE_FUNC_IN_IRAM=y +# end of Hardware Abstraction Layer (HAL) and Low Level (LL) + +# +# Heap memory debugging +# +CONFIG_HEAP_POISONING_DISABLED=y +# CONFIG_HEAP_POISONING_LIGHT is not set +# CONFIG_HEAP_POISONING_COMPREHENSIVE is not set +CONFIG_HEAP_TRACING_OFF=y +# CONFIG_HEAP_TRACING_STANDALONE is not set +# CONFIG_HEAP_TRACING_TOHOST is not set +# CONFIG_HEAP_USE_HOOKS is not set +# CONFIG_HEAP_ABORT_WHEN_ALLOCATION_FAILS is not set +# CONFIG_HEAP_PLACE_FUNCTION_INTO_FLASH is not set +# end of Heap memory debugging + +CONFIG_IEEE802154_CCA_THRESHOLD=-60 +CONFIG_IEEE802154_PENDING_TABLE_SIZE=20 + +# +# Log output +# +CONFIG_LOG_DEFAULT_LEVEL_NONE=y +# CONFIG_LOG_DEFAULT_LEVEL_ERROR is not set +# CONFIG_LOG_DEFAULT_LEVEL_WARN is not set +# CONFIG_LOG_DEFAULT_LEVEL_INFO is not set +# CONFIG_LOG_DEFAULT_LEVEL_DEBUG is not set +# CONFIG_LOG_DEFAULT_LEVEL_VERBOSE is not set +CONFIG_LOG_DEFAULT_LEVEL=0 +CONFIG_LOG_MAXIMUM_EQUALS_DEFAULT=y +# CONFIG_LOG_MAXIMUM_LEVEL_ERROR is not set +# CONFIG_LOG_MAXIMUM_LEVEL_WARN is not set +# CONFIG_LOG_MAXIMUM_LEVEL_INFO is not set +# CONFIG_LOG_MAXIMUM_LEVEL_DEBUG is not set +# CONFIG_LOG_MAXIMUM_LEVEL_VERBOSE is not set +CONFIG_LOG_MAXIMUM_LEVEL=0 +# CONFIG_LOG_COLORS is not set +CONFIG_LOG_TIMESTAMP_SOURCE_RTOS=y +# CONFIG_LOG_TIMESTAMP_SOURCE_SYSTEM is not set +# end of Log output + +# +# LWIP +# +CONFIG_LWIP_LOCAL_HOSTNAME="espressif" +# CONFIG_LWIP_NETIF_API is not set +# CONFIG_LWIP_TCPIP_CORE_LOCKING is not set +# CONFIG_LWIP_CHECK_THREAD_SAFETY is not set +# CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES is not set +# CONFIG_LWIP_L2_TO_L3_COPY is not set +# CONFIG_LWIP_IRAM_OPTIMIZATION is not set +# CONFIG_LWIP_TIMERS_ONDEMAND is not set +CONFIG_LWIP_MAX_SOCKETS=10 +# CONFIG_LWIP_USE_ONLY_LWIP_SELECT is not set +# CONFIG_LWIP_SO_LINGER is not set +# CONFIG_LWIP_SO_REUSE is not set +# CONFIG_LWIP_SO_RCVBUF is not set +# CONFIG_LWIP_NETBUF_RECVINFO is not set +# CONFIG_LWIP_IP4_FRAG is not set +# CONFIG_LWIP_IP4_REASSEMBLY is not set +CONFIG_LWIP_IP_REASS_MAX_PBUFS=10 +# CONFIG_LWIP_IP_FORWARD is not set +# CONFIG_LWIP_STATS is not set +# CONFIG_LWIP_ESP_GRATUITOUS_ARP is not set +CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32 +# CONFIG_LWIP_DHCP_DOES_ARP_CHECK is not set +# CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set +# CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID is not set +# CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set +CONFIG_LWIP_DHCP_OPTIONS_LEN=68 +CONFIG_LWIP_NUM_NETIF_CLIENT_DATA=0 +CONFIG_LWIP_DHCP_COARSE_TIMER_SECS=1 + +# +# DHCP server +# +# CONFIG_LWIP_DHCPS is not set +# end of DHCP server + +# CONFIG_LWIP_AUTOIP is not set +CONFIG_LWIP_IPV4=y +# CONFIG_LWIP_IPV6 is not set +# CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set +# CONFIG_LWIP_NETIF_LOOPBACK is not set + +# +# TCP +# +CONFIG_LWIP_MAX_ACTIVE_TCP=16 +CONFIG_LWIP_MAX_LISTENING_TCP=16 +CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION=y +CONFIG_LWIP_TCP_MAXRTX=12 +CONFIG_LWIP_TCP_SYNMAXRTX=12 +CONFIG_LWIP_TCP_MSS=1440 +CONFIG_LWIP_TCP_TMR_INTERVAL=250 +CONFIG_LWIP_TCP_MSL=60000 +CONFIG_LWIP_TCP_FIN_WAIT_TIMEOUT=20000 +CONFIG_LWIP_TCP_SND_BUF_DEFAULT=5744 +CONFIG_LWIP_TCP_WND_DEFAULT=5744 +CONFIG_LWIP_TCP_RECVMBOX_SIZE=6 +CONFIG_LWIP_TCP_QUEUE_OOSEQ=y +# CONFIG_LWIP_TCP_SACK_OUT is not set +CONFIG_LWIP_TCP_OVERSIZE_MSS=y +# CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set +# CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set +# CONFIG_LWIP_WND_SCALE is not set +CONFIG_LWIP_TCP_RTO_TIME=1500 +# end of TCP + +# +# UDP +# +CONFIG_LWIP_MAX_UDP_PCBS=16 +CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 +# end of UDP + +# +# Checksums +# +# CONFIG_LWIP_CHECKSUM_CHECK_IP is not set +# CONFIG_LWIP_CHECKSUM_CHECK_UDP is not set +CONFIG_LWIP_CHECKSUM_CHECK_ICMP=y +# end of Checksums + +CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=3072 +CONFIG_LWIP_TCPIP_TASK_AFFINITY_NO_AFFINITY=y +# CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU0 is not set +CONFIG_LWIP_TCPIP_TASK_AFFINITY=0x7FFFFFFF +# CONFIG_LWIP_PPP_SUPPORT is not set +# CONFIG_LWIP_SLIP_SUPPORT is not set + +# +# ICMP +# +CONFIG_LWIP_ICMP=y +# CONFIG_LWIP_MULTICAST_PING is not set +# CONFIG_LWIP_BROADCAST_PING is not set +# end of ICMP + +# +# LWIP RAW API +# +CONFIG_LWIP_MAX_RAW_PCBS=16 +# end of LWIP RAW API + +# +# SNTP +# +CONFIG_LWIP_SNTP_MAX_SERVERS=1 +# CONFIG_LWIP_DHCP_GET_NTP_SRV is not set +CONFIG_LWIP_SNTP_UPDATE_DELAY=3600000 +# end of SNTP + +CONFIG_LWIP_BRIDGEIF_MAX_PORTS=7 +# CONFIG_LWIP_ESP_LWIP_ASSERT is not set + +# +# Hooks +# +# CONFIG_LWIP_HOOK_TCP_ISN_NONE is not set +CONFIG_LWIP_HOOK_TCP_ISN_DEFAULT=y +# CONFIG_LWIP_HOOK_TCP_ISN_CUSTOM is not set +CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_NONE=y +# CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_DEFAULT is not set +# CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_CUSTOM is not set +# end of Hooks + +# CONFIG_LWIP_DEBUG is not set +# end of LWIP + +# +# mbedTLS +# +CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y +# CONFIG_MBEDTLS_EXTERNAL_MEM_ALLOC is not set +# CONFIG_MBEDTLS_DEFAULT_MEM_ALLOC is not set +# CONFIG_MBEDTLS_CUSTOM_MEM_ALLOC is not set +CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN=y +CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN=16384 +CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096 +# CONFIG_MBEDTLS_DYNAMIC_BUFFER is not set +# CONFIG_MBEDTLS_DEBUG is not set + +# +# mbedTLS v3.x related +# +# CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH is not set +# CONFIG_MBEDTLS_X509_TRUSTED_CERT_CALLBACK is not set +# CONFIG_MBEDTLS_SSL_CONTEXT_SERIALIZATION is not set +# CONFIG_MBEDTLS_SSL_KEEP_PEER_CERTIFICATE is not set +CONFIG_MBEDTLS_PKCS7_C=y +# end of mbedTLS v3.x related + +# +# Certificate Bundle +# +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=y +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=y +# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN is not set +# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE is not set +# CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE is not set +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_MAX_CERTS=200 +# end of Certificate Bundle + +# CONFIG_MBEDTLS_ECP_RESTARTABLE is not set +CONFIG_MBEDTLS_CMAC_C=y +CONFIG_MBEDTLS_HARDWARE_AES=y +CONFIG_MBEDTLS_AES_USE_INTERRUPT=y +CONFIG_MBEDTLS_HARDWARE_GCM=y +CONFIG_MBEDTLS_HARDWARE_MPI=y +CONFIG_MBEDTLS_MPI_USE_INTERRUPT=y +CONFIG_MBEDTLS_HARDWARE_SHA=y +CONFIG_MBEDTLS_ROM_MD5=y +# CONFIG_MBEDTLS_ATCA_HW_ECDSA_SIGN is not set +# CONFIG_MBEDTLS_ATCA_HW_ECDSA_VERIFY is not set +# CONFIG_MBEDTLS_HAVE_TIME is not set +# CONFIG_MBEDTLS_ECDSA_DETERMINISTIC is not set +# CONFIG_MBEDTLS_SHA512_C is not set +# CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT is not set +# CONFIG_MBEDTLS_TLS_SERVER_ONLY is not set +# CONFIG_MBEDTLS_TLS_CLIENT_ONLY is not set +CONFIG_MBEDTLS_TLS_DISABLED=y +CONFIG_MBEDTLS_TLS_ENABLED=y + +# +# TLS Key Exchange Methods +# +# CONFIG_MBEDTLS_PSK_MODES is not set +CONFIG_MBEDTLS_KEY_EXCHANGE_RSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ELLIPTIC_CURVE=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_RSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_RSA=y +# end of TLS Key Exchange Methods + +CONFIG_MBEDTLS_SSL_RENEGOTIATION=y +CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=y +# CONFIG_MBEDTLS_SSL_PROTO_GMTSSL1_1 is not set +# CONFIG_MBEDTLS_SSL_PROTO_DTLS is not set +CONFIG_MBEDTLS_SSL_ALPN=y +CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS=y +CONFIG_MBEDTLS_SERVER_SSL_SESSION_TICKETS=y + +# +# Symmetric Ciphers +# +CONFIG_MBEDTLS_AES_C=y +# CONFIG_MBEDTLS_CAMELLIA_C is not set +# CONFIG_MBEDTLS_DES_C is not set +# CONFIG_MBEDTLS_BLOWFISH_C is not set +# CONFIG_MBEDTLS_XTEA_C is not set +CONFIG_MBEDTLS_CCM_C=y +CONFIG_MBEDTLS_GCM_C=y +# CONFIG_MBEDTLS_NIST_KW_C is not set +# end of Symmetric Ciphers + +# CONFIG_MBEDTLS_RIPEMD160_C is not set + +# +# Certificates +# +CONFIG_MBEDTLS_PEM_PARSE_C=y +CONFIG_MBEDTLS_PEM_WRITE_C=y +CONFIG_MBEDTLS_X509_CRL_PARSE_C=y +CONFIG_MBEDTLS_X509_CSR_PARSE_C=y +# end of Certificates + +CONFIG_MBEDTLS_ECP_C=y +# CONFIG_MBEDTLS_DHM_C is not set +CONFIG_MBEDTLS_ECDH_C=y +CONFIG_MBEDTLS_ECDSA_C=y +# CONFIG_MBEDTLS_ECJPAKE_C is not set +CONFIG_MBEDTLS_ECP_DP_SECP192R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP224R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP384R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP521R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP192K1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP224K1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP256K1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_BP256R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_BP384R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_BP512R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_CURVE25519_ENABLED=y +CONFIG_MBEDTLS_ECP_NIST_OPTIM=y +# CONFIG_MBEDTLS_POLY1305_C is not set +# CONFIG_MBEDTLS_CHACHA20_C is not set +# CONFIG_MBEDTLS_HKDF_C is not set +# CONFIG_MBEDTLS_THREADING_C is not set +# CONFIG_MBEDTLS_LARGE_KEY_SOFTWARE_MPI is not set +# CONFIG_MBEDTLS_SECURITY_RISKS is not set +# end of mbedTLS + +# +# ESP-MQTT Configurations +# +# CONFIG_MQTT_PROTOCOL_311 is not set +# CONFIG_MQTT_PROTOCOL_5 is not set +# CONFIG_MQTT_TRANSPORT_SSL is not set +# CONFIG_MQTT_MSG_ID_INCREMENTAL is not set +# CONFIG_MQTT_SKIP_PUBLISH_IF_DISCONNECTED is not set +# CONFIG_MQTT_REPORT_DELETED_MESSAGES is not set +# CONFIG_MQTT_USE_CUSTOM_CONFIG is not set +# CONFIG_MQTT_TASK_CORE_SELECTION_ENABLED is not set +# CONFIG_MQTT_CUSTOM_OUTBOX is not set +# end of ESP-MQTT Configurations + +# +# Newlib +# +CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF=y +# CONFIG_NEWLIB_STDOUT_LINE_ENDING_LF is not set +# CONFIG_NEWLIB_STDOUT_LINE_ENDING_CR is not set +# CONFIG_NEWLIB_STDIN_LINE_ENDING_CRLF is not set +# CONFIG_NEWLIB_STDIN_LINE_ENDING_LF is not set +CONFIG_NEWLIB_STDIN_LINE_ENDING_CR=y +# CONFIG_NEWLIB_NANO_FORMAT is not set +CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC_HRT=y +# CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC is not set +# CONFIG_NEWLIB_TIME_SYSCALL_USE_HRT is not set +# CONFIG_NEWLIB_TIME_SYSCALL_USE_NONE is not set +# end of Newlib + +# +# NVS +# +# CONFIG_NVS_ASSERT_ERROR_CHECK is not set +# end of NVS + +# +# OpenThread +# +# CONFIG_OPENTHREAD_ENABLED is not set + +# +# Thread Operational Dataset +# +CONFIG_OPENTHREAD_NETWORK_NAME="OpenThread-ESP" +CONFIG_OPENTHREAD_NETWORK_CHANNEL=15 +CONFIG_OPENTHREAD_NETWORK_PANID=0x1234 +CONFIG_OPENTHREAD_NETWORK_EXTPANID="dead00beef00cafe" +CONFIG_OPENTHREAD_NETWORK_MASTERKEY="00112233445566778899aabbccddeeff" +CONFIG_OPENTHREAD_NETWORK_PSKC="104810e2315100afd6bc9215a6bfac53" +# end of Thread Operational Dataset +# end of OpenThread + +# +# Protocomm +# +CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_0=y +CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_1=y +CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_2=y +# end of Protocomm + +# +# PThreads +# +CONFIG_PTHREAD_TASK_PRIO_DEFAULT=5 +CONFIG_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072 +CONFIG_PTHREAD_STACK_MIN=768 +CONFIG_PTHREAD_TASK_CORE_DEFAULT=-1 +CONFIG_PTHREAD_TASK_NAME_DEFAULT="pthread" +# end of PThreads + +# +# MMU Config +# +CONFIG_MMU_PAGE_SIZE_64KB=y +CONFIG_MMU_PAGE_MODE="64KB" +CONFIG_MMU_PAGE_SIZE=0x10000 +# end of MMU Config + +# +# SPI Flash driver +# +# CONFIG_SPI_FLASH_VERIFY_WRITE is not set +# CONFIG_SPI_FLASH_ENABLE_COUNTERS is not set +CONFIG_SPI_FLASH_ROM_DRIVER_PATCH=y +CONFIG_SPI_FLASH_DANGEROUS_WRITE_ABORTS=y +# CONFIG_SPI_FLASH_DANGEROUS_WRITE_FAILS is not set +# CONFIG_SPI_FLASH_DANGEROUS_WRITE_ALLOWED is not set +# CONFIG_SPI_FLASH_BYPASS_BLOCK_ERASE is not set +CONFIG_SPI_FLASH_YIELD_DURING_ERASE=y +CONFIG_SPI_FLASH_ERASE_YIELD_DURATION_MS=20 +CONFIG_SPI_FLASH_ERASE_YIELD_TICKS=1 +CONFIG_SPI_FLASH_WRITE_CHUNK_SIZE=1024 +# CONFIG_SPI_FLASH_SIZE_OVERRIDE is not set +# CONFIG_SPI_FLASH_CHECK_ERASE_TIMEOUT_DISABLED is not set +# CONFIG_SPI_FLASH_OVERRIDE_CHIP_DRIVER_LIST is not set + +# +# SPI Flash behavior when brownout +# +CONFIG_SPI_FLASH_BROWNOUT_RESET_XMC=y +CONFIG_SPI_FLASH_BROWNOUT_RESET=y +# end of SPI Flash behavior when brownout + +# +# Auto-detect flash chips +# +CONFIG_SPI_FLASH_VENDOR_XMC_SUPPORTED=y +CONFIG_SPI_FLASH_VENDOR_GD_SUPPORTED=y +CONFIG_SPI_FLASH_VENDOR_ISSI_SUPPORTED=y +CONFIG_SPI_FLASH_VENDOR_MXIC_SUPPORTED=y +CONFIG_SPI_FLASH_VENDOR_WINBOND_SUPPORTED=y +CONFIG_SPI_FLASH_VENDOR_BOYA_SUPPORTED=y +CONFIG_SPI_FLASH_VENDOR_TH_SUPPORTED=y +# CONFIG_SPI_FLASH_SUPPORT_ISSI_CHIP is not set +# CONFIG_SPI_FLASH_SUPPORT_MXIC_CHIP is not set +# CONFIG_SPI_FLASH_SUPPORT_GD_CHIP is not set +# CONFIG_SPI_FLASH_SUPPORT_WINBOND_CHIP is not set +# CONFIG_SPI_FLASH_SUPPORT_BOYA_CHIP is not set +# CONFIG_SPI_FLASH_SUPPORT_TH_CHIP is not set +# end of Auto-detect flash chips + +# CONFIG_SPI_FLASH_ENABLE_ENCRYPTED_READ_WRITE is not set +# end of SPI Flash driver + +# +# SPIFFS Configuration +# +CONFIG_SPIFFS_MAX_PARTITIONS=3 + +# +# SPIFFS Cache Configuration +# +CONFIG_SPIFFS_CACHE=y +CONFIG_SPIFFS_CACHE_WR=y +# CONFIG_SPIFFS_CACHE_STATS is not set +# end of SPIFFS Cache Configuration + +CONFIG_SPIFFS_PAGE_CHECK=y +CONFIG_SPIFFS_GC_MAX_RUNS=10 +# CONFIG_SPIFFS_GC_STATS is not set +CONFIG_SPIFFS_PAGE_SIZE=256 +CONFIG_SPIFFS_OBJ_NAME_LEN=32 +# CONFIG_SPIFFS_FOLLOW_SYMLINKS is not set +CONFIG_SPIFFS_USE_MAGIC=y +CONFIG_SPIFFS_USE_MAGIC_LENGTH=y +CONFIG_SPIFFS_META_LENGTH=4 +CONFIG_SPIFFS_USE_MTIME=y + +# +# Debug Configuration +# +# CONFIG_SPIFFS_DBG is not set +# CONFIG_SPIFFS_API_DBG is not set +# CONFIG_SPIFFS_GC_DBG is not set +# CONFIG_SPIFFS_CACHE_DBG is not set +# CONFIG_SPIFFS_CHECK_DBG is not set +# CONFIG_SPIFFS_TEST_VISUALISATION is not set +# end of Debug Configuration +# end of SPIFFS Configuration + +# +# TCP Transport +# + +# +# Websocket +# +# CONFIG_WS_TRANSPORT is not set +# end of Websocket +# end of TCP Transport + +# +# Ultra Low Power (ULP) Co-processor +# +CONFIG_ULP_COPROC_ENABLED=y +# CONFIG_ULP_COPROC_TYPE_FSM is not set +CONFIG_ULP_COPROC_TYPE_RISCV=y +CONFIG_ULP_COPROC_RESERVE_MEM=8168 + +# +# ULP RISC-V Settings +# +CONFIG_ULP_RISCV_UART_BAUDRATE=9600 +CONFIG_ULP_RISCV_I2C_RW_TIMEOUT=500 +# end of ULP RISC-V Settings +# end of Ultra Low Power (ULP) Co-processor + +# +# Unity unit testing library +# +# CONFIG_UNITY_ENABLE_FLOAT is not set +# CONFIG_UNITY_ENABLE_DOUBLE is not set +# CONFIG_UNITY_ENABLE_64BIT is not set +# CONFIG_UNITY_ENABLE_COLOR is not set +# CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER is not set +# CONFIG_UNITY_ENABLE_FIXTURE is not set +# CONFIG_UNITY_ENABLE_BACKTRACE_ON_FAIL is not set +# end of Unity unit testing library + +# +# USB-OTG +# +CONFIG_USB_OTG_SUPPORTED=y +CONFIG_USB_HOST_CONTROL_TRANSFER_MAX_SIZE=256 +CONFIG_USB_HOST_HW_BUFFER_BIAS_BALANCED=y +# CONFIG_USB_HOST_HW_BUFFER_BIAS_IN is not set +# CONFIG_USB_HOST_HW_BUFFER_BIAS_PERIODIC_OUT is not set + +# +# Root Hub configuration +# +CONFIG_USB_HOST_DEBOUNCE_DELAY_MS=250 +CONFIG_USB_HOST_RESET_HOLD_MS=30 +CONFIG_USB_HOST_RESET_RECOVERY_MS=30 +CONFIG_USB_HOST_SET_ADDR_RECOVERY_MS=10 +# end of Root Hub configuration +# end of USB-OTG + +# +# Virtual file system +# +CONFIG_VFS_SUPPORT_IO=y +CONFIG_VFS_SUPPORT_DIR=y +CONFIG_VFS_SUPPORT_SELECT=y +CONFIG_VFS_SUPPRESS_SELECT_DEBUG_OUTPUT=y +CONFIG_VFS_SUPPORT_TERMIOS=y +CONFIG_VFS_MAX_COUNT=8 + +# +# Host File System I/O (Semihosting) +# +CONFIG_VFS_SEMIHOSTFS_MAX_MOUNT_POINTS=1 +# end of Host File System I/O (Semihosting) +# end of Virtual file system + +# +# Wear Levelling +# +# CONFIG_WL_SECTOR_SIZE_512 is not set +CONFIG_WL_SECTOR_SIZE_4096=y +CONFIG_WL_SECTOR_SIZE=4096 +# end of Wear Levelling + +# +# Wi-Fi Provisioning Manager +# +CONFIG_WIFI_PROV_SCAN_MAX_ENTRIES=16 +CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30 +CONFIG_WIFI_PROV_BLE_FORCE_ENCRYPTION=y +CONFIG_WIFI_PROV_STA_ALL_CHANNEL_SCAN=y +# CONFIG_WIFI_PROV_STA_FAST_SCAN is not set +# end of Wi-Fi Provisioning Manager +# end of Component config + +# CONFIG_IDF_EXPERIMENTAL_FEATURES is not set + +# Deprecated options for backward compatibility +# CONFIG_APP_BUILD_TYPE_ELF_RAM is not set +# CONFIG_NO_BLOBS is not set +# CONFIG_ESP32S2_NO_BLOBS is not set +CONFIG_LOG_BOOTLOADER_LEVEL_NONE=y +# CONFIG_LOG_BOOTLOADER_LEVEL_ERROR is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_WARN is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_INFO is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_DEBUG is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_VERBOSE is not set +CONFIG_LOG_BOOTLOADER_LEVEL=0 +# CONFIG_APP_ROLLBACK_ENABLE is not set +# CONFIG_FLASH_ENCRYPTION_ENABLED is not set +# CONFIG_FLASHMODE_QIO is not set +# CONFIG_FLASHMODE_QOUT is not set +CONFIG_FLASHMODE_DIO=y +# CONFIG_FLASHMODE_DOUT is not set +CONFIG_MONITOR_BAUD=115200 +# CONFIG_OPTIMIZATION_LEVEL_DEBUG is not set +# CONFIG_COMPILER_OPTIMIZATION_LEVEL_DEBUG is not set +# CONFIG_OPTIMIZATION_LEVEL_RELEASE is not set +# CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE is not set +CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED=y +# CONFIG_OPTIMIZATION_ASSERTIONS_SILENT is not set +# CONFIG_OPTIMIZATION_ASSERTIONS_DISABLED is not set +CONFIG_OPTIMIZATION_ASSERTION_LEVEL=2 +# CONFIG_CXX_EXCEPTIONS is not set +CONFIG_STACK_CHECK_NONE=y +# CONFIG_STACK_CHECK_NORM is not set +# CONFIG_STACK_CHECK_STRONG is not set +# CONFIG_STACK_CHECK_ALL is not set +# CONFIG_WARN_WRITE_STRINGS is not set +# CONFIG_ESP32_APPTRACE_DEST_TRAX is not set +CONFIG_ESP32_APPTRACE_DEST_NONE=y +CONFIG_ESP32_APPTRACE_LOCK_ENABLE=y +CONFIG_ADC2_DISABLE_DAC=y +# CONFIG_EXTERNAL_COEX_ENABLE is not set +# CONFIG_ESP_WIFI_EXTERNAL_COEXIST_ENABLE is not set +# CONFIG_EVENT_LOOP_PROFILING is not set +CONFIG_POST_EVENTS_FROM_ISR=y +CONFIG_POST_EVENTS_FROM_IRAM_ISR=y +# CONFIG_OTA_ALLOW_HTTP is not set +CONFIG_ESP32S2_RTC_CLK_SRC_INT_RC=y +# CONFIG_ESP32S2_RTC_CLK_SRC_EXT_CRYS is not set +# CONFIG_ESP32S2_RTC_CLK_SRC_EXT_OSC is not set +# CONFIG_ESP32S2_RTC_CLK_SRC_INT_8MD256 is not set +CONFIG_ESP32S2_RTC_CLK_CAL_CYCLES=576 +CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE=y +# CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION is not set +CONFIG_ESP32_PHY_MAX_WIFI_TX_POWER=15 +CONFIG_ESP32_PHY_MAX_TX_POWER=15 +CONFIG_REDUCE_PHY_TX_POWER=y +CONFIG_ESP32_REDUCE_PHY_TX_POWER=y +CONFIG_ESP32S2_SPIRAM_SUPPORT=y +CONFIG_DEFAULT_PSRAM_CLK_IO=30 +CONFIG_DEFAULT_PSRAM_CS_IO=26 +# CONFIG_ESP32S2_DEFAULT_CPU_FREQ_80 is not set +# CONFIG_ESP32S2_DEFAULT_CPU_FREQ_160 is not set +CONFIG_ESP32S2_DEFAULT_CPU_FREQ_240=y +CONFIG_ESP32S2_DEFAULT_CPU_FREQ_MHZ=240 +# CONFIG_ESP32S2_PANIC_PRINT_HALT is not set +CONFIG_ESP32S2_PANIC_PRINT_REBOOT=y +# CONFIG_ESP32S2_PANIC_SILENT_REBOOT is not set +# CONFIG_ESP32S2_PANIC_GDBSTUB is not set +CONFIG_ESP32S2_ALLOW_RTC_FAST_MEM_AS_HEAP=y +# CONFIG_ESP32S2_MEMPROT_FEATURE is not set +CONFIG_SYSTEM_EVENT_QUEUE_SIZE=32 +CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE=2304 +CONFIG_MAIN_TASK_STACK_SIZE=8192 +CONFIG_CONSOLE_UART_DEFAULT=y +# CONFIG_CONSOLE_UART_CUSTOM is not set +# CONFIG_CONSOLE_UART_NONE is not set +# CONFIG_ESP_CONSOLE_UART_NONE is not set +CONFIG_CONSOLE_UART=y +CONFIG_CONSOLE_UART_NUM=0 +CONFIG_CONSOLE_UART_BAUDRATE=115200 +CONFIG_INT_WDT=y +CONFIG_INT_WDT_TIMEOUT_MS=300 +# CONFIG_TASK_WDT is not set +# CONFIG_ESP_TASK_WDT is not set +# CONFIG_ESP32_DEBUG_STUBS_ENABLE is not set +CONFIG_ESP32S2_DEBUG_OCDAWARE=y +CONFIG_BROWNOUT_DET=y +CONFIG_ESP32S2_BROWNOUT_DET=y +CONFIG_ESP32S2_BROWNOUT_DET=y +CONFIG_BROWNOUT_DET_LVL_SEL_7=y +CONFIG_ESP32S2_BROWNOUT_DET_LVL_SEL_7=y +# CONFIG_BROWNOUT_DET_LVL_SEL_6 is not set +# CONFIG_ESP32S2_BROWNOUT_DET_LVL_SEL_6 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_5 is not set +# CONFIG_ESP32S2_BROWNOUT_DET_LVL_SEL_5 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_4 is not set +# CONFIG_ESP32S2_BROWNOUT_DET_LVL_SEL_4 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_3 is not set +# CONFIG_ESP32S2_BROWNOUT_DET_LVL_SEL_3 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_2 is not set +# CONFIG_ESP32S2_BROWNOUT_DET_LVL_SEL_2 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_1 is not set +# CONFIG_ESP32S2_BROWNOUT_DET_LVL_SEL_1 is not set +CONFIG_BROWNOUT_DET_LVL=7 +CONFIG_ESP32S2_BROWNOUT_DET_LVL=7 +CONFIG_IPC_TASK_STACK_SIZE=1536 +CONFIG_TIMER_TASK_STACK_SIZE=3584 +CONFIG_ESP32_WIFI_ENABLED=y +CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=10 +CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32 +# CONFIG_ESP32_WIFI_STATIC_TX_BUFFER is not set +CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER=y +CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=1 +CONFIG_ESP32_WIFI_CACHE_TX_BUFFER_NUM=32 +CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=32 +# CONFIG_ESP32_WIFI_CSI_ENABLED is not set +# CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED is not set +# CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED is not set +# CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED is not set +# CONFIG_ESP32_WIFI_AMSDU_TX_ENABLED is not set +CONFIG_ESP32_WIFI_NVS_ENABLED=y +CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN=752 +CONFIG_ESP32_WIFI_MGMT_SBUF_NUM=32 +CONFIG_ESP32_WIFI_IRAM_OPT=y +CONFIG_ESP32_WIFI_RX_IRAM_OPT=y +CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE=y +CONFIG_ESP32_WIFI_ENABLE_WPA3_OWE_STA=y +CONFIG_WPA_MBEDTLS_CRYPTO=y +CONFIG_WPA_MBEDTLS_TLS_CLIENT=y +# CONFIG_WPA_WAPI_PSK is not set +# CONFIG_WPA_SUITE_B_192 is not set +# CONFIG_WPA_11KV_SUPPORT is not set +# CONFIG_WPA_MBO_SUPPORT is not set +# CONFIG_WPA_DPP_SUPPORT is not set +# CONFIG_WPA_11R_SUPPORT is not set +# CONFIG_WPA_WPS_STRICT is not set +# CONFIG_WPA_DEBUG_PRINT is not set +# CONFIG_WPA_TESTING_OPTIONS is not set +# CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH is not set +# CONFIG_ESP32_ENABLE_COREDUMP_TO_UART is not set +CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE=y +CONFIG_TIMER_TASK_PRIORITY=1 +CONFIG_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_TIMER_QUEUE_LENGTH=10 +# CONFIG_ENABLE_STATIC_TASK_CLEAN_UP_HOOK is not set +# CONFIG_HAL_ASSERTION_SILIENT is not set +# CONFIG_L2_TO_L3_COPY is not set +# CONFIG_ESP_GRATUITOUS_ARP is not set +CONFIG_TCPIP_RECVMBOX_SIZE=32 +CONFIG_TCP_MAXRTX=12 +CONFIG_TCP_SYNMAXRTX=12 +CONFIG_TCP_MSS=1440 +CONFIG_TCP_MSL=60000 +CONFIG_TCP_SND_BUF_DEFAULT=5744 +CONFIG_TCP_WND_DEFAULT=5744 +CONFIG_TCP_RECVMBOX_SIZE=6 +CONFIG_TCP_QUEUE_OOSEQ=y +CONFIG_TCP_OVERSIZE_MSS=y +# CONFIG_TCP_OVERSIZE_QUARTER_MSS is not set +# CONFIG_TCP_OVERSIZE_DISABLE is not set +CONFIG_UDP_RECVMBOX_SIZE=6 +CONFIG_TCPIP_TASK_STACK_SIZE=3072 +CONFIG_TCPIP_TASK_AFFINITY_NO_AFFINITY=y +# CONFIG_TCPIP_TASK_AFFINITY_CPU0 is not set +CONFIG_TCPIP_TASK_AFFINITY=0x7FFFFFFF +# CONFIG_PPP_SUPPORT is not set +CONFIG_ESP32S2_TIME_SYSCALL_USE_RTC_SYSTIMER=y +CONFIG_ESP32S2_TIME_SYSCALL_USE_RTC_FRC1=y +# CONFIG_ESP32S2_TIME_SYSCALL_USE_RTC is not set +# CONFIG_ESP32S2_TIME_SYSCALL_USE_SYSTIMER is not set +# CONFIG_ESP32S2_TIME_SYSCALL_USE_FRC1 is not set +# CONFIG_ESP32S2_TIME_SYSCALL_USE_NONE is not set +CONFIG_ESP32_PTHREAD_TASK_PRIO_DEFAULT=5 +CONFIG_ESP32_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072 +CONFIG_ESP32_PTHREAD_STACK_MIN=768 +CONFIG_ESP32_PTHREAD_TASK_CORE_DEFAULT=-1 +CONFIG_ESP32_PTHREAD_TASK_NAME_DEFAULT="pthread" +CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ABORTS=y +# CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_FAILS is not set +# CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ALLOWED is not set +CONFIG_ESP32S2_ULP_COPROC_ENABLED=y +CONFIG_ESP32S2_ULP_COPROC_RISCV=y +CONFIG_ESP32S2_ULP_COPROC_RESERVE_MEM=8168 +CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT=y +CONFIG_SUPPORT_TERMIOS=y +CONFIG_SEMIHOSTFS_MAX_MOUNT_POINTS=1 +# End of deprecated options diff --git a/tools/testloradec.grc b/tools/testloradec.grc index f9a5235..ac7d684 100644 --- a/tools/testloradec.grc +++ b/tools/testloradec.grc @@ -61,6 +61,22 @@ blocks: coordinate: [1264, 48.0] rotation: 0 state: true +- name: blocks_complex_to_float_0_0 + id: blocks_complex_to_float + parameters: + affinity: '' + alias: '' + comment: '' + maxoutbuf: '0' + minoutbuf: '0' + vlen: FFTSIZE + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [1424, 344.0] + rotation: 0 + state: true - name: blocks_complex_to_mag_squared_0 id: blocks_complex_to_mag_squared parameters: @@ -107,7 +123,7 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [808, 524.0] + coordinate: [840, 664.0] rotation: 0 state: true - name: blocks_file_sink_1 @@ -164,6 +180,42 @@ blocks: coordinate: [1736, 160.0] rotation: 0 state: enabled +- name: blocks_file_sink_1_0_0_0 + id: blocks_file_sink + parameters: + affinity: '' + alias: '' + append: 'False' + comment: '' + file: /tmp/raw_Q.dat + type: float + unbuffered: 'False' + vlen: FFTSIZE + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [1816, 568.0] + rotation: 0 + state: enabled +- name: blocks_file_sink_1_0_1 + id: blocks_file_sink + parameters: + affinity: '' + alias: '' + append: 'False' + comment: '' + file: /tmp/raw_I.dat + type: float + unbuffered: 'False' + vlen: FFTSIZE + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [1848, 448.0] + rotation: 0 + state: enabled - name: blocks_message_debug_0 id: blocks_message_debug parameters: @@ -171,12 +223,11 @@ blocks: alias: '' comment: '' en_uvec: 'True' - log_level: info states: bus_sink: false bus_source: false bus_structure: null - coordinate: [1512, 608.0] + coordinate: [1544, 744.0] rotation: 0 state: true - name: blocks_nlog10_ff_0 @@ -233,7 +284,7 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [808, 124.0] + coordinate: [808, 48.0] rotation: 0 state: enabled - name: lora_sdr_crc_verif_0 @@ -250,7 +301,7 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [1152, 592.0] + coordinate: [1184, 728.0] rotation: 0 state: true - name: lora_sdr_deinterleaver_0 @@ -266,7 +317,7 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [1256, 372.0] + coordinate: [1288, 504.0] rotation: 0 state: true - name: lora_sdr_dewhitening_0 @@ -281,7 +332,7 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [1296, 480.0] + coordinate: [1328, 616.0] rotation: 0 state: true - name: lora_sdr_fft_demod_0 @@ -298,7 +349,7 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [816, 372.0] + coordinate: [848, 504.0] rotation: 0 state: true - name: lora_sdr_frame_sync_0 @@ -337,7 +388,7 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [1040, 372.0] + coordinate: [1072, 504.0] rotation: 0 state: true - name: lora_sdr_hamming_dec_0 @@ -353,7 +404,7 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [1472, 372.0] + coordinate: [1504, 504.0] rotation: 0 state: true - name: lora_sdr_header_decoder_0 @@ -374,7 +425,7 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [1016, 476.0] + coordinate: [1048, 616.0] rotation: 0 state: true - name: osmosdr_source_0 @@ -415,7 +466,7 @@ blocks: ant8: '' ant9: '' args: '"airspy=0"' - bb_gain0: '10' + bb_gain0: '25' bb_gain1: '20' bb_gain10: '20' bb_gain11: '20' @@ -552,7 +603,7 @@ blocks: dc_offset_mode7: '0' dc_offset_mode8: '0' dc_offset_mode9: '0' - freq0: '903900000' + freq0: '100000000' freq1: 100e6 freq10: 100e6 freq11: 100e6 @@ -584,7 +635,7 @@ blocks: freq7: 100e6 freq8: 100e6 freq9: 100e6 - gain0: '10' + gain0: '25' gain1: '10' gain10: '10' gain11: '10' @@ -648,7 +699,7 @@ blocks: gain_mode7: 'False' gain_mode8: 'False' gain_mode9: 'False' - if_gain0: '10' + if_gain0: '25' if_gain1: '20' if_gain10: '20' if_gain11: '20' @@ -1199,11 +1250,14 @@ blocks: connections: - [blocks_complex_to_float_0, '0', blocks_file_sink_1_0, '0'] - [blocks_complex_to_float_0, '1', blocks_file_sink_1_0_0, '0'] +- [blocks_complex_to_float_0_0, '0', blocks_file_sink_1_0_1, '0'] +- [blocks_complex_to_float_0_0, '1', blocks_file_sink_1_0_0_0, '0'] - [blocks_complex_to_mag_squared_0, '0', blocks_nlog10_ff_0, '0'] - [blocks_correctiq_0, '0', blocks_stream_to_vector_0, '0'] - [blocks_correctiq_0, '0', lora_sdr_frame_sync_0, '0'] - [blocks_correctiq_0, '0', qtgui_waterfall_sink_x_0, '0'] - [blocks_nlog10_ff_0, '0', blocks_file_sink_1, '0'] +- [blocks_stream_to_vector_0, '0', blocks_complex_to_float_0_0, '0'] - [blocks_stream_to_vector_0, '0', fft_vxx_0, '0'] - [fft_vxx_0, '0', blocks_complex_to_float_0, '0'] - [fft_vxx_0, '0', blocks_complex_to_mag_squared_0, '0'] @@ -1227,4 +1281,4 @@ connections: metadata: file_format: 1 - grc_version: 3.10.7.0 +