commit
972b965591
@ -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…
Reference in new issue