text: /* 
   * File:   test_main.c
   * 
   * main() ripped out of old stlink-hw.c
   */
  
  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>
  #include "stlink-common.h"
  #include "uglylogging.h"
  
  #define LOG_TAG __FILE__
  #define DLOG(format, args...)         ugly_log(UDEBUG, LOG_TAG, format, ## args)
  #define ILOG(format, args...)         ugly_log(UINFO, LOG_TAG, format, ## args)
  #define WLOG(format, args...)         ugly_log(UWARN, LOG_TAG, format, ## args)
  #define fatal(format, args...)        ugly_log(UFATAL, LOG_TAG, format, ## args)
  
  static void __attribute__((unused)) mark_buf(stlink_t *sl) {
      memset(sl->q_buf, 0, sizeof(sl->q_buf));
      sl->q_buf[0] = 0xaa;
      sl->q_buf[1] = 0xbb;
      sl->q_buf[2] = 0xcc;
      sl->q_buf[3] = 0xdd;
      sl->q_buf[4] = 0x11;
      sl->q_buf[15] = 0x22;
      sl->q_buf[16] = 0x33;
      sl->q_buf[63] = 0x44;
      sl->q_buf[64] = 0x69;
      sl->q_buf[1024 * 6 - 1] = 0x42; //6kB
      sl->q_buf[1024 * 8 - 1] = 0x42; //8kB
  }
  
  
  int main(int argc, char *argv[]) {
  	// set scpi lib debug level: 0 for no debug info, 10 for lots
  
  	switch (argc) {
  	case 1:
  		fputs(
  			"\nUsage: stlink-access-test [anything at all] ...\n"
  				"\n*** Notice: The stlink firmware violates the USB standard.\n"
  				"*** Because we just use libusb, we can just tell the kernel's\n"
  				"*** driver to simply ignore the device...\n"
  				"*** Unplug the stlink and execute once as root:\n"
  				"modprobe -r usb-storage && modprobe usb-storage quirks=483:3744:i\n\n",
  			stderr);
  		return EXIT_FAILURE;
  	default:
          break;
  	}
  
  	stlink_t *sl = stlink_v1_open(99);
  	if (sl == NULL)
  		return EXIT_FAILURE;
      
  	// we are in mass mode, go to swd
  	stlink_enter_swd_mode(sl);
  	stlink_current_mode(sl);
  	stlink_core_id(sl);
  	//----------------------------------------------------------------------
  
  	stlink_status(sl);
  	//stlink_force_debug(sl);
  	stlink_reset(sl);
  	stlink_status(sl);
  	// core system control block
  	stlink_read_mem32(sl, 0xe000ed00, 4);
  	DLOG("cpu id base register: SCB_CPUID = got 0x%08x expect 0x411fc231\n", read_uint32(sl->q_buf, 0));
  	// no MPU
  	stlink_read_mem32(sl, 0xe000ed90, 4);
  	DLOG("mpu type register: MPU_TYPER = got 0x%08x expect 0x0\n", read_uint32(sl->q_buf, 0));
  
  #if 0
  	stlink_read_mem32(sl, 0xe000edf0, 4);
  	DD(sl, "DHCSR = 0x%08x", read_uint32(sl->q_buf, 0));
  
  	stlink_read_mem32(sl, 0x4001100c, 4);
  	DD(sl, "GPIOC_ODR = 0x%08x", read_uint32(sl->q_buf, 0));
  #endif
  #if 0
  	// happy new year 2011: let blink all the leds
  	// see "RM0041 Reference manual - STM32F100xx advanced ARM-based 32-bit MCUs"
  
  #define GPIOC		0x40011000 // port C
  #define GPIOC_CRH	(GPIOC + 0x04) // port configuration register high
  #define GPIOC_ODR	(GPIOC + 0x0c) // port output data register
  #define LED_BLUE	(1<<8) // pin 8
  #define LED_GREEN	(1<<9) // pin 9
  	stlink_read_mem32(sl, GPIOC_CRH, 4);
  	uint32_t io_conf = read_uint32(sl->q_buf, 0);
  	DLOG("GPIOC_CRH = 0x%08x\n", io_conf);
  
  	// set: general purpose output push-pull, output mode, max speed 10 MHz.
  	write_uint32(sl->q_buf, 0x44444411);
  	stlink_write_mem32(sl, GPIOC_CRH, 4);
  
  	memset(sl->q_buf, 0, sizeof(sl->q_buf));
  	for (int i = 0; i < 100; i++) {
  		write_uint32(sl->q_buf, LED_BLUE | LED_GREEN);
  		stlink_write_mem32(sl, GPIOC_ODR, 4);
  		/* stlink_read_mem32(sl, 0x4001100c, 4); */
  		/* DD(sl, "GPIOC_ODR = 0x%08x", read_uint32(sl->q_buf, 0)); */
  		usleep(100 * 1000);
  
  		memset(sl->q_buf, 0, sizeof(sl->q_buf));
  		stlink_write_mem32(sl, GPIOC_ODR, 4); // PC lo
          usleep(100 * 1000);
  	}
  	write_uint32(sl->q_buf, io_conf); // set old state
  
  #endif
  #if 0
  	// TODO rtfm: stlink doesn't have flash write routines
  	// writing to the flash area confuses the fw for the next read access
  
  	//stlink_read_mem32(sl, 0, 1024*6);
  	// flash 0x08000000 128kB
  	fputs("++++++++++ read a flash at 0x0800 0000\n", stderr);
  	stlink_read_mem32(sl, 0x08000000, 1024 * 6); //max 6kB
  	clear_buf(sl);
  	stlink_read_mem32(sl, 0x08000c00, 5);
  	stlink_read_mem32(sl, 0x08000c00, 4);
  	mark_buf(sl);
  	stlink_write_mem32(sl, 0x08000c00, 4);
  	stlink_read_mem32(sl, 0x08000c00, 256);
  	stlink_read_mem32(sl, 0x08000c00, 256);
  #endif
  #if 0
  	// sram 0x20000000 8kB
  	fputs("\n++++++++++ read/write 8bit, sram at 0x2000 0000 ++++++++++++++++\n\n", stderr);
      memset(sl->q_buf, 0, sizeof(sl->q_buf));
      mark_buf(sl);
  	//stlink_write_mem8(sl, 0x20000000, 16);
  
  	//stlink_write_mem8(sl, 0x20000000, 1);
  	//stlink_write_mem8(sl, 0x20000001, 1);
  	stlink_write_mem8(sl, 0x2000000b, 3);
  	stlink_read_mem32(sl, 0x20000000, 16);
  #endif
  #if 0
  	// a not aligned mem32 access doesn't work indeed
  	fputs("\n++++++++++ read/write 32bit, sram at 0x2000 0000 ++++++++++++++++\n\n", stderr);
      memset(sl->q_buf, 0, sizeof(sl->q_buf));
  	mark_buf(sl);
  	stlink_write_mem32(sl, 0x20000000, 1);
  	stlink_read_mem32(sl, 0x20000000, 16);
  	mark_buf(sl);
  	stlink_write_mem32(sl, 0x20000001, 1);
  	stlink_read_mem32(sl, 0x20000000, 16);
  	mark_buf(sl);
  	stlink_write_mem32(sl, 0x2000000b, 3);
  	stlink_read_mem32(sl, 0x20000000, 16);
  
  	mark_buf(sl);
  	stlink_write_mem32(sl, 0x20000000, 17);
  	stlink_read_mem32(sl, 0x20000000, 32);
  #endif
  #if 0
  	// sram 0x20000000 8kB
  	fputs("++++++++++ read/write 32bit, sram at 0x2000 0000 ++++++++++++\n", stderr);
      memset(sl->q_buf, 0, sizeof(sl->q_buf));
  	mark_buf(sl);
  	stlink_write_mem8(sl, 0x20000000, 64);
  	stlink_read_mem32(sl, 0x20000000, 64);
  
  	mark_buf(sl);
  	stlink_write_mem32(sl, 0x20000000, 1024 * 8); //8kB
  	stlink_read_mem32(sl, 0x20000000, 1024 * 6);
  	stlink_read_mem32(sl, 0x20000000 + 1024 * 6, 1024 * 2);
  #endif
  #if 1
      reg regs;
  	stlink_read_all_regs(sl, &regs);
  	stlink_step(sl);
  	fputs("++++++++++ write r0 = 0x12345678\n", stderr);
  	stlink_write_reg(sl, 0x12345678, 0);
  	stlink_read_reg(sl, 0, &regs);
  	stlink_read_all_regs(sl, &regs);
  #endif
  #if 0
  	stlink_run(sl);
  	stlink_status(sl);
  
  	stlink_force_debug(sl);
  	stlink_status(sl);
  #endif
  #if 0 /* read the system bootloader */
  	fputs("\n++++++++++ reading bootloader ++++++++++++++++\n\n", stderr);
  	stlink_fread(sl, "/tmp/barfoo", sl->sys_base, sl->sys_size);
  #endif
  #if 0 /* read the flash memory */
  	fputs("\n+++++++ read flash memory\n\n", stderr);
  	/* mark_buf(sl); */
  	stlink_read_mem32(sl, 0x08000000, 4);
  #endif
  #if 0 /* flash programming */
  	fputs("\n+++++++ program flash memory\n\n", stderr);
  	stlink_fwrite_flash(sl, "/tmp/foobar", 0x08000000);
  #endif
  #if 0 /* check file contents */
  	fputs("\n+++++++ check flash memory\n\n", stderr);
  	{
  	  const int res = stlink_fcheck_flash(sl, "/tmp/foobar", 0x08000000);
  	  printf("_____ stlink_fcheck_flash() == %d\n", res);
  	}
  #endif
  #if 0
  	fputs("\n+++++++ sram write and execute\n\n", stderr);
  	stlink_fwrite_sram(sl, "/tmp/foobar", sl->sram_base);
  	stlink_run_at(sl, sl->sram_base);
  #endif
  
  #if 0
  	stlink_run(sl);
  	stlink_status(sl);
  	//----------------------------------------------------------------------
  	// back to mass mode, just in case ...
  	stlink_exit_debug_mode(sl);
  	stlink_current_mode(sl);
  	stlink_close(sl);
  #endif
  
  	//fflush(stderr); fflush(stdout);
  	return EXIT_SUCCESS;
  }
  