A modified DAPLink firmware (from JiXin) for STM32F103C6T6
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

269 lines
7.0 KiB

/******************************************************************************
* @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(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, uint8_t *data)
{
uint8_t val;
uint8_t n = 0;
DEBUG("DATA:");
while (count != 0)
{
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; \
uint8_t bit; \
uint32_t val; \
uint8_t parity; \
uint8_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; \
SW_WRITE_BIT(bit); /* A3 Bit */ \
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 != 0; 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 = 0; \
parity = 0; \
for (n = 32; 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) & 1) \
{ \
ack = DAP_TRANSFER_ERROR; \
} \
if (data) *data = val; \
/* Turnaround */ \
for (n = DAP_Data.swd_conf.turnaround; n != 0; n--) \
{ \
SW_CLOCK_CYCLE(); \
} \
\
PIN_SWDIO_OUT_ENABLE(); \
} \
else \
{ \
/* Turnaround */ \
for (n = DAP_Data.swd_conf.turnaround; n != 0; n--) \
{ \
SW_CLOCK_CYCLE(); \
} \
\
PIN_SWDIO_OUT_ENABLE(); \
/* Write data */ \
val = *data; \
parity = 0; \
for (n = 32; n; n--) { \
SW_WRITE_BIT(val); /* Write WDATA[0:31] */ \
parity += val; \
val >>= 1; \
} \
SW_WRITE_BIT(parity); /* Write Parity Bit */ \
} \
/* Idle cycles */ \
n = DAP_Data.transfer.idle_cycles; \
if (n != 0) \
{ \
PIN_SWDIO_OUT(0); \
for (; n != 0; 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 != 0; 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 != 0; 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 != 0; 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)
{
if (DAP_Data.fast_clock)
return SWD_TransferFast(request, data);
else
return SWD_TransferSlow(request, data);
}
#endif /* (DAP_SWD != 0) */