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.
Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.
 
 
 

379 rader
11 KiB

  1. /***********************************************************************
  2. Copyright © 2019 Jean Michault.
  3. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation, either version 3 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program. If not, see <https://www.gnu.org/licenses/>.
  13. *************************************************************************/
  14. #include <wiringPi.h>
  15. #include <stdlib.h>
  16. #include <stdio.h>
  17. #include <stdbool.h>
  18. #include <string.h>
  19. #include <stdint.h>
  20. #include <unistd.h>
  21. #include "CCDebugger.h"
  22. uint8_t buffer[601];
  23. uint8_t data[260];
  24. uint8_t buf1[1024];
  25. uint8_t buf2[1024];
  26. struct page
  27. {
  28. uint32_t minoffset,maxoffset;
  29. uint8_t datas[2048];
  30. } Pages[128];
  31. void readXDATA(uint16_t offset,uint8_t *bytes, int len)
  32. {
  33. cc_execi(0x90, offset ); //MOV DPTR,#data16
  34. for ( int i=0 ; i<len;i++)
  35. {
  36. bytes[i] = cc_exec(0xE0); //MOVX A,@DPTR
  37. cc_exec(0xA3); // INC DPTR
  38. }
  39. }
  40. void writeXDATA(uint16_t offset,uint8_t *bytes, int len)
  41. {
  42. cc_execi(0x90,offset); //MOV DPTR,#data16
  43. for ( int i=0 ; i<len;i++)
  44. {
  45. cc_exec2(0x74,bytes[i]); // MOV A,#data
  46. cc_exec(0xF0); //MOVX @DPTR,A
  47. cc_exec(0xA3); // INC DPTR
  48. }
  49. }
  50. void readPage(int page,uint8_t *buf)
  51. {
  52. uint8_t bank=page>>4;
  53. // get FMAP
  54. uint8_t res = cc_exec2(0xE5, 0xC7);
  55. // select bank
  56. res = (res & 0xF8) | (bank & 0x07);
  57. res = cc_exec3(0x75, 0xC7, res); // MOV direct,#data
  58. // calculer l'adresse de destination
  59. uint32_t offset = ((page&0xf)<<11) + Pages[page].minoffset;
  60. // Setup DPTR
  61. cc_execi( 0x90, 0x8000+offset ); // MOV DPTR,#data16
  62. for(int i=Pages[page].minoffset ; i<=Pages[page].maxoffset ;i++)
  63. {
  64. res = cc_exec ( 0xE0 ); // MOVX A,@DPTR
  65. buf[i] = res;
  66. res = cc_exec ( 0xA3 ); // INC DPTR
  67. }
  68. }
  69. uint8_t verif1[2048];
  70. uint8_t verif2[2048];
  71. int verifPage(int page)
  72. {
  73. do
  74. {
  75. readPage(page,verif1);
  76. readPage(page,verif2);
  77. } while (memcmp(verif1,verif2,2048));
  78. for(int i=Pages[page].minoffset ; i<=Pages[page].maxoffset ;i++)
  79. {
  80. if(verif1[i] != Pages[page].datas[i])
  81. {
  82. printf("\nerror at 0x%x, 0x%x instead of 0x%x\n",i,verif1[i],Pages[page].datas[i]);
  83. return 1;
  84. }
  85. }
  86. return 0;
  87. }
  88. int writePage(int page)
  89. {
  90. uint8_t bank=page>>4;
  91. // get FMAP
  92. uint8_t res = cc_exec2(0xE5, 0xC7);
  93. // select bank
  94. res = (res & 0xF8) | (bank & 0x07);
  95. res = cc_exec3(0x75, 0xC7, res); // MOV direct,#data
  96. // calculer l'adresse de destination
  97. // round minoffset because FADDR is a word address
  98. Pages[page].minoffset = (Pages[page].minoffset & 0xfffffffc);
  99. // round maxoffset to write entire words
  100. Pages[page].maxoffset = (Pages[page].maxoffset |0x3);
  101. uint32_t offset = ((page&0xf)<<11) + Pages[page].minoffset;
  102. uint32_t len = Pages[page].maxoffset-Pages[page].minoffset+1;
  103. //FIXME : sometimes incorrect length is wrote
  104. //if(len&0xf && (Pages[page].minoffset+len<2032)) len= (len&0x7f0)+16;
  105. // configure DMA-0 pour DEBUG --> RAM
  106. uint8_t dma_desc0[8];
  107. dma_desc0[0] = 0x62;// src[15:8]
  108. dma_desc0[1] = 0x60;// src[7:0]
  109. dma_desc0[2] = 0x00;// dest[15:8]
  110. dma_desc0[3] = 0x00;// dest[7:0]
  111. dma_desc0[4] = (len>>8)&0xff;
  112. dma_desc0[5] = (len&0xff);
  113. dma_desc0[6] = 0x1f; //wordsize=0,tmode=0,trig=0x1F
  114. dma_desc0[7] = 0x19;//srcinc=0,destinc=1,irqmask=1,m8=0,priority=1
  115. writeXDATA( 0x1000, dma_desc0, 8 );
  116. cc_exec3( 0x75, 0xD4, 0x00);
  117. cc_exec3( 0x75, 0xD5, 0x10);
  118. // configure DMA-1 pour RAM --> FLASH
  119. uint8_t dma_desc1[8];
  120. dma_desc1[0] = 0x00;// src[15:8]
  121. dma_desc1[1] = 0x00;// src[7:0]
  122. dma_desc1[2] = 0x62;// dest[15:8]
  123. dma_desc1[3] = 0x73;// dest[7:0]
  124. dma_desc1[4] = (len>>8)&0xff;
  125. dma_desc1[5] = (len&0xff);
  126. dma_desc1[6] = 0x12; //wordsize=0,tmode=0,trig=0x12
  127. dma_desc1[7] = 0x42;//srcinc=1,destinc=0,irqmask=1,m8=0,priority=2
  128. writeXDATA( 0x1008, dma_desc1, 8 );
  129. cc_exec3( 0x75, 0xD2, 0x08);
  130. cc_exec3( 0x75, 0xD3, 0x10);
  131. // clear flash status
  132. readXDATA(0x6270, &res, 1);
  133. res &=0x1F;
  134. writeXDATA(0x6270, &res, 1);
  135. // clear DMAIRQ 0 et 1
  136. res = cc_exec2(0xE5, 0xD1);
  137. res &= ~1;
  138. res &= ~2;
  139. cc_exec3(0x75,0xD1,res);
  140. // disarm DMA Channel 0 et 1
  141. res = cc_exec2(0xE5, 0xD6);
  142. res &= ~1;
  143. res &= ~2;
  144. cc_exec3(0x75,0xD6,res);
  145. // Upload to RAM through DMA-0
  146. // arm DMA channel 0 :
  147. res = cc_exec2(0xE5, 0xD6);
  148. res |= 1;
  149. cc_exec3(0x75,0xD6,res);
  150. cc_delay(200);
  151. // transfert de données en mode burst
  152. cc_write(0x80|( (len>>8)&0x7) );
  153. cc_write(len&0xff);
  154. for(int i=0 ; i<len ;i++)
  155. cc_write(Pages[page].datas[i+Pages[page].minoffset]);
  156. // wait DMA end :
  157. do
  158. {
  159. cc_delay(100);
  160. res = cc_exec2(0xE5, 0xD1);
  161. res &= 1;
  162. } while (res==0);
  163. // Clear DMA IRQ flag
  164. res = cc_exec2(0xE5, 0xD1);
  165. res &= ~1;
  166. cc_exec3(0x75,0xD1,res);
  167. // disarm DMA Channel 1
  168. res = cc_exec2(0xE5, 0xD6);
  169. res &= ~2;
  170. cc_exec3(0x75,0xD6,res);
  171. // écrire l'adresse de destination dans FADDRH FADDRL
  172. offset = ((page&0xff)<<11) + Pages[page].minoffset;
  173. res=(offset>>2)&0xff;
  174. writeXDATA( 0x6271, &res,1);
  175. res=(offset>>10)&0xff;
  176. writeXDATA( 0x6272, &res,1);
  177. // arm DMA channel 1 :
  178. res = cc_exec2(0xE5, 0xD6);
  179. res |= 2;
  180. cc_exec3(0x75,0xD6,res);
  181. cc_delay(200);
  182. // lancer la copie vers la FLASH
  183. readXDATA(0x6270, &res, 1);
  184. res |= 2;
  185. writeXDATA(0x6270, &res, 1);
  186. // wait DMA end :
  187. do
  188. {
  189. sleep(1);
  190. res = cc_exec2(0xE5, 0xD1);
  191. res &= 2;
  192. } while (res==0);
  193. // vérifie qu'il n'y a pas eu de flash abort
  194. readXDATA(0x6270, &res, 1);
  195. if (res&0x20)
  196. {
  197. fprintf(stderr," flash error !!!\n");
  198. exit(1);
  199. }
  200. }
  201. void helpo()
  202. {
  203. fprintf(stderr,"usage : cc_write [-d pin_DD] [-c pin_DC] [-r pin_reset] file_to_flash\n");
  204. fprintf(stderr," -c : change pin_DC (default 27)\n");
  205. fprintf(stderr," -d : change pin_DD (default 28)\n");
  206. fprintf(stderr," -r : change reset pin (default 24)\n");
  207. fprintf(stderr," -m : change multiplier for time delay (default auto)\n");
  208. }
  209. int main(int argc,char *argv[])
  210. {
  211. int opt;
  212. int rePin=24;
  213. int dcPin=27;
  214. int ddPin=28;
  215. int setMult=-1;
  216. while( (opt=getopt(argc,argv,"m:d:c:r:h?")) != -1)
  217. {
  218. switch(opt)
  219. {
  220. case 'm' :
  221. setMult=atoi(optarg);
  222. break;
  223. case 'd' : // DD pinglo
  224. ddPin=atoi(optarg);
  225. break;
  226. case 'c' : // DC pinglo
  227. dcPin=atoi(optarg);
  228. break;
  229. case 'r' : // restarigi pinglo
  230. rePin=atoi(optarg);
  231. break;
  232. case 'h' : // helpo
  233. case '?' : // helpo
  234. helpo();
  235. exit(0);
  236. break;
  237. }
  238. }
  239. if( optind >= argc ) { helpo(); exit(1); }
  240. FILE * ficin = fopen(argv[optind],"r");
  241. if(!ficin) { fprintf(stderr," Can't open file %s.\n",argv[optind]); exit(1); }
  242. // on initialise les ports GPIO et le debugger
  243. cc_init(rePin,dcPin,ddPin);
  244. if(setMult>0) cc_setmult(setMult);
  245. // entrée en mode debug
  246. cc_enter();
  247. // envoi de la commande getChipID :
  248. uint16_t ID;
  249. ID = cc_getChipID();
  250. printf(" ID = %04x.\n",ID);
  251. for (int page=0 ; page<128 ; page++)
  252. {
  253. memset(Pages[page].datas,0xff,2048);
  254. Pages[page].minoffset=0xffff;
  255. Pages[page].maxoffset=0;
  256. }
  257. uint16_t ela=0; // extended linear address
  258. uint32_t sla=0; // start linear address
  259. // read hex file
  260. int line=0;
  261. int maxpage=0;
  262. while(fgets(buffer,600,ficin))
  263. {
  264. int sum=0,cksum,type;
  265. uint32_t addr,len;
  266. line++;
  267. if(line%10==0) { printf("\r reading line %d.");fflush(stdout); }
  268. if(buffer[0] != ':') { fprintf(stderr,"incorrect hex file ( : missing)\n"); exit(1); }
  269. if(strlen(buffer)<3 ) { fprintf(stderr,"incorrect hex file ( incomplete line)\n"); exit(1); }
  270. if(!sscanf(buffer+1,"%02x",&len)) { fprintf(stderr,"incorrect hex file (incorrect length\n"); exit(1); }
  271. if(strlen(buffer)<(11 + (len * 2))) { fprintf(stderr,"incorrect hex file ( incomplete line)\n"); exit(1); }
  272. if(!sscanf(buffer+3,"%04x",&addr)) { fprintf(stderr,"incorrect hex file (incorrect addr)\n"); exit(1); }
  273. if(!sscanf(buffer+7,"%02x",&type)) { fprintf(stderr,"incorrect hex file (incorrect record type\n"); exit(1); }
  274. if(type == 4)
  275. {
  276. if(!sscanf(buffer+9,"%04x",&ela)) { fprintf(stderr,"incorrect hex file (incorrect extended addr)\n"); exit(1); }
  277. sla=ela<<16;
  278. continue;
  279. }
  280. if(type == 5)
  281. {
  282. if(!sscanf(buffer+9,"%08x",&sla)) { fprintf(stderr,"incorrect hex file (incorrect extended addr)\n"); exit(1); }
  283. ela = sla>>16;
  284. continue;
  285. }
  286. if(type==1) // EOF
  287. {
  288. break;
  289. }
  290. if(type) { fprintf(stderr,"incorrect hex file (record type %d not implemented\n",type); exit(1); }
  291. sum = (len & 255) + ((addr >> 8) & 255) + (addr & 255) + (type & 255);
  292. int i;
  293. for( i=0 ; i<len ; i++)
  294. {
  295. if(!sscanf(buffer+9+2*i,"%02x",&data[i])) { fprintf(stderr,"incorrect hex file (incorrect data)\n"); exit(1); }
  296. sum+=data[i];
  297. }
  298. if(!sscanf(buffer+9+2*i,"%02x",&cksum)) { fprintf(stderr,"incorrect hex file line %d (incorrect checksum)\n",line); exit(1); }
  299. if ( ((sum & 255) + (cksum & 255)) & 255 ) { fprintf(stderr,"incorrect hex file line %d (bad checksum) %x %x\n",line,(-sum)&255,cksum); exit(1); }
  300. // stock datas
  301. int page= (sla+addr)>>11;
  302. if (page>maxpage) maxpage=page;
  303. uint16_t start=(sla+addr)&0x7ff;
  304. if(start+len> 2048) // some datas are for next page
  305. { //copy end of datas to next page
  306. if (page+1>maxpage) maxpage=page+1;
  307. memcpy(&Pages[page+1].datas[0]
  308. ,data+2048-start,(start+len-2048));
  309. if(0 < Pages[page+1].minoffset) Pages[page+1].minoffset=0;
  310. if( (start+len-2048-1) > Pages[page].maxoffset) Pages[page].maxoffset=start+len-2048-1;
  311. len=2048-start;
  312. }
  313. memcpy(&Pages[page].datas[start]
  314. ,data,len);
  315. if(start < Pages[page].minoffset) Pages[page].minoffset=start;
  316. if( (start+len-1) > Pages[page].maxoffset) Pages[page].maxoffset=start+len-1;
  317. }
  318. printf("\n file loaded (%d lines read).\n",line);
  319. // activer DMA
  320. uint8_t conf=cc_getConfig();
  321. conf &= ~0x4;
  322. cc_setConfig(conf);
  323. for (int page=0 ; page <= maxpage ; page++)
  324. {
  325. if(Pages[page].maxoffset<Pages[page].minoffset) continue;
  326. printf("\rwriting page %3d/%3d.",page+1,maxpage+1);
  327. fflush(stdout);
  328. writePage(page);
  329. }
  330. printf("\n");
  331. // lire les données et les vérifier
  332. int badPage=0;
  333. for (int page=0 ; page <= maxpage ; page++)
  334. {
  335. if(Pages[page].maxoffset<Pages[page].minoffset) continue;
  336. printf("\rverifying page %3d/%3d.",page+1,maxpage+1);
  337. fflush(stdout);
  338. badPage += verifPage(page);
  339. }
  340. printf("\n");
  341. if (!badPage)
  342. printf(" flash OK.\n");
  343. else
  344. printf(" Errors found in %d pages.\n",badPage);
  345. // sortie du mode debug et désactivation :
  346. cc_setActive(false);
  347. // reboot
  348. cc_reset();
  349. fclose(ficin);
  350. }