From e5cd85ebf889f3d6d171dc0c2747cf4123174c55 Mon Sep 17 00:00:00 2001 From: cnlohr Date: Sun, 17 Nov 2024 01:09:49 -0500 Subject: [PATCH] add skitterrx --- ch32v/ch32v003-skitterrx/Makefile | 18 + ch32v/ch32v003-skitterrx/adcrx.c | 387 ++++++++++++++++++ ch32v/ch32v003-skitterrx/funconfig.h | 10 + .../ch32v003-skitterrx/sim/timtestskitter.ods | Bin 0 -> 52638 bytes ch32v/ch32v003-skitterrx/usb_config.h | 155 +++++++ 5 files changed, 570 insertions(+) create mode 100644 ch32v/ch32v003-skitterrx/Makefile create mode 100644 ch32v/ch32v003-skitterrx/adcrx.c create mode 100644 ch32v/ch32v003-skitterrx/funconfig.h create mode 100644 ch32v/ch32v003-skitterrx/sim/timtestskitter.ods create mode 100644 ch32v/ch32v003-skitterrx/usb_config.h diff --git a/ch32v/ch32v003-skitterrx/Makefile b/ch32v/ch32v003-skitterrx/Makefile new file mode 100644 index 0000000..5e2cdf7 --- /dev/null +++ b/ch32v/ch32v003-skitterrx/Makefile @@ -0,0 +1,18 @@ +all : flash + +TARGET:=adcrx +TARGET_MCU:=CH32V003 +CH32V003FUN:=../ch32v003fun/ch32v003fun + +ADDITIONAL_C_FILES+=../rv003usb/rv003usb/rv003usb.S ../rv003usb/rv003usb/rv003usb.c +EXTRA_CFLAGS:=-I../rv003usb/lib -I../rv003usb/rv003usb -mstrict-align -Wno-unused-function + +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-skitterrx/adcrx.c b/ch32v/ch32v003-skitterrx/adcrx.c new file mode 100644 index 0000000..07f5a2e --- /dev/null +++ b/ch32v/ch32v003-skitterrx/adcrx.c @@ -0,0 +1,387 @@ +/** + +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. + + +#include "ch32v003fun.h" +#include +#include +#include "rv003usb.h" + +uint8_t scratchout[15]; +volatile int outready = 0; +uint8_t scratchin[255]; +volatile int inready = 0; + + +#define PWM_PERIOD (28-1) //For 27.000500MHz +#define QUADRATURE + +uint32_t TQ = 128; + +#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; + int Q = TQ; + + // 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 ) + { + 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 ) + { + + int ti = i>>3; + int tq = q>>3; + int is = (ti*ti + tq*tq)>>8; + + int s = 1<<( ( 32 - __builtin_clz(is) )/2); + s = (s + is/s)/2; + + //int tv = (i>>PWM_OUTPUT) + (PWM_PERIOD/2); + //if( tv < 0 ) tv = 0; + //if( tv >= PWM_PERIOD ) tv = PWM_PERIOD-1; + //TIM1->CH4CVR = tv; + + //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: %08lx CFGR0: %08lx\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(); +} + + + + + + +void usb_handle_user_in_request( struct usb_endpoint * e, uint8_t * scratchpad, int endp, uint32_t sendtok, struct rv003usb_internal * ist ) +{ + // Make sure we only deal with control messages. Like get/set feature reports. + if( endp ) + { + usb_send_empty( sendtok ); + } +} + +void usb_handle_user_data( struct usb_endpoint * e, int current_endpoint, uint8_t * data, int len, struct rv003usb_internal * ist ) +{ + if( outready ) + { + // Send NACK (can't accept any more data right now) + usb_send_data( 0, 0, 2, 0x5A ); + return; + } + + usb_send_data( 0, 0, 2, 0xD2 ); // Send ACK + int offset = e->count<<3; + int torx = e->max_len - offset; + if( torx > len ) torx = len; + if( torx > 0 ) + { + memcpy( scratchout + offset, data, torx ); + e->count++; + if( ( e->count << 3 ) >= e->max_len ) + { + outready = e->max_len; + } + } +} + + +void usb_handle_hid_get_report_start( struct usb_endpoint * e, int reqLen, uint32_t lValueLSBIndexMSB ) +{ + if( reqLen > sizeof( scratchin ) ) reqLen = sizeof( scratchin ); + + // You can check the lValueLSBIndexMSB word to decide what you want to do here + // But, whatever you point this at will be returned back to the host PC where + // it calls hid_get_feature_report. + // + // Please note, that on some systems, for this to work, your return length must + // match the length defined in HID_REPORT_COUNT, in your HID report, in usb_config.h + + if( reqLen > inready ) inready = inready; + e->opaque = scratchin; + e->max_len = reqLen; +} + +void usb_handle_hid_set_report_start( struct usb_endpoint * e, int reqLen, uint32_t lValueLSBIndexMSB ) +{ + // Here is where you get an alert when the host PC calls hid_send_feature_report. + // + // You can handle the appropriate message here. Please note that in this + // example, the data is chunked into groups-of-8-bytes. + // + // Note that you may need to make this match HID_REPORT_COUNT, in your HID + // report, in usb_config.h + + if( outready ) reqLen = 0; + if( reqLen > sizeof( scratchout ) ) reqLen = sizeof( scratchout ); + e->opaque = scratchout; + e->max_len = reqLen; +} + + +void usb_handle_other_control_message( struct usb_endpoint * e, struct usb_urb * s, struct rv003usb_internal * ist ) +{ + LogUEvent( SysTick->CNT, s->wRequestTypeLSBRequestMSB, s->lValueLSBIndexMSB, s->wLength ); +} + + + + + + + + + + diff --git a/ch32v/ch32v003-skitterrx/funconfig.h b/ch32v/ch32v003-skitterrx/funconfig.h new file mode 100644 index 0000000..eb91275 --- /dev/null +++ b/ch32v/ch32v003-skitterrx/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-skitterrx/sim/timtestskitter.ods b/ch32v/ch32v003-skitterrx/sim/timtestskitter.ods new file mode 100644 index 0000000000000000000000000000000000000000..e69483cdb481b87a34576c1afb0ac7349b668b96 GIT binary patch literal 52638 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 literal 0 HcmV?d00001 diff --git a/ch32v/ch32v003-skitterrx/usb_config.h b/ch32v/ch32v003-skitterrx/usb_config.h new file mode 100644 index 0000000..f001937 --- /dev/null +++ b/ch32v/ch32v003-skitterrx/usb_config.h @@ -0,0 +1,155 @@ +#ifndef _USB_CONFIG_H +#define _USB_CONFIG_H + +//Defines the number of endpoints for this device. (Always add one for EP0). For two EPs, this should be 3. +#define ENDPOINTS 2 + +#define USB_PORT D // [A,C,D] GPIO Port to use with D+, D- and DPU +#define USB_PIN_DP 3 // [0-4] GPIO Number for USB D+ Pin +#define USB_PIN_DM 4 // [0-4] GPIO Number for USB D- Pin +#define USB_PIN_DPU 5 // [0-7] GPIO for feeding the 1.5k Pull-Up on USB D- Pin; Comment out if not used / tied to 3V3! + +#define RV003USB_DEBUG_TIMING 0 +#define RV003USB_OPTIMIZE_FLASH 1 +#define RV003USB_EVENT_DEBUGGING 0 +#define RV003USB_HANDLE_IN_REQUEST 1 +#define RV003USB_OTHER_CONTROL 0 +#define RV003USB_HANDLE_USER_DATA 1 +#define RV003USB_HID_FEATURES 1 +#define RV003USB_USER_DATA_HANDLES_TOKEN 1 + +#ifndef __ASSEMBLER__ + +#include + +#ifdef INSTANCE_DESCRIPTORS + +//Taken from http://www.usbmadesimple.co.uk/ums_ms_desc_dev.htm +static const uint8_t device_descriptor[] = { + 18, //Length + 1, //Type (Device) + 0x10, 0x01, //Spec + 0x0, //Device Class + 0x0, //Device Subclass + 0x0, //Device Protocol (000 = use config descriptor) + 0x08, //Max packet size for EP0 (This has to be 8 because of the USB Low-Speed Standard) + 0xcd, 0xab, //ID Vendor + 0x11, 0x11, //ID Product + 0x02, 0x00, //ID Rev + 1, //Manufacturer string + 2, //Product string + 3, //Serial string + 1, //Max number of configurations +}; + +static const uint8_t special_hid_desc[] = { + HID_USAGE_PAGE ( 0xff ), // Vendor-defined page. + HID_USAGE ( 0x00 ), + HID_REPORT_SIZE ( 8 ), + HID_COLLECTION ( HID_COLLECTION_LOGICAL ), + HID_REPORT_COUNT ( 255 ), // IN + HID_REPORT_ID ( 0xa4 ) + HID_USAGE ( 0x01 ), + HID_FEATURE ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) , + HID_REPORT_COUNT_N ( 256, 2 ), // OUT + HID_REPORT_ID ( 0xad ) + HID_USAGE ( 0x01 ), + HID_COLLECTION_END, +}; + +static const uint8_t config_descriptor[] = { + // configuration descriptor, USB spec 9.6.3, page 264-266, Table 9-10 + 9, // bLength; + 2, // bDescriptorType; + 0x22, 0x00, // wTotalLength + + //34, 0x00, //for just the one descriptor + + 0x01, // bNumInterfaces (Normally 1) + 0x01, // bConfigurationValue + 0x00, // iConfiguration + 0x80, // bmAttributes (was 0xa0) + 0x64, // bMaxPower (200mA) + + //Class FF device. + 9, // bLength + 4, // bDescriptorType + 0, // bInterfaceNumber = 1 instead of 0 -- well make it second. + 0, // bAlternateSetting + 1, // bNumEndpoints + 0x03, // bInterfaceClass (0x03 = HID) + 0x00, // bInterfaceSubClass + 0xff, // bInterfaceProtocol (1 = Keyboard, 2 = Mouse) + 0, // iInterface + + 9, // bLength + 0x21, // bDescriptorType (HID) + 0x10,0x01, // bcd 1.1 + 0x00, //country code + 0x01, // Num descriptors + 0x22, // DescriptorType[0] (HID) + sizeof(special_hid_desc), 0x00, + + 7, // endpoint descriptor (For endpoint 1) + 0x05, // Endpoint Descriptor (Must be 5) + 0x81, // Endpoint Address + 0x03, // Attributes + 0x01, 0x00, // Size (We aren't using it) + 100, // Interval (We don't use it.) +}; + +#define STR_MANUFACTURER u"CNLohr" +#define STR_PRODUCT u"RV003 RVSWDIO Programmer" +#define STR_SERIAL u"RVSWDIO003-01" + +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, special_hid_desc, sizeof(special_hid_desc)}, + {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 // INSTANCE_DESCRIPTORS + +#endif + +#endif