Skip to content
Snippets Groups Projects
Commit 09f0bada authored by cnlohr's avatar cnlohr
Browse files

My esp32s2 is a signal generator now I guess.

Add ability to use vendor commands with programmers.
parent 555e8ccf
No related branches found
No related tags found
No related merge requests found
// Could be defined here, or in the processor defines.
#define SYSTEM_CORE_CLOCK 24000000
#include "ch32v003fun.h"
#include <stdio.h>
#define APB_CLOCK SYSTEM_CORE_CLOCK
uint32_t count;
void RamFunction() __attribute__((naked));
void RamFunction()
{
asm volatile("\n\
li a0, 1 | (1<<4)\n\
li a1, (1<<16) | (1<<(16+4))\n\
la a2, 0x40011410\n\
1:\n\
c.sw a0, 0(a2)\n\
c.sw a1, 0(a2)\n\
c.sw a0, 0(a2)\n\
c.sw a1, 0(a2)\n\
c.sw a0, 0(a2)\n\
c.sw a1, 0(a2)\n\
c.sw a0, 0(a2)\n\
c.sw a1, 0(a2)\n\
j 1b" );
}
uint8_t rambuffer[128];
int main()
{
EXTEN->EXTEN_CTR = EXTEN_LDO_TRIM; // Boost LDO.
SystemInitHSEPLL( RCC_HSEBYP );
// When running from RAM appears to go up to about 96MHz.
// Enable GPIOD.
RCC->APB2PCENR |= RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOC;
// GPIO D0 Push-Pull, 10MHz Output
GPIOD->CFGLR &= ~(0xf<<(4*0));
GPIOD->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP)<<(4*0);
// GPIO D0 Push-Pull, 10MHz Output
GPIOD->CFGLR &= ~(0xf<<(4*4));
GPIOD->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP)<<(4*4);
// GPIO D0 Push-Pull, 10MHz Output
GPIOC->CFGLR &= ~(0xf<<(4*4));
GPIOC->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP)<<(4*4);
memcpy( rambuffer, RamFunction, 128 );
void (*fn)() = (void*) rambuffer;
fn();
}
...@@ -840,6 +840,7 @@ void SystemInitHSEPLL( int HSEBYP ) ...@@ -840,6 +840,7 @@ void SystemInitHSEPLL( int HSEBYP )
RCC->CTLR = RCC_HSION | RCC_HSEON | RCC_PLLON | HSEBYP; // Enable HSE and keep HSI+PLL on. RCC->CTLR = RCC_HSION | RCC_HSEON | RCC_PLLON | HSEBYP; // Enable HSE and keep HSI+PLL on.
while(!(RCC->CTLR&RCC_HSERDY)); while(!(RCC->CTLR&RCC_HSERDY));
RCC->CFGR0 = RCC_SW_HSE | RCC_HPRE_DIV1; // HCLK = SYSCLK = APB1 and use HSE for System Clock. RCC->CFGR0 = RCC_SW_HSE | RCC_HPRE_DIV1; // HCLK = SYSCLK = APB1 and use HSE for System Clock.
FLASH->ACTLR = FLASH_ACTLR_LATENCY_1; // 1 Cycle Latency
RCC->CTLR = RCC_HSEON | HSEBYP; // Turn off PLL and HSI. RCC->CTLR = RCC_HSEON | HSEBYP; // Turn off PLL and HSI.
RCC->CFGR0 = RCC_SW_HSE | RCC_HPRE_DIV1 | RCC_PLLSRC_HSE_Mul2; // Use PLL with HSE. RCC->CFGR0 = RCC_SW_HSE | RCC_HPRE_DIV1 | RCC_PLLSRC_HSE_Mul2; // Use PLL with HSE.
RCC->CTLR = RCC_HSEON | RCC_PLLON | HSEBYP; // Turn PLL Back on.. RCC->CTLR = RCC_HSEON | RCC_PLLON | HSEBYP; // Turn PLL Back on..
......
No preview for this file type
...@@ -13,7 +13,7 @@ int main() ...@@ -13,7 +13,7 @@ int main()
SystemInit48HSI(); SystemInit48HSI();
// Enable GPIOD. // Enable GPIOD.
RCC->APB2PCENR |= RCC_APB2Periph_GPIOD; RCC->APB2PCENR |= RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOC;
// GPIO D0 Push-Pull, 10MHz Output // GPIO D0 Push-Pull, 10MHz Output
GPIOD->CFGLR &= ~(0xf<<(4*0)); GPIOD->CFGLR &= ~(0xf<<(4*0));
...@@ -23,12 +23,18 @@ int main() ...@@ -23,12 +23,18 @@ int main()
GPIOD->CFGLR &= ~(0xf<<(4*4)); GPIOD->CFGLR &= ~(0xf<<(4*4));
GPIOD->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP)<<(4*4); GPIOD->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP)<<(4*4);
// GPIO D0 Push-Pull, 10MHz Output
GPIOC->CFGLR &= ~(0xf<<(4*4));
GPIOC->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP)<<(4*4);
while(1) while(1)
{ {
GPIOD->BSHR = 1 | (1<<4); // Turn on GPIOD0 GPIOD->BSHR = 1 | (1<<4); // Turn on GPIOD0&D4
Delay_Ms( 200 ); GPIOC->BSHR = 1; // Turn on GPIOC0
Delay_Ms( 250 );
GPIOD->BSHR = (1<<16) | (1<<(16+4)); // Turn off GPIOD0 GPIOD->BSHR = (1<<16) | (1<<(16+4)); // Turn off GPIOD0
Delay_Ms( 200 ); GPIOC->BSHR = (1<<16); // Turn off GPIOC0
Delay_Ms( 250 );
count++; count++;
} }
} }
...@@ -11,7 +11,6 @@ ...@@ -11,7 +11,6 @@
#include "minichlink.h" #include "minichlink.h"
#include "../ch32v003fun/ch32v003fun.h" #include "../ch32v003fun/ch32v003fun.h"
static int64_t SimpleReadNumberInt( const char * number, int64_t defaultNumber );
static int64_t StringToMemoryAddress( const char * number ); static int64_t StringToMemoryAddress( const char * number );
static void StaticUpdatePROGBUFRegs( void * dev ); static void StaticUpdatePROGBUFRegs( void * dev );
static int InternalUnlockBootloader( void * dev ); static int InternalUnlockBootloader( void * dev );
...@@ -41,9 +40,11 @@ int main( int argc, char ** argv ) ...@@ -41,9 +40,11 @@ int main( int argc, char ** argv )
int status; int status;
int must_be_end = 0; int must_be_end = 0;
int doing_unblock = (argc > 1 && argv[1][0] == '-' && argv[1][1] == 'u' ); int skip_startup =
(argc > 1 && argv[1][0] == '-' && argv[1][1] == 'u' ) |
(argc > 1 && argv[1][0] == '-' && argv[1][1] == 'X' );
if( !doing_unblock && MCF.SetupInterface ) if( !skip_startup && MCF.SetupInterface )
{ {
if( MCF.SetupInterface( dev ) < 0 ) if( MCF.SetupInterface( dev ) < 0 )
{ {
...@@ -178,6 +179,19 @@ keep_going: ...@@ -178,6 +179,19 @@ keep_going:
goto unimplemented; goto unimplemented;
break; break;
} }
case 'X':
{
iarg++;
if( iarg >= argc )
{
fprintf( stderr, "Vendor command requires an actual command\n" );
goto unimplemented;
}
if( MCF.VendorCommand )
if( MCF.VendorCommand( dev, argv[iarg++] ) )
goto unimplemented;
break;
}
case 'r': case 'r':
{ {
if( MCF.HaltMode ) MCF.HaltMode( dev, 0 ); if( MCF.HaltMode ) MCF.HaltMode( dev, 0 );
...@@ -409,7 +423,7 @@ unimplemented: ...@@ -409,7 +423,7 @@ unimplemented:
static int StaticUnlockFlash( void * dev, struct InternalState * iss ); static int StaticUnlockFlash( void * dev, struct InternalState * iss );
static int64_t SimpleReadNumberInt( const char * number, int64_t defaultNumber ) int64_t SimpleReadNumberInt( const char * number, int64_t defaultNumber )
{ {
if( !number || !number[0] ) return defaultNumber; if( !number || !number[0] ) return defaultNumber;
int radix = 10; int radix = 10;
......
...@@ -54,6 +54,8 @@ struct MiniChlinkFunctions ...@@ -54,6 +54,8 @@ struct MiniChlinkFunctions
int (*PerformSongAndDance)( void * dev ); int (*PerformSongAndDance)( void * dev );
int (*VendorCommand)( void * dev, const char * command );
// Do Not override these. they are cursed. // Do Not override these. they are cursed.
int (*WriteHalfWord)( void * dev, uint32_t address_to_write, uint32_t data ); int (*WriteHalfWord)( void * dev, uint32_t address_to_write, uint32_t data );
int (*ReadHalfWord)( void * dev, uint32_t address_to_read, uint32_t * data ); int (*ReadHalfWord)( void * dev, uint32_t address_to_read, uint32_t * data );
...@@ -116,5 +118,8 @@ void * TryInit_ESP32S2CHFUN(); ...@@ -116,5 +118,8 @@ void * TryInit_ESP32S2CHFUN();
// Returns 0 if ok, populated, 1 if not populated. // Returns 0 if ok, populated, 1 if not populated.
int SetupAutomaticHighLevelFunctions( void * dev ); int SetupAutomaticHighLevelFunctions( void * dev );
// Useful for converting numbers like 0x, etc.
int64_t SimpleReadNumberInt( const char * number, int64_t defaultNumber );
#endif #endif
...@@ -255,6 +255,73 @@ int ESPVoidHighLevelState( void * dev ) ...@@ -255,6 +255,73 @@ int ESPVoidHighLevelState( void * dev )
return 0; return 0;
} }
int ESPVendorCommand( void * dev, const char * cmd )
{
char command[10] = { 0 };
char tbuf[10] = { 0 };
int fields[10];
char c;
int i = 0;
int f = 0;
while( (c = *cmd++) )
{
if( c == ':' ) break;
if( c == '\0' ) break;
if( i + 1 >= sizeof( command )) break;
command[i++] = c;
command[i] = 0;
}
i = 0;
f = 0;
while( 1 )
{
c = *cmd++;
if( c == ':' || c == '\0' )
{
fields[f++] = SimpleReadNumberInt( tbuf, 0 );
puts( tbuf );
if( f == 10 ) break;
tbuf[0] = 0;
i = 0;
if( c == '\0' ) break;
continue;
}
if( i + 1 >= sizeof( tbuf )) break;
tbuf[i++] = c;
tbuf[i] = 0;
}
printf( "Got Vendor Command \"%s\"\n", command );
ESPFlushLLCommands( dev );
if( strcasecmp( command, "ECLK" ) == 0 )
{
printf( "Setting up external clock on pin.\n" );
if( f < 5 )
{
fprintf( stderr, "Error: Need fields :use_apll:sdm0:sdm1:sdm2:odiv try 1:0:0:8:3 for 24MHz\n" );
fprintf( stderr, "Definition:\n\
use_apll = Configures APLL = 480 / 4 = 120\n\
40 * (SDM2 + SDM1/(2^8) + SDM0/(2^16) + 4) / ( 2 * (ODIV+2) );\n\
Datasheet recommends that numerator is between 300 and 500MHz.\n ");
return -9;
}
Write2LE( dev, 0x0cfe );
Write1( dev, fields[0] );
Write1( dev, fields[1] );
Write1( dev, fields[2] );
Write1( dev, fields[3] );
Write1( dev, fields[4] );
Write1( dev, 0 );
Write1( dev, 0 );
Write1( dev, 0 );
ESPFlushLLCommands( dev );
}
else
{
fprintf( stderr, "Error: Unknown vendor command %s\n", command );
}
return 0;
}
void * TryInit_ESP32S2CHFUN() void * TryInit_ESP32S2CHFUN()
{ {
#define VID 0x303a #define VID 0x303a
...@@ -287,7 +354,7 @@ void * TryInit_ESP32S2CHFUN() ...@@ -287,7 +354,7 @@ void * TryInit_ESP32S2CHFUN()
MCF.PerformSongAndDance = ESPPerformSongAndDance; MCF.PerformSongAndDance = ESPPerformSongAndDance;
MCF.BlockWrite64 = ESPBlockWrite64; MCF.BlockWrite64 = ESPBlockWrite64;
MCF.VendorCommand = ESPVendorCommand;
// Reset internal programmer state. // Reset internal programmer state.
Write2LE( eps, 0x0afe ); Write2LE( eps, 0x0afe );
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment