DAP(Debug Access Port) interface

Dependents:   USBMSD_LPC_HelloWorld lpcterm2 Simple-CMSIS-DAP 11u35_usbLocalFilesystem

Committer:
va009039
Date:
Sat Sep 14 11:21:12 2013 +0000
Revision:
0:76588be01e71
first commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
va009039 0:76588be01e71 1 // TransferCore.cpp 2013/9/14
va009039 0:76588be01e71 2 #include "TransferCore.h"
va009039 0:76588be01e71 3
va009039 0:76588be01e71 4 void transData::init(uint8_t* base, int pos)
va009039 0:76588be01e71 5 {
va009039 0:76588be01e71 6 _base = base;
va009039 0:76588be01e71 7 _pos = pos;
va009039 0:76588be01e71 8 }
va009039 0:76588be01e71 9
va009039 0:76588be01e71 10 void transData::append(uint32_t data)
va009039 0:76588be01e71 11 {
va009039 0:76588be01e71 12 ST<uint32_t>(_base+_pos, data);
va009039 0:76588be01e71 13 _pos += sizeof(uint32_t);
va009039 0:76588be01e71 14 }
va009039 0:76588be01e71 15
va009039 0:76588be01e71 16 uint8_t* transData::data()
va009039 0:76588be01e71 17 {
va009039 0:76588be01e71 18 return _base;
va009039 0:76588be01e71 19 }
va009039 0:76588be01e71 20
va009039 0:76588be01e71 21 int transData::length()
va009039 0:76588be01e71 22 {
va009039 0:76588be01e71 23 return _pos;
va009039 0:76588be01e71 24 }
va009039 0:76588be01e71 25
va009039 0:76588be01e71 26 int TransferCore::Transfer(SWD* swd, uint8_t* request, uint8_t* response) // 0x05
va009039 0:76588be01e71 27 {
va009039 0:76588be01e71 28 _swd = swd;
va009039 0:76588be01e71 29 reqData.init(request, 2);
va009039 0:76588be01e71 30 resData.init(response, 3);
va009039 0:76588be01e71 31 post_read = check_write = false;
va009039 0:76588be01e71 32 response_count = 0;
va009039 0:76588be01e71 33 uint8_t ack = 0;
va009039 0:76588be01e71 34 for(int count = reqData.get<uint8_t>(); count > 0; count--) {
va009039 0:76588be01e71 35 uint8_t cmd = reqData.get<uint8_t>();
va009039 0:76588be01e71 36 if (cmd & SWD_RnW) { // read register
va009039 0:76588be01e71 37 ack = read(cmd);
va009039 0:76588be01e71 38 check_write = false;
va009039 0:76588be01e71 39 } else { // write register
va009039 0:76588be01e71 40 ack = write(cmd);
va009039 0:76588be01e71 41 }
va009039 0:76588be01e71 42 if (ack != SWD_OK) {
va009039 0:76588be01e71 43 break;
va009039 0:76588be01e71 44 }
va009039 0:76588be01e71 45 response_count++;
va009039 0:76588be01e71 46 }
va009039 0:76588be01e71 47 if (ack == SWD_OK) {
va009039 0:76588be01e71 48 if (post_read) { // read previous data
va009039 0:76588be01e71 49 uint32_t data;
va009039 0:76588be01e71 50 ack = _swd->Transfer(DP_RDBUFF, &data);
va009039 0:76588be01e71 51 resData.append(data);
va009039 0:76588be01e71 52 } else if (check_write) { // check last write
va009039 0:76588be01e71 53 ack = _swd->Transfer(DP_RDBUFF, NULL);
va009039 0:76588be01e71 54 }
va009039 0:76588be01e71 55 }
va009039 0:76588be01e71 56 resData.data()[0] = 0x05; // transfer
va009039 0:76588be01e71 57 resData.data()[1] = response_count;
va009039 0:76588be01e71 58 resData.data()[2] = ack;
va009039 0:76588be01e71 59 return resData.length();
va009039 0:76588be01e71 60 }
va009039 0:76588be01e71 61
va009039 0:76588be01e71 62 uint8_t TransferCore::read(uint8_t cmd)
va009039 0:76588be01e71 63 {
va009039 0:76588be01e71 64 uint8_t ack = 0;
va009039 0:76588be01e71 65 uint32_t data;
va009039 0:76588be01e71 66 if (post_read) {
va009039 0:76588be01e71 67 if ((cmd & SWD_APnDP) && !(cmd & DAP_TRANSFER_MATCH_VALUE)) {
va009039 0:76588be01e71 68 ack = _swd->Transfer(cmd, &data); // next post_read
va009039 0:76588be01e71 69 } else {
va009039 0:76588be01e71 70 ack = _swd->Transfer(DP_RDBUFF, &data);
va009039 0:76588be01e71 71 post_read = false;
va009039 0:76588be01e71 72 }
va009039 0:76588be01e71 73 if (ack != SWD_OK) {
va009039 0:76588be01e71 74 return ack;
va009039 0:76588be01e71 75 }
va009039 0:76588be01e71 76 resData.append(data);
va009039 0:76588be01e71 77 }
va009039 0:76588be01e71 78 if (cmd & DAP_TRANSFER_MATCH_VALUE) {
va009039 0:76588be01e71 79 uint32_t match_value = reqData.get<uint32_t>();
va009039 0:76588be01e71 80 if (cmd & SWD_APnDP) {
va009039 0:76588be01e71 81 ack = _swd->Transfer(cmd, NULL);
va009039 0:76588be01e71 82 if (ack != SWD_OK) {
va009039 0:76588be01e71 83 return ack;
va009039 0:76588be01e71 84 }
va009039 0:76588be01e71 85 }
va009039 0:76588be01e71 86 for(int retry = match_retry; retry >= 0; retry--) {
va009039 0:76588be01e71 87 ack = _swd->Transfer(cmd, &data);
va009039 0:76588be01e71 88 if (ack == SWD_OK && (data&match_mask) == match_value) {
va009039 0:76588be01e71 89 return ack;
va009039 0:76588be01e71 90 }
va009039 0:76588be01e71 91 }
va009039 0:76588be01e71 92 return ack | DAP_TRANSFER_MISMATCH;
va009039 0:76588be01e71 93 } else {
va009039 0:76588be01e71 94 if (cmd & SWD_APnDP) {
va009039 0:76588be01e71 95 if (post_read == false) {
va009039 0:76588be01e71 96 ack = _swd->Transfer(cmd, NULL);
va009039 0:76588be01e71 97 post_read = true;
va009039 0:76588be01e71 98 }
va009039 0:76588be01e71 99 } else {
va009039 0:76588be01e71 100 ack = _swd->Transfer(cmd, &data);
va009039 0:76588be01e71 101 resData.append(data);
va009039 0:76588be01e71 102 }
va009039 0:76588be01e71 103 }
va009039 0:76588be01e71 104 return ack;
va009039 0:76588be01e71 105 }
va009039 0:76588be01e71 106
va009039 0:76588be01e71 107 uint8_t TransferCore::write(uint8_t cmd)
va009039 0:76588be01e71 108 {
va009039 0:76588be01e71 109 if (post_read) { // read previous data
va009039 0:76588be01e71 110 uint32_t data;
va009039 0:76588be01e71 111 uint8_t ack = _swd->Transfer(DP_RDBUFF, &data);
va009039 0:76588be01e71 112 if (ack != SWD_OK) {
va009039 0:76588be01e71 113 return ack;
va009039 0:76588be01e71 114 }
va009039 0:76588be01e71 115 resData.append(data);
va009039 0:76588be01e71 116 post_read = false;
va009039 0:76588be01e71 117 }
va009039 0:76588be01e71 118 if (cmd & DAP_TRANSFER_MATCH_MASK) {
va009039 0:76588be01e71 119 match_mask = reqData.get<uint32_t>();
va009039 0:76588be01e71 120 return SWD_OK;
va009039 0:76588be01e71 121 }
va009039 0:76588be01e71 122 check_write = true;
va009039 0:76588be01e71 123 uint32_t data = reqData.get<uint32_t>();
va009039 0:76588be01e71 124 return _swd->Transfer(cmd, &data);
va009039 0:76588be01e71 125 }
va009039 0:76588be01e71 126
va009039 0:76588be01e71 127 int TransferCore::TransferBlock(SWD* swd, uint8_t* request, uint8_t* response)
va009039 0:76588be01e71 128 {
va009039 0:76588be01e71 129 _swd = swd;
va009039 0:76588be01e71 130 reqData.init(request, 2);
va009039 0:76588be01e71 131 resData.init(response, 4);
va009039 0:76588be01e71 132 uint8_t ack = 0;
va009039 0:76588be01e71 133 response_count = 0;
va009039 0:76588be01e71 134 int count = reqData.get<uint16_t>();
va009039 0:76588be01e71 135 if (count > 0) {
va009039 0:76588be01e71 136 uint8_t cmd = reqData.get<uint8_t>();
va009039 0:76588be01e71 137 if (cmd & SWD_RnW) { // read register block
va009039 0:76588be01e71 138 ack = read_block(cmd, count);
va009039 0:76588be01e71 139 } else { // write register block
va009039 0:76588be01e71 140 ack = write_block(cmd, count);
va009039 0:76588be01e71 141 }
va009039 0:76588be01e71 142 }
va009039 0:76588be01e71 143 resData.data()[0] = 0x06; // transfer block
va009039 0:76588be01e71 144 ST<uint16_t>(resData.data()+1, response_count);
va009039 0:76588be01e71 145 resData.data()[3] = ack;
va009039 0:76588be01e71 146 return resData.length();
va009039 0:76588be01e71 147 }
va009039 0:76588be01e71 148
va009039 0:76588be01e71 149 uint8_t TransferCore::read_block(uint8_t cmd, int count)
va009039 0:76588be01e71 150 {
va009039 0:76588be01e71 151 if (cmd & SWD_APnDP) { // post AP read
va009039 0:76588be01e71 152 uint8_t ack = _swd->Transfer(cmd, NULL);
va009039 0:76588be01e71 153 if (ack != SWD_OK) {
va009039 0:76588be01e71 154 return ack;
va009039 0:76588be01e71 155 }
va009039 0:76588be01e71 156 }
va009039 0:76588be01e71 157 uint8_t ack = 0;
va009039 0:76588be01e71 158 while(count-- > 0) { // read DP/AP register
va009039 0:76588be01e71 159 if (count == 0 && (cmd & SWD_APnDP)) { // last AP read
va009039 0:76588be01e71 160 cmd = DP_RDBUFF;
va009039 0:76588be01e71 161 }
va009039 0:76588be01e71 162 uint32_t data;
va009039 0:76588be01e71 163 ack = _swd->Transfer(cmd, &data);
va009039 0:76588be01e71 164 if (ack != SWD_OK) {
va009039 0:76588be01e71 165 break;
va009039 0:76588be01e71 166 }
va009039 0:76588be01e71 167 resData.append(data);
va009039 0:76588be01e71 168 response_count++;
va009039 0:76588be01e71 169 }
va009039 0:76588be01e71 170 return ack;
va009039 0:76588be01e71 171 }
va009039 0:76588be01e71 172
va009039 0:76588be01e71 173 uint8_t TransferCore::write_block(uint8_t cmd, int count)
va009039 0:76588be01e71 174 {
va009039 0:76588be01e71 175 while(count-- > 0) {
va009039 0:76588be01e71 176 uint32_t data = reqData.get<uint32_t>();
va009039 0:76588be01e71 177 uint8_t ack = _swd->Transfer(cmd, &data);
va009039 0:76588be01e71 178 if (ack != SWD_OK) {
va009039 0:76588be01e71 179 return ack;
va009039 0:76588be01e71 180 }
va009039 0:76588be01e71 181 response_count++;
va009039 0:76588be01e71 182 }
va009039 0:76588be01e71 183 return _swd->Transfer(DP_RDBUFF, NULL);
va009039 0:76588be01e71 184 }