Update comments on nixietest + Add debug tool. + Add ch32v003 firmware for the controller.
This commit is contained in:
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
[submodule "firmware/ch32v003fun"]
|
||||
path = firmware/ch32v003fun
|
||||
url = https://github.com/cnlohr/ch32v003fun
|
||||
1
firmware/ch32v003fun
Submodule
1
firmware/ch32v003fun
Submodule
Submodule firmware/ch32v003fun added at fe86ce83da
12
firmware/nixitest1/Makefile
Normal file
12
firmware/nixitest1/Makefile
Normal file
@@ -0,0 +1,12 @@
|
||||
all : flash
|
||||
|
||||
TARGET:=nixitest1
|
||||
|
||||
CH32V003FUN:=../ch32v003fun/ch32v003fun
|
||||
MINICHLINK:=../ch32v003fun/minichlink
|
||||
include ../ch32v003fun/ch32v003fun/ch32v003fun.mk
|
||||
|
||||
flash : cv_flash
|
||||
clean : cv_clean
|
||||
|
||||
|
||||
190
firmware/nixitest1/nixitest1.c
Normal file
190
firmware/nixitest1/nixitest1.c
Normal file
@@ -0,0 +1,190 @@
|
||||
// Could be defined here, or in the processor defines.
|
||||
#define SYSTEM_CORE_CLOCK 48000000
|
||||
|
||||
#include "ch32v003fun.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#define APB_CLOCK SYSTEM_CORE_CLOCK
|
||||
|
||||
uint32_t count;
|
||||
|
||||
#define ABSOLUTE_MAX_ADC_SET 368 //172 volts (definitely do not exceed)
|
||||
#define PWM_PERIOD 70
|
||||
#define PWM_MAXIMUM_DUTY 40
|
||||
#define ERROR_P_TERM 0 // Actually a shift. 0 is rattl-y but averages out and gives tight control.
|
||||
|
||||
int target_feedback = 0;
|
||||
int lastadc = 0;
|
||||
|
||||
void ADC1_IRQHandler(void) __attribute__((interrupt));
|
||||
void ADC1_IRQHandler(void)
|
||||
{
|
||||
int adc = lastadc = ADC1->RDATAR;
|
||||
int err = target_feedback - adc;
|
||||
ADC1->STATR &= ~ADC_EOC;
|
||||
|
||||
if( err < 0 )
|
||||
TIM1->CH2CVR = 0;
|
||||
else
|
||||
{
|
||||
err = err >> ERROR_P_TERM;
|
||||
if( err > PWM_MAXIMUM_DUTY ) err = PWM_MAXIMUM_DUTY;
|
||||
TIM1->CH2CVR = err;
|
||||
}
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
static void SetupTimer()
|
||||
{
|
||||
// Main inductor is ~5uH.
|
||||
// Our peak current is ~200mA
|
||||
// Our target cycle duty is ~1/6
|
||||
// Our nominal voltage is ~4V
|
||||
// 4V / .000005H = 800000A/s / 0.2 = 0.00000025 = 250nS, but we are only on for 1/6 of the time., or 1.5uS. Let's set our period to be 64/48 = 652nS.
|
||||
|
||||
// GPIO A1 Push-Pull, Auto Function, 50 MHz Drive Current
|
||||
GPIOA->CFGLR &= ~(0xf<<(4*1));
|
||||
GPIOA->CFGLR |= (GPIO_Speed_50MHz | GPIO_CNF_OUT_PP_AF)<<(4*1);
|
||||
|
||||
// Enable Timer 1
|
||||
RCC->APB2PRSTR |= RCC_APB2Periph_TIM1;
|
||||
RCC->APB2PRSTR &= ~RCC_APB2Periph_TIM1;
|
||||
|
||||
TIM1->PSC = 0x0000; // Prescalar to 0x0000 (so, 24MHz base clock)
|
||||
TIM1->ATRLR = PWM_PERIOD;
|
||||
TIM1->SWEVGR = TIM_UG;
|
||||
TIM1->CCER = TIM_CC2E | TIM_CC2NP; // CH2 is control for FET.
|
||||
TIM1->CHCTLR1 = TIM_OC2M_2 | TIM_OC2M_1;
|
||||
|
||||
TIM1->CH2CVR = 0; // Actual duty cycle.
|
||||
|
||||
// Setup TRGO for ADC. TODO: this should be on update (TIM_MMS_1)
|
||||
TIM1->CTLR2 = TIM_MMS_1;
|
||||
|
||||
// Enable TIM1 outputs
|
||||
TIM1->BDTR = TIM_MOE;
|
||||
TIM1->CTLR1 = TIM_CEN;
|
||||
}
|
||||
|
||||
static void SetupADC()
|
||||
{
|
||||
// Configure ADC.
|
||||
// PD4 is analog input chl 7
|
||||
GPIOD->CFGLR &= ~(0xf<<(4*4)); // CNF = 00: Analog, MODE = 00: Input
|
||||
|
||||
// Reset the ADC to init all regs
|
||||
RCC->APB2PRSTR |= RCC_APB2Periph_ADC1;
|
||||
RCC->APB2PRSTR &= ~RCC_APB2Periph_ADC1;
|
||||
|
||||
// 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
|
||||
|
||||
// set sampling time for chl 7
|
||||
ADC1->SAMPTR2 = 6<<(3*7); // 0:7 => 3/9/15/30/43/57/73/241 cycles
|
||||
// (4 == 43 cycles), (6 = 73 cycles) Note these are alrady /2, so
|
||||
// setting this to 73 cycles actually makes it wait 256 total cycles
|
||||
// @ 48MHz.
|
||||
|
||||
// turn on ADC and set rule group to sw trig
|
||||
ADC1->CTLR2 |= ADC_ADON; // 0 = Use TRGO event for Timer 1.
|
||||
|
||||
// Reset calibration
|
||||
ADC1->CTLR2 |= ADC_RSTCAL;
|
||||
while(ADC1->CTLR2 & ADC_RSTCAL);
|
||||
|
||||
// Calibrate
|
||||
ADC1->CTLR2 |= ADC_CAL;
|
||||
while(ADC1->CTLR2 & ADC_CAL);
|
||||
|
||||
// Allow Timer1 TRGO to trigger ADC conversion.
|
||||
ADC1->CTLR2 |= ADC_EXTTRIG;
|
||||
|
||||
// enable the ADC Conversion Complete IRQ
|
||||
NVIC_EnableIRQ( ADC_IRQn );
|
||||
|
||||
// Enable the End-of-conversion interrupt.
|
||||
ADC1->CTLR1 = ADC_EOCIE;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
SystemInit48HSI();
|
||||
SetupDebugPrintf();
|
||||
Delay_Ms( 10 );
|
||||
|
||||
// Enable Peripherals
|
||||
RCC->APB2PCENR |= RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOA
|
||||
| RCC_APB2Periph_TIM1 | RCC_APB2Periph_ADC1;
|
||||
|
||||
GPIOD->CFGLR =
|
||||
(GPIO_Speed_10MHz | GPIO_CNF_OUT_PP)<<(4*6) | // GPIO D6 Push-Pull (for debug)
|
||||
(GPIO_Speed_50MHz | GPIO_CNF_OUT_PP)<<(4*7) | // DIG_AUX
|
||||
(GPIO_Speed_50MHz | GPIO_CNF_OUT_PP)<<(4*3) | // DIG_9
|
||||
(GPIO_Speed_50MHz | GPIO_CNF_OUT_PP)<<(4*2) | // DIG_8
|
||||
(GPIO_Speed_10MHz | GPIO_CNF_IN_FLOATING)<<(4*1) | // Leave PGM pin floating, dont make it an ADC.
|
||||
(GPIO_Speed_50MHz | GPIO_CNF_OUT_PP)<<(4*0); // DIG_DOT
|
||||
|
||||
GPIOC->CFGLR =
|
||||
(GPIO_Speed_50MHz | GPIO_CNF_OUT_PP)<<(4*0) | // DIG_0
|
||||
(GPIO_Speed_50MHz | GPIO_CNF_OUT_PP)<<(4*1) | // DIG_1
|
||||
(GPIO_Speed_50MHz | GPIO_CNF_OUT_PP)<<(4*2) | // DIG_2
|
||||
(GPIO_Speed_50MHz | GPIO_CNF_OUT_PP)<<(4*3) | // DIG_3
|
||||
(GPIO_Speed_50MHz | GPIO_CNF_OUT_PP)<<(4*4) | // DIG_4
|
||||
(GPIO_Speed_50MHz | GPIO_CNF_OUT_PP)<<(4*5) | // DIG_5
|
||||
(GPIO_Speed_50MHz | GPIO_CNF_OUT_PP)<<(4*6) | // DIG_6
|
||||
(GPIO_Speed_50MHz | GPIO_CNF_OUT_PP)<<(4*7); // DIG_7
|
||||
|
||||
|
||||
|
||||
GPIOC->BSHR = 1<<4;
|
||||
|
||||
SetupADC();
|
||||
SetupTimer();
|
||||
|
||||
*DMDATA0 = 0;
|
||||
|
||||
while(1)
|
||||
{
|
||||
GPIOD->BSHR = 1<<6;
|
||||
GPIOD->BSHR = (1<<(16+6));
|
||||
uint32_t dmdword = *DMDATA0;
|
||||
if( (dmdword & 0xf0) == 0x40 )
|
||||
{
|
||||
// ./minichlink -s 0x04 0x01110040
|
||||
// ./minichlink -g 0x04
|
||||
|
||||
// It is a valid status word back from the PC.
|
||||
int feedback = dmdword>>20;
|
||||
if( feedback > ABSOLUTE_MAX_ADC_SET ) feedback = ABSOLUTE_MAX_ADC_SET;
|
||||
target_feedback = feedback;
|
||||
|
||||
int segmenton = (dmdword>>16)&0x0f;
|
||||
// Other various things are lower.
|
||||
|
||||
// Turn everything off.
|
||||
GPIOC->BSHR = 0xff<<16;
|
||||
GPIOD->BSHR = 0b10001101 << 16;
|
||||
|
||||
if( segmenton >= 1 )
|
||||
{
|
||||
segmenton--;
|
||||
if( segmenton < 8 )
|
||||
GPIOC->BSHR = 1<<segmenton;
|
||||
else if( segmenton == 8 )
|
||||
GPIOD->BSHR = 1<<2;
|
||||
else if( segmenton == 9 )
|
||||
GPIOD->BSHR = 1<<3;
|
||||
else if( segmenton == 10 )
|
||||
GPIOD->BSHR = 1<<0;
|
||||
else if( segmenton == 11 )
|
||||
GPIOD->BSHR = 1<<7;
|
||||
}
|
||||
|
||||
*DMDATA0 = lastadc << 16;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
7
firmware/nixitest1/testnix/Makefile
Normal file
7
firmware/nixitest1/testnix/Makefile
Normal file
@@ -0,0 +1,7 @@
|
||||
all : testnix
|
||||
|
||||
testnix : testnix.c
|
||||
gcc -o $@ $^ ../../ch32v003fun/minichlink/minichlink.so -lX11
|
||||
|
||||
clean :
|
||||
rm -rf testnix
|
||||
7413
firmware/nixitest1/testnix/rawdraw_sf.h
Normal file
7413
firmware/nixitest1/testnix/rawdraw_sf.h
Normal file
File diff suppressed because it is too large
Load Diff
138
firmware/nixitest1/testnix/testnix.c
Normal file
138
firmware/nixitest1/testnix/testnix.c
Normal file
@@ -0,0 +1,138 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#define CNFG_IMPLEMENTATION
|
||||
#include "rawdraw_sf.h"
|
||||
|
||||
#include "../../ch32v003fun/minichlink/minichlink.h"
|
||||
|
||||
int targetnum = 0;
|
||||
|
||||
#define VOLTAGE_SCALE 2.01
|
||||
|
||||
const char * targdisp[] = { " ", "0", "9", "8", "7", "6", "5", "4", "3", "2", "1", ".", "N" };
|
||||
void HandleKey( int keycode, int bDown )
|
||||
{
|
||||
if( bDown )
|
||||
{
|
||||
switch( keycode )
|
||||
{
|
||||
case '~': case '`': targetnum = 0; break;
|
||||
case '1': targetnum = 10; break;
|
||||
case '2': targetnum = 9; break;
|
||||
case '3': targetnum = 8; break;
|
||||
case '4': targetnum = 7; break;
|
||||
case '5': targetnum = 6; break;
|
||||
case '6': targetnum = 5; break;
|
||||
case '7': targetnum = 4; break;
|
||||
case '8': targetnum = 3; break;
|
||||
case '9': targetnum = 2; break;
|
||||
case '0': targetnum = 1; break;
|
||||
case '-': case '_': targetnum = 11; break;
|
||||
case '=': case '+': targetnum = 12; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int do_set = 0;
|
||||
int sety = 0;
|
||||
void HandleButton( int x, int y, int button, int bDown ) { }
|
||||
void HandleMotion( int x, int y, int mask ) { sety = y; do_set = mask; }
|
||||
void HandleDestroy() { }
|
||||
|
||||
#define VOLTHISTSIZE 2048
|
||||
float volthist[VOLTHISTSIZE];
|
||||
int volthisthead = 0;
|
||||
|
||||
int main()
|
||||
{
|
||||
void * dev = TryInit_ESP32S2CHFUN();
|
||||
if( !dev )
|
||||
{
|
||||
fprintf( stderr, "Error: Couldn't find programmer\n" );
|
||||
return -9;
|
||||
}
|
||||
SetupAutomaticHighLevelFunctions( dev );
|
||||
if( MCF.SetupInterface( dev ) )
|
||||
{
|
||||
fprintf( stderr, "Error: failed to setup\n" );
|
||||
return -9;
|
||||
}
|
||||
uint32_t rmask = 0x17000040;
|
||||
|
||||
printf( "DEV: %p\n", dev );
|
||||
CNFGSetup( "nixitest1 debug app", 640, 480 );
|
||||
while(CNFGHandleInput())
|
||||
{
|
||||
const uint32_t GLOW = 0xFFD010FF;
|
||||
short w, h;
|
||||
int x, y;
|
||||
CNFGClearFrame();
|
||||
CNFGGetDimensions( &w, &h );
|
||||
|
||||
if( do_set )
|
||||
{
|
||||
do_set = 0;
|
||||
float set_v = 450 - sety;
|
||||
set_v = set_v/2;
|
||||
if( set_v > 0 && set_v < 180 )
|
||||
{
|
||||
rmask = ( ( (uint32_t)(set_v * VOLTAGE_SCALE) ) << 20 ) | 0x40;
|
||||
}
|
||||
}
|
||||
MCF.WriteReg32( dev, 0x04, rmask | targetnum << 16 );
|
||||
uint32_t status = 0xffffffff;
|
||||
int r = MCF.ReadReg32( dev, 0x04, &status );
|
||||
float voltage = ((float)(status>>16))/VOLTAGE_SCALE;
|
||||
volthist[volthisthead] = voltage;
|
||||
volthisthead = (volthisthead + 1) % VOLTHISTSIZE;
|
||||
CNFGColor( (voltage > 180)?0xff0000ff:GLOW );
|
||||
CNFGPenX = 1;
|
||||
CNFGPenY = 1;
|
||||
char cts[128];
|
||||
sprintf( cts, "HV Line: %3.0f V\nRStatus: %d", voltage, r );
|
||||
CNFGDrawText( cts, 4 );
|
||||
|
||||
for( y = 0; y < 2; y++ ) for( x = 0; x < 2; x++ )
|
||||
{
|
||||
CNFGPenX = 200+x;
|
||||
CNFGPenY = 1+y;
|
||||
CNFGDrawText( targdisp[targetnum], 10 );
|
||||
}
|
||||
|
||||
int i;
|
||||
int vhp = (volthisthead - 1 + VOLTHISTSIZE*100)%VOLTHISTSIZE;
|
||||
float vl = voltage;
|
||||
|
||||
CNFGColor( 0xff0000ff );
|
||||
CNFGTackSegment( 0, 450-180*2, w, 450-180*2 );
|
||||
CNFGPenX = w - 250; CNFGPenY = 450-180*2-10;
|
||||
CNFGDrawText( "WARNING: DO NOT EXCEED THIS LINE (180V)", 2 );
|
||||
|
||||
for( i = 0; i < 9; i++ )
|
||||
{
|
||||
CNFGColor( (i == 0 )?0xD0D0D0FF:0x303030ff );
|
||||
CNFGPenX = 1;
|
||||
CNFGPenY = 450 - 10 - i * 40;
|
||||
sprintf( cts, "%d volts", i * 20 );
|
||||
CNFGDrawText( cts, 2 );
|
||||
CNFGTackSegment( 0,450 - i * 40, w, 450 - i * 40 );
|
||||
CNFGColor( GLOW );
|
||||
}
|
||||
|
||||
|
||||
for( i = 0; i < w; i++ )
|
||||
{
|
||||
float v = volthist[vhp];
|
||||
if( v == 0 ) break;
|
||||
CNFGTackSegment( i, 450 - vl*2, i+1, 450 - v*2 );
|
||||
vhp = (vhp - 1 + VOLTHISTSIZE*100)%VOLTHISTSIZE;
|
||||
//printf( "%f\n", v );
|
||||
vl = v;
|
||||
}
|
||||
|
||||
CNFGSwapBuffers();
|
||||
} while( 1 );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1000,6 +1000,11 @@
|
||||
(effects (font (size 1.27 1.27)) (justify left bottom))
|
||||
(uuid 47c5a941-5ea6-4692-87af-c0393bd2065d)
|
||||
)
|
||||
(text "TODO:\n * Probably remove HVIMON >> DEFINITELY\n * Include pull-down on HVCTL >> DEFINITELY.\n"
|
||||
(at 24.13 147.32 0)
|
||||
(effects (font (size 1.27 1.27)) (justify left bottom))
|
||||
(uuid 5c570b8c-e31c-47bd-a56b-23a2e3a9d6d7)
|
||||
)
|
||||
|
||||
(global_label "DIG_1" (shape input) (at 31.75 52.07 180) (fields_autoplaced)
|
||||
(effects (font (size 1.27 1.27)) (justify right))
|
||||
|
||||
Reference in New Issue
Block a user