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.
 
 
 

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