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