DAP(Debug Access Port) interface
Dependents: USBMSD_LPC_HelloWorld lpcterm2 Simple-CMSIS-DAP 11u35_usbLocalFilesystem
TransferCore.cpp@0:76588be01e71, 2013-09-14 (annotated)
- Committer:
- va009039
- Date:
- Sat Sep 14 11:21:12 2013 +0000
- Revision:
- 0:76588be01e71
first commit
Who changed what in which revision?
User | Revision | Line number | New 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 | } |