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.
 
 
 

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