Port of flash_cc2531 to FreeBSD. This is likely more just include a wiringPi compatible library for FreeBSD. Any new files are BSD licensed and NOT GPLv3 license.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

768 lines
14 KiB

  1. /***********************************************************************
  2. * Copyright (c) 2014-2016 Ioannis Charalampidis
  3. * Copyright (c) 2015 Simon Schulz - github.com/fishpepper
  4. Copyright © 2019 Jean Michault.
  5. This program is free software: you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation, either version 3 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program. If not, see <https://www.gnu.org/licenses/>.
  15. *************************************************************************/
  16. #include <wiringPi.h>
  17. #include <stdint.h>
  18. #include <stdio.h>
  19. #include <stdlib.h>
  20. #include <stdbool.h>
  21. #include <time.h>
  22. #include "CCDebugger.h"
  23. /**
  24. * Switch reset pin
  25. */
  26. void cc_setDDDirection( uint8_t direction );
  27. /**
  28. * Software-overridable instruction table that can be used
  29. * for supporting other CCDebug-Compatible chips purely by software
  30. */
  31. uint8_t instr[16];
  32. /**
  33. * Local properties
  34. */
  35. int pinRST=24;
  36. int pinDC=28;
  37. int pinDD=29;
  38. uint8_t errorFlag=0;
  39. uint8_t ddIsOutput=false;
  40. uint8_t inDebugMode=false;
  41. uint8_t cc_active=false;
  42. /**
  43. * Instruction table indices
  44. */
  45. #define INSTR_VERSION 0
  46. #define I_HALT 1
  47. #define I_RESUME 2
  48. #define I_RD_CONFIG 3
  49. #define I_WR_CONFIG 4
  50. #define I_DEBUG_INSTR_1 5
  51. #define I_DEBUG_INSTR_2 6
  52. #define I_DEBUG_INSTR_3 7
  53. #define I_GET_CHIP_ID 8
  54. #define I_GET_PC 9
  55. #define I_READ_STATUS 10
  56. #define I_STEP_INSTR 11
  57. #define I_CHIP_ERASE 12
  58. #define I_SET_HW_BRKPNT 13
  59. #define I_GET_BM 14
  60. #define I_BURST_WRITE 15
  61. int cc_init( int pRST, int pDC, int pDD )
  62. {
  63. if(wiringPiSetup() == -1){
  64. printf("no wiring pi detected\n");
  65. return 0;
  66. }
  67. pinRST=pRST;
  68. pinDC=pDC;
  69. pinDD=pDD;
  70. // Prepare CC Pins
  71. pinMode(pinDC, OUTPUT);
  72. pinMode(pinDD, OUTPUT);
  73. pinMode(pinRST, OUTPUT);
  74. digitalWrite(pinDC, LOW);
  75. digitalWrite(pinDD, LOW);
  76. digitalWrite(pinRST, LOW);
  77. // Prepare default direction
  78. cc_setDDDirection(INPUT);
  79. // Default CCDebug instruction set for CC254x
  80. instr[INSTR_VERSION] = 1;
  81. instr[I_HALT] = 0x40;
  82. instr[I_RESUME] = 0x48;
  83. instr[I_RD_CONFIG] = 0x20;
  84. instr[I_WR_CONFIG] = 0x18;
  85. instr[I_DEBUG_INSTR_1] = 0x51;
  86. instr[I_DEBUG_INSTR_2] = 0x52;
  87. instr[I_DEBUG_INSTR_3] = 0x53;
  88. instr[I_GET_CHIP_ID] = 0x68;
  89. instr[I_GET_PC] = 0x28;
  90. instr[I_READ_STATUS] = 0x30;
  91. instr[I_STEP_INSTR] = 0x58;
  92. instr[I_CHIP_ERASE] = 0x10;
  93. // We are active by default
  94. cc_active = true;
  95. };
  96. /**
  97. * Activate/Deactivate debugger
  98. */
  99. void cc_setActive( uint8_t on )
  100. {
  101. // Reset error flag
  102. errorFlag = CC_ERROR_NONE;
  103. // Continue only if active
  104. if (on == cc_active) return;
  105. cc_active = on;
  106. if (on) {
  107. // Prepare CC Pins
  108. pinMode(pinDC, OUTPUT);
  109. pinMode(pinDD, OUTPUT);
  110. pinMode(pinRST, OUTPUT);
  111. digitalWrite(pinDC, LOW);
  112. digitalWrite(pinDD, LOW);
  113. digitalWrite(pinRST, LOW);
  114. // Default direction is INPUT
  115. cc_setDDDirection(INPUT);
  116. } else {
  117. // Before deactivating, exit debug mode
  118. if (inDebugMode)
  119. cc_exit();
  120. // Put everything in inactive mode
  121. pinMode(pinDC, INPUT);
  122. pinMode(pinDD, INPUT);
  123. pinMode(pinRST, INPUT);
  124. digitalWrite(pinDC, LOW);
  125. digitalWrite(pinDD, LOW);
  126. digitalWrite(pinRST, LOW);
  127. }
  128. }
  129. /**
  130. * Return the error flag
  131. */
  132. uint8_t cc_error()
  133. {
  134. return errorFlag;
  135. }
  136. /////////////////////////////////////////////////////////////////////
  137. /////////////////////////////////////////////////////////////////////
  138. //// LOW LEVEL FUNCTIONS ////
  139. /////////////////////////////////////////////////////////////////////
  140. /////////////////////////////////////////////////////////////////////
  141. /**
  142. * Delay a particular number of cycles
  143. */
  144. struct timespec tp={0,0};
  145. void cc_delay( unsigned char d )
  146. {
  147. volatile unsigned char i = 50*d;
  148. while( i-- );
  149. //tp.tv_nsec=40*d;
  150. //nanosleep(&tp,NULL);
  151. }
  152. /**
  153. * Enter debug mode
  154. */
  155. uint8_t cc_enter()
  156. {
  157. if (!cc_active) {
  158. errorFlag = CC_ERROR_NOT_ACTIVE;
  159. return 0;
  160. }
  161. // =============
  162. // Reset error flag
  163. errorFlag = CC_ERROR_NONE;
  164. // Enter debug mode
  165. digitalWrite(pinRST, LOW);
  166. cc_delay(200);
  167. digitalWrite(pinDC, HIGH);
  168. cc_delay(3);
  169. digitalWrite(pinDC, LOW);
  170. cc_delay(3);
  171. digitalWrite(pinDC, HIGH);
  172. cc_delay(3);
  173. digitalWrite(pinDC, LOW);
  174. cc_delay(4);
  175. digitalWrite(pinRST, HIGH);
  176. cc_delay(200);
  177. // We are now in debug mode
  178. inDebugMode = 1;
  179. // =============
  180. // Success
  181. return 0;
  182. };
  183. /**
  184. * Write a uint8_t to the debugger
  185. */
  186. uint8_t cc_write( uint8_t data )
  187. {
  188. if (!cc_active) {
  189. errorFlag = CC_ERROR_NOT_ACTIVE;
  190. return 0;
  191. };
  192. if (!inDebugMode) {
  193. errorFlag = CC_ERROR_NOT_DEBUGGING;
  194. return 0;
  195. }
  196. // =============
  197. uint8_t cnt;
  198. // Make sure DD is on output
  199. cc_setDDDirection(OUTPUT);
  200. // Sent uint8_ts
  201. for (cnt = 8; cnt; cnt--) {
  202. // First put data bit on bus
  203. if (data & 0x80)
  204. digitalWrite(pinDD, HIGH);
  205. else
  206. digitalWrite(pinDD, LOW);
  207. // Place clock on high (other end reads data)
  208. digitalWrite(pinDC, HIGH);
  209. // Shift & Delay
  210. data <<= 1;
  211. cc_delay(2);
  212. // Place clock down
  213. digitalWrite(pinDC, LOW);
  214. cc_delay(2);
  215. }
  216. // =============
  217. return 0;
  218. }
  219. /**
  220. * Wait until input is ready for reading
  221. */
  222. uint8_t cc_switchRead(uint8_t maxWaitCycles)
  223. {
  224. if (!cc_active) {
  225. errorFlag = CC_ERROR_NOT_ACTIVE;
  226. return 0;
  227. }
  228. if (!inDebugMode) {
  229. errorFlag = CC_ERROR_NOT_DEBUGGING;
  230. return 0;
  231. }
  232. // =============
  233. uint8_t cnt;
  234. uint8_t didWait = 0;
  235. // Switch to input
  236. cc_setDDDirection(INPUT);
  237. // Wait at least 83 ns before checking state t(dir_change)
  238. cc_delay(2);
  239. // Wait for DD to go LOW (Chip is READY)
  240. while (digitalRead(pinDD) == HIGH) {
  241. // Do 8 clock cycles
  242. for (cnt = 8; cnt; cnt--) {
  243. digitalWrite(pinDC, HIGH);
  244. cc_delay(2);
  245. digitalWrite(pinDC, LOW);
  246. cc_delay(2);
  247. }
  248. // Let next function know that we did wait
  249. didWait = 1;
  250. // Check if we ran out if wait cycles
  251. if (!--maxWaitCycles) {
  252. // If we are waiting for too long, we have lost the chip,
  253. // so also assume we are out of debugging mode
  254. errorFlag = CC_ERROR_NOT_WIRED;
  255. inDebugMode = 0;
  256. return 0;
  257. }
  258. }
  259. // Wait t(sample_wait)
  260. if (didWait) cc_delay(2);
  261. // =============
  262. return 0;
  263. }
  264. /**
  265. * Switch to output
  266. */
  267. uint8_t cc_switchWrite()
  268. {
  269. cc_setDDDirection(OUTPUT);
  270. return 0;
  271. }
  272. /**
  273. * Read an input uint8_t
  274. */
  275. uint8_t cc_read()
  276. {
  277. if (!cc_active) {
  278. errorFlag = CC_ERROR_NOT_ACTIVE;
  279. return 0;
  280. }
  281. // =============
  282. uint8_t cnt;
  283. uint8_t data = 0;
  284. // Switch to input
  285. cc_setDDDirection(INPUT);
  286. // Send 8 clock pulses if we are HIGH
  287. for (cnt = 8; cnt; cnt--) {
  288. digitalWrite(pinDC, HIGH);
  289. cc_delay(2);
  290. // Shift and read
  291. data <<= 1;
  292. if (digitalRead(pinDD) == HIGH)
  293. data |= 0x01;
  294. digitalWrite(pinDC, LOW);
  295. cc_delay(2);
  296. }
  297. // =============
  298. return data;
  299. }
  300. /**
  301. * Switch reset pin
  302. */
  303. void cc_setDDDirection( uint8_t direction )
  304. {
  305. // Switch direction if changed
  306. if (direction == ddIsOutput) return;
  307. ddIsOutput = direction;
  308. // Handle new direction
  309. if (ddIsOutput) {
  310. digitalWrite(pinDD, LOW); // Disable pull-up
  311. pinMode(pinDD, OUTPUT); // Enable output
  312. digitalWrite(pinDD, LOW); // Switch to low
  313. } else {
  314. digitalWrite(pinDD, LOW); // Disable pull-up
  315. pinMode(pinDD, INPUT); // Disable output
  316. digitalWrite(pinDD, LOW); // Don't use output pull-up
  317. }
  318. }
  319. /////////////////////////////////////////////////////////////////////
  320. /////////////////////////////////////////////////////////////////////
  321. //// HIGH LEVEL FUNCTIONS ////
  322. /////////////////////////////////////////////////////////////////////
  323. /////////////////////////////////////////////////////////////////////
  324. /**
  325. * Exit from debug mode
  326. */
  327. uint8_t cc_exit()
  328. {
  329. if (!cc_active) {
  330. errorFlag = CC_ERROR_NOT_ACTIVE;
  331. return 0;
  332. }
  333. if (!inDebugMode) {
  334. errorFlag = CC_ERROR_NOT_DEBUGGING;
  335. return 0;
  336. }
  337. uint8_t bAns;
  338. cc_write( instr[I_RESUME] ); // RESUME
  339. cc_switchRead(250);
  340. bAns = cc_read(); // debug status
  341. cc_switchWrite();
  342. inDebugMode = 0;
  343. return 0;
  344. }
  345. /**
  346. * Get debug configuration
  347. */
  348. uint8_t cc_getConfig() {
  349. if (!cc_active) {
  350. errorFlag = CC_ERROR_NOT_ACTIVE;
  351. return 0;
  352. }
  353. if (!inDebugMode) {
  354. errorFlag = CC_ERROR_NOT_DEBUGGING;
  355. return 0;
  356. }
  357. uint8_t bAns;
  358. cc_write( instr[I_RD_CONFIG] ); // RD_CONFIG
  359. cc_switchRead(250);
  360. bAns = cc_read(); // Config
  361. cc_switchWrite();
  362. return bAns;
  363. }
  364. /**
  365. * Set debug configuration
  366. */
  367. uint8_t cc_setConfig( uint8_t config ) {
  368. if (!cc_active) {
  369. errorFlag = CC_ERROR_NOT_ACTIVE;
  370. return 0;
  371. }
  372. if (!inDebugMode) {
  373. errorFlag = CC_ERROR_NOT_DEBUGGING;
  374. return 0;
  375. }
  376. uint8_t bAns;
  377. cc_write( instr[I_WR_CONFIG] ); // WR_CONFIG
  378. cc_write( config );
  379. cc_switchRead(250);
  380. bAns = cc_read(); // Config
  381. cc_switchWrite();
  382. return bAns;
  383. }
  384. /**
  385. * Invoke a debug instruction with 1 opcode
  386. */
  387. uint8_t cc_exec( uint8_t oc0 )
  388. {
  389. if (!cc_active) {
  390. errorFlag = CC_ERROR_NOT_ACTIVE;
  391. return 0;
  392. }
  393. if (!inDebugMode) {
  394. errorFlag = CC_ERROR_NOT_DEBUGGING;
  395. return 0;
  396. }
  397. uint8_t bAns;
  398. cc_write( instr[I_DEBUG_INSTR_1] ); // DEBUG_INSTR + 1b
  399. cc_write( oc0 );
  400. cc_switchRead(250);
  401. bAns = cc_read(); // Accumulator
  402. cc_switchWrite();
  403. return bAns;
  404. }
  405. /**
  406. * Invoke a debug instruction with 2 opcodes
  407. */
  408. uint8_t cc_exec2( uint8_t oc0, uint8_t oc1 )
  409. {
  410. if (!cc_active) {
  411. errorFlag = CC_ERROR_NOT_ACTIVE;
  412. return 0;
  413. }
  414. if (!inDebugMode) {
  415. errorFlag = CC_ERROR_NOT_DEBUGGING;
  416. return 0;
  417. }
  418. uint8_t bAns;
  419. cc_write( instr[I_DEBUG_INSTR_2] ); // DEBUG_INSTR + 2b
  420. cc_write( oc0 );
  421. cc_write( oc1 );
  422. cc_switchRead(250);
  423. bAns = cc_read(); // Accumulator
  424. cc_switchWrite();
  425. return bAns;
  426. }
  427. /**
  428. * Invoke a debug instruction with 3 opcodes
  429. */
  430. uint8_t cc_exec3( uint8_t oc0, uint8_t oc1, uint8_t oc2 )
  431. {
  432. if (!cc_active) {
  433. errorFlag = CC_ERROR_NOT_ACTIVE;
  434. return 0;
  435. }
  436. if (!inDebugMode) {
  437. errorFlag = CC_ERROR_NOT_DEBUGGING;
  438. return 0;
  439. }
  440. uint8_t bAns;
  441. cc_write( instr[I_DEBUG_INSTR_3] ); // DEBUG_INSTR + 3b
  442. cc_write( oc0 );
  443. cc_write( oc1 );
  444. cc_write( oc2 );
  445. cc_switchRead(250);
  446. bAns = cc_read(); // Accumulator
  447. cc_switchWrite();
  448. return bAns;
  449. }
  450. /**
  451. * Invoke a debug instruction with 1 opcode + 16-bit immediate
  452. */
  453. uint8_t cc_execi( uint8_t oc0, unsigned short c0 )
  454. {
  455. if (!cc_active) {
  456. errorFlag = CC_ERROR_NOT_ACTIVE;
  457. return 0;
  458. }
  459. if (!inDebugMode) {
  460. errorFlag = CC_ERROR_NOT_DEBUGGING;
  461. return 0;
  462. }
  463. uint8_t bAns;
  464. cc_write( instr[I_DEBUG_INSTR_3] ); // DEBUG_INSTR + 3b
  465. cc_write( oc0 );
  466. cc_write( (c0 >> 8) & 0xFF );
  467. cc_write( c0 & 0xFF );
  468. cc_switchRead(250);
  469. bAns = cc_read(); // Accumulator
  470. cc_switchWrite();
  471. return bAns;
  472. }
  473. /**
  474. * Return chip ID
  475. */
  476. unsigned short cc_getChipID() {
  477. if (!cc_active) {
  478. errorFlag = CC_ERROR_NOT_ACTIVE;
  479. return 0;
  480. }
  481. if (!inDebugMode) {
  482. errorFlag = CC_ERROR_NOT_DEBUGGING;
  483. return 0;
  484. }
  485. unsigned short bAns;
  486. uint8_t bRes;
  487. cc_write( instr[I_GET_CHIP_ID] ); // GET_CHIP_ID
  488. cc_switchRead(250);
  489. bRes = cc_read(); // High order
  490. bAns = bRes << 8;
  491. bRes = cc_read(); // Low order
  492. bAns |= bRes;
  493. cc_switchWrite();
  494. return bAns;
  495. }
  496. /**
  497. * Return PC
  498. */
  499. unsigned short cc_getPC() {
  500. if (!cc_active) {
  501. errorFlag = CC_ERROR_NOT_ACTIVE;
  502. return 0;
  503. }
  504. if (!inDebugMode) {
  505. errorFlag = CC_ERROR_NOT_DEBUGGING;
  506. return 0;
  507. }
  508. unsigned short bAns;
  509. uint8_t bRes;
  510. cc_write( instr[I_GET_PC] ); // GET_PC
  511. cc_switchRead(250);
  512. bRes = cc_read(); // High order
  513. bAns = bRes << 8;
  514. bRes = cc_read(); // Low order
  515. bAns |= bRes;
  516. cc_switchWrite();
  517. return bAns;
  518. }
  519. /**
  520. * Return debug status
  521. */
  522. uint8_t cc_getStatus() {
  523. if (!cc_active) {
  524. errorFlag = CC_ERROR_NOT_ACTIVE;
  525. return 0;
  526. }
  527. if (!inDebugMode) {
  528. errorFlag = CC_ERROR_NOT_DEBUGGING;
  529. return 0;
  530. }
  531. uint8_t bAns;
  532. cc_write( instr[I_READ_STATUS] ); // READ_STATUS
  533. cc_switchRead(250);
  534. bAns = cc_read(); // debug status
  535. cc_switchWrite();
  536. return bAns;
  537. }
  538. /**
  539. * Step instruction
  540. */
  541. uint8_t cc_step() {
  542. if (!cc_active) {
  543. errorFlag = CC_ERROR_NOT_ACTIVE;
  544. return 0;
  545. }
  546. if (!inDebugMode) {
  547. errorFlag = CC_ERROR_NOT_DEBUGGING;
  548. return 0;
  549. }
  550. uint8_t bAns;
  551. cc_write( instr[I_STEP_INSTR] ); // STEP_INSTR
  552. cc_switchRead(250);
  553. bAns = cc_read(); // Accumulator
  554. cc_switchWrite();
  555. return bAns;
  556. }
  557. /**
  558. * resume instruction
  559. */
  560. uint8_t cc_resume() {
  561. if (!cc_active) {
  562. errorFlag = CC_ERROR_NOT_ACTIVE;
  563. return 0;
  564. }
  565. if (!inDebugMode) {
  566. errorFlag = CC_ERROR_NOT_DEBUGGING;
  567. return 0;
  568. }
  569. uint8_t bAns;
  570. cc_write( instr[I_RESUME] ); //RESUME
  571. cc_switchRead(250);
  572. bAns = cc_read(); // Accumulator
  573. cc_switchWrite();
  574. return bAns;
  575. }
  576. /**
  577. * halt instruction
  578. */
  579. uint8_t cc_halt() {
  580. if (!cc_active) {
  581. errorFlag = CC_ERROR_NOT_ACTIVE;
  582. return 0;
  583. }
  584. if (!inDebugMode) {
  585. errorFlag = CC_ERROR_NOT_DEBUGGING;
  586. return 0;
  587. }
  588. uint8_t bAns;
  589. cc_write( instr[I_HALT] ); //HALT
  590. cc_switchRead(250);
  591. bAns = cc_read(); // Accumulator
  592. cc_switchWrite();
  593. return bAns;
  594. }
  595. /**
  596. * Mass-erase all chip configuration & Lock Bits
  597. */
  598. uint8_t cc_chipErase()
  599. {
  600. if (!cc_active) {
  601. errorFlag = CC_ERROR_NOT_ACTIVE;
  602. return 0;
  603. };
  604. if (!inDebugMode) {
  605. errorFlag = CC_ERROR_NOT_DEBUGGING;
  606. return 0;
  607. }
  608. uint8_t bAns;
  609. cc_write( instr[I_CHIP_ERASE] ); // CHIP_ERASE
  610. cc_switchRead(250);
  611. bAns = cc_read(); // Debug status
  612. cc_switchWrite();
  613. return bAns;
  614. }
  615. /**
  616. * Update the debug instruction table
  617. */
  618. uint8_t cc_updateInstructionTable( uint8_t newTable[16] )
  619. {
  620. // Copy table entries
  621. for (uint8_t i=0; i<16; i++)
  622. instr[i] = newTable[i];
  623. // Return the new version
  624. return instr[INSTR_VERSION];
  625. }
  626. /**
  627. * Get the instruction table version
  628. */
  629. uint8_t cc_getInstructionTableVersion()
  630. {
  631. // Return version of instruction table
  632. return instr[INSTR_VERSION];
  633. }