|
发表于 2019-8-23 17:26:47
|
显示全部楼层
USBDM下载器的SWD还真是SPI硬件实现的,给力
最有价值的两个软件包:
USBDM_API_Example.zip
(722.19 KB, 下载次数: 150)
USBDM_Kinetis_Firmware.zip
(314.11 KB, 下载次数: 15)
部分代码截图:
- /*! \file
- \brief ARM-SWD routines
- \verbatim
- USBDM
- Copyright (C) 2007 Peter O'Donoghue
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- \endverbatim
- Change History
- +==================================================================================================
- | 10 Feb 2014 | Dramatically extended retry times to allow for slow clocks V4.10.6.20
- | 30 Aug 2012 | ARM-JTAG & ARM-SWD Changes V4.9.5
- +==================================================================================================
- \endverbatim
- */
- #include "Common.h"
- #include "Configure.h"
- #include "Commands.h"
- #include "SWD.h"
- #include "Commands.h"
- #include "BDM.h"
- #include "CmdProcessing.h"
- #include "BDMCommon.h"
- #include "SPI.h"
- #include "TargetDefines.h"
- #include "SWD.h"
- //#define SLOWER_METHOD
- #if TARGET_CAPABILITY & CAP_ARM_SWD
- //! SPI CTAR value
- //#define SPI_CTAR_MASK (SPI_CTAR_CPOL_MASK|SPI_CTAR_CPHA_MASK|SPI_CTAR_LSBFE_MASK|SPI_CTAR_PASC(1)|SPI_CTAR_ASC(0))
- #define SPI_CTAR_MASK (SPI_CTAR_LSBFE_MASK|SPI_CTAR_PASC(1)|SPI_CTAR_ASC(0))
- // SPI_PUSHR_PCS for Tx operations
- #define SWD_PUSHR_TX SPI_PUSHR_PCS((1<<0)|(1<<1)) // PCS0=SWDIO_O_En, PCS1=SWDCLK_En
- // SPI_PUSHR_PCS for Rx operations
- #define SWD_PUSHR_RX SPI_PUSHR_PCS((1<<1)) // PCS1=SWDCLK_En
- #define SWD_READ_IDCODE 0xA5 // (Park,Stop,Parity,A[32],R/W,AP/DP,Start) = 10100101
- // Masks for SWD_WR_DP_ABORT clear sticky
- #define SWD_DP_ABORT_CLEAR_STICKY_ERRORS_B3 0x1E
- // Masks for SWD_WR_DP_ABORT abort AP
- #define SWD_DP_ABORT_ABORT_AP_B3 0x01
- // Masks for SWD_RD_DP_STATUS
- #define SWD_RD_DP_STATUS_ANYERROR_B3 0xB2
- //! Calculate parity
- //!
- //! @param data data to calculate parity for
- //!
- //! @return 0/1 indicating even/odd parity
- //!
- __forceinline
- static inline uint8_t calcParity(const uint8_t dataptr[]) {
- uint32_t data = dataptr[0]^dataptr[1]^dataptr[2]^dataptr[3];
- data = (data>>4)^data;
- data = (data>>2)^data;
- data = (data>>1)^data;
- return data&1;
- }
- //! Sets the SWD interface to an idle state
- //! RESET=3-state, SWCLK=High, SWDIO=3-state
- //!
- void swd_interfaceIdle(void) {
- #ifdef RESET_3STATE
- RESET_3STATE();
- #endif
- }
- //! Initialise the SWD interface and sets it to an idle state
- //! RESET=3-state, SWCLK=High, SWDIO=3-state, SPI initialised
- //!
- //! @note This includes once-off initialisation such as PUPs etc
- //!
- void swd_init(void) {
- swd_interfaceIdle();
- // 4 pins SWD_OUT, SWD_OUT_EN, SWCLK_OUT, SWCLK_OUT_EN
- SWCLK_OUT_INIT();
- SWD_OUT_INIT();
- SWD_IN_INIT();
- RESET_OUT_INIT();
- #ifdef RESET_IN_INIT
- RESET_IN_INIT();
- #endif
- #ifdef SWCLK_ENABLE
- SWCLK_ENABLE();
- #endif
- #ifdef SWD_3STATE
- SWD_3STATE();
- #endif
- spi_init(SPI_CTAR_MASK|SPI_CTAR_FMSZ(8-1), // 8-bit transfer
- SPI_CTAR_MASK|SPI_CTAR_FMSZ(4-1)); // 4-bit transfer
- }
- //! Turns off the SWD interface
- //!
- //! Depending upon settings, may leave target power on.
- //!
- void swd_off( void ) {
- #if ((HW_CAPABILITY & CAP_FLASH) != 0)
- (void)bdmSetVpp(BDM_TARGET_VPP_OFF);
- #endif
- if (!bdm_option.leaveTargetPowered) {
- VDD_OFF();
- }
- swd_interfaceIdle();
- #ifdef SWCLK_3STATE
- SWCLK_3STATE();
- #endif
- #ifdef SWD_3STATE
- SWD_3STATE();
- #endif
- SWCLK_OUT_FINI();
- SWD_OUT_FINI();
- SWD_IN_FINI();
- RESET_OUT_FINI();
- #ifdef RESET_IN_FINI
- RESET_IN_FINI();
- #endif
- }
- static const int ctas_8bit = 0;
- static const int ctas_Xbit = 1;
- //! Transmit a 8-bit word to the target
- //!
- //! @param send - data to send
- //!
- //! @return BDM_RC_OK => success
- //!
- __forceinline
- static inline void spi_tx8(uint8_t data) {
- SWD_ENABLE();
- SPI0->PUSHR = SPI_PUSHR_CTAS(ctas_8bit)|SPI_PUSHR_EOQ_MASK|SWD_PUSHR_TX|SPI_PUSHR_TXDATA(data);
- while ((SPI0->SR & SPI_SR_EOQF_MASK) == 0) {
- }
- (void)SPI0->POPR; // Discard read data
- SPI0->SR = SPI_SR_RFDF_MASK|SPI_SR_EOQF_MASK;
- SWD_3STATE();
- }
复制代码
|
|