#ifndef _MINICHLINK_H #define _MINICHLINK_H #include <stdint.h> struct MiniChlinkFunctions { // All functions return 0 if OK, negative number if fault, positive number as status code. // Low-level functions, if they exist. int (*WriteReg32)( void * dev, uint8_t reg_7_bit, uint32_t command ); int (*ReadReg32)( void * dev, uint8_t reg_7_bit, uint32_t * commandresp ); int (*FlushLLCommands)( void * dev ); int (*DelayUS)( void * dev, int microseconds ); // Higher-level functions can be generated automatically. int (*SetupInterface)( void * dev ); int (*Control3v3)( void * dev, int bOn ); int (*Control5v)( void * dev, int bOn ); int (*Unbrick)( void * dev ); // Turns on chip, erases everything, powers off. int (*Exit)( void * dev ); int (*HaltMode)( void * dev, int mode ); //0 for halt, 1 for reset, 2 for resume int (*ConfigureNRSTAsGPIO)( void * dev, int one_if_yes_gpio ); // No boundary or limit rules. Must support any combination of alignment and size. int (*WriteBinaryBlob)( void * dev, uint32_t address_to_write, uint32_t blob_size, uint8_t * blob ); int (*ReadBinaryBlob)( void * dev, uint32_t address_to_read_from, uint32_t read_size, uint8_t * blob ); int (*Erase)( void * dev, uint32_t address, uint32_t length, int type ); //type = 0 for fast, 1 for whole-chip // MUST be 4-byte-aligned. int (*VoidHighLevelState)( void * dev ); int (*WriteWord)( void * dev, uint32_t address_to_write, uint32_t data ); int (*ReadWord)( void * dev, uint32_t address_to_read, uint32_t * data ); // Debugging operations. // Note: You must already be in break mode to use these otherwise they // will return nonsensical data. // For x0...xN, use 0x1000 + regno. // For PC, use 0x7b1 int (*ReadCPURegister)( void * dev, uint32_t regno, uint32_t * regret ); int (*WriteCPURegister)( void * dev, uint32_t regno, uint32_t regval ); // Actually returns 17 registers (All 16 CPU registers + the debug register) int (*ReadAllCPURegisters)( void * dev, uint32_t * regret ); int (*WriteAllCPURegisters)( void * dev, uint32_t * regret ); int (*SetEnableBreakpoints)( void * dev, int halt_on_break, int single_step ); int (*WaitForFlash)( void * dev ); int (*WaitForDoneOp)( void * dev, int ignore ); int (*PrintChipInfo)( void * dev ); // Geared for flash, but could be anything. int (*BlockWrite64)( void * dev, uint32_t address_to_write, uint8_t * data ); // TODO: What about 64-byte block-reads? // TODO: What about byte read/write? // TODO: What about half read/write? // Returns positive if received text. // Returns negative if error. // Returns 0 if no text waiting. // Note: YOU CANNOT make lsb of leaveflagA bit in place 0x80 be high!!! int (*PollTerminal)( void * dev, uint8_t * buffer, int maxlen, uint32_t leaveflagA, int leaveflagB ); int (*PerformSongAndDance)( void * dev ); int (*VendorCommand)( void * dev, const char * command ); // Probably no need to override these. The base layer handles them. int (*WriteHalfWord)( void * dev, uint32_t address_to_write, uint16_t data ); int (*ReadHalfWord)( void * dev, uint32_t address_to_read, uint16_t * data ); int (*WriteByte)( void * dev, uint32_t address_to_write, uint8_t data ); int (*ReadByte)( void * dev, uint32_t address_to_read, uint8_t * data ); }; /** If you are writing a driver, the minimal number of functions you can implement are: WriteReg32 ReadReg32 FlushLLCommands */ // Convert a 4-character string to an int. #define STTAG( x ) (*((uint32_t*)(x))) struct InternalState; struct ProgrammerStructBase { struct InternalState * internal; // You can put other things here. }; struct InternalState { uint32_t statetag; uint32_t currentstateval; uint32_t flash_unlocked; int lastwriteflags; int processor_in_mode; int autoincrement; uint32_t ram_base; uint32_t ram_size; }; #define DMDATA0 0x04 #define DMDATA1 0x05 #define DMCONTROL 0x10 #define DMSTATUS 0x11 #define DMHARTINFO 0x12 #define DMABSTRACTCS 0x16 #define DMCOMMAND 0x17 #define DMABSTRACTAUTO 0x18 #define DMPROGBUF0 0x20 #define DMPROGBUF1 0x21 #define DMPROGBUF2 0x22 #define DMPROGBUF3 0x23 #define DMPROGBUF4 0x24 #define DMPROGBUF5 0x25 #define DMPROGBUF6 0x26 #define DMPROGBUF7 0x27 #define DMCPBR 0x7C #define DMCFGR 0x7D #define DMSHDWCFGR 0x7E #if defined( WIN32 ) || defined( _WIN32 ) #if defined( MINICHLINK_AS_LIBRARY ) #define DLLDECORATE __declspec(dllexport) #elif defined( MINICHLINK_IMPORT ) #define DLLDECORATE __declspec(dllimport) #else #define DLLDECORATE #endif #else #define DLLDECORATE #endif void * MiniCHLinkInitAsDLL(struct MiniChlinkFunctions ** MCFO) DLLDECORATE; extern struct MiniChlinkFunctions MCF; // Returns 'dev' on success, else 0. void * TryInit_WCHLinkE(); void * TryInit_ESP32S2CHFUN(); void * TryInit_NHCLink042(void); // Returns 0 if ok, populated, 1 if not populated. int SetupAutomaticHighLevelFunctions( void * dev ); // Useful for converting numbers like 0x, etc. int64_t SimpleReadNumberInt( const char * number, int64_t defaultNumber ); // For drivers to call int DefaultVoidHighLevelState( void * dev ); // GDBSever Functions int SetupGDBServer( void * dev ); int PollGDBServer( void * dev ); int IsGDBServerInShadowHaltState( void * dev ); void ExitGDBServer( void * dev ); #endif