mirror of
https://github.com/XIVN1987/DAPLink.git
synced 2026-09-27 06:26:16 +00:00
add AT32F425 porting
This commit is contained in:
+1808
File diff suppressed because it is too large
Load Diff
+334
@@ -0,0 +1,334 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2020 ARM Limited. All rights reserved.
|
||||
* Copyright 2019, Cypress Semiconductor Corporation
|
||||
* or a subsidiary of Cypress Semiconductor Corporation.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* ----------------------------------------------------------------------
|
||||
*
|
||||
* $Date: 26. November 2019
|
||||
* $Revision: V2.0.0
|
||||
*
|
||||
* Project: CMSIS-DAP Include
|
||||
* Title: DAP.h Definitions
|
||||
*
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef __DAP_H__
|
||||
#define __DAP_H__
|
||||
|
||||
|
||||
// DAP Firmware Version
|
||||
#ifdef DAP_FW_V1
|
||||
#define DAP_FW_VER "1.2.0"
|
||||
#else
|
||||
#define DAP_FW_VER "2.0.0"
|
||||
#endif
|
||||
|
||||
// DAP Command IDs
|
||||
#define ID_DAP_Info 0x00U
|
||||
#define ID_DAP_HostStatus 0x01U
|
||||
#define ID_DAP_Connect 0x02U
|
||||
#define ID_DAP_Disconnect 0x03U
|
||||
#define ID_DAP_TransferConfigure 0x04U
|
||||
#define ID_DAP_Transfer 0x05U
|
||||
#define ID_DAP_TransferBlock 0x06U
|
||||
#define ID_DAP_TransferAbort 0x07U
|
||||
#define ID_DAP_WriteABORT 0x08U
|
||||
#define ID_DAP_Delay 0x09U
|
||||
#define ID_DAP_ResetTarget 0x0AU
|
||||
#define ID_DAP_SWJ_Pins 0x10U
|
||||
#define ID_DAP_SWJ_Clock 0x11U
|
||||
#define ID_DAP_SWJ_Sequence 0x12U
|
||||
#define ID_DAP_SWD_Configure 0x13U
|
||||
#define ID_DAP_SWD_Sequence 0x1DU
|
||||
#define ID_DAP_JTAG_Sequence 0x14U
|
||||
#define ID_DAP_JTAG_Configure 0x15U
|
||||
#define ID_DAP_JTAG_IDCODE 0x16U
|
||||
#define ID_DAP_SWO_Transport 0x17U
|
||||
#define ID_DAP_SWO_Mode 0x18U
|
||||
#define ID_DAP_SWO_Baudrate 0x19U
|
||||
#define ID_DAP_SWO_Control 0x1AU
|
||||
#define ID_DAP_SWO_Status 0x1BU
|
||||
#define ID_DAP_SWO_ExtendedStatus 0x1EU
|
||||
#define ID_DAP_SWO_Data 0x1CU
|
||||
|
||||
#define ID_DAP_QueueCommands 0x7EU
|
||||
#define ID_DAP_ExecuteCommands 0x7FU
|
||||
|
||||
// DAP Vendor Command IDs
|
||||
#define ID_DAP_Vendor0 0x80U
|
||||
#define ID_DAP_Vendor1 0x81U
|
||||
#define ID_DAP_Vendor2 0x82U
|
||||
#define ID_DAP_Vendor3 0x83U
|
||||
#define ID_DAP_Vendor4 0x84U
|
||||
#define ID_DAP_Vendor5 0x85U
|
||||
#define ID_DAP_Vendor6 0x86U
|
||||
#define ID_DAP_Vendor7 0x87U
|
||||
#define ID_DAP_Vendor8 0x88U
|
||||
#define ID_DAP_Vendor9 0x89U
|
||||
#define ID_DAP_Vendor10 0x8AU
|
||||
#define ID_DAP_Vendor11 0x8BU
|
||||
#define ID_DAP_Vendor12 0x8CU
|
||||
#define ID_DAP_Vendor13 0x8DU
|
||||
#define ID_DAP_Vendor14 0x8EU
|
||||
#define ID_DAP_Vendor15 0x8FU
|
||||
#define ID_DAP_Vendor16 0x90U
|
||||
#define ID_DAP_Vendor17 0x91U
|
||||
#define ID_DAP_Vendor18 0x92U
|
||||
#define ID_DAP_Vendor19 0x93U
|
||||
#define ID_DAP_Vendor20 0x94U
|
||||
#define ID_DAP_Vendor21 0x95U
|
||||
#define ID_DAP_Vendor22 0x96U
|
||||
#define ID_DAP_Vendor23 0x97U
|
||||
#define ID_DAP_Vendor24 0x98U
|
||||
#define ID_DAP_Vendor25 0x99U
|
||||
#define ID_DAP_Vendor26 0x9AU
|
||||
#define ID_DAP_Vendor27 0x9BU
|
||||
#define ID_DAP_Vendor28 0x9CU
|
||||
#define ID_DAP_Vendor29 0x9DU
|
||||
#define ID_DAP_Vendor30 0x9EU
|
||||
#define ID_DAP_Vendor31 0x9FU
|
||||
|
||||
// DAP Extended range of Vendor Command IDs
|
||||
|
||||
#define ID_DAP_VendorExFirst 0xA0U
|
||||
#define ID_DAP_VendorExLast 0xFEU
|
||||
|
||||
#define ID_DAP_Invalid 0xFFU
|
||||
|
||||
// DAP Status Code
|
||||
#define DAP_OK 0U
|
||||
#define DAP_ERROR 0xFFU
|
||||
|
||||
// DAP ID
|
||||
#define DAP_ID_VENDOR 1U
|
||||
#define DAP_ID_PRODUCT 2U
|
||||
#define DAP_ID_SER_NUM 3U
|
||||
#define DAP_ID_CMSIS_DAP_VER 4U
|
||||
#define DAP_ID_FW_VER 4U // Deprecated alias of DAP_ID_CMSIS_DAP_VER for backwards compatibility.
|
||||
#define DAP_ID_DEVICE_VENDOR 5U
|
||||
#define DAP_ID_DEVICE_NAME 6U
|
||||
#define DAP_ID_PRODUCT_FW_VER 7U
|
||||
#define DAP_ID_CAPABILITIES 0xF0U
|
||||
#define DAP_ID_TIMESTAMP_CLOCK 0xF1U
|
||||
#define DAP_ID_SWO_BUFFER_SIZE 0xFDU
|
||||
#define DAP_ID_PACKET_COUNT 0xFEU
|
||||
#define DAP_ID_PACKET_SIZE 0xFFU
|
||||
|
||||
// DAP Host Status
|
||||
#define DAP_DEBUGGER_CONNECTED 0U
|
||||
#define DAP_TARGET_RUNNING 1U
|
||||
|
||||
// DAP Port
|
||||
#define DAP_PORT_AUTODETECT 0U // Autodetect Port
|
||||
#define DAP_PORT_DISABLED 0U // Port Disabled (I/O pins in High-Z)
|
||||
#define DAP_PORT_SWD 1U // SWD Port (SWCLK, SWDIO) + nRESET
|
||||
#define DAP_PORT_JTAG 2U // 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 (1U<<0)
|
||||
#define DAP_TRANSFER_RnW (1U<<1)
|
||||
#define DAP_TRANSFER_A2 (1U<<2)
|
||||
#define DAP_TRANSFER_A3 (1U<<3)
|
||||
#define DAP_TRANSFER_MATCH_VALUE (1U<<4)
|
||||
#define DAP_TRANSFER_MATCH_MASK (1U<<5)
|
||||
#define DAP_TRANSFER_TIMESTAMP (1U<<7)
|
||||
|
||||
// DAP Transfer Response
|
||||
#define DAP_TRANSFER_OK (1U<<0)
|
||||
#define DAP_TRANSFER_WAIT (1U<<1)
|
||||
#define DAP_TRANSFER_FAULT (1U<<2)
|
||||
#define DAP_TRANSFER_ERROR (1U<<3)
|
||||
#define DAP_TRANSFER_MISMATCH (1U<<4)
|
||||
|
||||
// DAP SWO Trace Mode
|
||||
#define DAP_SWO_OFF 0U
|
||||
#define DAP_SWO_UART 1U
|
||||
#define DAP_SWO_MANCHESTER 2U
|
||||
|
||||
// DAP SWO Trace Status
|
||||
#define DAP_SWO_CAPTURE_ACTIVE (1U<<0)
|
||||
#define DAP_SWO_CAPTURE_PAUSED (1U<<1)
|
||||
#define DAP_SWO_STREAM_ERROR (1U<<6)
|
||||
#define DAP_SWO_BUFFER_OVERRUN (1U<<7)
|
||||
|
||||
|
||||
// Debug Port Register Addresses
|
||||
#define DP_IDCODE 0x00U // IDCODE Register (SW Read only)
|
||||
#define DP_ABORT 0x00U // Abort Register (SW Write only)
|
||||
#define DP_CTRL_STAT 0x04U // Control & Status
|
||||
#define DP_WCR 0x04U // Wire Control Register (SW Only)
|
||||
#define DP_SELECT 0x08U // Select Register (JTAG R/W & SW W)
|
||||
#define DP_RESEND 0x08U // Resend (SW Read Only)
|
||||
#define DP_RDBUFF 0x0CU // Read Buffer (Read Only)
|
||||
|
||||
// JTAG IR Codes
|
||||
#define JTAG_ABORT 0x08U
|
||||
#define JTAG_DPACC 0x0AU
|
||||
#define JTAG_APACC 0x0BU
|
||||
#define JTAG_IDCODE 0x0EU
|
||||
#define JTAG_BYPASS 0x0FU
|
||||
|
||||
// JTAG Sequence Info
|
||||
#define JTAG_SEQUENCE_TCK 0x3FU // TCK count
|
||||
#define JTAG_SEQUENCE_TMS 0x40U // TMS value
|
||||
#define JTAG_SEQUENCE_TDO 0x80U // TDO capture
|
||||
|
||||
// SWD Sequence Info
|
||||
#define SWD_SEQUENCE_CLK 0x3FU // SWCLK count
|
||||
#define SWD_SEQUENCE_DIN 0x80U // SWDIO capture
|
||||
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include "cmsis_compiler.h"
|
||||
|
||||
// DAP Data structure
|
||||
typedef struct {
|
||||
uint8_t debug_port; // Debug Port
|
||||
uint8_t fast_clock; // Fast Clock Flag
|
||||
uint8_t padding[2];
|
||||
uint32_t clock_delay; // Clock Delay
|
||||
uint32_t timestamp; // Last captured Timestamp
|
||||
struct { // Transfer Configuration
|
||||
uint8_t idle_cycles; // Idle cycles after transfer
|
||||
uint8_t padding[3];
|
||||
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
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
// Functions
|
||||
extern void SWJ_Sequence (uint32_t count, const uint8_t *data);
|
||||
extern void SWD_Sequence (uint32_t info, const uint8_t *swdo, uint8_t *swdi);
|
||||
extern void JTAG_Sequence (uint32_t info, const 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 (uint32_t request, uint32_t *data);
|
||||
extern uint8_t SWD_Transfer (uint32_t request, uint32_t *data);
|
||||
|
||||
extern void Delayms (uint32_t delay);
|
||||
|
||||
extern uint32_t SWO_Transport (const uint8_t *request, uint8_t *response);
|
||||
extern uint32_t SWO_Mode (const uint8_t *request, uint8_t *response);
|
||||
extern uint32_t SWO_Baudrate (const uint8_t *request, uint8_t *response);
|
||||
extern uint32_t SWO_Control (const uint8_t *request, uint8_t *response);
|
||||
extern uint32_t SWO_Status (uint8_t *response);
|
||||
extern uint32_t SWO_ExtendedStatus (const uint8_t *request, uint8_t *response);
|
||||
extern uint32_t SWO_Data (const uint8_t *request, uint8_t *response);
|
||||
|
||||
extern void SWO_QueueTransfer (uint8_t *buf, uint32_t num);
|
||||
extern void SWO_AbortTransfer (void);
|
||||
extern void SWO_TransferComplete (void);
|
||||
|
||||
extern uint32_t UART_SWO_Mode (uint32_t enable);
|
||||
extern uint32_t UART_SWO_Baudrate (uint32_t baudrate);
|
||||
extern uint32_t UART_SWO_Control (uint32_t active);
|
||||
extern void UART_SWO_Capture (uint8_t *buf, uint32_t num);
|
||||
extern uint32_t UART_SWO_GetCount (void);
|
||||
|
||||
extern uint32_t Manchester_SWO_Mode (uint32_t enable);
|
||||
extern uint32_t Manchester_SWO_Baudrate (uint32_t baudrate);
|
||||
extern uint32_t Manchester_SWO_Control (uint32_t active);
|
||||
extern void Manchester_SWO_Capture (uint8_t *buf, uint32_t num);
|
||||
extern uint32_t Manchester_SWO_GetCount (void);
|
||||
|
||||
extern uint32_t DAP_ProcessVendorCommand (const uint8_t *request, uint8_t *response);
|
||||
extern uint32_t DAP_ProcessCommand (const uint8_t *request, uint8_t *response);
|
||||
extern uint32_t DAP_ExecuteCommand (const uint8_t *request, uint8_t *response);
|
||||
|
||||
extern void DAP_Setup (void);
|
||||
|
||||
// Configurable delay for clock generation
|
||||
#ifndef DELAY_SLOW_CYCLES
|
||||
#define DELAY_SLOW_CYCLES 3U // Number of cycles for one iteration
|
||||
#endif
|
||||
#if defined(__CC_ARM)
|
||||
__STATIC_FORCEINLINE void PIN_DELAY_SLOW (uint32_t delay) {
|
||||
uint32_t count = delay;
|
||||
while (--count);
|
||||
}
|
||||
#else
|
||||
__STATIC_FORCEINLINE void PIN_DELAY_SLOW (uint32_t delay) {
|
||||
__ASM volatile (
|
||||
".syntax unified\n"
|
||||
"0:\n\t"
|
||||
"subs %0,%0,#1\n\t"
|
||||
"bne 0b\n"
|
||||
: "+l" (delay) : : "cc"
|
||||
);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Fixed delay for fast clock generation
|
||||
#ifndef DELAY_FAST_CYCLES
|
||||
#define DELAY_FAST_CYCLES 0U // Number of cycles: 0..3
|
||||
#endif
|
||||
__STATIC_FORCEINLINE void PIN_DELAY_FAST (void) {
|
||||
#if (DELAY_FAST_CYCLES >= 1U)
|
||||
__NOP();
|
||||
#endif
|
||||
#if (DELAY_FAST_CYCLES >= 2U)
|
||||
__NOP();
|
||||
#endif
|
||||
#if (DELAY_FAST_CYCLES >= 3U)
|
||||
__NOP();
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* __DAP_H__ */
|
||||
@@ -0,0 +1,370 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2017 ARM Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* ----------------------------------------------------------------------
|
||||
*
|
||||
* $Date: 1. December 2017
|
||||
* $Revision: V2.0.0
|
||||
*
|
||||
* Project: CMSIS-DAP Source
|
||||
* Title: JTAG_DP.c CMSIS-DAP JTAG DP I/O
|
||||
*
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#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, const 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 == 0U) {
|
||||
n = 64U;
|
||||
}
|
||||
|
||||
if (info & JTAG_SEQUENCE_TMS) {
|
||||
PIN_TMS_SET();
|
||||
} else {
|
||||
PIN_TMS_CLR();
|
||||
}
|
||||
|
||||
while (n) {
|
||||
i_val = *tdi++;
|
||||
o_val = 0U;
|
||||
for (k = 8U; 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++ = (uint8_t)o_val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// JTAG Set IR
|
||||
// ir: IR value
|
||||
// return: none
|
||||
#define JTAG_IR_Function(speed) /**/ \
|
||||
static 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(1U); \
|
||||
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] - 1U; 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(1U); \
|
||||
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(1U); \
|
||||
}
|
||||
|
||||
|
||||
// JTAG Transfer I/O
|
||||
// request: A[3:2] RnW APnDP
|
||||
// data: DATA[31:0]
|
||||
// return: ACK[2:0]
|
||||
#define JTAG_TransferFunction(speed) /**/ \
|
||||
static 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 = 0U; \
|
||||
for (n = 31U; 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 - 1U; \
|
||||
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 = 31U; n; n--) { \
|
||||
JTAG_CYCLE_TDI(val); /* Set D0..D30 */ \
|
||||
val >>= 1; \
|
||||
} \
|
||||
n = DAP_Data.jtag_dev.count - DAP_Data.jtag_dev.index - 1U; \
|
||||
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(1U); \
|
||||
\
|
||||
/* Capture Timestamp */ \
|
||||
if (request & DAP_TRANSFER_TIMESTAMP) { \
|
||||
DAP_Data.timestamp = TIMESTAMP_GET(); \
|
||||
} \
|
||||
\
|
||||
/* Idle cycles */ \
|
||||
n = DAP_Data.transfer.idle_cycles; \
|
||||
while (n--) { \
|
||||
JTAG_CYCLE_TCK(); /* Idle */ \
|
||||
} \
|
||||
\
|
||||
return ((uint8_t)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 = 0U;
|
||||
for (n = 31U; 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(0U);
|
||||
JTAG_CYCLE_TCK(); /* Set RnW=0 (Write) */
|
||||
JTAG_CYCLE_TCK(); /* Set A2=0 */
|
||||
JTAG_CYCLE_TCK(); /* Set A3=0 */
|
||||
|
||||
for (n = 31U; n; n--) {
|
||||
JTAG_CYCLE_TDI(data); /* Set D0..D30 */
|
||||
data >>= 1;
|
||||
}
|
||||
n = DAP_Data.jtag_dev.count - DAP_Data.jtag_dev.index - 1U;
|
||||
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(1U);
|
||||
}
|
||||
|
||||
|
||||
// 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(uint32_t request, uint32_t *data) {
|
||||
if (DAP_Data.fast_clock) {
|
||||
return JTAG_TransferFast(request, data);
|
||||
} else {
|
||||
return JTAG_TransferSlow(request, data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif /* (DAP_JTAG != 0) */
|
||||
+800
@@ -0,0 +1,800 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2017 ARM Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* ----------------------------------------------------------------------
|
||||
*
|
||||
* $Date: 1. December 2017
|
||||
* $Revision: V2.0.0
|
||||
*
|
||||
* Project: CMSIS-DAP Source
|
||||
* Title: SWO.c CMSIS-DAP SWO I/O
|
||||
*
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "DAP_config.h"
|
||||
#include "DAP.h"
|
||||
#if (SWO_UART != 0)
|
||||
#include "Driver_USART.h"
|
||||
#endif
|
||||
#if (SWO_STREAM != 0)
|
||||
#include "cmsis_os2.h"
|
||||
#endif
|
||||
|
||||
#if (SWO_STREAM != 0)
|
||||
#ifdef DAP_FW_V1
|
||||
#error "SWO Streaming Trace not supported in DAP V1!"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if (SWO_UART != 0)
|
||||
|
||||
#ifndef SWO_USART_PORT
|
||||
#define SWO_USART_PORT 0 /* USART Port Number */
|
||||
#endif
|
||||
|
||||
// USART Driver
|
||||
#define _USART_Driver_(n) Driver_USART##n
|
||||
#define USART_Driver_(n) _USART_Driver_(n)
|
||||
extern ARM_DRIVER_USART USART_Driver_(SWO_USART_PORT);
|
||||
#define pUSART (&USART_Driver_(SWO_USART_PORT))
|
||||
|
||||
static uint8_t USART_Ready = 0U;
|
||||
|
||||
#endif /* (SWO_UART != 0) */
|
||||
|
||||
|
||||
#if ((SWO_UART != 0) || (SWO_MANCHESTER != 0))
|
||||
|
||||
|
||||
#define SWO_STREAM_TIMEOUT 50U /* Stream timeout in ms */
|
||||
|
||||
#define USB_BLOCK_SIZE 512U /* USB Block Size */
|
||||
#define TRACE_BLOCK_SIZE 64U /* Trace Block Size (2^n: 32...512) */
|
||||
|
||||
// Trace State
|
||||
static uint8_t TraceTransport = 0U; /* Trace Transport */
|
||||
static uint8_t TraceMode = 0U; /* Trace Mode */
|
||||
static uint8_t TraceStatus = 0U; /* Trace Status without Errors */
|
||||
static uint8_t TraceError[2] = {0U, 0U}; /* Trace Error flags (banked) */
|
||||
static uint8_t TraceError_n = 0U; /* Active Trace Error bank */
|
||||
|
||||
// Trace Buffer
|
||||
static uint8_t TraceBuf[SWO_BUFFER_SIZE]; /* Trace Buffer (must be 2^n) */
|
||||
static volatile uint32_t TraceIndexI = 0U; /* Incoming Trace Index */
|
||||
static volatile uint32_t TraceIndexO = 0U; /* Outgoing Trace Index */
|
||||
static volatile uint8_t TraceUpdate; /* Trace Update Flag */
|
||||
static uint32_t TraceBlockSize; /* Current Trace Block Size */
|
||||
|
||||
#if (TIMESTAMP_CLOCK != 0U)
|
||||
// Trace Timestamp
|
||||
static volatile struct {
|
||||
uint32_t index;
|
||||
uint32_t tick;
|
||||
} TraceTimestamp;
|
||||
#endif
|
||||
|
||||
// Trace Helper functions
|
||||
static void ClearTrace (void);
|
||||
static void ResumeTrace (void);
|
||||
static uint32_t GetTraceCount (void);
|
||||
static uint8_t GetTraceStatus (void);
|
||||
static void SetTraceError (uint8_t flag);
|
||||
|
||||
#if (SWO_STREAM != 0)
|
||||
extern osThreadId_t SWO_ThreadId;
|
||||
static volatile uint8_t TransferBusy = 0U; /* Transfer Busy Flag */
|
||||
static uint32_t TransferSize; /* Current Transfer Size */
|
||||
#endif
|
||||
|
||||
|
||||
#if (SWO_UART != 0)
|
||||
|
||||
// USART Driver Callback function
|
||||
// event: event mask
|
||||
static void USART_Callback (uint32_t event) {
|
||||
uint32_t index_i;
|
||||
uint32_t index_o;
|
||||
uint32_t count;
|
||||
uint32_t num;
|
||||
|
||||
if (event & ARM_USART_EVENT_RECEIVE_COMPLETE) {
|
||||
#if (TIMESTAMP_CLOCK != 0U)
|
||||
TraceTimestamp.tick = TIMESTAMP_GET();
|
||||
#endif
|
||||
index_o = TraceIndexO;
|
||||
index_i = TraceIndexI;
|
||||
index_i += TraceBlockSize;
|
||||
TraceIndexI = index_i;
|
||||
#if (TIMESTAMP_CLOCK != 0U)
|
||||
TraceTimestamp.index = index_i;
|
||||
#endif
|
||||
num = TRACE_BLOCK_SIZE - (index_i & (TRACE_BLOCK_SIZE - 1U));
|
||||
count = index_i - index_o;
|
||||
if (count <= (SWO_BUFFER_SIZE - num)) {
|
||||
index_i &= SWO_BUFFER_SIZE - 1U;
|
||||
TraceBlockSize = num;
|
||||
pUSART->Receive(&TraceBuf[index_i], num);
|
||||
} else {
|
||||
TraceStatus = DAP_SWO_CAPTURE_ACTIVE | DAP_SWO_CAPTURE_PAUSED;
|
||||
}
|
||||
TraceUpdate = 1U;
|
||||
#if (SWO_STREAM != 0)
|
||||
if (TraceTransport == 2U) {
|
||||
if (count >= (USB_BLOCK_SIZE - (index_o & (USB_BLOCK_SIZE - 1U)))) {
|
||||
osThreadFlagsSet(SWO_ThreadId, 1U);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (event & ARM_USART_EVENT_RX_OVERFLOW) {
|
||||
SetTraceError(DAP_SWO_BUFFER_OVERRUN);
|
||||
}
|
||||
if (event & (ARM_USART_EVENT_RX_BREAK |
|
||||
ARM_USART_EVENT_RX_FRAMING_ERROR |
|
||||
ARM_USART_EVENT_RX_PARITY_ERROR)) {
|
||||
SetTraceError(DAP_SWO_STREAM_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
// Enable or disable UART SWO Mode
|
||||
// enable: enable flag
|
||||
// return: 1 - Success, 0 - Error
|
||||
__WEAK uint32_t UART_SWO_Mode (uint32_t enable) {
|
||||
int32_t status;
|
||||
|
||||
USART_Ready = 0U;
|
||||
|
||||
if (enable != 0U) {
|
||||
status = pUSART->Initialize(USART_Callback);
|
||||
if (status != ARM_DRIVER_OK) {
|
||||
return (0U);
|
||||
}
|
||||
status = pUSART->PowerControl(ARM_POWER_FULL);
|
||||
if (status != ARM_DRIVER_OK) {
|
||||
pUSART->Uninitialize();
|
||||
return (0U);
|
||||
}
|
||||
} else {
|
||||
pUSART->Control(ARM_USART_CONTROL_RX, 0U);
|
||||
pUSART->Control(ARM_USART_ABORT_RECEIVE, 0U);
|
||||
pUSART->PowerControl(ARM_POWER_OFF);
|
||||
pUSART->Uninitialize();
|
||||
}
|
||||
return (1U);
|
||||
}
|
||||
|
||||
// Configure UART SWO Baudrate
|
||||
// baudrate: requested baudrate
|
||||
// return: actual baudrate or 0 when not configured
|
||||
__WEAK uint32_t UART_SWO_Baudrate (uint32_t baudrate) {
|
||||
int32_t status;
|
||||
uint32_t index;
|
||||
uint32_t num;
|
||||
|
||||
if (baudrate > SWO_UART_MAX_BAUDRATE) {
|
||||
baudrate = SWO_UART_MAX_BAUDRATE;
|
||||
}
|
||||
|
||||
if (TraceStatus & DAP_SWO_CAPTURE_ACTIVE) {
|
||||
pUSART->Control(ARM_USART_CONTROL_RX, 0U);
|
||||
if (pUSART->GetStatus().rx_busy) {
|
||||
TraceIndexI += pUSART->GetRxCount();
|
||||
pUSART->Control(ARM_USART_ABORT_RECEIVE, 0U);
|
||||
}
|
||||
}
|
||||
|
||||
status = pUSART->Control(ARM_USART_MODE_ASYNCHRONOUS |
|
||||
ARM_USART_DATA_BITS_8 |
|
||||
ARM_USART_PARITY_NONE |
|
||||
ARM_USART_STOP_BITS_1,
|
||||
baudrate);
|
||||
|
||||
if (status == ARM_DRIVER_OK) {
|
||||
USART_Ready = 1U;
|
||||
} else {
|
||||
USART_Ready = 0U;
|
||||
return (0U);
|
||||
}
|
||||
|
||||
if (TraceStatus & DAP_SWO_CAPTURE_ACTIVE) {
|
||||
if ((TraceStatus & DAP_SWO_CAPTURE_PAUSED) == 0U) {
|
||||
index = TraceIndexI & (SWO_BUFFER_SIZE - 1U);
|
||||
num = TRACE_BLOCK_SIZE - (index & (TRACE_BLOCK_SIZE - 1U));
|
||||
TraceBlockSize = num;
|
||||
pUSART->Receive(&TraceBuf[index], num);
|
||||
}
|
||||
pUSART->Control(ARM_USART_CONTROL_RX, 1U);
|
||||
}
|
||||
|
||||
return (baudrate);
|
||||
}
|
||||
|
||||
// Control UART SWO Capture
|
||||
// active: active flag
|
||||
// return: 1 - Success, 0 - Error
|
||||
__WEAK uint32_t UART_SWO_Control (uint32_t active) {
|
||||
int32_t status;
|
||||
|
||||
if (active) {
|
||||
if (!USART_Ready) {
|
||||
return (0U);
|
||||
}
|
||||
TraceBlockSize = 1U;
|
||||
status = pUSART->Receive(&TraceBuf[0], 1U);
|
||||
if (status != ARM_DRIVER_OK) {
|
||||
return (0U);
|
||||
}
|
||||
status = pUSART->Control(ARM_USART_CONTROL_RX, 1U);
|
||||
if (status != ARM_DRIVER_OK) {
|
||||
return (0U);
|
||||
}
|
||||
} else {
|
||||
pUSART->Control(ARM_USART_CONTROL_RX, 0U);
|
||||
if (pUSART->GetStatus().rx_busy) {
|
||||
TraceIndexI += pUSART->GetRxCount();
|
||||
pUSART->Control(ARM_USART_ABORT_RECEIVE, 0U);
|
||||
}
|
||||
}
|
||||
return (1U);
|
||||
}
|
||||
|
||||
// Start UART SWO Capture
|
||||
// buf: pointer to buffer for capturing
|
||||
// num: number of bytes to capture
|
||||
__WEAK void UART_SWO_Capture (uint8_t *buf, uint32_t num) {
|
||||
TraceBlockSize = num;
|
||||
pUSART->Receive(buf, num);
|
||||
}
|
||||
|
||||
// Get UART SWO Pending Trace Count
|
||||
// return: number of pending trace data bytes
|
||||
__WEAK uint32_t UART_SWO_GetCount (void) {
|
||||
uint32_t count;
|
||||
|
||||
if (pUSART->GetStatus().rx_busy) {
|
||||
count = pUSART->GetRxCount();
|
||||
} else {
|
||||
count = 0U;
|
||||
}
|
||||
return (count);
|
||||
}
|
||||
|
||||
#endif /* (SWO_UART != 0) */
|
||||
|
||||
|
||||
#if (SWO_MANCHESTER != 0)
|
||||
|
||||
// Enable or disable Manchester SWO Mode
|
||||
// enable: enable flag
|
||||
// return: 1 - Success, 0 - Error
|
||||
__WEAK uint32_t Manchester_SWO_Mode (uint32_t enable) {
|
||||
return (0U);
|
||||
}
|
||||
|
||||
// Configure Manchester SWO Baudrate
|
||||
// baudrate: requested baudrate
|
||||
// return: actual baudrate or 0 when not configured
|
||||
__WEAK uint32_t Manchester_SWO_Baudrate (uint32_t baudrate) {
|
||||
return (0U);
|
||||
}
|
||||
|
||||
// Control Manchester SWO Capture
|
||||
// active: active flag
|
||||
// return: 1 - Success, 0 - Error
|
||||
__WEAK uint32_t Manchester_SWO_Control (uint32_t active) {
|
||||
return (0U);
|
||||
}
|
||||
|
||||
// Start Manchester SWO Capture
|
||||
// buf: pointer to buffer for capturing
|
||||
// num: number of bytes to capture
|
||||
__WEAK void Manchester_SWO_Capture (uint8_t *buf, uint32_t num) {
|
||||
}
|
||||
|
||||
// Get Manchester SWO Pending Trace Count
|
||||
// return: number of pending trace data bytes
|
||||
__WEAK uint32_t Manchester_SWO_GetCount (void) {
|
||||
}
|
||||
|
||||
#endif /* (SWO_MANCHESTER != 0) */
|
||||
|
||||
|
||||
// Clear Trace Errors and Data
|
||||
static void ClearTrace (void) {
|
||||
|
||||
#if (SWO_STREAM != 0)
|
||||
if (TraceTransport == 2U) {
|
||||
if (TransferBusy != 0U) {
|
||||
SWO_AbortTransfer();
|
||||
TransferBusy = 0U;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
TraceError[0] = 0U;
|
||||
TraceError[1] = 0U;
|
||||
TraceError_n = 0U;
|
||||
TraceIndexI = 0U;
|
||||
TraceIndexO = 0U;
|
||||
|
||||
#if (TIMESTAMP_CLOCK != 0U)
|
||||
TraceTimestamp.index = 0U;
|
||||
TraceTimestamp.tick = 0U;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Resume Trace Capture
|
||||
static void ResumeTrace (void) {
|
||||
uint32_t index_i;
|
||||
uint32_t index_o;
|
||||
|
||||
if (TraceStatus == (DAP_SWO_CAPTURE_ACTIVE | DAP_SWO_CAPTURE_PAUSED)) {
|
||||
index_i = TraceIndexI;
|
||||
index_o = TraceIndexO;
|
||||
if ((index_i - index_o) < SWO_BUFFER_SIZE) {
|
||||
index_i &= SWO_BUFFER_SIZE - 1U;
|
||||
switch (TraceMode) {
|
||||
#if (SWO_UART != 0)
|
||||
case DAP_SWO_UART:
|
||||
TraceStatus = DAP_SWO_CAPTURE_ACTIVE;
|
||||
UART_SWO_Capture(&TraceBuf[index_i], 1U);
|
||||
break;
|
||||
#endif
|
||||
#if (SWO_MANCHESTER != 0)
|
||||
case DAP_SWO_MANCHESTER:
|
||||
TraceStatus = DAP_SWO_CAPTURE_ACTIVE;
|
||||
Manchester_SWO_Capture(&TraceBuf[index_i], 1U);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get Trace Count
|
||||
// return: number of available data bytes in trace buffer
|
||||
static uint32_t GetTraceCount (void) {
|
||||
uint32_t count;
|
||||
|
||||
if (TraceStatus == DAP_SWO_CAPTURE_ACTIVE) {
|
||||
do {
|
||||
TraceUpdate = 0U;
|
||||
count = TraceIndexI - TraceIndexO;
|
||||
switch (TraceMode) {
|
||||
#if (SWO_UART != 0)
|
||||
case DAP_SWO_UART:
|
||||
count += UART_SWO_GetCount();
|
||||
break;
|
||||
#endif
|
||||
#if (SWO_MANCHESTER != 0)
|
||||
case DAP_SWO_MANCHESTER:
|
||||
count += Manchester_SWO_GetCount();
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} while (TraceUpdate != 0U);
|
||||
} else {
|
||||
count = TraceIndexI - TraceIndexO;
|
||||
}
|
||||
|
||||
return (count);
|
||||
}
|
||||
|
||||
// Get Trace Status (clear Error flags)
|
||||
// return: Trace Status (Active flag and Error flags)
|
||||
static uint8_t GetTraceStatus (void) {
|
||||
uint8_t status;
|
||||
uint32_t n;
|
||||
|
||||
n = TraceError_n;
|
||||
TraceError_n ^= 1U;
|
||||
status = TraceStatus | TraceError[n];
|
||||
TraceError[n] = 0U;
|
||||
|
||||
return (status);
|
||||
}
|
||||
|
||||
// Set Trace Error flag(s)
|
||||
// flag: error flag(s) to set
|
||||
static void SetTraceError (uint8_t flag) {
|
||||
TraceError[TraceError_n] |= flag;
|
||||
}
|
||||
|
||||
|
||||
// Process SWO Transport command and prepare response
|
||||
// request: pointer to request data
|
||||
// response: pointer to response data
|
||||
// return: number of bytes in response (lower 16 bits)
|
||||
// number of bytes in request (upper 16 bits)
|
||||
uint32_t SWO_Transport (const uint8_t *request, uint8_t *response) {
|
||||
uint8_t transport;
|
||||
uint32_t result;
|
||||
|
||||
if ((TraceStatus & DAP_SWO_CAPTURE_ACTIVE) == 0U) {
|
||||
transport = *request;
|
||||
switch (transport) {
|
||||
case 0U:
|
||||
case 1U:
|
||||
#if (SWO_STREAM != 0)
|
||||
case 2U:
|
||||
#endif
|
||||
TraceTransport = transport;
|
||||
result = 1U;
|
||||
break;
|
||||
default:
|
||||
result = 0U;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
result = 0U;
|
||||
}
|
||||
|
||||
if (result != 0U) {
|
||||
*response = DAP_OK;
|
||||
} else {
|
||||
*response = DAP_ERROR;
|
||||
}
|
||||
|
||||
return ((1U << 16) | 1U);
|
||||
}
|
||||
|
||||
|
||||
// Process SWO Mode command and prepare response
|
||||
// request: pointer to request data
|
||||
// response: pointer to response data
|
||||
// return: number of bytes in response (lower 16 bits)
|
||||
// number of bytes in request (upper 16 bits)
|
||||
uint32_t SWO_Mode (const uint8_t *request, uint8_t *response) {
|
||||
uint8_t mode;
|
||||
uint32_t result;
|
||||
|
||||
mode = *request;
|
||||
|
||||
switch (TraceMode) {
|
||||
#if (SWO_UART != 0)
|
||||
case DAP_SWO_UART:
|
||||
UART_SWO_Mode(0U);
|
||||
break;
|
||||
#endif
|
||||
#if (SWO_MANCHESTER != 0)
|
||||
case DAP_SWO_MANCHESTER:
|
||||
Manchester_SWO_Mode(0U);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (mode) {
|
||||
case DAP_SWO_OFF:
|
||||
result = 1U;
|
||||
break;
|
||||
#if (SWO_UART != 0)
|
||||
case DAP_SWO_UART:
|
||||
result = UART_SWO_Mode(1U);
|
||||
break;
|
||||
#endif
|
||||
#if (SWO_MANCHESTER != 0)
|
||||
case DAP_SWO_MANCHESTER:
|
||||
result = Manchester_SWO_Mode(1U);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
result = 0U;
|
||||
break;
|
||||
}
|
||||
if (result != 0U) {
|
||||
TraceMode = mode;
|
||||
} else {
|
||||
TraceMode = DAP_SWO_OFF;
|
||||
}
|
||||
|
||||
TraceStatus = 0U;
|
||||
|
||||
if (result != 0U) {
|
||||
*response = DAP_OK;
|
||||
} else {
|
||||
*response = DAP_ERROR;
|
||||
}
|
||||
|
||||
return ((1U << 16) | 1U);
|
||||
}
|
||||
|
||||
|
||||
// Process SWO Baudrate command and prepare response
|
||||
// request: pointer to request data
|
||||
// response: pointer to response data
|
||||
// return: number of bytes in response (lower 16 bits)
|
||||
// number of bytes in request (upper 16 bits)
|
||||
uint32_t SWO_Baudrate (const uint8_t *request, uint8_t *response) {
|
||||
uint32_t baudrate;
|
||||
|
||||
baudrate = (uint32_t)(*(request+0) << 0) |
|
||||
(uint32_t)(*(request+1) << 8) |
|
||||
(uint32_t)(*(request+2) << 16) |
|
||||
(uint32_t)(*(request+3) << 24);
|
||||
|
||||
switch (TraceMode) {
|
||||
#if (SWO_UART != 0)
|
||||
case DAP_SWO_UART:
|
||||
baudrate = UART_SWO_Baudrate(baudrate);
|
||||
break;
|
||||
#endif
|
||||
#if (SWO_MANCHESTER != 0)
|
||||
case DAP_SWO_MANCHESTER:
|
||||
baudrate = Manchester_SWO_Baudrate(baudrate);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
baudrate = 0U;
|
||||
break;
|
||||
}
|
||||
|
||||
if (baudrate == 0U) {
|
||||
TraceStatus = 0U;
|
||||
}
|
||||
|
||||
*response++ = (uint8_t)(baudrate >> 0);
|
||||
*response++ = (uint8_t)(baudrate >> 8);
|
||||
*response++ = (uint8_t)(baudrate >> 16);
|
||||
*response = (uint8_t)(baudrate >> 24);
|
||||
|
||||
return ((4U << 16) | 4U);
|
||||
}
|
||||
|
||||
|
||||
// Process SWO Control command and prepare response
|
||||
// request: pointer to request data
|
||||
// response: pointer to response data
|
||||
// return: number of bytes in response (lower 16 bits)
|
||||
// number of bytes in request (upper 16 bits)
|
||||
uint32_t SWO_Control (const uint8_t *request, uint8_t *response) {
|
||||
uint8_t active;
|
||||
uint32_t result;
|
||||
|
||||
active = *request & DAP_SWO_CAPTURE_ACTIVE;
|
||||
|
||||
if (active != (TraceStatus & DAP_SWO_CAPTURE_ACTIVE)) {
|
||||
if (active) {
|
||||
ClearTrace();
|
||||
}
|
||||
switch (TraceMode) {
|
||||
#if (SWO_UART != 0)
|
||||
case DAP_SWO_UART:
|
||||
result = UART_SWO_Control(active);
|
||||
break;
|
||||
#endif
|
||||
#if (SWO_MANCHESTER != 0)
|
||||
case DAP_SWO_MANCHESTER:
|
||||
result = Manchester_SWO_Control(active);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
result = 0U;
|
||||
break;
|
||||
}
|
||||
if (result != 0U) {
|
||||
TraceStatus = active;
|
||||
#if (SWO_STREAM != 0)
|
||||
if (TraceTransport == 2U) {
|
||||
osThreadFlagsSet(SWO_ThreadId, 1U);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
result = 1U;
|
||||
}
|
||||
|
||||
if (result != 0U) {
|
||||
*response = DAP_OK;
|
||||
} else {
|
||||
*response = DAP_ERROR;
|
||||
}
|
||||
|
||||
return ((1U << 16) | 1U);
|
||||
}
|
||||
|
||||
|
||||
// Process SWO Status command and prepare response
|
||||
// response: pointer to response data
|
||||
// return: number of bytes in response
|
||||
uint32_t SWO_Status (uint8_t *response) {
|
||||
uint8_t status;
|
||||
uint32_t count;
|
||||
|
||||
status = GetTraceStatus();
|
||||
count = GetTraceCount();
|
||||
|
||||
*response++ = status;
|
||||
*response++ = (uint8_t)(count >> 0);
|
||||
*response++ = (uint8_t)(count >> 8);
|
||||
*response++ = (uint8_t)(count >> 16);
|
||||
*response = (uint8_t)(count >> 24);
|
||||
|
||||
return (5U);
|
||||
}
|
||||
|
||||
|
||||
// Process SWO Extended Status command and prepare response
|
||||
// request: pointer to request data
|
||||
// response: pointer to response data
|
||||
// return: number of bytes in response (lower 16 bits)
|
||||
// number of bytes in request (upper 16 bits)
|
||||
uint32_t SWO_ExtendedStatus (const uint8_t *request, uint8_t *response) {
|
||||
uint8_t cmd;
|
||||
uint8_t status;
|
||||
uint32_t count;
|
||||
#if (TIMESTAMP_CLOCK != 0U)
|
||||
uint32_t index;
|
||||
uint32_t tick;
|
||||
#endif
|
||||
uint32_t num;
|
||||
|
||||
num = 0U;
|
||||
cmd = *request;
|
||||
|
||||
if (cmd & 0x01U) {
|
||||
status = GetTraceStatus();
|
||||
*response++ = status;
|
||||
num += 1U;
|
||||
}
|
||||
|
||||
if (cmd & 0x02U) {
|
||||
count = GetTraceCount();
|
||||
*response++ = (uint8_t)(count >> 0);
|
||||
*response++ = (uint8_t)(count >> 8);
|
||||
*response++ = (uint8_t)(count >> 16);
|
||||
*response++ = (uint8_t)(count >> 24);
|
||||
num += 4U;
|
||||
}
|
||||
|
||||
#if (TIMESTAMP_CLOCK != 0U)
|
||||
if (cmd & 0x04U) {
|
||||
do {
|
||||
TraceUpdate = 0U;
|
||||
index = TraceTimestamp.index;
|
||||
tick = TraceTimestamp.tick;
|
||||
} while (TraceUpdate != 0U);
|
||||
*response++ = (uint8_t)(index >> 0);
|
||||
*response++ = (uint8_t)(index >> 8);
|
||||
*response++ = (uint8_t)(index >> 16);
|
||||
*response++ = (uint8_t)(index >> 24);
|
||||
*response++ = (uint8_t)(tick >> 0);
|
||||
*response++ = (uint8_t)(tick >> 8);
|
||||
*response++ = (uint8_t)(tick >> 16);
|
||||
*response++ = (uint8_t)(tick >> 24);
|
||||
num += 4U;
|
||||
}
|
||||
#endif
|
||||
|
||||
return ((1U << 16) | num);
|
||||
}
|
||||
|
||||
|
||||
// Process SWO Data command and prepare response
|
||||
// request: pointer to request data
|
||||
// response: pointer to response data
|
||||
// return: number of bytes in response (lower 16 bits)
|
||||
// number of bytes in request (upper 16 bits)
|
||||
uint32_t SWO_Data (const uint8_t *request, uint8_t *response) {
|
||||
uint8_t status;
|
||||
uint32_t count;
|
||||
uint32_t index;
|
||||
uint32_t n, i;
|
||||
|
||||
status = GetTraceStatus();
|
||||
count = GetTraceCount();
|
||||
|
||||
if (TraceTransport == 1U) {
|
||||
n = (uint32_t)(*(request+0) << 0) |
|
||||
(uint32_t)(*(request+1) << 8);
|
||||
if (n > (DAP_PACKET_SIZE - 4U)) {
|
||||
n = DAP_PACKET_SIZE - 4U;
|
||||
}
|
||||
if (count > n) {
|
||||
count = n;
|
||||
}
|
||||
} else {
|
||||
count = 0U;
|
||||
}
|
||||
|
||||
*response++ = status;
|
||||
*response++ = (uint8_t)(count >> 0);
|
||||
*response++ = (uint8_t)(count >> 8);
|
||||
|
||||
if (TraceTransport == 1U) {
|
||||
index = TraceIndexO;
|
||||
for (i = index, n = count; n; n--) {
|
||||
i &= SWO_BUFFER_SIZE - 1U;
|
||||
*response++ = TraceBuf[i++];
|
||||
}
|
||||
TraceIndexO = index + count;
|
||||
ResumeTrace();
|
||||
}
|
||||
|
||||
return ((2U << 16) | (3U + count));
|
||||
}
|
||||
|
||||
|
||||
#if (SWO_STREAM != 0)
|
||||
|
||||
// SWO Data Transfer complete callback
|
||||
void SWO_TransferComplete (void) {
|
||||
TraceIndexO += TransferSize;
|
||||
TransferBusy = 0U;
|
||||
ResumeTrace();
|
||||
osThreadFlagsSet(SWO_ThreadId, 1U);
|
||||
}
|
||||
|
||||
// SWO Thread
|
||||
__NO_RETURN void SWO_Thread (void *argument) {
|
||||
uint32_t timeout;
|
||||
uint32_t flags;
|
||||
uint32_t count;
|
||||
uint32_t index;
|
||||
uint32_t i, n;
|
||||
(void) argument;
|
||||
|
||||
timeout = osWaitForever;
|
||||
|
||||
for (;;) {
|
||||
flags = osThreadFlagsWait(1U, osFlagsWaitAny, timeout);
|
||||
if (TraceStatus & DAP_SWO_CAPTURE_ACTIVE) {
|
||||
timeout = SWO_STREAM_TIMEOUT;
|
||||
} else {
|
||||
timeout = osWaitForever;
|
||||
flags = osFlagsErrorTimeout;
|
||||
}
|
||||
if (TransferBusy == 0U) {
|
||||
count = GetTraceCount();
|
||||
if (count != 0U) {
|
||||
index = TraceIndexO & (SWO_BUFFER_SIZE - 1U);
|
||||
n = SWO_BUFFER_SIZE - index;
|
||||
if (count > n) {
|
||||
count = n;
|
||||
}
|
||||
if (flags != osFlagsErrorTimeout) {
|
||||
i = index & (USB_BLOCK_SIZE - 1U);
|
||||
if (i == 0U) {
|
||||
count &= ~(USB_BLOCK_SIZE - 1U);
|
||||
} else {
|
||||
n = USB_BLOCK_SIZE - i;
|
||||
if (count >= n) {
|
||||
count = n;
|
||||
} else {
|
||||
count = 0U;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (count != 0U) {
|
||||
TransferSize = count;
|
||||
TransferBusy = 1U;
|
||||
SWO_QueueTransfer(&TraceBuf[index], count);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* (SWO_STREAM != 0) */
|
||||
|
||||
|
||||
#endif /* ((SWO_UART != 0) || (SWO_MANCHESTER != 0)) */
|
||||
@@ -0,0 +1,286 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2017 ARM Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* ----------------------------------------------------------------------
|
||||
*
|
||||
* $Date: 1. December 2017
|
||||
* $Revision: V2.0.0
|
||||
*
|
||||
* Project: CMSIS-DAP Source
|
||||
* Title: SW_DP.c CMSIS-DAP SW DP I/O
|
||||
*
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#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(bit) \
|
||||
PIN_SWCLK_CLR(); \
|
||||
PIN_DELAY(); \
|
||||
bit = PIN_SWDIO_IN(); \
|
||||
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, const uint8_t *data) {
|
||||
uint32_t val;
|
||||
uint32_t n;
|
||||
|
||||
val = 0U;
|
||||
n = 0U;
|
||||
while (count--) {
|
||||
if (n == 0U) {
|
||||
val = *data++;
|
||||
n = 8U;
|
||||
}
|
||||
if (val & 1U) {
|
||||
PIN_SWDIO_TMS_SET();
|
||||
} else {
|
||||
PIN_SWDIO_TMS_CLR();
|
||||
}
|
||||
SW_CLOCK_CYCLE();
|
||||
val >>= 1;
|
||||
n--;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// Generate SWD Sequence
|
||||
// info: sequence information
|
||||
// swdo: pointer to SWDIO generated data
|
||||
// swdi: pointer to SWDIO captured data
|
||||
// return: none
|
||||
#if (DAP_SWD != 0)
|
||||
void SWD_Sequence (uint32_t info, const uint8_t *swdo, uint8_t *swdi) {
|
||||
uint32_t val;
|
||||
uint32_t bit;
|
||||
uint32_t n, k;
|
||||
|
||||
n = info & SWD_SEQUENCE_CLK;
|
||||
if (n == 0U) {
|
||||
n = 64U;
|
||||
}
|
||||
|
||||
if (info & SWD_SEQUENCE_DIN) {
|
||||
while (n) {
|
||||
val = 0U;
|
||||
for (k = 8U; k && n; k--, n--) {
|
||||
SW_READ_BIT(bit);
|
||||
val >>= 1;
|
||||
val |= bit << 7;
|
||||
}
|
||||
val >>= k;
|
||||
*swdi++ = (uint8_t)val;
|
||||
}
|
||||
} else {
|
||||
while (n) {
|
||||
val = *swdo++;
|
||||
for (k = 8U; k && n; k--, n--) {
|
||||
SW_WRITE_BIT(val);
|
||||
val >>= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#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) /**/ \
|
||||
static uint8_t SWD_Transfer##speed (uint32_t request, uint32_t *data) { \
|
||||
uint32_t ack; \
|
||||
uint32_t bit; \
|
||||
uint32_t val; \
|
||||
uint32_t parity; \
|
||||
\
|
||||
uint32_t n; \
|
||||
\
|
||||
/* Packet Request */ \
|
||||
parity = 0U; \
|
||||
SW_WRITE_BIT(1U); /* 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; \
|
||||
SW_WRITE_BIT(bit); /* A3 Bit */ \
|
||||
parity += bit; \
|
||||
SW_WRITE_BIT(parity); /* Parity Bit */ \
|
||||
SW_WRITE_BIT(0U); /* Stop Bit */ \
|
||||
SW_WRITE_BIT(1U); /* Park Bit */ \
|
||||
\
|
||||
/* Turnaround */ \
|
||||
PIN_SWDIO_OUT_DISABLE(); \
|
||||
for (n = DAP_Data.swd_conf.turnaround; n; n--) { \
|
||||
SW_CLOCK_CYCLE(); \
|
||||
} \
|
||||
\
|
||||
/* Acknowledge response */ \
|
||||
SW_READ_BIT(bit); \
|
||||
ack = bit << 0; \
|
||||
SW_READ_BIT(bit); \
|
||||
ack |= bit << 1; \
|
||||
SW_READ_BIT(bit); \
|
||||
ack |= bit << 2; \
|
||||
\
|
||||
if (ack == DAP_TRANSFER_OK) { /* OK response */ \
|
||||
/* Data transfer */ \
|
||||
if (request & DAP_TRANSFER_RnW) { \
|
||||
/* Read data */ \
|
||||
val = 0U; \
|
||||
parity = 0U; \
|
||||
for (n = 32U; n; n--) { \
|
||||
SW_READ_BIT(bit); /* Read RDATA[0:31] */ \
|
||||
parity += bit; \
|
||||
val >>= 1; \
|
||||
val |= bit << 31; \
|
||||
} \
|
||||
SW_READ_BIT(bit); /* Read Parity */ \
|
||||
if ((parity ^ bit) & 1U) { \
|
||||
ack = DAP_TRANSFER_ERROR; \
|
||||
} \
|
||||
if (data) { *data = val; } \
|
||||
/* 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 */ \
|
||||
val = *data; \
|
||||
parity = 0U; \
|
||||
for (n = 32U; n; n--) { \
|
||||
SW_WRITE_BIT(val); /* Write WDATA[0:31] */ \
|
||||
parity += val; \
|
||||
val >>= 1; \
|
||||
} \
|
||||
SW_WRITE_BIT(parity); /* Write Parity Bit */ \
|
||||
} \
|
||||
/* Capture Timestamp */ \
|
||||
if (request & DAP_TRANSFER_TIMESTAMP) { \
|
||||
DAP_Data.timestamp = TIMESTAMP_GET(); \
|
||||
} \
|
||||
/* Idle cycles */ \
|
||||
n = DAP_Data.transfer.idle_cycles; \
|
||||
if (n) { \
|
||||
PIN_SWDIO_OUT(0U); \
|
||||
for (; n; n--) { \
|
||||
SW_CLOCK_CYCLE(); \
|
||||
} \
|
||||
} \
|
||||
PIN_SWDIO_OUT(1U); \
|
||||
return ((uint8_t)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) != 0U)) { \
|
||||
for (n = 32U+1U; 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) == 0U)) { \
|
||||
PIN_SWDIO_OUT(0U); \
|
||||
for (n = 32U+1U; n; n--) { \
|
||||
SW_CLOCK_CYCLE(); /* Dummy Write WDATA[0:31] + Parity */ \
|
||||
} \
|
||||
} \
|
||||
PIN_SWDIO_OUT(1U); \
|
||||
return ((uint8_t)ack); \
|
||||
} \
|
||||
\
|
||||
/* Protocol error */ \
|
||||
for (n = DAP_Data.swd_conf.turnaround + 32U + 1U; n; n--) { \
|
||||
SW_CLOCK_CYCLE(); /* Back off data phase */ \
|
||||
} \
|
||||
PIN_SWDIO_OUT_ENABLE(); \
|
||||
PIN_SWDIO_OUT(1U); \
|
||||
return ((uint8_t)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(uint32_t request, uint32_t *data) {
|
||||
if (DAP_Data.fast_clock) {
|
||||
return SWD_TransferFast(request, data);
|
||||
} else {
|
||||
return SWD_TransferSlow(request, data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif /* (DAP_SWD != 0) */
|
||||
@@ -0,0 +1,147 @@
|
||||
/**
|
||||
* @file debug_ca.h
|
||||
* @brief Access to ARM DAP (Cortex-A) using CMSIS-DAP protocol
|
||||
*
|
||||
* DAPLink Interface Firmware
|
||||
* Copyright (c) 2009-2016, ARM Limited, All Rights Reserved
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef DEBUG_CA_H
|
||||
#define DEBUG_CA_H
|
||||
|
||||
#include "debug_cm.h"
|
||||
|
||||
// Debug registers
|
||||
#define DEBUG_REGSITER_BASE (0x80030000)
|
||||
|
||||
#define DBGDIDR (DEBUG_REGSITER_BASE + (0 * 4)) // Debug ID
|
||||
#define DBGWFAR (DEBUG_REGSITER_BASE + (6 * 4)) // Watchpoint Fault Address
|
||||
#define DBGVCR (DEBUG_REGSITER_BASE + (7 * 4)) // Vector Catch
|
||||
#define DBGECR (DEBUG_REGSITER_BASE + (9 * 4)) // Event Catch
|
||||
#define DBGDTRRX (DEBUG_REGSITER_BASE + (32 * 4)) // Host to Target Data Transfer
|
||||
#define DBGITR (DEBUG_REGSITER_BASE + (33 * 4)) // WO Instruction Transfer
|
||||
#define DBGDSCR (DEBUG_REGSITER_BASE + (34 * 4)) // Debug Status and Control
|
||||
#define DBGDTRTX (DEBUG_REGSITER_BASE + (35 * 4)) // Target to Host Data Transfer
|
||||
#define DBGDRCR (DEBUG_REGSITER_BASE + (36 * 4)) // Debug Run Control
|
||||
#define DBGEACR (DEBUG_REGSITER_BASE + (37 * 4)) // External Auxiliary Control
|
||||
#define DBGPCSR (DEBUG_REGSITER_BASE + (40 * 4)) // Program Counter Sampling
|
||||
#define DBGCIDSR (DEBUG_REGSITER_BASE + (41 * 4)) // Context ID Sampling
|
||||
#define DBGVIDSR (DEBUG_REGSITER_BASE + (42 * 4)) // Virtualization ID Sampling
|
||||
#define DBGBVR0 (DEBUG_REGSITER_BASE + (64 * 4)) // Breakpoint Value
|
||||
#define DBGBVR1 (DEBUG_REGSITER_BASE + (65 * 4)) // Breakpoint Value
|
||||
#define DBGBVR2 (DEBUG_REGSITER_BASE + (66 * 4)) // Breakpoint Value
|
||||
#define DBGBVR3 (DEBUG_REGSITER_BASE + (67 * 4)) // Breakpoint Value
|
||||
#define DBGBVR4 (DEBUG_REGSITER_BASE + (68 * 4)) // Breakpoint Value
|
||||
#define DBGBVR5 (DEBUG_REGSITER_BASE + (69 * 4)) // Breakpoint Value
|
||||
#define DBGBVR6 (DEBUG_REGSITER_BASE + (70 * 4)) // Breakpoint Value
|
||||
#define DBGBVR7 (DEBUG_REGSITER_BASE + (71 * 4)) // Breakpoint Value
|
||||
#define DBGBVR8 (DEBUG_REGSITER_BASE + (72 * 4)) // Breakpoint Value
|
||||
#define DBGBVR9 (DEBUG_REGSITER_BASE + (73 * 4)) // Breakpoint Value
|
||||
#define DBGBVR10 (DEBUG_REGSITER_BASE + (74 * 4)) // Breakpoint Value
|
||||
#define DBGBVR11 (DEBUG_REGSITER_BASE + (75 * 4)) // Breakpoint Value
|
||||
#define DBGBVR12 (DEBUG_REGSITER_BASE + (76 * 4)) // Breakpoint Value
|
||||
#define DBGBVR13 (DEBUG_REGSITER_BASE + (77 * 4)) // Breakpoint Value
|
||||
#define DBGBVR14 (DEBUG_REGSITER_BASE + (78 * 4)) // Breakpoint Value
|
||||
#define DBGBVR15 (DEBUG_REGSITER_BASE + (79 * 4)) // Breakpoint Value
|
||||
#define DBGBCR0 (DEBUG_REGSITER_BASE + (80 * 4)) // Breakpoint Control
|
||||
#define DBGBCR1 (DEBUG_REGSITER_BASE + (81 * 4)) // Breakpoint Control
|
||||
#define DBGBCR2 (DEBUG_REGSITER_BASE + (82 * 4)) // Breakpoint Control
|
||||
#define DBGBCR3 (DEBUG_REGSITER_BASE + (83 * 4)) // Breakpoint Control
|
||||
#define DBGBCR4 (DEBUG_REGSITER_BASE + (84 * 4)) // Breakpoint Control
|
||||
#define DBGBCR5 (DEBUG_REGSITER_BASE + (85 * 4)) // Breakpoint Control
|
||||
#define DBGBCR6 (DEBUG_REGSITER_BASE + (86 * 4)) // Breakpoint Control
|
||||
#define DBGBCR7 (DEBUG_REGSITER_BASE + (87 * 4)) // Breakpoint Control
|
||||
#define DBGBCR8 (DEBUG_REGSITER_BASE + (88 * 4)) // Breakpoint Control
|
||||
#define DBGBCR9 (DEBUG_REGSITER_BASE + (89 * 4)) // Breakpoint Control
|
||||
#define DBGBCR10 (DEBUG_REGSITER_BASE + (90 * 4)) // Breakpoint Control
|
||||
#define DBGBCR11 (DEBUG_REGSITER_BASE + (91 * 4)) // Breakpoint Control
|
||||
#define DBGBCR12 (DEBUG_REGSITER_BASE + (92 * 4)) // Breakpoint Control
|
||||
#define DBGBCR13 (DEBUG_REGSITER_BASE + (93 * 4)) // Breakpoint Control
|
||||
#define DBGBCR14 (DEBUG_REGSITER_BASE + (94 * 4)) // Breakpoint Control
|
||||
#define DBGBCR15 (DEBUG_REGSITER_BASE + (95 * 4)) // Breakpoint Control
|
||||
#define DBGWVR0 (DEBUG_REGSITER_BASE + (96 * 4)) // Watchpoint Value
|
||||
#define DBGWVR1 (DEBUG_REGSITER_BASE + (97 * 4)) // Watchpoint Value
|
||||
#define DBGWVR2 (DEBUG_REGSITER_BASE + (98 * 4)) // Watchpoint Value
|
||||
#define DBGWVR3 (DEBUG_REGSITER_BASE + (99 * 4)) // Watchpoint Value
|
||||
#define DBGWVR4 (DEBUG_REGSITER_BASE + (100 * 4)) // Watchpoint Value
|
||||
#define DBGWVR5 (DEBUG_REGSITER_BASE + (101 * 4)) // Watchpoint Value
|
||||
#define DBGWVR6 (DEBUG_REGSITER_BASE + (102 * 4)) // Watchpoint Value
|
||||
#define DBGWVR7 (DEBUG_REGSITER_BASE + (103 * 4)) // Watchpoint Value
|
||||
#define DBGWVR8 (DEBUG_REGSITER_BASE + (104 * 4)) // Watchpoint Value
|
||||
#define DBGWVR9 (DEBUG_REGSITER_BASE + (105 * 4)) // Watchpoint Value
|
||||
#define DBGWVR10 (DEBUG_REGSITER_BASE + (106 * 4)) // Watchpoint Value
|
||||
#define DBGWVR11 (DEBUG_REGSITER_BASE + (107 * 4)) // Watchpoint Value
|
||||
#define DBGWVR12 (DEBUG_REGSITER_BASE + (108 * 4)) // Watchpoint Value
|
||||
#define DBGWVR13 (DEBUG_REGSITER_BASE + (109 * 4)) // Watchpoint Value
|
||||
#define DBGWVR14 (DEBUG_REGSITER_BASE + (110 * 4)) // Watchpoint Value
|
||||
#define DBGWVR15 (DEBUG_REGSITER_BASE + (111 * 4)) // Watchpoint Value
|
||||
#define DBGWCR0 (DEBUG_REGSITER_BASE + (112 * 4)) // Watchpoint Control
|
||||
#define DBGWCR1 (DEBUG_REGSITER_BASE + (113 * 4)) // Watchpoint Control
|
||||
#define DBGWCR2 (DEBUG_REGSITER_BASE + (114 * 4)) // Watchpoint Control
|
||||
#define DBGWCR3 (DEBUG_REGSITER_BASE + (115 * 4)) // Watchpoint Control
|
||||
#define DBGWCR4 (DEBUG_REGSITER_BASE + (116 * 4)) // Watchpoint Control
|
||||
#define DBGWCR5 (DEBUG_REGSITER_BASE + (117 * 4)) // Watchpoint Control
|
||||
#define DBGWCR6 (DEBUG_REGSITER_BASE + (118 * 4)) // Watchpoint Control
|
||||
#define DBGWCR7 (DEBUG_REGSITER_BASE + (119 * 4)) // Watchpoint Control
|
||||
#define DBGWCR8 (DEBUG_REGSITER_BASE + (120 * 4)) // Watchpoint Control
|
||||
#define DBGWCR9 (DEBUG_REGSITER_BASE + (121 * 4)) // Watchpoint Control
|
||||
#define DBGWCR10 (DEBUG_REGSITER_BASE + (122 * 4)) // Watchpoint Control
|
||||
#define DBGWCR11 (DEBUG_REGSITER_BASE + (123 * 4)) // Watchpoint Control
|
||||
#define DBGWCR12 (DEBUG_REGSITER_BASE + (124 * 4)) // Watchpoint Control
|
||||
#define DBGWCR13 (DEBUG_REGSITER_BASE + (125 * 4)) // Watchpoint Control
|
||||
#define DBGWCR14 (DEBUG_REGSITER_BASE + (126 * 4)) // Watchpoint Control
|
||||
#define DBGWCR15 (DEBUG_REGSITER_BASE + (127 * 4)) // Watchpoint Control
|
||||
#define DBGBXVR0 (DEBUG_REGSITER_BASE + (144 * 4)) // Breakpoint Extended Valueb
|
||||
#define DBGBXVR1 (DEBUG_REGSITER_BASE + (145 * 4)) // Breakpoint Extended Valueb
|
||||
#define DBGBXVR2 (DEBUG_REGSITER_BASE + (146 * 4)) // Breakpoint Extended Valueb
|
||||
#define DBGBXVR3 (DEBUG_REGSITER_BASE + (147 * 4)) // Breakpoint Extended Valueb
|
||||
#define DBGBXVR4 (DEBUG_REGSITER_BASE + (148 * 4)) // Breakpoint Extended Valueb
|
||||
#define DBGBXVR5 (DEBUG_REGSITER_BASE + (149 * 4)) // Breakpoint Extended Valueb
|
||||
#define DBGBXVR6 (DEBUG_REGSITER_BASE + (150 * 4)) // Breakpoint Extended Valueb
|
||||
#define DBGBXVR7 (DEBUG_REGSITER_BASE + (151 * 4)) // Breakpoint Extended Valueb
|
||||
#define DBGBXVR8 (DEBUG_REGSITER_BASE + (152 * 4)) // Breakpoint Extended Valueb
|
||||
#define DBGBXVR9 (DEBUG_REGSITER_BASE + (153 * 4)) // Breakpoint Extended Valueb
|
||||
#define DBGBXVR10 (DEBUG_REGSITER_BASE + (154 * 4)) // Breakpoint Extended Valueb
|
||||
#define DBGBXVR11 (DEBUG_REGSITER_BASE + (155 * 4)) // Breakpoint Extended Valueb
|
||||
#define DBGBXVR12 (DEBUG_REGSITER_BASE + (156 * 4)) // Breakpoint Extended Valueb
|
||||
#define DBGBXVR13 (DEBUG_REGSITER_BASE + (157 * 4)) // Breakpoint Extended Valueb
|
||||
#define DBGBXVR14 (DEBUG_REGSITER_BASE + (158 * 4)) // Breakpoint Extended Valueb
|
||||
#define DBGBXVR15 (DEBUG_REGSITER_BASE + (159 * 4)) // Breakpoint Extended Valueb
|
||||
#define DBGOSLAR (DEBUG_REGSITER_BASE + (192 * 4)) // OS Lock Access
|
||||
#define DBGOSLSR (DEBUG_REGSITER_BASE + (193 * 4)) // OS Lock Status
|
||||
#define DBGPRCR (DEBUG_REGSITER_BASE + (196 * 4)) // Powerdown and Reset Control
|
||||
#define DBGPRSR (DEBUG_REGSITER_BASE + (197 * 4)) // Powerdown and Reset Status
|
||||
#define DBGITCTRL (DEBUG_REGSITER_BASE + (960 * 4)) // Integration Mode Control
|
||||
#define DBGCLAIMSET (DEBUG_REGSITER_BASE + (1000 * 4)) // Claim Tag Set
|
||||
#define DBGCLAIMCLR (DEBUG_REGSITER_BASE + (1001 * 4)) // Claim Tag Clear
|
||||
#define DBGLAR (DEBUG_REGSITER_BASE + (1004 * 4)) // Lock Access
|
||||
#define DBGLSR (DEBUG_REGSITER_BASE + (1005 * 4)) // Lock Status
|
||||
#define DBGAUTHSTATUS (DEBUG_REGSITER_BASE + (1006 * 4)) // Authentication Status
|
||||
#define DBGDEVID2 (DEBUG_REGSITER_BASE + (1008 * 4)) // Debug Device ID 2
|
||||
#define DBGDEVID1 (DEBUG_REGSITER_BASE + (1009 * 4)) // Debug Device ID 1
|
||||
#define DBGDEVID (DEBUG_REGSITER_BASE + (1010 * 4)) // Debug Device ID
|
||||
#define DBGDEVTYPE (DEBUG_REGSITER_BASE + (1011 * 4)) // Device Type
|
||||
#define DBGPID0 (DEBUG_REGSITER_BASE + (1012 * 4)) // Debug Peripheral ID
|
||||
#define DBGPID1 (DEBUG_REGSITER_BASE + (1013 * 4)) // Debug Peripheral ID
|
||||
#define DBGPID2 (DEBUG_REGSITER_BASE + (1014 * 4)) // Debug Peripheral ID
|
||||
#define DBGPID3 (DEBUG_REGSITER_BASE + (1015 * 4)) // Debug Peripheral ID
|
||||
#define DBGPID4 (DEBUG_REGSITER_BASE + (1016 * 4)) // Debug Peripheral ID
|
||||
#define DBGCID0 (DEBUG_REGSITER_BASE + (1020 * 4)) // Debug Component ID
|
||||
#define DBGCID1 (DEBUG_REGSITER_BASE + (1021 * 4)) // Debug Component ID
|
||||
#define DBGCID2 (DEBUG_REGSITER_BASE + (1022 * 4)) // Debug Component ID
|
||||
#define DBGCID3 (DEBUG_REGSITER_BASE + (1023 * 4)) // Debug Component ID
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,168 @@
|
||||
/**
|
||||
* @file debug_cm.h
|
||||
* @brief Access to ARM DAP (Cortex-M) using CMSIS-DAP protocol
|
||||
*
|
||||
* DAPLink Interface Firmware
|
||||
* Copyright (c) 2009-2016, ARM Limited, All Rights Reserved
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef DEBUG_CM_H
|
||||
#define DEBUG_CM_H
|
||||
|
||||
#include "DAP.h"
|
||||
|
||||
// SWD register access
|
||||
#define SWD_REG_AP (1)
|
||||
#define SWD_REG_DP (0)
|
||||
#define SWD_REG_R (1<<1)
|
||||
#define SWD_REG_W (0<<1)
|
||||
#define SWD_REG_ADR(a) (a & 0x0c)
|
||||
|
||||
// Abort Register definitions
|
||||
#define DAPABORT 0x00000001 // DAP Abort
|
||||
#define STKCMPCLR 0x00000002 // Clear STICKYCMP Flag (SW Only)
|
||||
#define STKERRCLR 0x00000004 // Clear STICKYERR Flag (SW Only)
|
||||
#define WDERRCLR 0x00000008 // Clear WDATAERR Flag (SW Only)
|
||||
#define ORUNERRCLR 0x00000010 // Clear STICKYORUN Flag (SW Only)
|
||||
|
||||
// Debug Control and Status definitions
|
||||
#define ORUNDETECT 0x00000001 // Overrun Detect
|
||||
#define STICKYORUN 0x00000002 // Sticky Overrun
|
||||
#define TRNMODE 0x0000000C // Transfer Mode Mask
|
||||
#define TRNNORMAL 0x00000000 // Transfer Mode: Normal
|
||||
#define TRNVERIFY 0x00000004 // Transfer Mode: Pushed Verify
|
||||
#define TRNCOMPARE 0x00000008 // Transfer Mode: Pushed Compare
|
||||
#define STICKYCMP 0x00000010 // Sticky Compare
|
||||
#define STICKYERR 0x00000020 // Sticky Error
|
||||
#define READOK 0x00000040 // Read OK (SW Only)
|
||||
#define WDATAERR 0x00000080 // Write Data Error (SW Only)
|
||||
#define MASKLANE 0x00000F00 // Mask Lane Mask
|
||||
#define MASKLANE0 0x00000100 // Mask Lane 0
|
||||
#define MASKLANE1 0x00000200 // Mask Lane 1
|
||||
#define MASKLANE2 0x00000400 // Mask Lane 2
|
||||
#define MASKLANE3 0x00000800 // Mask Lane 3
|
||||
#define TRNCNT 0x001FF000 // Transaction Counter Mask
|
||||
#define CDBGRSTREQ 0x04000000 // Debug Reset Request
|
||||
#define CDBGRSTACK 0x08000000 // Debug Reset Acknowledge
|
||||
#define CDBGPWRUPREQ 0x10000000 // Debug Power-up Request
|
||||
#define CDBGPWRUPACK 0x20000000 // Debug Power-up Acknowledge
|
||||
#define CSYSPWRUPREQ 0x40000000 // System Power-up Request
|
||||
#define CSYSPWRUPACK 0x80000000 // System Power-up Acknowledge
|
||||
|
||||
// Debug Select Register definitions
|
||||
#define CTRLSEL 0x00000001 // CTRLSEL (SW Only)
|
||||
#define APBANKSEL 0x000000F0 // APBANKSEL Mask
|
||||
#define APSEL 0xFF000000 // APSEL Mask
|
||||
|
||||
// Access Port Register Addresses
|
||||
#define AP_CSW 0x00 // Control and Status Word
|
||||
#define AP_TAR 0x04 // Transfer Address
|
||||
#define AP_DRW 0x0C // Data Read/Write
|
||||
#define AP_BD0 0x10 // Banked Data 0
|
||||
#define AP_BD1 0x14 // Banked Data 1
|
||||
#define AP_BD2 0x18 // Banked Data 2
|
||||
#define AP_BD3 0x1C // Banked Data 3
|
||||
#define AP_ROM 0xF8 // Debug ROM Address
|
||||
#define AP_IDR 0xFC // Identification Register
|
||||
|
||||
// AP Control and Status Word definitions
|
||||
#define CSW_SIZE 0x00000007 // Access Size: Selection Mask
|
||||
#define CSW_SIZE8 0x00000000 // Access Size: 8-bit
|
||||
#define CSW_SIZE16 0x00000001 // Access Size: 16-bit
|
||||
#define CSW_SIZE32 0x00000002 // Access Size: 32-bit
|
||||
#define CSW_ADDRINC 0x00000030 // Auto Address Increment Mask
|
||||
#define CSW_NADDRINC 0x00000000 // No Address Increment
|
||||
#define CSW_SADDRINC 0x00000010 // Single Address Increment
|
||||
#define CSW_PADDRINC 0x00000020 // Packed Address Increment
|
||||
#define CSW_DBGSTAT 0x00000040 // Debug Status
|
||||
#define CSW_TINPROG 0x00000080 // Transfer in progress
|
||||
#define CSW_HPROT 0x02000000 // User/Privilege Control
|
||||
#define CSW_MSTRTYPE 0x20000000 // Master Type Mask
|
||||
#define CSW_MSTRCORE 0x00000000 // Master Type: Core
|
||||
#define CSW_MSTRDBG 0x20000000 // Master Type: Debug
|
||||
#define CSW_RESERVED 0x01000000 // Reserved Value
|
||||
|
||||
// Core Debug Register Address Offsets
|
||||
#define DBG_OFS 0x0DF0 // Debug Register Offset inside NVIC
|
||||
#define DBG_HCSR_OFS 0x00 // Debug Halting Control & Status Register
|
||||
#define DBG_CRSR_OFS 0x04 // Debug Core Register Selector Register
|
||||
#define DBG_CRDR_OFS 0x08 // Debug Core Register Data Register
|
||||
#define DBG_EMCR_OFS 0x0C // Debug Exception & Monitor Control Register
|
||||
|
||||
// Core Debug Register Addresses
|
||||
#define DBG_HCSR (DBG_Addr + DBG_HCSR_OFS)
|
||||
#define DBG_CRSR (DBG_Addr + DBG_CRSR_OFS)
|
||||
#define DBG_CRDR (DBG_Addr + DBG_CRDR_OFS)
|
||||
#define DBG_EMCR (DBG_Addr + DBG_EMCR_OFS)
|
||||
|
||||
// Debug Halting Control and Status Register definitions
|
||||
#define C_DEBUGEN 0x00000001 // Debug Enable
|
||||
#define C_HALT 0x00000002 // Halt
|
||||
#define C_STEP 0x00000004 // Step
|
||||
#define C_MASKINTS 0x00000008 // Mask Interrupts
|
||||
#define C_SNAPSTALL 0x00000020 // Snap Stall
|
||||
#define S_REGRDY 0x00010000 // Register R/W Ready Flag
|
||||
#define S_HALT 0x00020000 // Halt Flag
|
||||
#define S_SLEEP 0x00040000 // Sleep Flag
|
||||
#define S_LOCKUP 0x00080000 // Lockup Flag
|
||||
#define S_RETIRE_ST 0x01000000 // Sticky Retire Flag
|
||||
#define S_RESET_ST 0x02000000 // Sticky Reset Flag
|
||||
#define DBGKEY 0xA05F0000 // Debug Key
|
||||
|
||||
// Debug Exception and Monitor Control Register definitions
|
||||
#define VC_CORERESET 0x00000001 // Reset Vector Catch
|
||||
#define VC_MMERR 0x00000010 // Debug Trap on MMU Fault
|
||||
#define VC_NOCPERR 0x00000020 // Debug Trap on No Coprocessor Fault
|
||||
#define VC_CHKERR 0x00000040 // Debug Trap on Checking Error Fault
|
||||
#define VC_STATERR 0x00000080 // Debug Trap on State Error Fault
|
||||
#define VC_BUSERR 0x00000100 // Debug Trap on Bus Error Fault
|
||||
#define VC_INTERR 0x00000200 // Debug Trap on Interrupt Error Fault
|
||||
#define VC_HARDERR 0x00000400 // Debug Trap on Hard Fault
|
||||
#define MON_EN 0x00010000 // Monitor Enable
|
||||
#define MON_PEND 0x00020000 // Monitor Pend
|
||||
#define MON_STEP 0x00040000 // Monitor Step
|
||||
#define MON_REQ 0x00080000 // Monitor Request
|
||||
#define TRCENA 0x01000000 // Trace Enable (DWT, ITM, ETM, TPIU)
|
||||
|
||||
// NVIC: Interrupt Controller Type Register
|
||||
#define NVIC_ICT (NVIC_Addr + 0x0004)
|
||||
#define INTLINESNUM 0x0000001F // Interrupt Line Numbers
|
||||
|
||||
// NVIC: CPUID Base Register
|
||||
#define NVIC_CPUID (NVIC_Addr + 0x0D00)
|
||||
#define CPUID_PARTNO 0x0000FFF0 // Part Number Mask
|
||||
#define CPUID_REVISION 0x0000000F // Revision Mask
|
||||
#define CPUID_VARIANT 0x00F00000 // Variant Mask
|
||||
|
||||
// NVIC: Application Interrupt/Reset Control Register
|
||||
#define NVIC_AIRCR (NVIC_Addr + 0x0D0C)
|
||||
#define VECTRESET 0x00000001 // Reset Cortex-M (except Debug)
|
||||
#define VECTCLRACTIVE 0x00000002 // Clear Active Vector Bit
|
||||
#define SYSRESETREQ 0x00000004 // Reset System (except Debug)
|
||||
#define VECTKEY 0x05FA0000 // Write Key
|
||||
|
||||
// NVIC: Debug Fault Status Register
|
||||
#define NVIC_DFSR (NVIC_Addr + 0x0D30)
|
||||
#define HALTED 0x00000001 // Halt Flag
|
||||
#define BKPT 0x00000002 // BKPT Flag
|
||||
#define DWTTRAP 0x00000004 // DWT Match
|
||||
#define VCATCH 0x00000008 // Vector Catch Flag
|
||||
#define EXTERNAL 0x00000010 // External Debug Request
|
||||
|
||||
// Data Watchpoint and Trace unit
|
||||
#define DWT_PCSR 0xe000101c // DWT PC Sampling Register
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,90 @@
|
||||
/**
|
||||
* @file SWD_flash.c
|
||||
* @brief Program target flash through SWD
|
||||
*/
|
||||
#include "swd_host.h"
|
||||
#include "SWD_flash.h"
|
||||
|
||||
|
||||
extern const program_target_t flash_algo;
|
||||
|
||||
|
||||
error_t target_flash_init(uint32_t flash_start, uint32_t func)
|
||||
{
|
||||
if(func == 0)
|
||||
{
|
||||
if (0 == swd_set_target_state_hw(RESET_PROGRAM)) {
|
||||
return ERROR_RESET;
|
||||
}
|
||||
|
||||
// Download flash programming algorithm to target and initialise.
|
||||
if (0 == swd_write_memory(flash_algo.algo_start, (uint8_t *)flash_algo.algo_blob, flash_algo.algo_size)) {
|
||||
return ERROR_ALGO_DL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (0 != swd_flash_syscall_exec(&flash_algo.sys_call_s, flash_algo.init, flash_start, 0, func, 0)) {
|
||||
return ERROR_INIT;
|
||||
}
|
||||
}
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
error_t target_flash_uninit(uint32_t func)
|
||||
{
|
||||
if (0 != swd_flash_syscall_exec(&flash_algo.sys_call_s, flash_algo.init, func, 0, 0, 0)) {
|
||||
return ERROR_UNINIT;
|
||||
}
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
error_t target_flash_program_page(uint32_t addr, const uint8_t *buf, uint32_t size)
|
||||
{
|
||||
while (size > 0) {
|
||||
uint32_t write_size = size > flash_algo.program_buffer_size ? flash_algo.program_buffer_size : size;
|
||||
|
||||
// Write page to buffer
|
||||
if (!swd_write_memory(flash_algo.program_buffer, (uint8_t *)buf, write_size)) {
|
||||
return ERROR_ALGO_DATA_SEQ;
|
||||
}
|
||||
|
||||
// Run flash programming
|
||||
if (swd_flash_syscall_exec(&flash_algo.sys_call_s,
|
||||
flash_algo.program_page,
|
||||
addr,
|
||||
flash_algo.program_buffer_size,
|
||||
flash_algo.program_buffer,
|
||||
0)) {
|
||||
return ERROR_WRITE;
|
||||
}
|
||||
|
||||
addr += write_size;
|
||||
buf += write_size;
|
||||
size -= write_size;
|
||||
}
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
error_t target_flash_erase_sector(uint32_t addr)
|
||||
{
|
||||
if (0 != swd_flash_syscall_exec(&flash_algo.sys_call_s, flash_algo.erase_sector, addr, 0, 0, 0)) {
|
||||
return ERROR_ERASE_SECTOR;
|
||||
}
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
error_t target_flash_erase_chip(void)
|
||||
{
|
||||
error_t status = ERROR_SUCCESS;
|
||||
|
||||
if (0 != swd_flash_syscall_exec(&flash_algo.sys_call_s, flash_algo.erase_chip, 0, 0, 0, 0)) {
|
||||
return ERROR_ERASE_ALL;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
#ifndef __SWD_FLASH_H__
|
||||
#define __SWD_FLASH_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
typedef enum {
|
||||
/* Shared errors */
|
||||
ERROR_SUCCESS = 0,
|
||||
ERROR_FAILURE,
|
||||
ERROR_INTERNAL,
|
||||
|
||||
/* Target flash errors */
|
||||
ERROR_RESET,
|
||||
ERROR_ALGO_DL,
|
||||
ERROR_ALGO_DATA_SEQ,
|
||||
ERROR_INIT,
|
||||
ERROR_UNINIT,
|
||||
ERROR_SECURITY_BITS,
|
||||
ERROR_UNLOCK,
|
||||
ERROR_ERASE_SECTOR,
|
||||
ERROR_ERASE_ALL,
|
||||
ERROR_WRITE,
|
||||
|
||||
// Add new values here
|
||||
|
||||
ERROR_COUNT
|
||||
} error_t;
|
||||
|
||||
|
||||
error_t target_flash_init(uint32_t flash_start, uint32_t func);
|
||||
error_t target_flash_uninit(uint32_t func);
|
||||
error_t target_flash_program_page(uint32_t addr, const uint8_t *buf, uint32_t size);
|
||||
error_t target_flash_erase_sector(uint32_t addr);
|
||||
error_t target_flash_erase_chip(void);
|
||||
|
||||
|
||||
#endif // __SWD_FLASH_H__
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,39 @@
|
||||
#ifndef SWDHOST_CM_H
|
||||
#define SWDHOST_CM_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "flash_blob.h"
|
||||
|
||||
|
||||
typedef enum {
|
||||
RESET_HOLD, // Hold target in reset
|
||||
RESET_PROGRAM, // Reset target and setup for flash programming.
|
||||
RESET_RUN, // Reset target and run normally
|
||||
NO_DEBUG, // Disable debug on running target
|
||||
DEBUG, // Enable debug on running target
|
||||
HALT, // Halt the target without resetting it
|
||||
RUN // Resume the target without resetting it
|
||||
} TARGET_RESET_STATE;
|
||||
|
||||
|
||||
uint8_t swd_init(void);
|
||||
uint8_t swd_off(void);
|
||||
uint8_t swd_init_debug(void);
|
||||
uint8_t swd_read_dp(uint8_t adr, uint32_t *val);
|
||||
uint8_t swd_write_dp(uint8_t adr, uint32_t val);
|
||||
uint8_t swd_read_ap(uint32_t adr, uint32_t *val);
|
||||
uint8_t swd_write_ap(uint32_t adr, uint32_t val);
|
||||
uint8_t swd_read_memory(uint32_t address, uint8_t *data, uint32_t size);
|
||||
uint8_t swd_write_memory(uint32_t address, uint8_t *data, uint32_t size);
|
||||
uint8_t swd_flash_syscall_exec(const program_syscall_t *sysCallParam, uint32_t entry, uint32_t arg1, uint32_t arg2, uint32_t arg3, uint32_t arg4);
|
||||
void swd_set_target_reset(uint8_t asserted);
|
||||
uint8_t swd_set_target_state_hw(TARGET_RESET_STATE state);
|
||||
uint8_t swd_set_target_state_sw(TARGET_RESET_STATE state);
|
||||
|
||||
|
||||
uint8_t swd_read_word(uint32_t addr, uint32_t *val);
|
||||
uint8_t swd_write_word(uint32_t addr, uint32_t val);
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,33 @@
|
||||
#ifndef FLASH_BLOB_H
|
||||
#define FLASH_BLOB_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint32_t breakpoint;
|
||||
uint32_t static_base;
|
||||
uint32_t stack_pointer;
|
||||
} program_syscall_t;
|
||||
|
||||
typedef struct {
|
||||
const uint32_t init;
|
||||
const uint32_t uninit;
|
||||
const uint32_t erase_chip;
|
||||
const uint32_t erase_sector;
|
||||
const uint32_t program_page;
|
||||
const program_syscall_t sys_call_s;
|
||||
const uint32_t program_buffer;
|
||||
const uint32_t algo_start;
|
||||
const uint32_t algo_size;
|
||||
const uint32_t *algo_blob;
|
||||
const uint32_t program_buffer_size;
|
||||
} program_target_t;
|
||||
|
||||
typedef struct {
|
||||
const uint32_t start;
|
||||
const uint32_t size;
|
||||
} sector_info_t;
|
||||
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user