-
Notifications
You must be signed in to change notification settings - Fork 12
/
Copy pathdap_target.c
139 lines (118 loc) · 4.98 KB
/
dap_target.c
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/*
* Copyright (c) 2014-2016, Alex Taradov <[email protected]>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*- Includes ----------------------------------------------------------------*/
#include <unistd.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include "dap.h"
/*- Definitions -------------------------------------------------------------*/
#define DHCSR 0xe000edf0
#define DEMCR 0xe000edfc
#define AIRCR 0xe000ed0c
#define DSU_CTRL_STATUS 0x41002100
#define DSU_DID 0x41002118
#define NVMCTRL_CTRLA 0x41004000
#define NVMCTRL_CTRLB 0x41004004
#define NVMCTRL_PARAM 0x41004008
#define NVMCTRL_INTFLAG 0x41004014
#define NVMCTRL_STATUS 0x41004018
#define NVMCTRL_ADDR 0x4100401c
#define NVMCTRL_CMD_ER 0xa502
#define NVMCTRL_CMD_WP 0xa504
#define NVMCTRL_CMD_EAR 0xa505
#define NVMCTRL_CMD_WAP 0xa506
#define NVMCTRL_CMD_WL 0xa50f
#define NVMCTRL_CMD_UR 0xa541
#define NVMCTRL_CMD_PBC 0xa544
#define NVMCTRL_CMD_SSB 0xa545
/*- Implementations ---------------------------------------------------------*/
//-----------------------------------------------------------------------------
void dap_target_select(void)
{
// Stop the core
dap_write_word(DHCSR, 0xa05f0003);
dap_write_word(DEMCR, 0x00000001);
dap_write_word(AIRCR, 0x05fa0004);
// Enable automatic writes
dap_write_word(NVMCTRL_CTRLB, 0);
}
//-----------------------------------------------------------------------------
void dap_target_deselect(void)
{
dap_write_word(DEMCR, 0x00000000);
dap_write_word(AIRCR, 0x05fa0004);
}
//-----------------------------------------------------------------------------
void dap_target_erase(void)
{
dap_write_word(DSU_CTRL_STATUS, 0x00001f00); // Clear flags
dap_write_word(DSU_CTRL_STATUS, 0x00000010); // Chip erase
while (0 == (dap_read_word(DSU_CTRL_STATUS) & 0x00000100));
}
//-----------------------------------------------------------------------------
void dap_target_lock(void)
{
dap_write_word(NVMCTRL_CTRLA, NVMCTRL_CMD_SSB); // Set Security Bit
}
//-----------------------------------------------------------------------------
void dap_target_erase_row(uint32_t addr)
{
dap_write_word(NVMCTRL_ADDR, addr >> 1);
dap_write_word(NVMCTRL_CTRLA, NVMCTRL_CMD_UR); // Unlock Region
while (0 == (dap_read_word(NVMCTRL_INTFLAG) & 1));
dap_write_word(NVMCTRL_CTRLA, NVMCTRL_CMD_ER); // Erase Row
while (0 == (dap_read_word(NVMCTRL_INTFLAG) & 1));
}
//-----------------------------------------------------------------------------
void dap_target_write_page(uint32_t addr, uint8_t *data)
{
dap_write_word(NVMCTRL_ADDR, addr >> 1);
dap_write_word(NVMCTRL_CTRLA, NVMCTRL_CMD_UR); // Unlock Region
while (0 == (dap_read_word(NVMCTRL_INTFLAG) & 1));
for (int offs = 0; offs < TARGET_PAGE_SIZE; offs += sizeof(uint32_t))
{
uint32_t value =
((uint32_t)data[offs + 3] << 24) | ((uint32_t)data[offs + 2] << 16) |
((uint32_t)data[offs + 1] << 8) | (uint32_t)data[offs];
dap_write_word(addr + offs, value);
}
}
//-----------------------------------------------------------------------------
void dap_target_read_page(uint32_t addr, uint8_t *data)
{
for (int offs = 0; offs < TARGET_PAGE_SIZE; offs += sizeof(uint32_t))
{
uint32_t value = dap_read_word(addr + offs);
data[offs + 0] = (value >> 0) & 0xff;
data[offs + 1] = (value >> 8) & 0xff;
data[offs + 2] = (value >> 16) & 0xff;
data[offs + 3] = (value >> 24) & 0xff;
}
}