-
Notifications
You must be signed in to change notification settings - Fork 250
/
Copy pathswdloader.h
104 lines (84 loc) · 3.29 KB
/
swdloader.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
//
// swdloader.h
//
// Circle - A C++ bare metal environment for Raspberry Pi
// Copyright (C) 2021 R. Stange <[email protected]>
//
// 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 3 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, see <http://www.gnu.org/licenses/>.
//
#ifndef _pico_swdloader_h
#define _pico_swdloader_h
#include <circle/gpiopin.h>
#include <circle/timer.h>
#include <circle/types.h>
class CSWDLoader /// Loads a program via the Serial Wire Debug interface to the RP2040
{
public:
const static unsigned DefaultClockRateKHz = 400; ///< Default clock rate in KHz
public:
/// \param nClockPin GPIO pin to which SWCLK is connected
/// \param nDataPin GPIO pin to which SWDIO is connected
/// \param nResetPin Optional GPIO pin to which RESET (RUN) is connected (active LOW)
/// \param nClockRateKHz Requested interface clock rate in KHz
/// \note GPIO pin numbers are SoC number, not header positions.
/// \note The actual clock rate may be smaller than the requested.
CSWDLoader (unsigned nClockPin, unsigned nDataPin, unsigned nResetPin = 0,
unsigned nClockRateKHz = DefaultClockRateKHz);
~CSWDLoader (void);
/// \brief Reset RP2040 and attach to SW debug port
/// \return Operation successful?
boolean Initialize (void);
/// \brief Halt the RP2040, load a program image and start it
/// \param pProgram Pointer to program image in memory
/// \param nProgSize Size of the program image (must be a multiple of 4)
/// \param nAddress Load and start address of the program image
boolean Load (const void *pProgram, size_t nProgSize, u32 nAddress);
public:
/// \brief Halt the RP2040
/// \return Operation successful?
boolean Halt (void);
/// \brief Load a chunk of a program image (or entire program)
/// \param pChunk Pointer to the chunk in memory
/// \param nChunkSize Size of the chunk (must be a multiple of 4)
/// \param nAddress Load address of the chunk
/// \return Operation successful?
boolean LoadChunk (const void *pChunk, size_t nChunkSize, u32 nAddress);
/// \brief Start program image
/// \param nAddress Start address of the program image
/// \return Operation successful?
boolean Start (u32 nAddress);
private:
boolean PowerOn (void);
boolean WriteMem (u32 nAddress, u32 nData);
boolean ReadMem (u32 nAddress, u32 *pData);
boolean WriteData (u8 uchRequest, u32 nData);
boolean ReadData (u8 uchRequest, u32 *pData);
void SelectTarget (u32 nCPUAPID, u8 uchInstanceID);
void BeginTransaction (void);
void EndTransaction (void);
void Dormant2SWD (void);
void LineReset (void);
void WriteIdle (void);
void WriteBits (u32 nBits, unsigned nBitCount);
u32 ReadBits (unsigned nBitCount);
void WriteClock (void);
private:
unsigned m_bResetAvailable;
unsigned m_nDelayNanos;
CGPIOPin m_ResetPin;
CGPIOPin m_ClockPin;
CGPIOPin m_DataPin;
CTimer *m_pTimer;
};
#endif