mirror of
https://github.com/cnlohr/lolra.git
synced 2026-06-17 00:09:31 +00:00
Fix a multitude of bugs. Some sillier than others.
This commit is contained in:
+1
-1
Submodule ch32v/ch32v003fun updated: aa91922a06...7bf80c92cc
@@ -0,0 +1,29 @@
|
|||||||
|
# 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.
|
||||||
|
|
||||||
@@ -60,19 +60,22 @@ SOFTWARE.
|
|||||||
|
|
||||||
#include "ch32v003fun.h"
|
#include "ch32v003fun.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
#define SH1107_128x128
|
#define SH1107_128x128
|
||||||
#define SSD1306_REMAP_I2C
|
#define SSD1306_REMAP_I2C
|
||||||
#define PWM_OUTPUT
|
#define PWM_OUTPUT
|
||||||
#define ENABLE_OLED
|
#define ENABLE_OLED
|
||||||
|
#define PROFILING_PIN PA0
|
||||||
|
|
||||||
#include "ssd1306_i2c.h"
|
#include "ssd1306_i2c.h"
|
||||||
#include "ssd1306.h"
|
#include "ssd1306.h"
|
||||||
#include "./usb_config.h"
|
#include "./usb_config.h"
|
||||||
#include "../ch32v003fun/examples_v20x/otg_device/otgusb.h"
|
#include "../ch32v003fun/examples_v20x/otg_device/otgusb.h"
|
||||||
|
|
||||||
|
|
||||||
#define ADC_BUFFSIZE 1024
|
#define ADC_BUFFSIZE 512
|
||||||
|
|
||||||
volatile uint16_t adc_buffer[ADC_BUFFSIZE];
|
volatile uint16_t adc_buffer[ADC_BUFFSIZE];
|
||||||
|
|
||||||
@@ -135,7 +138,7 @@ const int32_t g_goertzel_coefficient_s = 2129111628;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
int intensity_max = 1;
|
int intensity_average = 1;
|
||||||
|
|
||||||
#define LOG_GOERTZEL_LIST 512
|
#define LOG_GOERTZEL_LIST 512
|
||||||
int16_t qibaselogs[LOG_GOERTZEL_LIST*2];
|
int16_t qibaselogs[LOG_GOERTZEL_LIST*2];
|
||||||
@@ -262,7 +265,6 @@ uint32_t tc;
|
|||||||
|
|
||||||
volatile uint16_t * adc_tail = adc_buffer;
|
volatile uint16_t * adc_tail = adc_buffer;
|
||||||
|
|
||||||
|
|
||||||
uint32_t g_goertzel_samples;
|
uint32_t g_goertzel_samples;
|
||||||
uint32_t g_goertzel_outs;
|
uint32_t g_goertzel_outs;
|
||||||
int32_t g_goertzel, g_goertzelp, g_goertzelp2;
|
int32_t g_goertzel, g_goertzelp, g_goertzelp2;
|
||||||
@@ -271,7 +273,9 @@ int32_t g_goertzelp_store, g_goertzelp2_store;
|
|||||||
void DMA1_Channel1_IRQHandler( void ) __attribute__((interrupt));
|
void DMA1_Channel1_IRQHandler( void ) __attribute__((interrupt));
|
||||||
void DMA1_Channel1_IRQHandler( void )
|
void DMA1_Channel1_IRQHandler( void )
|
||||||
{
|
{
|
||||||
//GPIOD->BSHR = 1; // Turn on GPIOD0 for profiling
|
#ifdef PROFILING_PIN
|
||||||
|
funDigitalWrite( PROFILING_PIN, 1 );
|
||||||
|
#endif
|
||||||
|
|
||||||
// Timer goes backwards when we are moving forwards.
|
// Timer goes backwards when we are moving forwards.
|
||||||
volatile uint16_t * adc_buffer_end = 0;
|
volatile uint16_t * adc_buffer_end = 0;
|
||||||
@@ -285,6 +289,7 @@ void DMA1_Channel1_IRQHandler( void )
|
|||||||
uint32_t goertzel_samples = g_goertzel_samples;
|
uint32_t goertzel_samples = g_goertzel_samples;
|
||||||
// Backup flags.
|
// Backup flags.
|
||||||
volatile int intfr = DMA1->INTFR;
|
volatile int intfr = DMA1->INTFR;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
// Clear all possible flags.
|
// Clear all possible flags.
|
||||||
@@ -381,17 +386,18 @@ void DMA1_Channel1_IRQHandler( void )
|
|||||||
|
|
||||||
int s = rr * rr + ri * ri;
|
int s = rr * rr + ri * ri;
|
||||||
//int intensity = 1<<( ( 32 - __builtin_clz(s) )/2);
|
//int intensity = 1<<( ( 32 - __builtin_clz(s) )/2);
|
||||||
|
#define ABS(x) (((x)<0)?-(x):(x))
|
||||||
int intensity = (abs(rr) + abs(ri)) * 26100 / 32768;
|
int intensity = (ABS(rr) + ABS(ri)) * 26100 / 32768; // Found experimentally (Also try to avoid divide-by-zero.
|
||||||
|
if( intensity == 0 )
|
||||||
|
intensity = 1;
|
||||||
intensity = (intensity + s/intensity)/2;
|
intensity = (intensity + s/intensity)/2;
|
||||||
intensity = (intensity + s/intensity)/2;
|
intensity = (intensity + s/intensity)/2;
|
||||||
intensity = (intensity + s/intensity)/2;
|
intensity = (intensity + s/intensity)/2;
|
||||||
|
intensity_average = intensity_average - (intensity_average>>10) + (intensity);
|
||||||
intensity_max = intensity_max - (intensity_max>>10) + (intensity>>2);
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef PWM_OUTPUT
|
#ifdef PWM_OUTPUT
|
||||||
intensity = intensity * g_volume_pwm * g_pwm_period / (intensity_max>>(7-7));
|
intensity = intensity * g_volume_pwm * g_pwm_period / (intensity_average>>(10-8));
|
||||||
if( intensity >= g_pwm_period-1 ) intensity = g_pwm_period-2;
|
if( intensity >= g_pwm_period-1 ) intensity = g_pwm_period-2;
|
||||||
if( intensity < 1 ) intensity = 1;
|
if( intensity < 1 ) intensity = 1;
|
||||||
TIM1->CH2CVR = intensity; // Actual duty cycle (Off to begin with)
|
TIM1->CH2CVR = intensity; // Actual duty cycle (Off to begin with)
|
||||||
@@ -404,7 +410,6 @@ void DMA1_Channel1_IRQHandler( void )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
intfr = DMA1->INTFR;
|
intfr = DMA1->INTFR;
|
||||||
} while( intfr & DMA1_IT_GL1 );
|
} while( intfr & DMA1_IT_GL1 );
|
||||||
|
|
||||||
@@ -412,8 +417,10 @@ void DMA1_Channel1_IRQHandler( void )
|
|||||||
g_goertzelp = goertzelp;
|
g_goertzelp = goertzelp;
|
||||||
g_goertzel = goertzel;
|
g_goertzel = goertzel;
|
||||||
g_goertzel_samples = goertzel_samples;
|
g_goertzel_samples = goertzel_samples;
|
||||||
|
|
||||||
//GPIOD->BSHR = 1<<16; // Turn off GPIOD0 for profiling
|
#ifdef PROFILING_PIN
|
||||||
|
funDigitalWrite( PROFILING_PIN, 0 ); // For profiling
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32_t gets2()
|
static inline uint32_t gets2()
|
||||||
@@ -453,8 +460,8 @@ void InnerLoop()
|
|||||||
int rr = qibaselogs[glread++];
|
int rr = qibaselogs[glread++];
|
||||||
int ri = qibaselogs[glread++];
|
int ri = qibaselogs[glread++];
|
||||||
|
|
||||||
rr = rr * 100 / (intensity_max>>4);
|
rr = rr * 512 / (intensity_average>>4);
|
||||||
ri = ri * 100 / (intensity_max>>4);
|
ri = ri * 512 / (intensity_average>>4);
|
||||||
|
|
||||||
rr += 64;
|
rr += 64;
|
||||||
ri += 64;
|
ri += 64;
|
||||||
@@ -471,7 +478,7 @@ void InnerLoop()
|
|||||||
|
|
||||||
#ifdef ENABLE_OLED
|
#ifdef ENABLE_OLED
|
||||||
char cts[32];
|
char cts[32];
|
||||||
snprintf( cts, 32, "%d %d", intensity_max, intensity );
|
snprintf( cts, 32, "%d", intensity_average );
|
||||||
|
|
||||||
ssd1306_drawstr( 0, 0, cts, 1 );
|
ssd1306_drawstr( 0, 0, cts, 1 );
|
||||||
|
|
||||||
@@ -481,6 +488,7 @@ void InnerLoop()
|
|||||||
//if( ik == sizeof(ssd1306_buffer) ) ik = 0;
|
//if( ik == sizeof(ssd1306_buffer) ) ik = 0;
|
||||||
|
|
||||||
ssd1306_setbuf(0);
|
ssd1306_setbuf(0);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
Delay_Ms(17);
|
Delay_Ms(17);
|
||||||
#endif
|
#endif
|
||||||
@@ -537,8 +545,14 @@ int main()
|
|||||||
#ifdef ENABLE_OLED
|
#ifdef ENABLE_OLED
|
||||||
ssd1306_i2c_setup();
|
ssd1306_i2c_setup();
|
||||||
ssd1306_i2c_init();
|
ssd1306_i2c_init();
|
||||||
ssd1306_init();
|
|
||||||
ssd1306_setbuf(0);
|
if( ssd1306_init() )
|
||||||
|
printf( "Failed to initialize OLED\n" );
|
||||||
|
else
|
||||||
|
printf( "Initialized OLED\n" );
|
||||||
|
|
||||||
|
ssd1306_setbuf(1);
|
||||||
|
ssd1306_refresh();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
@@ -569,12 +583,15 @@ int main()
|
|||||||
EXTEN->EXTEN_CTR |= EXTEN_OPA_NSEL;
|
EXTEN->EXTEN_CTR |= EXTEN_OPA_NSEL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef PROFILING_PIN
|
||||||
|
funPinMode( PROFILING_PIN, GPIO_CFGLR_OUT_50Mhz_PP );
|
||||||
|
#endif
|
||||||
|
|
||||||
SetupTimer1();
|
SetupTimer1();
|
||||||
|
|
||||||
|
|
||||||
funPinMode( PA0, GPIO_CFGLR_OUT_10Mhz_PP );
|
|
||||||
|
|
||||||
USBOTGSetup();
|
USBOTGSetup();
|
||||||
|
|
||||||
|
|
||||||
InnerLoop();
|
InnerLoop();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -583,18 +600,25 @@ int main()
|
|||||||
|
|
||||||
|
|
||||||
uint8_t scratchpad[256];
|
uint8_t scratchpad[256];
|
||||||
|
int g_isConfigurePacket = 0;
|
||||||
|
|
||||||
int HandleHidUserSetReportSetup( struct _USBState * ctx, tusb_control_request_t * req )
|
int HandleHidUserSetReportSetup( struct _USBState * ctx, tusb_control_request_t * req )
|
||||||
{
|
{
|
||||||
int id = req->wValue & 0xff;
|
int id = req->wValue & 0xff;
|
||||||
if( id == 0xaa )
|
g_isConfigurePacket = 0;
|
||||||
|
if( id == 0xaa && req->wLength < sizeof( scratchpad ) )
|
||||||
{
|
{
|
||||||
// memset( scratchpad, 0x55, sizeof(scratchpad) );
|
// memset( scratchpad, 0x55, sizeof(scratchpad) );
|
||||||
//printf( "SET REPORT! %d [%02x]\n", req->wLength, scratchpad[200] );
|
//printf( "SET REPORT! %d [%02x]\n", req->wLength, scratchpad[200] );
|
||||||
ctx->pCtrlPayloadPtr = scratchpad;
|
ctx->pCtrlPayloadPtr = scratchpad;
|
||||||
return req->wLength;
|
return req->wLength;
|
||||||
}
|
}
|
||||||
|
else if( id == 0xac && req->wLength < sizeof( scratchpad ) )
|
||||||
|
{
|
||||||
|
g_isConfigurePacket = 1;
|
||||||
|
ctx->pCtrlPayloadPtr = scratchpad;
|
||||||
|
return req->wLength;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -623,6 +647,11 @@ int HandleHidUserReportDataIn( struct _USBState * ctx, uint8_t * data, int len )
|
|||||||
|
|
||||||
void HandleHidUserReportOutComplete( struct _USBState * ctx )
|
void HandleHidUserReportOutComplete( struct _USBState * ctx )
|
||||||
{
|
{
|
||||||
|
if( g_isConfigurePacket )
|
||||||
|
{
|
||||||
|
printf( "Is Configure Packet\n" );
|
||||||
|
g_isConfigurePacket = 0;
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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 ( 254 ), // 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
|
||||||
|
|
||||||
Reference in New Issue
Block a user