800*320工程文件+初始demo提交
This commit is contained in:
445
SW/examples/common/btdm/SWD.c
Normal file
445
SW/examples/common/btdm/SWD.c
Normal file
@ -0,0 +1,445 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* @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);
|
||||
}
|
Reference in New Issue
Block a user