205 lines
6.6 KiB
C
205 lines
6.6 KiB
C
#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 );
|
|
int (*ConfigureReadProtection)( void * dev, int one_if_yes_protect );
|
|
|
|
// 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 (*PrepForLongOp)( void * dev ); // Called before the command that will take a while.
|
|
int (*WaitForFlash)( void * dev );
|
|
int (*WaitForDoneOp)( void * dev, int ignore );
|
|
|
|
int (*PrintChipInfo)( void * dev );
|
|
|
|
// Geared for flash, but could be anything. Note: If in flash, must also erase.
|
|
int (*BlockWrite64)( void * dev, uint32_t address_to_write, uint8_t * data );
|
|
|
|
// 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
|
|
*/
|
|
|
|
inline static int IsAddressFlash( uint32_t addy ) { return ( addy & 0xff000000 ) == 0x08000000 || ( addy & 0x1FFFF000 ) == 0x1FFFF000; }
|
|
|
|
#define HALT_MODE_HALT_AND_RESET 0
|
|
#define HALT_MODE_REBOOT 1
|
|
#define HALT_MODE_RESUME 2
|
|
#define HALT_MODE_GO_TO_BOOTLOADER 3
|
|
#define HALT_MODE_HALT_BUT_NO_RESET 5
|
|
|
|
// 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.
|
|
};
|
|
|
|
#define MAX_FLASH_SECTORS 262144
|
|
|
|
enum RiscVChip {
|
|
CHIP_CH32V10x = 0x01,
|
|
CHIP_CH57x = 0x02,
|
|
CHIP_CH56x = 0x03,
|
|
CHIP_CH32V20x = 0x05,
|
|
CHIP_CH32V30x = 0x06,
|
|
CHIP_CH58x = 0x07,
|
|
CHIP_CH32V003 = 0x09
|
|
};
|
|
|
|
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;
|
|
int sector_size;
|
|
int flash_size;
|
|
enum RiscVChip target_chip_type;
|
|
uint8_t flash_sector_status[MAX_FLASH_SECTORS]; // 0 means unerased/unknown. 1 means erased.
|
|
};
|
|
|
|
|
|
#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
|
|
|
|
/* initialization hints for init functions */
|
|
/* could be expanded with more in the future (e.g., PID/VID hints, priorities, ...)*/
|
|
/* not all init functions currently need these hints. */
|
|
typedef struct {
|
|
const char * serial_port;
|
|
const char * specific_programmer;
|
|
} init_hints_t;
|
|
|
|
void * MiniCHLinkInitAsDLL(struct MiniChlinkFunctions ** MCFO, const init_hints_t* init_hints) DLLDECORATE;
|
|
extern struct MiniChlinkFunctions MCF;
|
|
|
|
// Returns 'dev' on success, else 0.
|
|
void * TryInit_WCHLinkE(void);
|
|
void * TryInit_ESP32S2CHFUN(void);
|
|
void * TryInit_NHCLink042(void);
|
|
void * TryInit_B003Fun(void);
|
|
void * TryInit_Ardulink(const init_hints_t*);
|
|
|
|
// 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 );
|
|
int InternalUnlockBootloader( void * dev );
|
|
int InternalIsMemoryErased( struct InternalState * iss, uint32_t address );
|
|
void InternalMarkMemoryNotErased( struct InternalState * iss, uint32_t address );
|
|
int InternalUnlockFlash( void * dev, struct InternalState * iss );
|
|
|
|
// GDBSever Functions
|
|
int SetupGDBServer( void * dev );
|
|
int PollGDBServer( void * dev );
|
|
int IsGDBServerInShadowHaltState( void * dev );
|
|
void ExitGDBServer( void * dev );
|
|
|
|
#endif
|
|
|