MXC-A36_2024.04.18/fr3092_mcu/examples/common/btdm/SWD.c

446 lines
12 KiB
C
Raw Permalink Normal View History

2024-04-17 19:45:26 +08:00
/*
******************************************************************************
* @file SWD.c
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2023
* @brief SWD module Demo.
******************************************************************************
* @attention
*
* Copyright (c) 2023 FreqChip.
* All rights reserved.
******************************************************************************
*/
#include "co_util.h"
#include "fr30xx.h"
#include "SWD.h"
#define PMU_SWD_IE 0x43
#define PMU_SWD_DATA 0x49
#define PMU_SWD_DIR 0x4b
#define PMU_SWD_IOMUX 0x5b
#define PMU_SWD_PULL_EN 0x45
#define PMU_SWD_PULL_SEL 0x47
//#define PMU_SWD_IE 0x42
//#define PMU_SWD_DATA 0x48
//#define PMU_SWD_DIR 0x4a
//#define PMU_SWD_IOMUX 0x59
#define SWD_CLK_H 0x01
#define SWD_CLK_L 0x02
#define SWD_DATA_H 0x02
#define SWD_DATA_L 0x01
static uint8_t SWD_DATA,SWD_CLK;
#define ool_write_ram(addr, data) frspim_wr_ram(FR_SPI_PMU_CHAN,(addr),1, (data))
#define ool_read_ram(addr) (uint8_t)frspim_rd_ram(FR_SPI_PMU_CHAN,(addr),1)
/*---------------------------------- Porting ----------------------------------------*/
#define RAM_CODE __RAM_CODE
#define SWD_CLK_SET_H() {SWD_CLK = SWD_CLK_H; \
ool_write_ram(PMU_SWD_DATA,SWD_DATA | SWD_CLK);}
#define SWD_CLK_SET_L() {SWD_CLK = SWD_CLK_L; \
ool_write_ram(PMU_SWD_DATA,SWD_DATA & SWD_CLK);}
#define SWD_IO_SET_H() {SWD_DATA = SWD_DATA_H; \
ool_write_ram(PMU_SWD_DATA,SWD_CLK | SWD_DATA);}
#define SWD_IO_SET_L() {SWD_DATA = SWD_DATA_L; \
ool_write_ram(PMU_SWD_DATA,SWD_CLK & SWD_DATA);}
#define SWD_IO_IN() (ool_read_ram(PMU_SWD_DATA) & 0x02)
#define SWD_IO_OUT_ENABLE() (ool_write_ram(PMU_SWD_DIR,0x00))
#define SWD_IO_OUT_DISABLE() (ool_write_ram(PMU_SWD_DIR,0x02))
void SWD_IO_init(void)
{
ool_write_ram(PMU_SWD_PULL_EN, 0x03);
ool_write_ram(PMU_SWD_PULL_SEL, 0x00);
ool_write_ram(PMU_SWD_IE, 0x03);
ool_write_ram(PMU_SWD_DIR, 0x00);
ool_write_ram(PMU_SWD_DATA, 0x03);
ool_write_ram(PMU_SWD_IOMUX, 0x00);
SWD_CLK_SET_L();
SWD_IO_SET_L();
}
/*---------------------------------- Porting end ----------------------------------------*/
#define SW_CLOCK_CYCLE() \
SWD_CLK_SET_H(); \
SWD_DELAY(); \
SWD_CLK_SET_L(); \
SWD_DELAY()
#define SW_WRITE_BIT_0() \
SWD_IO_SET_L(); \
SWD_DELAY(); \
SWD_DELAY(); \
SWD_CLK_SET_H(); \
SWD_DELAY(); \
SWD_DELAY(); \
SWD_CLK_SET_L()
#define SW_WRITE_BIT_1() \
SWD_IO_SET_H(); \
SWD_DELAY(); \
SWD_DELAY(); \
SWD_CLK_SET_H(); \
SWD_DELAY(); \
SWD_DELAY(); \
SWD_CLK_SET_L()
#define SW_READ_BIT(BIT) \
SWD_CLK_SET_H(); \
SWD_DELAY(); \
SWD_DELAY(); \
SWD_CLK_SET_L(); \
SWD_DELAY(); \
SWD_DELAY(); \
BIT = SWD_IO_IN()
RAM_CODE static inline void SW_WRITE_BIT(uint32_t BIT)
{
switch (BIT)
{
case 0:
{
SW_WRITE_BIT_0();
}break;
case 1:
{
SW_WRITE_BIT_1();
}break;
default:break;
}
}
RAM_CODE int SWD_TransferFunction(uint32_t request, uint32_t *data, uint32_t Trailing)
{
int i;
uint32_t W_Parity;
uint32_t ACK;
bool BitBuffer[33];
bool ACKBuffer[3];
bool APnDP = (request >> 0) & 1;
bool RnW = (request >> 1) & 1;
bool A2 = (request >> 2) & 1;
bool A3 = (request >> 3) & 1;
bool parity = (APnDP + RnW + A2 + A3) & 0x01;
if (RnW == 0)
{
/* Prepare data */
W_Parity = 0;
for (i = 0; i < 32; i++)
{
BitBuffer[i] = (*data >> i) & 1;
W_Parity += BitBuffer[i];
}
W_Parity &= 0x01;
BitBuffer[32] = W_Parity;
}
SWD_IO_OUT_ENABLE();
/* Packet Request */
SW_WRITE_BIT(1U); /* Start Bit */
SW_WRITE_BIT(APnDP); /* APnDP Bit */
SW_WRITE_BIT(RnW); /* RnW Bit */
SW_WRITE_BIT(A2); /* A2 Bit */
SW_WRITE_BIT(A3); /* A3 Bit */
SW_WRITE_BIT(parity); /* parity Bit */
SW_WRITE_BIT(0U); /* Stop Bit */
SW_WRITE_BIT(1U); /* Park Bit */
/* Turnaround */
SWD_IO_OUT_DISABLE();
__NOP();__NOP();__NOP();__NOP();__NOP();SWD_DELAY();
SWD_CLK_SET_H();
__NOP();__NOP();__NOP();__NOP();__NOP();
__NOP();__NOP();__NOP();__NOP();__NOP();
__NOP();__NOP();__NOP();__NOP();__NOP();
/* Acknowledge response */
SW_READ_BIT(ACKBuffer[0]);
SW_READ_BIT(ACKBuffer[1]);
SW_READ_BIT(ACKBuffer[2]);
ACK = (ACKBuffer[0] << 2) | (ACKBuffer[1] << 1) | ACKBuffer[2];
/* OK response */
if (ACK == DAP_TRANSFER_OK)
{
/* Data transfer */
if (RnW == 1)
{
/* Read data */
/* Read RDATA[0:31] */
SW_READ_BIT(BitBuffer[0]);
SW_READ_BIT(BitBuffer[1]);
SW_READ_BIT(BitBuffer[2]);
SW_READ_BIT(BitBuffer[3]);
SW_READ_BIT(BitBuffer[4]);
SW_READ_BIT(BitBuffer[5]);
SW_READ_BIT(BitBuffer[6]);
SW_READ_BIT(BitBuffer[7]);
SW_READ_BIT(BitBuffer[8]);
SW_READ_BIT(BitBuffer[9]);
SW_READ_BIT(BitBuffer[10]);
SW_READ_BIT(BitBuffer[11]);
SW_READ_BIT(BitBuffer[12]);
SW_READ_BIT(BitBuffer[13]);
SW_READ_BIT(BitBuffer[14]);
SW_READ_BIT(BitBuffer[15]);
SW_READ_BIT(BitBuffer[16]);
SW_READ_BIT(BitBuffer[17]);
SW_READ_BIT(BitBuffer[18]);
SW_READ_BIT(BitBuffer[19]);
SW_READ_BIT(BitBuffer[20]);
SW_READ_BIT(BitBuffer[21]);
SW_READ_BIT(BitBuffer[22]);
SW_READ_BIT(BitBuffer[23]);
SW_READ_BIT(BitBuffer[24]);
SW_READ_BIT(BitBuffer[25]);
SW_READ_BIT(BitBuffer[26]);
SW_READ_BIT(BitBuffer[27]);
SW_READ_BIT(BitBuffer[28]);
SW_READ_BIT(BitBuffer[29]);
SW_READ_BIT(BitBuffer[30]);
SW_READ_BIT(BitBuffer[31]);
/* Read Parity */
SW_READ_BIT(BitBuffer[32]);
/* Trailing */
__NOP();__NOP();__NOP();__NOP();__NOP();
for (i = 0; i < Trailing; i++)
{
SW_CLOCK_CYCLE();
}
*data = 0;
for (i = 0; i < 32; i++)
{
*data |= (BitBuffer[i] << i);
}
}
else
{
/* Write data */
/* Turnaround */
SWD_CLK_SET_H();
__NOP();__NOP();__NOP();__NOP();__NOP();SWD_DELAY();
SWD_CLK_SET_L();
__NOP();__NOP();__NOP();__NOP();__NOP();SWD_DELAY();
SWD_CLK_SET_H();
__NOP();__NOP();__NOP();__NOP();__NOP();SWD_DELAY();
SWD_CLK_SET_L();
__NOP();__NOP();__NOP();__NOP();__NOP();SWD_DELAY();
SWD_IO_OUT_ENABLE();
/* Write WDATA[0:31] */
SW_WRITE_BIT(BitBuffer[0]);
SW_WRITE_BIT(BitBuffer[1]);
SW_WRITE_BIT(BitBuffer[2]);
SW_WRITE_BIT(BitBuffer[3]);
SW_WRITE_BIT(BitBuffer[4]);
SW_WRITE_BIT(BitBuffer[5]);
SW_WRITE_BIT(BitBuffer[6]);
SW_WRITE_BIT(BitBuffer[7]);
SW_WRITE_BIT(BitBuffer[8]);
SW_WRITE_BIT(BitBuffer[9]);
SW_WRITE_BIT(BitBuffer[10]);
SW_WRITE_BIT(BitBuffer[11]);
SW_WRITE_BIT(BitBuffer[12]);
SW_WRITE_BIT(BitBuffer[13]);
SW_WRITE_BIT(BitBuffer[14]);
SW_WRITE_BIT(BitBuffer[15]);
SW_WRITE_BIT(BitBuffer[16]);
SW_WRITE_BIT(BitBuffer[17]);
SW_WRITE_BIT(BitBuffer[18]);
SW_WRITE_BIT(BitBuffer[19]);
SW_WRITE_BIT(BitBuffer[20]);
SW_WRITE_BIT(BitBuffer[21]);
SW_WRITE_BIT(BitBuffer[22]);
SW_WRITE_BIT(BitBuffer[23]);
SW_WRITE_BIT(BitBuffer[24]);
SW_WRITE_BIT(BitBuffer[25]);
SW_WRITE_BIT(BitBuffer[26]);
SW_WRITE_BIT(BitBuffer[27]);
SW_WRITE_BIT(BitBuffer[28]);
SW_WRITE_BIT(BitBuffer[29]);
SW_WRITE_BIT(BitBuffer[30]);
SW_WRITE_BIT(BitBuffer[31]);
/* Write Parity Bit */
SW_WRITE_BIT(BitBuffer[32]);
SWD_IO_OUT_DISABLE();
__NOP();__NOP();__NOP();__NOP();__NOP();
__NOP();__NOP();__NOP();__NOP();__NOP();
__NOP();__NOP();__NOP();__NOP();__NOP();
__NOP();__NOP();__NOP();__NOP();__NOP();
/* Trailing */
for (i = 0; i < Trailing; i++)
{
SW_CLOCK_CYCLE();
}
}
}
else
{
/* WAIT or FAULT response */
if (ACK == DAP_TRANSFER_WAIT)
{
SW_CLOCK_CYCLE();
SW_CLOCK_CYCLE();
return -1;
}
else
{
return -2;
}
}
return 0;
}
RAM_CODE void SWD_Line_Reset(uint32_t fu32_CNT)
{
int i;
SWD_IO_OUT_ENABLE();
SWD_IO_SET_H();
for (i = 0; i < fu32_CNT; i++)
{
SW_CLOCK_CYCLE();
}
SWD_IO_SET_L();
for (int i = 0; i < 16; i++)
{
SW_CLOCK_CYCLE();
}
}
RAM_CODE void SWD_Connect(void)
{
uint32_t Data;
/* Line Reset */
SWD_Line_Reset(56);
SWD_Line_Reset(59);
SWD_Line_Reset(59);
for (int i = 0; i < 16; i++)
{
SW_CLOCK_CYCLE();
}
/* Read IDCODE */
SWD_TransferFunction(REQ_DP|REQ_R|REQ_ADDR_0, &Data, 6); co_delay_10us(1);
}
RAM_CODE void SWD_Enable_Debug(void)
{
uint32_t Data;
/* Write Abort */
Data = 0x0000001E;
SWD_TransferFunction(REQ_DP|REQ_W|REQ_ADDR_0, &Data, 7); co_delay_10us(1);
/* Write CTRL/STAT */
Data = 0x50000000;
SWD_TransferFunction(REQ_DP|REQ_W|REQ_ADDR_1, &Data, 7); co_delay_10us(1);
}
RAM_CODE void SWD_W_REG(uint32_t ADDR, uint32_t Value)
{
uint32_t Data;
/* Write Abort */
Data = 0x0000001E;
SWD_TransferFunction(REQ_DP|REQ_W|REQ_ADDR_0, &Data, 7);
/* Write Select */
Data = 0x00000000;
SWD_TransferFunction(REQ_DP|REQ_W|REQ_ADDR_2, &Data, 0);
/* Write CSW */
Data = 0x23000012;
SWD_TransferFunction(REQ_AP|REQ_W|REQ_ADDR_0, &Data, 0);
/* Write TAR */
Data = ADDR;
SWD_TransferFunction(REQ_AP|REQ_W|REQ_ADDR_1, &Data, 0);
/* Write DRW */
Data = Value;
SWD_TransferFunction(REQ_AP|REQ_W|REQ_ADDR_3, &Data, 7);
/* Read RDBUFF */
SWD_TransferFunction(REQ_DP|REQ_R|REQ_ADDR_3, &Data, 3);
}
RAM_CODE void SWD_R_REG(uint32_t ADDR, uint32_t *Buffer, uint32_t Length)
{
int ERR;int first = 0;
uint32_t Data;
/* Write Abort */
Data = 0x0000001E;
SWD_TransferFunction(REQ_DP|REQ_W|REQ_ADDR_0, &Data, 7);
/* Write Select */
Data = 0x00000000;
SWD_TransferFunction(REQ_DP|REQ_W|REQ_ADDR_2, &Data, 0);
/* Write CSW */
Data = 0x23000012;
SWD_TransferFunction(REQ_AP|REQ_W|REQ_ADDR_0, &Data, 0);
/* Write TAR */
Data = ADDR;
SWD_TransferFunction(REQ_AP|REQ_W|REQ_ADDR_1, &Data, 0);
while(Length)
{
/* Read DRW */
ERR = SWD_TransferFunction(REQ_AP|REQ_R|REQ_ADDR_3, Buffer, 3);
if (ERR == 0)
{
if (first)
{
Length--;
Buffer++;
}
first++;
}
else if (ERR == -2)
Length = 0;
SWD_DELAY();
SWD_DELAY();
}
}
RAM_CODE void SWD_W_SystemReg(void)
{
SWD_IO_init();
SWD_Connect();
SWD_Enable_Debug();
/* BIT24: enable cache clock */
SWD_W_REG(0x50000008, 0x09000803);
/* enable exchange memory clock */
SWD_W_REG(0x50000010, 0x1000);
}