Initial commit

master
powertomato 12 years ago
commit 972b965591
  1. 1505
      src/DAP.c
  2. 221
      src/DAP.h
  3. 659
      src/DAP_config.h
  4. 122
      src/DAP_vendor.c
  5. 15
      src/Debug.h
  6. 365
      src/JTAG_DP.c
  7. 248
      src/SW_DP.c
  8. 51
      src/Timer.c
  9. 20
      src/Timer.h
  10. 20
      src/device.h
  11. 28
      src/ftdi_vars.c
  12. 50
      src/ftdi_vars.h
  13. 55
      src/main.c
  14. 171
      src/socket_ipc.c

File diff suppressed because it is too large Load Diff

@ -0,0 +1,221 @@
/******************************************************************************
* @file DAP.h
* @brief CMSIS-DAP Definitions
* @version V1.00
* @date 31. May 2012
*
* @note
* Copyright (C) 2012 ARM Limited. All rights reserved.
*
* @par
* ARM Limited (ARM) is supplying this software for use with Cortex-M
* processor based microcontrollers.
*
* @par
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
******************************************************************************/
#ifndef __DAP_H__
#define __DAP_H__
#include <stddef.h>
#include <stdint.h>
#include "Timer.h"
// DAP Command IDs
#define ID_DAP_Info 0x00
#define ID_DAP_LED 0x01
#define ID_DAP_Connect 0x02
#define ID_DAP_Disconnect 0x03
#define ID_DAP_TransferConfigure 0x04
#define ID_DAP_Transfer 0x05
#define ID_DAP_TransferBlock 0x06
#define ID_DAP_TransferAbort 0x07
#define ID_DAP_WriteABORT 0x08
#define ID_DAP_Delay 0x09
#define ID_DAP_ResetTarget 0x0A
#define ID_DAP_SWJ_Pins 0x10
#define ID_DAP_SWJ_Clock 0x11
#define ID_DAP_SWJ_Sequence 0x12
#define ID_DAP_SWD_Configure 0x13
#define ID_DAP_JTAG_Sequence 0x14
#define ID_DAP_JTAG_Configure 0x15
#define ID_DAP_JTAG_IDCODE 0x16
// DAP Vendor Command IDs
#define ID_DAP_Vendor0 0x80
#define ID_DAP_Vendor1 0x81
#define ID_DAP_Vendor2 0x82
#define ID_DAP_Vendor3 0x83
#define ID_DAP_Vendor4 0x84
#define ID_DAP_Vendor5 0x85
#define ID_DAP_Vendor6 0x86
#define ID_DAP_Vendor7 0x87
#define ID_DAP_Vendor8 0x88
#define ID_DAP_Vendor9 0x89
#define ID_DAP_Vendor10 0x8A
#define ID_DAP_Vendor11 0x8B
#define ID_DAP_Vendor12 0x8C
#define ID_DAP_Vendor13 0x8D
#define ID_DAP_Vendor14 0x8E
#define ID_DAP_Vendor15 0x8F
#define ID_DAP_Vendor16 0x90
#define ID_DAP_Vendor17 0x91
#define ID_DAP_Vendor18 0x92
#define ID_DAP_Vendor19 0x93
#define ID_DAP_Vendor20 0x94
#define ID_DAP_Vendor21 0x95
#define ID_DAP_Vendor22 0x96
#define ID_DAP_Vendor23 0x97
#define ID_DAP_Vendor24 0x98
#define ID_DAP_Vendor25 0x99
#define ID_DAP_Vendor26 0x9A
#define ID_DAP_Vendor27 0x9B
#define ID_DAP_Vendor28 0x9C
#define ID_DAP_Vendor29 0x9D
#define ID_DAP_Vendor30 0x9E
#define ID_DAP_Vendor31 0x9F
#define ID_DAP_Invalid 0xFF
// DAP Status Code
#define DAP_OK 0
#define DAP_ERROR 0xFF
// DAP ID
#define DAP_ID_VENDOR 1
#define DAP_ID_PRODUCT 2
#define DAP_ID_SER_NUM 3
#define DAP_ID_FW_VER 4
#define DAP_ID_DEVICE_VENDOR 5
#define DAP_ID_DEVICE_NAME 6
#define DAP_ID_CAPABILITIES 0xF0
#define DAP_ID_PACKET_COUNT 0xFE
#define DAP_ID_PACKET_SIZE 0xFF
// DAP LEDs
#define DAP_LED_DEBUGGER_CONNECTED 0
#define DAP_LED_TARGET_RUNNING 1
// DAP Port
#define DAP_PORT_AUTODETECT 0 // Autodetect Port
#define DAP_PORT_DISABLED 0 // Port Disabled (I/O pins in High-Z)
#define DAP_PORT_SWD 1 // SWD Port (SWCLK, SWDIO) + nRESET
#define DAP_PORT_JTAG 2 // JTAG Port (TCK, TMS, TDI, TDO, nTRST) + nRESET
// DAP SWJ Pins
#define DAP_SWJ_SWCLK_TCK 0 // SWCLK/TCK
#define DAP_SWJ_SWDIO_TMS 1 // SWDIO/TMS
#define DAP_SWJ_TDI 2 // TDI
#define DAP_SWJ_TDO 3 // TDO
#define DAP_SWJ_nTRST 5 // nTRST
#define DAP_SWJ_nRESET 7 // nRESET
// DAP Transfer Request
#define DAP_TRANSFER_APnDP (1<<0)
#define DAP_TRANSFER_RnW (1<<1)
#define DAP_TRANSFER_A2 (1<<2)
#define DAP_TRANSFER_A3 (1<<3)
#define DAP_TRANSFER_MATCH_VALUE (1<<4)
#define DAP_TRANSFER_MATCH_MASK (1<<5)
// DAP Transfer Response
#define DAP_TRANSFER_OK (1<<0)
#define DAP_TRANSFER_WAIT (1<<1)
#define DAP_TRANSFER_FAULT (1<<2)
#define DAP_TRANSFER_ERROR (1<<3)
#define DAP_TRANSFER_MISMATCH (1<<4)
// Debug Port Register Addresses
#define DP_IDCODE 0x00 // IDCODE Register (SW Read only)
#define DP_ABORT 0x00 // Abort Register (SW Write only)
#define DP_CTRL_STAT 0x04 // Control & Status
#define DP_WCR 0x04 // Wire Control Register (SW Only)
#define DP_SELECT 0x08 // Select Register (JTAG R/W & SW W)
#define DP_RESEND 0x08 // Resend (SW Read Only)
#define DP_RDBUFF 0x0C // Read Buffer (Read Only)
// JTAG IR Codes
#define JTAG_ABORT 0x08
#define JTAG_DPACC 0x0A
#define JTAG_APACC 0x0B
#define JTAG_IDCODE 0x0E
#define JTAG_BYPASS 0x0F
// JTAG Sequence Info
#define JTAG_SEQUENCE_TCK 0x3F // TCK count
#define JTAG_SEQUENCE_TMS 0x40 // TMS value
#define JTAG_SEQUENCE_TDO 0x80 // TDO capture
// DAP Data structure
typedef struct {
uint8_t debug_port; // Debug Port
uint8_t fast_clock; // Fast Clock Flag
uint32_t clock_delay; // Clock Delay
struct { // Transfer Configuration
uint8_t idle_cycles; // Idle cycles after transfer
uint16_t retry_count; // Number of retries after WAIT response
uint16_t match_retry; // Number of retries if read value does not match
uint32_t match_mask; // Match Mask
} transfer;
#if (DAP_SWD != 0)
struct { // SWD Configuration
uint8_t turnaround; // Turnaround period
uint8_t data_phase; // Always generate Data Phase
} swd_conf;
#endif
#if (DAP_JTAG != 0)
struct { // JTAG Device Chain
uint8_t count; // Number of devices
uint8_t index; // Device index (device at TDO has index 0)
#if (DAP_JTAG_DEV_CNT != 0)
uint8_t ir_length[DAP_JTAG_DEV_CNT]; // IR Length in bits
uint16_t ir_before[DAP_JTAG_DEV_CNT]; // Bits before IR
uint16_t ir_after [DAP_JTAG_DEV_CNT]; // Bits after IR
#endif
} jtag_dev;
#endif
} DAP_Data_t;
extern DAP_Data_t DAP_Data; // DAP Data
extern volatile uint8_t DAP_TransferAbort; // Transfer Abort Flag
// Functions
extern void SWJ_Sequence (uint32_t count, uint8_t *data);
extern void JTAG_Sequence (uint32_t info, uint8_t *tdi, uint8_t *tdo);
extern void JTAG_IR (uint32_t ir);
extern uint32_t JTAG_ReadIDCode (void);
extern void JTAG_WriteAbort (uint32_t data);
extern uint8_t JTAG_Transfer (uint8_t request, uint32_t *data);
extern uint8_t SWD_Transfer (uint8_t request, uint32_t *data);
extern uint32_t DAP_ProcessVendorCommand (uint8_t *request, uint8_t *response);
extern uint32_t DAP_ProcessCommand (uint8_t *request, uint8_t *response);
extern void DAP_Setup (void);
// Configurable delay for clock generation
#define DELAY_SLOW_CYCLES 1 // Number of cycles for one iteration
static __forceinline void PIN_DELAY_SLOW (uint32_t delay) {
//Delayus(delay);
//printf("delay %d\n",delay);
FTDI_SUBMIT();
}
// Fixed delay for fast clock generation
#define DELAY_FAST_CYCLES 0 // Number of cycles
static __forceinline void PIN_DELAY_FAST (void) {
//__nop();
FTDI_SUBMIT();
}
#endif /* __DAP_H__ */

@ -0,0 +1,659 @@
/**************************************************************************//**
* @file DAP_config.h
* @brief CMSIS-DAP Configuration File (Template)
* @version V1.00
* @date 31. May 2012
*
* @note
* Copyright (C) 2012 ARM Limited. All rights reserved.
*
* @par
* ARM Limited (ARM) is supplying this software for use with Cortex-M
* processor based microcontrollers.
*
* @par
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
******************************************************************************/
#ifndef __DAP_CONFIG_H__
#define __DAP_CONFIG_H__
//**************************************************************************************************
/**
\defgroup DAP_Config_Debug_gr CMSIS-DAP Debug Unit Information
\ingroup DAP_ConfigIO_gr
@{
Provides definitions about:
- Definition of Cortex-M processor parameters used in CMSIS-DAP Debug Unit.
- Debug Unit communication packet size.
- Debug Access Port communication mode (JTAG or SWD).
- Optional information about a connected Target Device (for Evaluation Boards).
*/
#include "ftdi_vars.h"
#include "device.h" // Debug Unit Cortex-M Processor Header File
#include "Debug.h"
#include <stdint.h>
#include <stdlib.h>
/// Processor Clock of the Cortex-M MCU used in the Debug Unit.
/// On the Desktop-libftdi version, this is the maximum resolution of the timer
/// This value is used to calculate the SWD/JTAG clock speed.
#define CPU_CLOCK 1000000 ///< Clock in Hz
/// Number of processor cycles for I/O Port write operations.
/// This value is used to calculate the SWD/JTAG clock speed that is generated with I/O
/// Port write operations in the Debug Unit by a Cortex-M MCU. Most Cortex-M processors
/// requrie 2 processor cycles for a I/O Port Write operation. If the Debug Unit uses
/// a Cortex-M0+ processor with high-speed peripheral I/O only 1 processor cycle might be
/// requrired.
#define IO_PORT_WRITE_CYCLES 0 ///< I/O Cycles: 2=default, 1=Cortex-M0+ fast I/0
/// Indicate that Serial Wire Debug (SWD) communication mode is available at the Debug Access Port.
/// This information is returned by the command \ref DAP_Info as part of <b>Capabilities</b>.
#define DAP_SWD 1 ///< SWD Mode: 1 = available, 0 = not available
/// Indicate that JTAG communication mode is available at the Debug Port.
/// This information is returned by the command \ref DAP_Info as part of <b>Capabilities</b>.
#define DAP_JTAG 1 ///< JTAG Mode: 1 = available, 0 = not available.
/// Configure maximum number of JTAG devices on the scan chain connected to the Debug Access Port.
/// This setting impacts the RAM requirements of the Debug Unit. Valid range is 1 .. 255.
#define DAP_JTAG_DEV_CNT 8 ///< Maximum number of JTAG devices on scan chain
/// Default communication mode on the Debug Access Port.
/// Used for the command \ref DAP_Connect when Port Default mode is selected.
#define DAP_DEFAULT_PORT 1 ///< Default JTAG/SWJ Port Mode: 1 = SWD, 2 = JTAG.
/// Default communication speed on the Debug Access Port for SWD and JTAG mode.
/// Used to initialize the default SWD/JTAG clock frequency.
/// The command \ref DAP_SWJ_Clock can be used to overwrite this default setting.
#define DAP_DEFAULT_SWJ_CLOCK 10000 ///< Default SWD/JTAG clock frequency in Hz.
/// Maximum Package Size for Command and Response data.
/// This configuration settings is used to optimized the communication performance with the
/// debugger and depends on the USB peripheral. Change setting to 1024 for High-Speed USB.
#define DAP_PACKET_SIZE 64 ///< USB: 64 = Full-Speed, 1024 = High-Speed.
/// Maximum Package Buffers for Command and Response data.
/// This configuration settings is used to optimized the communication performance with the
/// debugger and depends on the USB peripheral. For devices with limited RAM or USB buffer the
/// setting can be reduced (valid range is 1 .. 255). Change setting to 4 for High-Speed USB.
#define DAP_PACKET_COUNT 64 ///< Buffers: 64 = Full-Speed, 4 = High-Speed.
/// Debug Unit is connected to fixed Target Device.
/// The Debug Unit may be part of an evaluation board and always connected to a fixed
/// known device. In this case a Device Vendor and Device Name string is stored which
/// may be used by the debugger or IDE to configure device parameters.
#define TARGET_DEVICE_FIXED 0 ///< Target Device: 1 = known, 0 = unknown;
#if TARGET_DEVICE_FIXED
#define TARGET_DEVICE_VENDOR "ARM" ///< String indicating the Silicon Vendor
#define TARGET_DEVICE_NAME "Cortex-M4" ///< String indicating the Target Device
#endif
///@}
//**************************************************************************************************
/**
\defgroup DAP_Config_PortIO_gr CMSIS-DAP Hardware I/O Pin Access
\ingroup DAP_ConfigIO_gr
@{
Standard I/O Pins of the CMSIS-DAP Hardware Debug Port support standard JTAG mode
and Serial Wire Debug (SWD) mode. In SWD mode only 2 pins are required to implement the debug
interface of a device. The following I/O Pins are provided:
JTAG I/O Pin | SWD I/O Pin | CMSIS-DAP Hardware pin mode
---------------------------- | -------------------- | ---------------------------------------------
TCK: Test Clock | SWCLK: Clock | Output Push/Pull
TMS: Test Mode Select | SWDIO: Data I/O | Output Push/Pull; Input (for receiving data)
TDI: Test Data Input | | Output Push/Pull
TDO: Test Data Output | | Input
nTRST: Test Reset (optional) | | Output Open Drain with pull-up resistor
nRESET: Device Reset | nRESET: Device Reset | Output Open Drain with pull-up resistor
DAP Hardware I/O Pin Access Functions
-------------------------------------
The various I/O Pins are accessed by functions that implement the Read, Write, Set, or Clear to
these I/O Pins.
For the SWDIO I/O Pin there are additional functions that are called in SWD I/O mode only.
This functions are provided to achieve faster I/O that is possible with some advanced GPIO
peripherals that can independently write/read a single I/O pin without affecting any other pins
of the same I/O port. The following SWDIO I/O Pin functions are provided:
- \ref PIN_SWDIO_OUT_ENABLE to enable the output mode from the DAP hardware.
- \ref PIN_SWDIO_OUT_DISABLE to enable the input mode to the DAP hardware.
- \ref PIN_SWDIO_IN to read from the SWDIO I/O pin with utmost possible speed.
- \ref PIN_SWDIO_OUT to write to the SWDIO I/O pin with utmost possible speed.
*/
// Configure DAP I/O pins ------------------------------
#define TMS_SWDIO DCD
#define TCK_SWCLK RI
#define TDO_SWO RXD
#define TDI RTS
#define nRESET DTR
#define nTRST TXD
#define LED_CONN CTS
#define LED_RUN DSR
static __inline const char* pin_to_str(uint8_t pin){
switch(pin){
case TMS_SWDIO:
return "TMS_SWDIO(DCD)";
case TCK_SWCLK:
return "TCK_SWCLK(RI)";
case TDO_SWO:
return "TDO_SWO(RXD)";
case TDI:
return "TDI(RTS)";
case nRESET:
return "nRESET(DTR)";
case nTRST:
return "nTRST(TXD)";
case LED_CONN:
return "LED_CONN(CTS)";
case LED_RUN:
return "LED_RUN(DSR)";
default:
return "???";
}
}
static __inline void FTDI_BITBANG_SETUP() {
int success;
/* Enable bitbang mode */
success = ftdi_set_bitmode(&__ftdic, dir_state, BITMODE_BITBANG );
if( success<0 ){
DEBUG("Could not change to async. bitbang: %s\n",ftdi_get_error_string(&__ftdic));
}
success = ftdi_write_data(&__ftdic,&out_state,1);
if( success < 0){
DEBUG("Could not write pins: %s\n",ftdi_get_error_string(&__ftdic));
}
/*ftdi_read_data_set_chunksize(&__ftdic,1);
ftdi_write_data_set_chunksize(&__ftdic,1);*/
}
/** Setup of the Debug Unit I/O pins and LEDs (called when Debug Unit is initialized).
This function performs the initialization of the CMSIS-DAP Hardware I/O Pins and the
Status LEDs. In detail the operation of Hardware I/O and LED pins are enabled and set:
- I/O clock system enabled.
- all I/O pins: input buffer enabled, output pins are set to HighZ mode.
- for nTRST, nRESET a weak pull-up (if available) is enabled.
- LED output pins are enabled and LEDs are turned off.
*/
static __inline void DAP_SETUP (void) {
/* Initialize context for subsequent function calls */
ftdi_init(&__ftdic);
int success;
/* Open FTDI device based on FT232R vendor & product IDs */
success = ftdi_usb_open(&__ftdic, VID, PID);
if(success < 0) {
DEBUG("Can't open device [%x:%x]: %s\n",VID,PID,ftdi_get_error_string(&__ftdic));
exit(1);
}
dir_state = LED_CONN|LED_RUN;
out_state = 0xFF & ~(LED_CONN|LED_RUN);
FTDI_BITBANG_SETUP();
success = ftdi_set_baudrate (&__ftdic, DAP_DEFAULT_SWJ_CLOCK/2);
if( success < 0){
DEBUG("Could not set baudrate: %s\n",ftdi_get_error_string(&__ftdic));
}
uint8_t foo;
success = ftdi_read_data(&__ftdic,&foo,1);
}
static __forceinline void FTDI_WRITE_OUT( ) {
int success;
if( out_state_buff_pos==0 ){
DEBUG("buffer is empty %d \n",out_state_buff_pos);
return;
}
success = ftdi_write_data(&__ftdic,out_state_buff,out_state_buff_pos);
if( success<0 ){
DEBUG("Could not write pins: %s\n",ftdi_get_error_string(&__ftdic));
exit(1);
}
out_state_buff_pos=0;
}
static __forceinline void FTDI_SUBMIT( ) {
out_state_buff[out_state_buff_pos] = out_state;
out_state_buff_pos++;
if( out_state_buff_pos>=BUFFER_SIZE ){
DEBUG("FTDI bitbang-buffer overflow!\n");
FTDI_WRITE_OUT( );
}
}
/** Setup JTAG I/O pins: TCK, TMS, TDI, TDO, nTRST, and nRESET.
Configures the DAP Hardware I/O pins for JTAG mode:
- TCK, TMS, TDI, nTRST, nRESET to output mode and set to high level.
- TDO to input mode.
*/
static __inline void PORT_JTAG_SETUP (void) {
/* Initialize context for subsequent function calls */
dir_state = LED_CONN|LED_RUN|TCK_SWCLK|TMS_SWDIO|TDI|nRESET;;
out_state = TCK_SWCLK | TMS_SWDIO | TDI | nTRST | nRESET;
FTDI_BITBANG_SETUP();
}
/** Setup SWD I/O pins: SWCLK, SWDIO, and nRESET.
Configures the DAP Hardware I/O pins for Serial Wire Debug (SWD) mode:
- SWCLK, SWDIO, nRESET to output mode and set to default high level.
- TDI, TMS, nTRST to HighZ mode (pins are unused in SWD mode).
*/
static __inline void PORT_SWD_SETUP (void) {
/* Initialize context for subsequent function calls */
dir_state = LED_CONN|LED_RUN|TCK_SWCLK|TMS_SWDIO|nRESET;
out_state = TCK_SWCLK | TMS_SWDIO | nRESET;
FTDI_BITBANG_SETUP();
}
static __inline void FTDI_BEGIN_READ(){
/* submit signal change buffer */
FTDI_SUBMIT();
FTDI_WRITE_OUT();
/* flush read buffer */
int success;
success = ftdi_set_bitmode(&__ftdic, dir_state, BITMODE_SYNCBB );
if( success<0 ){
DEBUG("Could not change to sync. bitbang: %s\n",ftdi_get_error_string(&__ftdic));
}
success = ftdi_usb_purge_rx_buffer(&__ftdic);
if( success<0 ){
DEBUG("Could not flush buffer: %s\n",ftdi_get_error_string(&__ftdic));
}
//memset ( pin_read_buff, 0, BUFFER_SIZE*sizeof(int) );
is_in_read_mode = 1;
}
static __inline void FTDI_END_READ(){
int success, remaining;
uint32_t read_size;
read_size = remaining = out_state_buff_pos;
FTDI_SUBMIT();
FTDI_WRITE_OUT();
success = 0;
uint8_t *ptr = in_buff;
while( remaining ){
success = ftdi_read_data(&__ftdic,ptr,remaining);
if( success<0 ){
DEBUG("Error while read: %s\n",ftdi_get_error_string(&__ftdic));
exit(1);
}
ptr+=success;
remaining-=success;
printf("try %d\n", success);
}
printf("Read %d/%d bytes\n",(int)(ptr-in_buff),read_size);
if( read_size!=success ){
DEBUG("Not sufficient bytes read: %s\n",ftdi_get_error_string(&__ftdic));
}else{
DEBUG("Read %d bytes\n",read_size);
int i;
for(i=0;i<read_size;i++){
printf("%x ",in_buff[i] & dir_state);
}
printf("\n");
}
success = ftdi_set_bitmode(&__ftdic, dir_state, BITMODE_BITBANG );
if( success<0 ){
DEBUG("Could not change to async. bitbang: %s\n",ftdi_get_error_string(&__ftdic));
}
}
static __forceinline uint32_t PIN_IN ( uint8_t pin ) {
uint8_t c;
if( dir_state & pin ){
//dir_state &= ~pin;
//ftdi_set_bitmode(&__ftdic, dir_state, BITMODE_BITBANG );
DEBUG("Pin %s is not an input pin!\n", pin_to_str(pin));
}
int success = ftdi_read_pins(&__ftdic,&c);
if(success < 0){
DEBUG("Could not read pin: %s\n",ftdi_get_error_string(&__ftdic));
}
return (c & pin)!=0 ? 1 : 0;
}
static __forceinline void PIN_SET ( uint8_t pin, uint32_t bit ) {
if( !(dir_state & pin) ){
//dir_state |= pin;
//ftdi_set_bitmode(&__ftdic, dir_state, BITMODE_BITBANG );
DEBUG("Pin %s is not an output pin!\n", pin_to_str(pin));
return;
}
if(bit){
out_state |= pin;
}else{
out_state &= ~pin;
}
}
/*
static __forceinline void PIN_SET ( uint8_t pin, uint32_t bit ) {
int success;
uint8_t is_set = out_state & pin;
if(bit){
out_state |= pin;
success = ftdi_write_data(&__ftdic,&out_state,1);
if( success<0 ){
DEBUG("Could not write pin TCK_SWCLK: %s\n",ftdi_get_error_string(&__ftdic));
if(!is_set){
out_state &= ~pin;
}
}
}else{
out_state &= ~pin;
success = ftdi_write_data(&__ftdic,&out_state,1);
if( success<0 ){
DEBUG("Could not write pin TCK_SWCLK: %s\n",ftdi_get_error_string(&__ftdic));
if(is_set){
out_state |= pin;
}
}
}
}
*/
/** Disable JTAG/SWD I/O Pins.
Disables the DAP Hardware I/O pins which configures:
- TCK/SWCLK, TMS/SWDIO, TDI, TDO, nTRST, nRESET to High-Z mode.
*/
static __inline void PORT_OFF (void) {
//TODO HighZ?
ftdi_disable_bitbang(&__ftdic);
ftdi_deinit(&__ftdic);
}
// SWCLK/TCK I/O pin -------------------------------------
/** SWCLK/TCK I/O pin: Get Input.
\return Current status of the SWCLK/TCK DAP hardware I/O pin.
*/
static __forceinline uint32_t PIN_SWCLK_TCK_IN (void) {
return PIN_IN(TCK_SWCLK);
}
/** SWCLK/TCK I/O pin: Set Output to High.
Set the SWCLK/TCK DAP hardware I/O pin to high level.
*/
static __forceinline void PIN_SWCLK_TCK_SET (void) {
PIN_SET(TCK_SWCLK,1);
}
/** SWCLK/TCK I/O pin: Set Output to Low.
Set the SWCLK/TCK DAP hardware I/O pin to low level.
*/
static __forceinline void PIN_SWCLK_TCK_CLR (void) {
PIN_SET(TCK_SWCLK,0);
}
// SWDIO/TMS Pin I/O --------------------------------------
/** SWDIO/TMS I/O pin: Get Input.
\return Current status of the SWDIO/TMS DAP hardware I/O pin.
*/
static __forceinline uint32_t PIN_SWDIO_TMS_IN (void) {
return PIN_IN(TMS_SWDIO);
}
/** SWDIO/TMS I/O pin: Set Output to High.
Set the SWDIO/TMS DAP hardware I/O pin to high level.
*/
static __forceinline void PIN_SWDIO_TMS_SET (void) {
PIN_SET(TMS_SWDIO,1);
}
/** SWDIO/TMS I/O pin: Set Output to Low.
Set the SWDIO/TMS DAP hardware I/O pin to low level.
*/
static __forceinline void PIN_SWDIO_TMS_CLR (void) {
PIN_SET(TMS_SWDIO,0);
}
static __inline uint8_t bit_count(uint8_t v){
/*
* http://stackoverflow.com/questions/3815165/how-to-implement-bitcount-using-only-bitwise-operators
* 0x55=01010101, 0x33=00110011, 0x0F=00001111
* v = [v7][v6][v5][v4][v3][v2][v1][v0]
* 1.
* c = 0[v6]0[v4]0[v2]0[v0] + 0[v7]0[v5]0[v3]0[v1]
* c = [v7+v6][v5+v4][v3+v2][v1+v0]
* 2.
* c = 00[v5+v4]00[v1+v0] + 00[v7+v6]00[v3+v2]
* c = [v7+v6+v5+v4][v3+v2+v1+v0]
* 3.
* c = 0000[v3+v2+v1+v0] + c=0000[v7+v6+v5+v4]
* c = [v7+v6+v5+v4+v3+v2+v1+v0]
*/
uint8_t c = 0;
c = (v & 0x55) + ((v >> 1) & 0x55) ;
c = (c & 0x33) + ((c >> 2) & 0x33);
c = (c & 0x0F) + ((c >> 4) & 0x0F);
return c;
}
/** SWDIO I/O pin: Get Input (used in SWD mode only).
\return Current status of the SWDIO DAP hardware I/O pin.
*/
static __forceinline void PIN_SWDIO_IN (uint8_t *ptr,uint8_t bit){
if( ptr!=NULL ){
DEBUG("setting read-to-pointer for pin reads!\n");
read_slot = ptr;
if( bit_count(bit)==1 ){
pin_read_mask=bit;
}else{
pin_read_mask=1;
}
}
/* correlate the read with the output buffer */
pin_read_buff[pin_read_pos].pos = out_state_buff_pos;
pin_read_buff[pin_read_pos].bitmask = pin_read_mask;
pin_read_mask = pin_read_mask<<1;
if( !pin_read_mask ){
pin_read_mask = 1;
read_slot += 1;
}
pin_read_buff[pin_read_pos].ptr = read_slot;
pin_read_pos++;
if( pin_read_pos==BUFFER_SIZE ){
DEBUG("read buffer overflow!\n");
}
}
/** SWDIO I/O pin: Set Output (used in SWD mode only).
\param bit Output value for the SWDIO DAP hardware I/O pin.
*/
static __forceinline void PIN_SWDIO_OUT (uint32_t bit) {
PIN_SET(TMS_SWDIO,bit);
}
/** SWDIO I/O pin: Switch to Output mode (used in SWD mode only).
Configure the SWDIO DAP hardware I/O pin to output mode. This function is
called prior \ref PIN_SWDIO_OUT function calls.
*/
static __forceinline void PIN_SWDIO_OUT_ENABLE (void) {
/* SWD is changing DIO line to output, submit current IO state
and send it to FTDI*/
DEBUG("SWDIO -> out\n");
dir_state |= TMS_SWDIO;
int success = ftdi_set_bitmode(&__ftdic, dir_state, __ftdic.bitbang_mode );
if( success<0 ){
DEBUG("Could not change SWDIO to out: %s\n",ftdi_get_error_string(&__ftdic));
}
}
/** SWDIO I/O pin: Switch to Input mode (used in SWD mode only).
Configure the SWDIO DAP hardware I/O pin to input mode. This function is
called prior \ref PIN_SWDIO_IN function calls.
*/
static __forceinline void PIN_SWDIO_OUT_DISABLE (void) {
/* SWD is changing DIO line to input, submit current IO state
and send it to FTDI */
DEBUG("SWDIO -> in\n");
dir_state &= ~TMS_SWDIO;
int success = ftdi_set_bitmode(&__ftdic, dir_state, __ftdic.bitbang_mode );
if( success<0 ){
DEBUG("Could not change SWDIO to in: %s\n",ftdi_get_error_string(&__ftdic));
}
}
// TDI Pin I/O ---------------------------------------------
/** TDI I/O pin: Get Input.
\return Current status of the TDI DAP hardware I/O pin.
*/
static __forceinline uint32_t PIN_TDI_IN (void) {
return PIN_IN(TDI);
}
/** TDI I/O pin: Set Output.
\param bit Output value for the TDI DAP hardware I/O pin.
*/
static __forceinline void PIN_TDI_OUT (uint32_t bit) {
PIN_SET(TDI,bit);
}
// TDO Pin I/O ---------------------------------------------
/** TDO I/O pin: Get Input.
\return Current status of the TDO DAP hardware I/O pin.
*/
static __forceinline uint32_t PIN_TDO_IN (void) {
return PIN_IN(TDO_SWO);
}
// nTRST Pin I/O -------------------------------------------
/** nTRST I/O pin: Get Input.
\return Current status of the nTRST DAP hardware I/O pin.
*/
static __forceinline uint32_t PIN_nTRST_IN (void) {
return PIN_IN(nTRST);
}
/** nTRST I/O pin: Set Output.
\param bit JTAG TRST Test Reset pin status:
- 0: issue a JTAG TRST Test Reset.
- 1: release JTAG TRST Test Reset.
*/
static __forceinline void PIN_nTRST_OUT (uint32_t bit) {
PIN_SET(nTRST,bit);
}
// nRESET Pin I/O------------------------------------------
/** nRESET I/O pin: Get Input.
\return Current status of the nRESET DAP hardware I/O pin.
*/
static __forceinline uint32_t PIN_nRESET_IN (void) {
return PIN_IN(nRESET);
}
/** nRESET I/O pin: Set Output.
\param bit target device hardware reset pin status:
- 0: issue a device hardware reset.
- 1: release device hardware reset.
*/
static __forceinline void PIN_nRESET_OUT (uint32_t bit) {
PIN_SET(nRESET,bit);
}
///@}
//**************************************************************************************************
/**
\defgroup DAP_Config_LEDs_gr CMSIS-DAP Hardware Status LEDs
\ingroup DAP_ConfigIO_gr
@{
CMSIS-DAP Hardware may provide LEDs that indicate the status of the CMSIS-DAP Debug Unit.
It is recommended to provide the following LEDs for status indication:
- Connect LED: is active when the DAP hardware is connected to a debugger.
- Running LED: is active when the debugger has put the target device into running state.
*/
/** Debug Unit: Set status of Connected LED.
\param bit status of the Connect LED.
- 1: Connect LED ON: debugger is connected to CMSIS-DAP Debug Unit.
- 0: Connect LED OFF: debugger is not connected to CMSIS-DAP Debug Unit.
*/
static __inline void LED_CONNECTED_OUT (uint32_t bit) {
PIN_SET(LED_CONN,bit);
}
/** Debug Unit: Set status Target Running LED.
\param bit status of the Target Running LED.
- 1: Target Running LED ON: program execution in target started.
- 0: Target Running LED OFF: program execution in target stopped.
*/
static __inline void LED_RUNNING_OUT (uint32_t bit) {
PIN_SET( LED_RUN,bit);
}
///@}
//**************************************************************************************************
/**
\defgroup DAP_Config_Initialization_gr CMSIS-DAP Initialization
\ingroup DAP_ConfigIO_gr
@{
CMSIS-DAP Hardware I/O and LED Pins are initialized with the function \ref DAP_SETUP.
*/
/** Reset Target Device with custom specific I/O pin or command sequence.
This function allows the optional implementation of a device specific reset sequence.
It is called when the command \ref DAP_ResetTarget and is for example required
when a device needs a time-critical unlock sequence that enables the debug port.
\return 0 = no device specific reset sequence is implemented.\n
1 = a device specific reset sequence is implemented.
*/
static __inline uint32_t RESET_TARGET (void) {
return (0); // change to '1' when a device reset sequence is implemented
}
///@}
#endif /* __DAP_CONFIG_H__ */

@ -0,0 +1,122 @@
/**************************************************************************//**
* @file DAP_vendor.c
* @brief CMSIS-DAP Vendor Commands
* @version V1.00
* @date 1. June 2012
*
* @note
* Copyright (C) 2012 ARM Limited. All rights reserved.
*
* @par
* ARM Limited (ARM) is supplying this software for use with Cortex-M
* processor based microcontrollers.
*
* @par
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
******************************************************************************/
#include "DAP_config.h"
#include "DAP.h"
//**************************************************************************************************
/**
\defgroup DAP_Vendor_Adapt_gr Adapt Vendor Commands
\ingroup DAP_Vendor_gr
@{
The file DAP_vendor.c provides template source code for extension of a Debug Unit with
Vendor Commands. Copy this file to the project folder of the Debug Unit and add the
file to the MDK-ARM project under the file group Configuration.
*/
/** Process DAP Vendor Command and prepare Response Data
\param request pointer to request data
\param response pointer to response data
\return number of bytes in Response Data
*/
#define PIN_DELAY() PIN_DELAY_SLOW(DAP_Data.clock_delay)
#define SWJ_CLOCK_CYCLE() \
PIN_SWCLK_TCK_CLR(); \
PIN_DELAY(); \
PIN_SWCLK_TCK_SET(); \
PIN_DELAY()
uint32_t DAP_ProcessVendorCommand(uint8_t *request, uint8_t *response) {
uint32_t num = 0;
switch (request[0]) { // first byte in request is Command ID
case ID_DAP_Vendor0:
#if 0 // example user command
*response++ = *request++; // copy Command ID
num++; // increment return count
if (*request == 1) { // when first command data byte is 1
*response++ = 'U'; // send 'U' as response
num++; // increment return count
}
#endif
break;
case ID_DAP_Vendor1:
response[0]=request[0];
int i;
for(i=0;i<100;i++){
PIN_SWCLK_TCK_CLR();
PIN_DELAY();
PIN_SWCLK_TCK_SET();
PIN_DELAY();
}
break;
case ID_DAP_Vendor2:
response[0]=request[0];
uint8_t bit=0;
PIN_SWDIO_OUT_DISABLE();
FTDI_BEGIN_READ();
PIN_SWCLK_TCK_CLR();
PIN_DELAY();
PIN_SWDIO_IN(&bit,1);
PIN_SWCLK_TCK_SET();
PIN_DELAY();
PIN_SWDIO_OUT_ENABLE();
FTDI_END_READ();
break;
case ID_DAP_Vendor3: break;
case ID_DAP_Vendor4: break;
case ID_DAP_Vendor5: break;
case ID_DAP_Vendor6: break;
case ID_DAP_Vendor7: break;
case ID_DAP_Vendor8: break;
case ID_DAP_Vendor9: break;
case ID_DAP_Vendor10: break;
case ID_DAP_Vendor11: break;
case ID_DAP_Vendor12: break;
case ID_DAP_Vendor13: break;
case ID_DAP_Vendor14: break;
case ID_DAP_Vendor15: break;
case ID_DAP_Vendor16: break;
case ID_DAP_Vendor17: break;
case ID_DAP_Vendor18: break;
case ID_DAP_Vendor19: break;
case ID_DAP_Vendor20: break;
case ID_DAP_Vendor21: break;
case ID_DAP_Vendor22: break;
case ID_DAP_Vendor23: break;
case ID_DAP_Vendor24: break;
case ID_DAP_Vendor25: break;
case ID_DAP_Vendor26: break;
case ID_DAP_Vendor27: break;
case ID_DAP_Vendor28: break;
case ID_DAP_Vendor29: break;
case ID_DAP_Vendor30: break;
case ID_DAP_Vendor31: break;
}
return (num);
}
///@}

@ -0,0 +1,15 @@
/*
* Debug.c
*
* Created on: 01.11.2014
* Author: powertomato
*/
#include <stdio.h>
#ifndef SRC_DEBUG_H_
#define SRC_DEBUG_H_
#define DEBUG(format, ...) fprintf (stderr, format, ##__VA_ARGS__)
#endif //SRC_DEBUG_H_

@ -0,0 +1,365 @@
/******************************************************************************
* @file JTAG_DP.c
* @brief CMSIS-DAP JTAG DP I/O
* @version V1.00
* @date 31. May 2012
*
* @note
* Copyright (C) 2012 ARM Limited. All rights reserved.
*
* @par
* ARM Limited (ARM) is supplying this software for use with Cortex-M
* processor based microcontrollers.
*
* @par
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
******************************************************************************/
#include "DAP_config.h"
#include "DAP.h"
// JTAG Macros
#define PIN_TCK_SET PIN_SWCLK_TCK_SET
#define PIN_TCK_CLR PIN_SWCLK_TCK_CLR
#define PIN_TMS_SET PIN_SWDIO_TMS_SET
#define PIN_TMS_CLR PIN_SWDIO_TMS_CLR
#define JTAG_CYCLE_TCK() \
PIN_TCK_CLR(); \
PIN_DELAY(); \
PIN_TCK_SET(); \
PIN_DELAY()
#define JTAG_CYCLE_TDI(tdi) \
PIN_TDI_OUT(tdi); \
PIN_TCK_CLR(); \
PIN_DELAY(); \
PIN_TCK_SET(); \
PIN_DELAY()
#define JTAG_CYCLE_TDO(tdo) \
PIN_TCK_CLR(); \
PIN_DELAY(); \
tdo = PIN_TDO_IN(); \
PIN_TCK_SET(); \
PIN_DELAY()
#define JTAG_CYCLE_TDIO(tdi,tdo) \
PIN_TDI_OUT(tdi); \
PIN_TCK_CLR(); \
PIN_DELAY(); \
tdo = PIN_TDO_IN(); \
PIN_TCK_SET(); \
PIN_DELAY()
#define PIN_DELAY() PIN_DELAY_SLOW(DAP_Data.clock_delay)
#if (DAP_JTAG != 0)
// Generate JTAG Sequence
// info: sequence information
// tdi: pointer to TDI generated data
// tdo: pointer to TDO captured data
// return: none
void JTAG_Sequence (uint32_t info, uint8_t *tdi, uint8_t *tdo) {
uint32_t i_val;
uint32_t o_val;
uint32_t bit;
uint32_t n, k;
n = info & JTAG_SEQUENCE_TCK;
if (n == 0) n = 64;
if (info & JTAG_SEQUENCE_TMS) {
PIN_TMS_SET();
} else {
PIN_TMS_CLR();
}
while (n) {
i_val = *tdi++;
o_val = 0;
for (k = 8; k && n; k--, n--) {
JTAG_CYCLE_TDIO(i_val, bit);
i_val >>= 1;
o_val >>= 1;
o_val |= bit << 7;
}
o_val >>= k;
if (info & JTAG_SEQUENCE_TDO) {
*tdo++ = o_val;
}
}
}
// JTAG Set IR
// ir: IR value
// return: none
#define JTAG_IR_Function(speed) /**/ \
void JTAG_IR_##speed (uint32_t ir) { \
uint32_t n; \
\
PIN_TMS_SET(); \
JTAG_CYCLE_TCK(); /* Select-DR-Scan */ \
JTAG_CYCLE_TCK(); /* Select-IR-Scan */ \
PIN_TMS_CLR(); \
JTAG_CYCLE_TCK(); /* Capture-IR */ \
JTAG_CYCLE_TCK(); /* Shift-IR */ \
\
PIN_TDI_OUT(1); \
for (n = DAP_Data.jtag_dev.ir_before[DAP_Data.jtag_dev.index]; n; n--) { \
JTAG_CYCLE_TCK(); /* Bypass before data */ \
} \
for (n = DAP_Data.jtag_dev.ir_length[DAP_Data.jtag_dev.index] - 1; n; n--) { \
JTAG_CYCLE_TDI(ir); /* Set IR bits (except last) */ \
ir >>= 1; \
} \
n = DAP_Data.jtag_dev.ir_after[DAP_Data.jtag_dev.index]; \
if (n) { \
JTAG_CYCLE_TDI(ir); /* Set last IR bit */ \
PIN_TDI_OUT(1); \
for (--n; n; n--) { \
JTAG_CYCLE_TCK(); /* Bypass after data */ \
} \
PIN_TMS_SET(); \
JTAG_CYCLE_TCK(); /* Bypass & Exit1-IR */ \
} else { \
PIN_TMS_SET(); \
JTAG_CYCLE_TDI(ir); /* Set last IR bit & Exit1-IR */ \
} \
\
JTAG_CYCLE_TCK(); /* Update-IR */ \
PIN_TMS_CLR(); \
JTAG_CYCLE_TCK(); /* Idle */ \
PIN_TDI_OUT(1); \
}
// JTAG Transfer I/O
// request: A[3:2] RnW APnDP
// data: DATA[31:0]
// return: ACK[2:0]
#define JTAG_TransferFunction(speed) /**/ \
uint8_t JTAG_Transfer##speed (uint32_t request, uint32_t *data) { \
uint32_t ack; \
uint32_t bit; \
uint32_t val; \
uint32_t n; \
\
PIN_TMS_SET(); \
JTAG_CYCLE_TCK(); /* Select-DR-Scan */ \
PIN_TMS_CLR(); \
JTAG_CYCLE_TCK(); /* Capture-DR */ \
JTAG_CYCLE_TCK(); /* Shift-DR */ \
\
for (n = DAP_Data.jtag_dev.index; n; n--) { \
JTAG_CYCLE_TCK(); /* Bypass before data */ \
} \
\
JTAG_CYCLE_TDIO(request >> 1, bit); /* Set RnW, Get ACK.0 */ \
ack = bit << 1; \
JTAG_CYCLE_TDIO(request >> 2, bit); /* Set A2, Get ACK.1 */ \
ack |= bit << 0; \
JTAG_CYCLE_TDIO(request >> 3, bit); /* Set A3, Get ACK.2 */ \
ack |= bit << 2; \
\
if (ack != DAP_TRANSFER_OK) { \
/* Exit on error */ \
PIN_TMS_SET(); \
JTAG_CYCLE_TCK(); /* Exit1-DR */ \
goto exit; \
} \
\
if (request & DAP_TRANSFER_RnW) { \
/* Read Transfer */ \
val = 0; \
for (n = 31; n; n--) { \
JTAG_CYCLE_TDO(bit); /* Get D0..D30 */ \
val |= bit << 31; \
val >>= 1; \
} \
n = DAP_Data.jtag_dev.count - DAP_Data.jtag_dev.index - 1; \
if (n) { \
JTAG_CYCLE_TDO(bit); /* Get D31 */ \
for (--n; n; n--) { \
JTAG_CYCLE_TCK(); /* Bypass after data */ \
} \
PIN_TMS_SET(); \
JTAG_CYCLE_TCK(); /* Bypass & Exit1-DR */ \
} else { \
PIN_TMS_SET(); \
JTAG_CYCLE_TDO(bit); /* Get D31 & Exit1-DR */ \
} \
val |= bit << 31; \
if (data) *data = val; \
} else { \
/* Write Transfer */ \
val = *data; \
for (n = 31; n; n--) { \
JTAG_CYCLE_TDI(val); /* Set D0..D30 */ \
val >>= 1; \
} \
n = DAP_Data.jtag_dev.count - DAP_Data.jtag_dev.index - 1; \
if (n) { \
JTAG_CYCLE_TDI(val); /* Set D31 */ \
for (--n; n; n--) { \
JTAG_CYCLE_TCK(); /* Bypass after data */ \
} \
PIN_TMS_SET(); \
JTAG_CYCLE_TCK(); /* Bypass & Exit1-DR */ \
} else { \
PIN_TMS_SET(); \
JTAG_CYCLE_TDI(val); /* Set D31 & Exit1-DR */ \
} \
} \
\
exit: \
JTAG_CYCLE_TCK(); /* Update-DR */ \
PIN_TMS_CLR(); \
JTAG_CYCLE_TCK(); /* Idle */ \
PIN_TDI_OUT(1); \
\
/* Idle cycles */ \
n = DAP_Data.transfer.idle_cycles; \
while (n--) { \
JTAG_CYCLE_TCK(); /* Idle */ \
} \
\
return (ack); \
}
#undef PIN_DELAY
#define PIN_DELAY() PIN_DELAY_FAST()
JTAG_IR_Function(Fast);
JTAG_TransferFunction(Fast);
#undef PIN_DELAY
#define PIN_DELAY() PIN_DELAY_SLOW(DAP_Data.clock_delay)
JTAG_IR_Function(Slow);
JTAG_TransferFunction(Slow);
// JTAG Read IDCODE register
// return: value read
uint32_t JTAG_ReadIDCode (void) {
uint32_t bit;
uint32_t val;
uint32_t n;
PIN_TMS_SET();
JTAG_CYCLE_TCK(); /* Select-DR-Scan */
PIN_TMS_CLR();
JTAG_CYCLE_TCK(); /* Capture-DR */
JTAG_CYCLE_TCK(); /* Shift-DR */
for (n = DAP_Data.jtag_dev.index; n; n--) {
JTAG_CYCLE_TCK(); /* Bypass before data */
}
val = 0;
for (n = 31; n; n--) {
JTAG_CYCLE_TDO(bit); /* Get D0..D30 */
val |= bit << 31;
val >>= 1;
}
PIN_TMS_SET();
JTAG_CYCLE_TDO(bit); /* Get D31 & Exit1-DR */
val |= bit << 31;
JTAG_CYCLE_TCK(); /* Update-DR */
PIN_TMS_CLR();
JTAG_CYCLE_TCK(); /* Idle */
return (val);
}
// JTAG Write ABORT register
// data: value to write
// return: none
void JTAG_WriteAbort (uint32_t data) {
uint32_t n;
PIN_TMS_SET();
JTAG_CYCLE_TCK(); /* Select-DR-Scan */
PIN_TMS_CLR();
JTAG_CYCLE_TCK(); /* Capture-DR */
JTAG_CYCLE_TCK(); /* Shift-DR */
for (n = DAP_Data.jtag_dev.index; n; n--) {
JTAG_CYCLE_TCK(); /* Bypass before data */
}
PIN_TDI_OUT(0);
JTAG_CYCLE_TCK(); /* Set RnW=0 (Write) */
JTAG_CYCLE_TCK(); /* Set A2=0 */
JTAG_CYCLE_TCK(); /* Set A3=0 */
for (n = 31; n; n--) {
JTAG_CYCLE_TDI(data); /* Set D0..D30 */
data >>= 1;
}
n = DAP_Data.jtag_dev.count - DAP_Data.jtag_dev.index - 1;
if (n) {
JTAG_CYCLE_TDI(data); /* Set D31 */
for (--n; n; n--) {
JTAG_CYCLE_TCK(); /* Bypass after data */
}
PIN_TMS_SET();
JTAG_CYCLE_TCK(); /* Bypass & Exit1-DR */
} else {
PIN_TMS_SET();
JTAG_CYCLE_TDI(data); /* Set D31 & Exit1-DR */
}
JTAG_CYCLE_TCK(); /* Update-DR */
PIN_TMS_CLR();
JTAG_CYCLE_TCK(); /* Idle */
PIN_TDI_OUT(1);
}
// JTAG Set IR
// ir: IR value
// return: none
void JTAG_IR (uint32_t ir) {
if (DAP_Data.fast_clock) {
JTAG_IR_Fast(ir);
} else {
JTAG_IR_Slow(ir);
}
}
// JTAG Transfer I/O
// request: A[3:2] RnW APnDP
// data: DATA[31:0]
// return: ACK[2:0]
uint8_t JTAG_Transfer(uint8_t request, uint32_t *data)
{
return JTAG_TransferSlow(request, data);
#if 0 //XXX JTAG transfer fast
if (DAP_Data.fast_clock)
{
return JTAG_TransferFast(request, data);
return JTAG_TransferSlow(request, data);
} else {
return JTAG_TransferSlow(request, data);
}
#endif
}
#endif /* (DAP_JTAG != 0) */

@ -0,0 +1,248 @@
/******************************************************************************
* @file SW_DP.c
* @brief CMSIS-DAP SW DP I/O
* @version V1.00
* @date 31. May 2012
*
* @note
* Copyright (C) 2012 ARM Limited. All rights reserved.
*
* @par
* ARM Limited (ARM) is supplying this software for use with Cortex-M
* processor based microcontrollers.
*
* @par
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
******************************************************************************/
#include "DAP_config.h"
#include "DAP.h"
// SW Macros
#define PIN_SWCLK_SET PIN_SWCLK_TCK_SET
#define PIN_SWCLK_CLR PIN_SWCLK_TCK_CLR
#define SW_CLOCK_CYCLE() \
PIN_SWCLK_CLR(); \
PIN_DELAY(); \
PIN_SWCLK_SET(); \
PIN_DELAY()
#define SW_WRITE_BIT(bit) \
PIN_SWDIO_OUT(bit); \
PIN_SWCLK_CLR(); \
PIN_DELAY(); \
PIN_SWCLK_SET(); \
PIN_DELAY()
#define SW_READ_BIT(ptr,bit) \
PIN_SWCLK_CLR(); \
PIN_DELAY(); \
PIN_SWDIO_IN(ptr,bit); \
PIN_SWCLK_SET(); \
PIN_DELAY()
#define PIN_DELAY() PIN_DELAY_SLOW(DAP_Data.clock_delay)
// Generate SWJ Sequence
// count: sequence bit count
// data: pointer to sequence bit data
// return: none
#if ((DAP_SWD != 0) || (DAP_JTAG != 0))
void SWJ_Sequence (uint32_t count, uint8_t *data)
{
uint8_t val;
uint8_t n;
val = 0;
n = 0;
DEBUG("DATA:");
while (count--)
{
if (n == 0)
{
val = *data++;
DEBUG(" %02X", val);
n = 8;
}
if (val & 1)
{
PIN_SWDIO_TMS_SET();
}
else
{
PIN_SWDIO_TMS_CLR();
}
SW_CLOCK_CYCLE();
val >>= 1;
n--;
}
DEBUG("\n");
}
#endif
#if (DAP_SWD != 0)
// SWD Transfer I/O
// request: A[3:2] RnW APnDP
// data: DATA[31:0]
// return: ACK[2:0]
#define SWD_TransferFunction(speed) /**/ \
uint8_t SWD_Transfer##speed (uint8_t request, uint32_t *data) { \
uint8_t ack; \
uint32_t bit; \
uint8_t val[4]; \
uint32_t parity; \
\
uint32_t n; \
\
/* Packet Request */ \
parity = 0; \
SW_WRITE_BIT(1); /* Start Bit */ \
bit = request >> 0; \
SW_WRITE_BIT(bit); /* APnDP Bit */ \
parity += bit; \
bit = request >> 1; \
SW_WRITE_BIT(bit); /* RnW Bit */ \
parity += bit; \
bit = request >> 2; \
SW_WRITE_BIT(bit); /* A2 Bit */ \
parity += bit; \
bit = request >> 3; \
parity += bit; \
SW_WRITE_BIT(parity); /* Parity Bit */ \
SW_WRITE_BIT(0); /* Stop Bit */ \
SW_WRITE_BIT(1); /* Park Bit */ \
\
/* Turnaround */ \
PIN_SWDIO_OUT_DISABLE(); \
for (n = DAP_Data.swd_conf.turnaround; n; n--) { \
SW_CLOCK_CYCLE(); \
} \
\
/* Acknowledge response */ \
SW_READ_BIT(&ack,1); \
SW_READ_BIT(NULL,0); \
SW_READ_BIT(NULL,0); \
FTDI_END_READ(); \
\
if (ack == DAP_TRANSFER_OK) { /* OK response */ \
/* Data transfer */ \
if (request & DAP_TRANSFER_RnW) { \
/* Read data */ \
memset( val, 0, 4); \
parity = 0; \
SW_READ_BIT(val,1); \
for (n = 31; n; n--) { \
SW_READ_BIT(NULL,0); /* Read RDATA[0:31] */ \
} /*TODO calc parity */ \
SW_READ_BIT((uint8_t*)&parity,1); /* Read parity bit */ \
FTDI_END_READ(); \
if ((parity ^ bit) & 1) { \
ack = DAP_TRANSFER_ERROR; \
} \
if (data){ *data = val[0]<<24 | val[1]<<16 | val[2]<<8 | val[3]; } \
/* Turnaround */ \
for (n = DAP_Data.swd_conf.turnaround; n; n--) { \
SW_CLOCK_CYCLE(); \
} \
PIN_SWDIO_OUT_ENABLE(); \
} else { \
/* Turnaround */ \
for (n = DAP_Data.swd_conf.turnaround; n; n--) { \
SW_CLOCK_CYCLE(); \
} \
PIN_SWDIO_OUT_ENABLE(); \
/* Write data */ \
uint32_t dat = *data; \
parity = 0; \
for (n = 32; n; n--) { \
SW_WRITE_BIT(dat); /* Write WDATA[0:31] */ \
parity += dat; \
dat >>= 1; \
} \
SW_WRITE_BIT(parity); /* Write Parity Bit */ \
} \
/* Idle cycles */ \
n = DAP_Data.transfer.idle_cycles; \
if (n) { \
PIN_SWDIO_OUT(0); \
for (; n; n--) { \
SW_CLOCK_CYCLE(); \
} \
} \
PIN_SWDIO_OUT(1); \
return (ack); \
} \
\
if ((ack == DAP_TRANSFER_WAIT) || (ack == DAP_TRANSFER_FAULT)) { \
/* WAIT or FAULT response */ \
if (DAP_Data.swd_conf.data_phase && ((request & DAP_TRANSFER_RnW) != 0)) { \
for (n = 32+1; n; n--) { \
SW_CLOCK_CYCLE(); /* Dummy Read RDATA[0:31] + Parity */ \
} \
} \
/* Turnaround */ \
for (n = DAP_Data.swd_conf.turnaround; n; n--) { \
SW_CLOCK_CYCLE(); \
} \
PIN_SWDIO_OUT_ENABLE(); \
if (DAP_Data.swd_conf.data_phase && ((request & DAP_TRANSFER_RnW) == 0)) { \
PIN_SWDIO_OUT(0); \
for (n = 32+1; n; n--) { \
SW_CLOCK_CYCLE(); /* Dummy Write WDATA[0:31] + Parity */ \
} \
} \
PIN_SWDIO_OUT(1); \
return (ack); \
} \
\
/* Protocol error */ \
for (n = DAP_Data.swd_conf.turnaround + 32 + 1; n; n--) { \
SW_CLOCK_CYCLE(); /* Back off data phase */ \
} \
PIN_SWDIO_OUT(1); \
return (ack); \
}
#undef PIN_DELAY
#define PIN_DELAY() PIN_DELAY_FAST()
SWD_TransferFunction(Fast);
#undef PIN_DELAY
#define PIN_DELAY() PIN_DELAY_SLOW(DAP_Data.clock_delay)
SWD_TransferFunction(Slow);
// SWD Transfer I/O
// request: A[3:2] RnW APnDP
// data: DATA[31:0]
// return: ACK[2:0]
uint8_t SWD_Transfer(uint8_t request, uint32_t *data)
{
return SWD_TransferSlow(request, data);
#if 0 // XXX SWD transer fast
if (DAP_Data.fast_clock)
{
return SWD_TransferFast(request, data);
}
else
{
return SWD_TransferSlow(request, data);
}
#endif
}
#endif /* (DAP_SWD != 0) */

@ -0,0 +1,51 @@
/*
* Timer.c
*
* Created on: 01.11.2014
* Author: powertomato
*/
#include "Timer.h"
#include "device.h" /* for NULL*/
static int64_t get_time() {
struct timeval tv;
gettimeofday(&tv,NULL);
return tv.tv_sec*(uint64_t)1000000+tv.tv_usec;
}
static int64_t target_time = -1;
void TIMER_START (uint32_t usec)
{
target_time = get_time()+usec;
}
void TIMER_STOP (void)
{
target_time = -1;
}
uint32_t TIMER_EXPIRED (void)
{
if(target_time==-1){
return 0;
}else if( target_time <= get_time() ){
return 1;
}
return 0;
}
void Delayus(uint64_t us) {
TIMER_START(us);
// TODO usleep nanosleep
while( !TIMER_EXPIRED());
}
// Delay for specified time
// delay: delay time in ms
void Delayms(uint32_t delay)
{
//delay *= (CPU_CLOCK / 1000 + (DELAY_SLOW_CYCLES-1)) / DELAY_SLOW_CYCLES;
//PIN_DELAY_SLOW(delay);
Delayus(delay*1000);
}

@ -0,0 +1,20 @@
/*
* Timer.h
*
* Created on: 01.11.2014
* Author: powertomato
*/
#ifndef SRC_TIMER_H_
#define SRC_TIMER_H_
#include <stdint.h>
#include <sys/time.h>
void TIMER_START (uint32_t usec);
void TIMER_STOP (void);
uint32_t TIMER_EXPIRED (void);
void Delayus(uint64_t us);
void Delayms(uint32_t delay);
#endif /* SRC_TIMER_H_ */

@ -0,0 +1,20 @@
/*
* device.h
*
* Created on: 01.11.2014
* Author: powertomato
*/
#ifndef SRC_DEVICE_H_
#define SRC_DEVICE_H_
#define __weak
#ifdef __forceinline
#undef __forceinline
#endif
#define __forceinline __inline
#ifndef NULL
# define NULL ((void*)0)
#endif
#endif /* SRC_DEVICE_H_ */

@ -0,0 +1,28 @@
/*
* ftdi.c
*
* Created on: 01.11.2014
* Author: powertomato
*/
#include "ftdi_vars.h"
struct ftdi_context __ftdic;
uint16_t VID = 0x0403;
uint16_t PID = 0x6001;
uint8_t out_state;
uint8_t dir_state;
uint8_t out_state_buff[BUFFER_SIZE];
int out_state_buff_pos = 0;
uint8_t in_buff[BUFFER_SIZE];
uint8_t *read_slot;
red_pos_t pin_read_buff[BUFFER_SIZE];
int pin_read_pos = 0;
uint8_t pin_read_mask = 1;
int is_in_read_mode = 0;

@ -0,0 +1,50 @@
/*
* ftdi.h
*
* Created on: 01.11.2014
* Author: powertomato
*/
#ifndef SRC_FTDI_VARS_H_
#define SRC_FTDI_VARS_H_
#include <libftdi1/ftdi.h>
#define BUFFER_SIZE (64*4)
#define RI (1<<7)
#define DCD (1<<6)
#define DSR (1<<5)
#define DTR (1<<4)
#define CTS (1<<3)
#define RTS (1<<2)
#define RXD (1<<1)
#define TXD (1<<0)
typedef struct {
uint8_t* ptr;
uint8_t bitmask;
int pos;
} red_pos_t;
extern struct ftdi_context __ftdic;
extern uint16_t VID;
extern uint16_t PID;
extern uint8_t out_state;
extern uint8_t dir_state;
extern uint8_t out_state_buff[BUFFER_SIZE];
extern int out_state_buff_pos;
extern uint8_t in_buff[BUFFER_SIZE];
extern uint8_t *read_slot;
extern red_pos_t pin_read_buff[BUFFER_SIZE];
extern int pin_read_pos;
extern uint8_t pin_read_mask;
extern int is_in_read_mode;
#endif /* SRC_FTDI_VARS_H_ */

@ -0,0 +1,55 @@
/******************************************************************************
* @file main.c
* @brief CMSIS-DAP Main module
* @version V1.00
* @date 31. May 2012
*
* @note
* Copyright (C) 2012 ARM Limited. All rights reserved.
*
* @par
* ARM Limited (ARM) is supplying this software for use with Cortex-M
* processor based microcontrollers.
*
* @par
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
******************************************************************************/
#include <libftdi1/ftdi.h>
#include "DAP_config.h"
#include "DAP.h"
#include <libftdi1/ftdi.h>
extern void wait_for_client(void);
extern void process_data(void);
// Main program
int main (void) {
DAP_Setup(); // DAP Setup
//DAP_PACKET_COUNT
LED_CONNECTED_OUT(1); // Turn on Debugger Connected LED
LED_RUNNING_OUT(1); // Turn on Target Running LED
Delayms(500); // Wait for 500ms
LED_RUNNING_OUT(0); // Turn off Target Running LED
LED_CONNECTED_OUT(0); // Turn off Debugger Connected LED
printf("Wait client... ");
fflush(stdout);
wait_for_client();
printf("connected\n");
while (1) { // Endless Loop
//usbd_hid_process(); // Process USB HID Data
// TODO thread sleep
//printf("process_data\n");
process_data();
//Delayms(1000);
}
}

@ -0,0 +1,171 @@
/*
* socket_ipc.c
*
* Created on: 03.11.2014
* Author: powertomato
*/
#include <stdio.h>
#include <fcntl.h>
#include "DAP_config.h"
#include "DAP.h"
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <netinet/in.h>
#include <string.h>
#include <stdlib.h>
static volatile uint8_t request_full; // Request Buffer Usage Flag
static volatile uint32_t request_head; // ReqBuff Buffer In Index
static volatile uint32_t request_tail; // ReqBuff Buffer Out Index
static volatile uint8_t response_full; // Response Buffer Usage Flag
static volatile uint32_t response_head; // Response Buffer In Index
static volatile uint32_t response_tail; // Response Buffer Out Index
static uint8_t request_buff[DAP_PACKET_COUNT][DAP_PACKET_SIZE]; // ReqBuff Buffer
static uint8_t response_buff[DAP_PACKET_COUNT][DAP_PACKET_SIZE]; // Response Buffer
#ifdef __CYGWIN__ /*include oddness...*/
typedef struct {
sa_family_t sin_family; /* Address family */
in_port_t sin_port; /* Port number */
struct in_addr sin_addr; /* Internet address */
/* Pad to size of `struct sockaddr'. */
unsigned char __pad[__SOCK_SIZE__ - sizeof(short int)
- sizeof(unsigned short int) - sizeof(struct in_addr)];
} sockaddr_in_t;
#else
typedef struct sockaddr_in sockaddr_in_t;
#endif
int sockfd, newsockfd, portno, clilen;
sockaddr_in_t serv_addr;
sockaddr_in_t cli_addr;
// USB HID Callback: when system initializes
void wait_for_client(void) {
request_full = 0;
request_head = 0;
request_tail = 0;
response_full = 0;
response_head = 0;
response_tail = 0;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
DEBUG("ERROR opening socket");
exit(1);
}
bzero((char *) &serv_addr, sizeof(serv_addr));
portno = 4777;
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);
if (bind(sockfd, (struct sockaddr *) &serv_addr,
sizeof(serv_addr)) < 0){
DEBUG("ERROR on binding");
exit(1);
}
listen(sockfd,5);
clilen = sizeof(cli_addr);
newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, (socklen_t*)&clilen);
if (newsockfd < 0){
DEBUG("ERROR on accept");
exit(1);
}
int flags;
flags = fcntl(newsockfd, F_GETFL, 0);
if(flags < 0 ){
flags = 0;
}
if( fcntl(newsockfd, F_SETFL, flags | O_NONBLOCK) < 0 ){
DEBUG("ERROR seting non-blocking!\n");
}
}
// USB HID Callback: when data needs to be prepared for the host
int write_response() {
if ((response_tail != response_head) || response_full) {
int n = write(newsockfd,response_buff[response_tail],DAP_PACKET_SIZE);
if (n != DAP_PACKET_SIZE){
DEBUG("ERROR writing to socket");
}
// remove a response
response_tail = (response_tail+1) % DAP_PACKET_COUNT;
response_full = 0;
return (DAP_PACKET_SIZE);
}
return (0);
}
// USB HID Callback: when data is received from the host
void buffer_request(uint8_t *buff, int len) {
if (len == 0){
return;
}
if (buff[0] == ID_DAP_TransferAbort) {
DAP_TransferAbort = 1;
return;
}
if (request_full) {
return; // Discard packet when buffer is full
}
// add a request
memcpy(request_buff[request_head], buff, len);
request_head++;
if (request_head == DAP_PACKET_COUNT) {
request_head = 0;
}
if (request_head == request_tail) {
request_full = 1;
}
}
// Process USB HID Data
void process_data(void) {
static uint8_t buff[DAP_PACKET_SIZE];
static int buff_pos = 0;
int n;
n = read(newsockfd,buff+buff_pos,DAP_PACKET_SIZE);
if( n>0 ) {
buff_pos += n;
if( buff_pos==DAP_PACKET_SIZE ) {
buffer_request(buff,DAP_PACKET_SIZE);
buff_pos=0;
}
}
// Process pending requests
if ((request_tail != request_head) || request_full) {
// Process DAP Command and prepare response
DAP_ProcessCommand(request_buff[request_tail], response_buff[response_head]);
if( out_state_buff_pos != 0 ){
FTDI_WRITE_OUT();
}
// remove a request
request_tail = (request_tail + 1) % DAP_PACKET_COUNT;
request_full = 0;
// add a response
response_head = (response_head + 1) % DAP_PACKET_COUNT;
if (response_head == response_tail) {
response_full = 1;
}
write_response();
}
}
Loading…
Cancel
Save