Arrow / Mbed OS DAPLink Reset
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers SW_DP.c Source File

SW_DP.c

00001 /*
00002  * Copyright (c) 2013-2017 ARM Limited. All rights reserved.
00003  *
00004  * SPDX-License-Identifier: Apache-2.0
00005  *
00006  * Licensed under the Apache License, Version 2.0 (the License); you may
00007  * not use this file except in compliance with the License.
00008  * You may obtain a copy of the License at
00009  *
00010  * www.apache.org/licenses/LICENSE-2.0
00011  *
00012  * Unless required by applicable law or agreed to in writing, software
00013  * distributed under the License is distributed on an AS IS BASIS, WITHOUT
00014  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00015  * See the License for the specific language governing permissions and
00016  * limitations under the License.
00017  *
00018  * ----------------------------------------------------------------------
00019  *
00020  * $Date:        1. December 2017
00021  * $Revision:    V2.0.0
00022  *
00023  * Project:      CMSIS-DAP Source
00024  * Title:        SW_DP.c CMSIS-DAP SW DP I/O
00025  *
00026  *---------------------------------------------------------------------------*/
00027 
00028 #include "DAP_config.h"
00029 #include "DAP.h"
00030 
00031 
00032 // SW Macros
00033 
00034 #define PIN_SWCLK_SET PIN_SWCLK_TCK_SET
00035 #define PIN_SWCLK_CLR PIN_SWCLK_TCK_CLR
00036 
00037 #define SW_CLOCK_CYCLE()                \
00038   PIN_SWCLK_CLR();                      \
00039   PIN_DELAY();                          \
00040   PIN_SWCLK_SET();                      \
00041   PIN_DELAY()
00042 
00043 #define SW_WRITE_BIT(bit)               \
00044   PIN_SWDIO_OUT(bit);                   \
00045   PIN_SWCLK_CLR();                      \
00046   PIN_DELAY();                          \
00047   PIN_SWCLK_SET();                      \
00048   PIN_DELAY()
00049 
00050 #define SW_READ_BIT(bit)                \
00051   PIN_SWCLK_CLR();                      \
00052   PIN_DELAY();                          \
00053   bit = PIN_SWDIO_IN();                 \
00054   PIN_SWCLK_SET();                      \
00055   PIN_DELAY()
00056 
00057 #define PIN_DELAY() PIN_DELAY_SLOW(DAP_Data.clock_delay)
00058 
00059 
00060 // Generate SWJ Sequence
00061 //   count:  sequence bit count
00062 //   data:   pointer to sequence bit data
00063 //   return: none
00064 #if ((DAP_SWD != 0) || (DAP_JTAG != 0))
00065 void SWJ_Sequence (uint32_t count, const uint8_t *data) {
00066   uint32_t val;
00067   uint32_t n;
00068 
00069   val = 0U;
00070   n = 0U;
00071   while (count--) {
00072     if (n == 0U) {
00073       val = *data++;
00074       n = 8U;
00075     }
00076     if (val & 1U) {
00077       PIN_SWDIO_TMS_SET();
00078     } else {
00079       PIN_SWDIO_TMS_CLR();
00080     }
00081     SW_CLOCK_CYCLE();
00082     val >>= 1;
00083     n--;
00084   }
00085 }
00086 #endif
00087 
00088 
00089 // Generate SWD Sequence
00090 //   info:   sequence information
00091 //   swdo:   pointer to SWDIO generated data
00092 //   swdi:   pointer to SWDIO captured data
00093 //   return: none
00094 #if (DAP_SWD != 0)
00095 void SWD_Sequence (uint32_t info, const uint8_t *swdo, uint8_t *swdi) {
00096   uint32_t val;
00097   uint32_t bit;
00098   uint32_t n, k;
00099 
00100   n = info & SWD_SEQUENCE_CLK;
00101   if (n == 0U) {
00102     n = 64U;
00103   }
00104 
00105   if (info & SWD_SEQUENCE_DIN) {
00106     while (n) {
00107       val = 0U;
00108       for (k = 8U; k && n; k--, n--) {
00109         SW_READ_BIT(bit);
00110         val >>= 1;
00111         val  |= bit << 7;
00112       }
00113       val >>= k;
00114       *swdi++ = (uint8_t)val;
00115     }
00116   } else {
00117     while (n) {
00118       val = *swdo++;
00119       for (k = 8U; k && n; k--, n--) {
00120         SW_WRITE_BIT(val);
00121         val >>= 1;
00122       }
00123     }
00124   }
00125 }
00126 #endif
00127 
00128 
00129 #if (DAP_SWD != 0)
00130 
00131 
00132 // SWD Transfer I/O
00133 //   request: A[3:2] RnW APnDP
00134 //   data:    DATA[31:0]
00135 //   return:  ACK[2:0]
00136 #define SWD_TransferFunction(speed)     /**/                                    \
00137 static uint8_t SWD_Transfer##speed (uint32_t request, uint32_t *data) {         \
00138   uint32_t ack;                                                                 \
00139   uint32_t bit;                                                                 \
00140   uint32_t val;                                                                 \
00141   uint32_t parity;                                                              \
00142                                                                                 \
00143   uint32_t n;                                                                   \
00144                                                                                 \
00145   /* Packet Request */                                                          \
00146   parity = 0U;                                                                  \
00147   SW_WRITE_BIT(1U);                     /* Start Bit */                         \
00148   bit = request >> 0;                                                           \
00149   SW_WRITE_BIT(bit);                    /* APnDP Bit */                         \
00150   parity += bit;                                                                \
00151   bit = request >> 1;                                                           \
00152   SW_WRITE_BIT(bit);                    /* RnW Bit */                           \
00153   parity += bit;                                                                \
00154   bit = request >> 2;                                                           \
00155   SW_WRITE_BIT(bit);                    /* A2 Bit */                            \
00156   parity += bit;                                                                \
00157   bit = request >> 3;                                                           \
00158   SW_WRITE_BIT(bit);                    /* A3 Bit */                            \
00159   parity += bit;                                                                \
00160   SW_WRITE_BIT(parity);                 /* Parity Bit */                        \
00161   SW_WRITE_BIT(0U);                     /* Stop Bit */                          \
00162   SW_WRITE_BIT(1U);                     /* Park Bit */                          \
00163                                                                                 \
00164   /* Turnaround */                                                              \
00165   PIN_SWDIO_OUT_DISABLE();                                                      \
00166   for (n = DAP_Data.swd_conf.turnaround; n; n--) {                              \
00167     SW_CLOCK_CYCLE();                                                           \
00168   }                                                                             \
00169                                                                                 \
00170   /* Acknowledge response */                                                    \
00171   SW_READ_BIT(bit);                                                             \
00172   ack  = bit << 0;                                                              \
00173   SW_READ_BIT(bit);                                                             \
00174   ack |= bit << 1;                                                              \
00175   SW_READ_BIT(bit);                                                             \
00176   ack |= bit << 2;                                                              \
00177                                                                                 \
00178   if (ack == DAP_TRANSFER_OK) {         /* OK response */                       \
00179     /* Data transfer */                                                         \
00180     if (request & DAP_TRANSFER_RnW) {                                           \
00181       /* Read data */                                                           \
00182       val = 0U;                                                                 \
00183       parity = 0U;                                                              \
00184       for (n = 32U; n; n--) {                                                   \
00185         SW_READ_BIT(bit);               /* Read RDATA[0:31] */                  \
00186         parity += bit;                                                          \
00187         val >>= 1;                                                              \
00188         val  |= bit << 31;                                                      \
00189       }                                                                         \
00190       SW_READ_BIT(bit);                 /* Read Parity */                       \
00191       if ((parity ^ bit) & 1U) {                                                \
00192         ack = DAP_TRANSFER_ERROR;                                               \
00193       }                                                                         \
00194       if (data) { *data = val; }                                                \
00195       /* Turnaround */                                                          \
00196       for (n = DAP_Data.swd_conf.turnaround; n; n--) {                          \
00197         SW_CLOCK_CYCLE();                                                       \
00198       }                                                                         \
00199       PIN_SWDIO_OUT_ENABLE();                                                   \
00200     } else {                                                                    \
00201       /* Turnaround */                                                          \
00202       for (n = DAP_Data.swd_conf.turnaround; n; n--) {                          \
00203         SW_CLOCK_CYCLE();                                                       \
00204       }                                                                         \
00205       PIN_SWDIO_OUT_ENABLE();                                                   \
00206       /* Write data */                                                          \
00207       val = *data;                                                              \
00208       parity = 0U;                                                              \
00209       for (n = 32U; n; n--) {                                                   \
00210         SW_WRITE_BIT(val);              /* Write WDATA[0:31] */                 \
00211         parity += val;                                                          \
00212         val >>= 1;                                                              \
00213       }                                                                         \
00214       SW_WRITE_BIT(parity);             /* Write Parity Bit */                  \
00215     }                                                                           \
00216     /* Capture Timestamp */                                                     \
00217     if (request & DAP_TRANSFER_TIMESTAMP) {                                     \
00218       DAP_Data.timestamp = TIMESTAMP_GET();                                     \
00219     }                                                                           \
00220     /* Idle cycles */                                                           \
00221     n = DAP_Data.transfer.idle_cycles;                                          \
00222     if (n) {                                                                    \
00223       PIN_SWDIO_OUT(0U);                                                        \
00224       for (; n; n--) {                                                          \
00225         SW_CLOCK_CYCLE();                                                       \
00226       }                                                                         \
00227     }                                                                           \
00228     PIN_SWDIO_OUT(1U);                                                          \
00229     return ((uint8_t)ack);                                                      \
00230   }                                                                             \
00231                                                                                 \
00232   if ((ack == DAP_TRANSFER_WAIT) || (ack == DAP_TRANSFER_FAULT)) {              \
00233     /* WAIT or FAULT response */                                                \
00234     if (DAP_Data.swd_conf.data_phase && ((request & DAP_TRANSFER_RnW) != 0U)) { \
00235       for (n = 32U+1U; n; n--) {                                                \
00236         SW_CLOCK_CYCLE();               /* Dummy Read RDATA[0:31] + Parity */   \
00237       }                                                                         \
00238     }                                                                           \
00239     /* Turnaround */                                                            \
00240     for (n = DAP_Data.swd_conf.turnaround; n; n--) {                            \
00241       SW_CLOCK_CYCLE();                                                         \
00242     }                                                                           \
00243     PIN_SWDIO_OUT_ENABLE();                                                     \
00244     if (DAP_Data.swd_conf.data_phase && ((request & DAP_TRANSFER_RnW) == 0U)) { \
00245       PIN_SWDIO_OUT(0U);                                                        \
00246       for (n = 32U+1U; n; n--) {                                                \
00247         SW_CLOCK_CYCLE();               /* Dummy Write WDATA[0:31] + Parity */  \
00248       }                                                                         \
00249     }                                                                           \
00250     PIN_SWDIO_OUT(1U);                                                          \
00251     return ((uint8_t)ack);                                                      \
00252   }                                                                             \
00253                                                                                 \
00254   /* Protocol error */                                                          \
00255   for (n = DAP_Data.swd_conf.turnaround + 32U + 1U; n; n--) {                   \
00256     SW_CLOCK_CYCLE();                   /* Back off data phase */               \
00257   }                                                                             \
00258   PIN_SWDIO_OUT_ENABLE();                                                       \
00259   PIN_SWDIO_OUT(1U);                                                            \
00260   return ((uint8_t)ack);                                                        \
00261 }
00262 
00263 
00264 #undef  PIN_DELAY
00265 #define PIN_DELAY() PIN_DELAY_FAST()
00266 SWD_TransferFunction(Fast)
00267 
00268 #undef  PIN_DELAY
00269 #define PIN_DELAY() PIN_DELAY_SLOW(DAP_Data.clock_delay)
00270 SWD_TransferFunction(Slow)
00271 
00272 
00273 // SWD Transfer I/O
00274 //   request: A[3:2] RnW APnDP
00275 //   data:    DATA[31:0]
00276 //   return:  ACK[2:0]
00277 uint8_t  SWD_Transfer(uint32_t request, uint32_t *data) {
00278   if (DAP_Data.fast_clock) {
00279     return SWD_TransferFast(request, data);
00280   } else {
00281     return SWD_TransferSlow(request, data);
00282   }
00283 }
00284 
00285 
00286 #endif  /* (DAP_SWD != 0) */