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

Add ability to read-back data.

parent 44ac3404
No related branches found
No related tags found
No related merge requests found
#include <stdio.h>
#include <stdlib.h>
#include "wch_link_base.h"
......@@ -36,6 +37,8 @@ const uint8_t * bootloader = (const uint8_t*)
"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" \
"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff";
static int64_t SimpleReadNumberInt( const char * number, int64_t defaultNumber );
int bootloader_len = 512;
int main( int argc, char ** argv )
......@@ -107,8 +110,84 @@ keep_going:
4, "\x81\x06\x01\x01" );
break;
*/
case 'w':
case 'o':
{
int i;
int transferred;
if( argchar[2] != 0 ) goto help;
iarg++;
argchar = 0; // Stop advancing
if( iarg + 2 >= argc ) goto help;
uint64_t offset = SimpleReadNumberInt( argv[iarg++], -1 );
uint64_t amount = SimpleReadNumberInt( argv[iarg++], -1 );
if( offset > 0xffffffff || amount > 0xffffffff )
{
fprintf( stderr, "Error: memory value request out of range.\n" );
return -9;
}
// Round up amount.
amount = ( amount + 3 ) & 0xfffffffc;
FILE * f = fopen( argv[iarg], "wb" );
if( !f )
{
fprintf( stderr, "Error: can't open write file \"%s\"\n", argv[iarg] );
return -9;
}
uint32_t * readbuff = malloc( amount );
int readbuffplace = 0;
wch_link_command( devh, "\x81\x06\x01\x01", 4, 0, 0, 0 );
// Flush out any pending data.
libusb_bulk_transfer( devh, 0x82, rbuff, 1024, &transferred, 1 );
// 3/8 = Read Memory
// First 4 bytes are big-endian location.
// Next 4 bytes are big-endian amount.
uint8_t readop[11] = { 0x81, 0x03, 0x08, };
readop[3] = (offset>>24)&0xff;
readop[4] = (offset>>16)&0xff;
readop[5] = (offset>>8)&0xff;
readop[6] = (offset>>0)&0xff;
readop[7] = (amount>>24)&0xff;
readop[8] = (amount>>16)&0xff;
readop[9] = (amount>>8)&0xff;
readop[10] = (amount>>0)&0xff;
wch_link_command( devh, readop, 11, 0, 0, 0 );
// Perform operation
wch_link_command( devh, "\x81\x02\x01\x0c", 4, 0, 0, 0 );
uint32_t remain = amount;
while( remain )
{
transferred = 0;
WCHCHECK( libusb_bulk_transfer( devh, 0x82, rbuff, 1024, &transferred, WCHTIMEOUT ) );
memcpy( ((uint8_t*)readbuff) + readbuffplace, rbuff, transferred );
readbuffplace += transferred;
remain -= transferred;
}
// Flip internal endian. Must be done separately in case something was unaligned when
// reading.
for( i = 0; i < readbuffplace/4; i++ )
{
uint32_t r = readbuff[i];
readbuff[i] = (r>>24) | ((r & 0xff0000) >> 8) | ((r & 0xff00)<<8) | (( r & 0xff )<<24);
}
fwrite( readbuff, readbuffplace, 1, f );
free( readbuff );
fclose( f );
break;
}
case 'w':
{
if( argchar[2] != 0 ) goto help;
iarg++;
argchar = 0; // Stop advancing
......@@ -207,5 +286,36 @@ help:
// fprintf( stderr, " -P Enable Read Protection (UNTESTED)\n" );
// fprintf( stderr, " -p Disable Read Protection (UNTESTED)\n" );
fprintf( stderr, " -w [binary image to write]\n" );
fprintf( stderr, " -o [memory address, decimal or 0x, try 0x08000000] [size, decimal or 0x, try 16384] [output binary image]\n" );
return -1;
}
#if defined(WINDOWS) || defined(WIN32) || defined(_WIN32)
#define strtoll _strtoi64
#endif
static int64_t SimpleReadNumberInt( const char * number, int64_t defaultNumber )
{
if( !number || !number[0] ) return defaultNumber;
int radix = 10;
if( number[0] == '0' )
{
char nc = number[1];
number+=2;
if( nc == 0 ) return 0;
else if( nc == 'x' ) radix = 16;
else if( nc == 'b' ) radix = 2;
else { number--; radix = 8; }
}
char * endptr;
uint64_t ret = strtoll( number, &endptr, radix );
if( endptr == number )
{
return defaultNumber;
}
else
{
return ret;
}
}
......@@ -4,7 +4,7 @@ tcc wch_erase.c libusb-1.0.dll
tcc wch_reset.c libusb-1.0.dll
tcc wch_write_simple.c libusb-1.0.dll
tcc minichlink.c libusb-1.0.dll
tcc wch_dump_flash.c libusb-1.0.dll
rem wch_erase.exe
rem wch_write_simple.exe ..\barebones\barebones.bin
rem wch_reset.exe
#include <stdio.h>
#include "wch_link_base.h"
// TODO Make me actually query data!
int main()
{
int i;
int transferred;
int status;
char rbuff[1024];
libusb_device_handle * devh = wch_link_base_setup();
wch_link_command( devh, "\x81\x06\x01\x01", 4, 0, 0, 0 );
// Flush out any pending data.
libusb_bulk_transfer( devh, 0x82, rbuff, 1024, &transferred, 1 );
// 3/8 = Read Memory
// First 4 bytes are big-endian location.
// Next 4 bytes are big-endian amount.
uint8_t readop[11] = { 0x81, 0x03, 0x08, };
uint32_t readptr = 0x08000000;
uint32_t amount = 16384;
readop[3] = (readptr>>24)&0xff;
readop[4] = (readptr>>16)&0xff;
readop[5] = (readptr>>8)&0xff;
readop[6] = (readptr>>0)&0xff;
readop[7] = (amount>>24)&0xff;
readop[8] = (amount>>16)&0xff;
readop[9] = (amount>>8)&0xff;
readop[10] = (amount>>0)&0xff;
wch_link_command( devh, readop, 11, 0, 0, 0 );
// Perform operation
wch_link_command( devh, "\x81\x02\x01\x0c", 4, 0, 0, 0 );
printf( "WARNING ENDIAN WILL BE REVERSED\n" );
uint32_t remain = amount;
while( remain )
{
WCHCHECK( libusb_bulk_transfer( devh, 0x82, rbuff, 1024, &transferred, WCHTIMEOUT ) );
for( i = 0; i < transferred; i++ )
printf( "%08x", (uint8_t)rbuff[i] );
printf( "\n" );
remain -= transferred;
}
wch_link_command( devh, "\x81\x0d\x01\xff", 4, 0, 0, 0 );
}
......@@ -99,8 +99,12 @@ static inline libusb_device_handle * wch_link_base_setup()
// Place part into reset.
wch_link_command( devh, "\x81\x0d\x01\x01", 4, &transferred, rbuff, 1024 ); // Reply is: "\x82\x0d\x04\x02\x08\x02\x00"
// TODO: What in the world is this? It doesn't appear to be needed.
wch_link_command( devh, "\x81\x0c\x02\x09\x01", 5, 0, 0, 0 ); //Reply is: 820c0101
// This puts the processor on hold to allow the debugger to run.
wch_link_command( devh, "\x81\x0d\x01\x02", 4, 0, 0, 0 ); // Reply: Ignored, 820d050900300500
wch_link_command( devh, "\x81\x11\x01\x09", 4, &transferred, rbuff, 1024 ); // Reply: Chip ID + Other data (see below)
if( transferred != 20 )
{
......
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