avr_isp_prog.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639
  1. #include "avr_isp_prog.h"
  2. #include "avr_isp_prog_cmd.h"
  3. #include <furi.h>
  4. #define AVR_ISP_PROG_TX_RX_BUF_SIZE 320
  5. #define TAG "AvrIspProg"
  6. struct AvrIspProgSignature {
  7. uint8_t vendor;
  8. uint8_t part_family;
  9. uint8_t part_number;
  10. };
  11. typedef struct AvrIspProgSignature AvrIspProgSignature;
  12. struct AvrIspProgCfgDevice {
  13. uint8_t devicecode;
  14. uint8_t revision;
  15. uint8_t progtype;
  16. uint8_t parmode;
  17. uint8_t polling;
  18. uint8_t selftimed;
  19. uint8_t lockbytes;
  20. uint8_t fusebytes;
  21. uint8_t flashpoll;
  22. uint16_t eeprompoll;
  23. uint16_t pagesize;
  24. uint16_t eepromsize;
  25. uint32_t flashsize;
  26. };
  27. typedef struct AvrIspProgCfgDevice AvrIspProgCfgDevice;
  28. struct AvrIspProg {
  29. AvrIspSpiSw* spi;
  30. AvrIspProgCfgDevice* cfg;
  31. FuriStreamBuffer* stream_rx;
  32. FuriStreamBuffer* stream_tx;
  33. uint16_t error;
  34. uint16_t addr;
  35. bool pmode;
  36. bool exit;
  37. bool rst_active_high;
  38. uint8_t buff[AVR_ISP_PROG_TX_RX_BUF_SIZE];
  39. AvrIspProgCallback callback;
  40. void* context;
  41. };
  42. static void avr_isp_prog_end_pmode(AvrIspProg* instance);
  43. AvrIspProg* avr_isp_prog_init(void) {
  44. AvrIspProg* instance = malloc(sizeof(AvrIspProg));
  45. instance->cfg = malloc(sizeof(AvrIspProgCfgDevice));
  46. instance->stream_rx =
  47. furi_stream_buffer_alloc(sizeof(int8_t) * AVR_ISP_PROG_TX_RX_BUF_SIZE, sizeof(int8_t));
  48. instance->stream_tx =
  49. furi_stream_buffer_alloc(sizeof(int8_t) * AVR_ISP_PROG_TX_RX_BUF_SIZE, sizeof(int8_t));
  50. instance->rst_active_high = false;
  51. instance->exit = false;
  52. return instance;
  53. }
  54. void avr_isp_prog_free(AvrIspProg* instance) {
  55. furi_assert(instance);
  56. if(instance->spi) avr_isp_prog_end_pmode(instance);
  57. furi_stream_buffer_free(instance->stream_tx);
  58. furi_stream_buffer_free(instance->stream_rx);
  59. free(instance->cfg);
  60. free(instance);
  61. }
  62. size_t avr_isp_prog_spaces_rx(AvrIspProg* instance) {
  63. return furi_stream_buffer_spaces_available(instance->stream_rx);
  64. }
  65. bool avr_isp_prog_rx(AvrIspProg* instance, uint8_t* data, size_t len) {
  66. furi_assert(instance);
  67. furi_assert(data);
  68. furi_assert(len != 0);
  69. size_t ret = furi_stream_buffer_send(instance->stream_rx, data, sizeof(uint8_t) * len, 0);
  70. return ret == sizeof(uint8_t) * len;
  71. }
  72. size_t avr_isp_prog_tx(AvrIspProg* instance, uint8_t* data, size_t max_len) {
  73. furi_assert(instance);
  74. return furi_stream_buffer_receive(instance->stream_tx, data, sizeof(int8_t) * max_len, 0);
  75. }
  76. void avr_isp_prog_exit(AvrIspProg* instance) {
  77. furi_assert(instance);
  78. instance->exit = true;
  79. }
  80. void avr_isp_prog_set_tx_callback(AvrIspProg* instance, AvrIspProgCallback callback, void* context) {
  81. furi_assert(instance);
  82. furi_assert(context);
  83. instance->callback = callback;
  84. instance->context = context;
  85. }
  86. static void avr_isp_prog_tx_ch(AvrIspProg* instance, uint8_t data) {
  87. furi_assert(instance);
  88. furi_stream_buffer_send(instance->stream_tx, &data, sizeof(uint8_t), FuriWaitForever);
  89. }
  90. static uint8_t avr_isp_prog_getch(AvrIspProg* instance) {
  91. furi_assert(instance);
  92. uint8_t data[1] = {0};
  93. while(furi_stream_buffer_receive(instance->stream_rx, &data, sizeof(int8_t), 30) == 0) {
  94. if(instance->exit) break;
  95. };
  96. return data[0];
  97. }
  98. static void avr_isp_prog_fill(AvrIspProg* instance, size_t len) {
  99. furi_assert(instance);
  100. for(size_t x = 0; x < len; x++) {
  101. instance->buff[x] = avr_isp_prog_getch(instance);
  102. }
  103. }
  104. static void avr_isp_prog_reset_target(AvrIspProg* instance, bool reset) {
  105. furi_assert(instance);
  106. avr_isp_spi_sw_res_set(instance->spi, (reset == instance->rst_active_high) ? true : false);
  107. }
  108. static uint8_t avr_isp_prog_spi_transaction(
  109. AvrIspProg* instance,
  110. uint8_t cmd,
  111. uint8_t addr_hi,
  112. uint8_t addr_lo,
  113. uint8_t data) {
  114. furi_assert(instance);
  115. avr_isp_spi_sw_txrx(instance->spi, cmd);
  116. avr_isp_spi_sw_txrx(instance->spi, addr_hi);
  117. avr_isp_spi_sw_txrx(instance->spi, addr_lo);
  118. return avr_isp_spi_sw_txrx(instance->spi, data);
  119. }
  120. static void avr_isp_prog_empty_reply(AvrIspProg* instance) {
  121. furi_assert(instance);
  122. if(avr_isp_prog_getch(instance) == CRC_EOP) {
  123. avr_isp_prog_tx_ch(instance, STK_INSYNC);
  124. avr_isp_prog_tx_ch(instance, STK_OK);
  125. } else {
  126. instance->error++;
  127. avr_isp_prog_tx_ch(instance, STK_NOSYNC);
  128. }
  129. }
  130. static void avr_isp_prog_breply(AvrIspProg* instance, uint8_t data) {
  131. furi_assert(instance);
  132. if(avr_isp_prog_getch(instance) == CRC_EOP) {
  133. avr_isp_prog_tx_ch(instance, STK_INSYNC);
  134. avr_isp_prog_tx_ch(instance, data);
  135. avr_isp_prog_tx_ch(instance, STK_OK);
  136. } else {
  137. instance->error++;
  138. avr_isp_prog_tx_ch(instance, STK_NOSYNC);
  139. }
  140. }
  141. static void avr_isp_prog_get_version(AvrIspProg* instance, uint8_t data) {
  142. furi_assert(instance);
  143. switch(data) {
  144. case STK_HW_VER:
  145. avr_isp_prog_breply(instance, AVR_ISP_HWVER);
  146. break;
  147. case STK_SW_MAJOR:
  148. avr_isp_prog_breply(instance, AVR_ISP_SWMAJ);
  149. break;
  150. case STK_SW_MINOR:
  151. avr_isp_prog_breply(instance, AVR_ISP_SWMIN);
  152. break;
  153. case AVP_ISP_CONNECT_TYPE:
  154. avr_isp_prog_breply(instance, AVP_ISP_SERIAL_CONNECT_TYPE);
  155. break;
  156. default:
  157. avr_isp_prog_breply(instance, AVR_ISP_RESP_0);
  158. }
  159. }
  160. static void avr_isp_prog_set_cfg(AvrIspProg* instance) {
  161. furi_assert(instance);
  162. // call this after reading cfg packet into buff[]
  163. instance->cfg->devicecode = instance->buff[0];
  164. instance->cfg->revision = instance->buff[1];
  165. instance->cfg->progtype = instance->buff[2];
  166. instance->cfg->parmode = instance->buff[3];
  167. instance->cfg->polling = instance->buff[4];
  168. instance->cfg->selftimed = instance->buff[5];
  169. instance->cfg->lockbytes = instance->buff[6];
  170. instance->cfg->fusebytes = instance->buff[7];
  171. instance->cfg->flashpoll = instance->buff[8];
  172. // ignore (instance->buff[9] == instance->buff[8]) //FLASH polling value. Same as “flashpoll”
  173. instance->cfg->eeprompoll = instance->buff[10] << 8 | instance->buff[11];
  174. instance->cfg->pagesize = instance->buff[12] << 8 | instance->buff[13];
  175. instance->cfg->eepromsize = instance->buff[14] << 8 | instance->buff[15];
  176. instance->cfg->flashsize = instance->buff[16] << 24 | instance->buff[17] << 16 |
  177. instance->buff[18] << 8 | instance->buff[19];
  178. // avr devices have active low reset, at89sx are active high
  179. instance->rst_active_high = (instance->cfg->devicecode >= 0xe0);
  180. }
  181. static bool
  182. avr_isp_prog_set_pmode(AvrIspProg* instance, uint8_t a, uint8_t b, uint8_t c, uint8_t d) {
  183. furi_assert(instance);
  184. uint8_t res = 0;
  185. avr_isp_spi_sw_txrx(instance->spi, a);
  186. avr_isp_spi_sw_txrx(instance->spi, b);
  187. res = avr_isp_spi_sw_txrx(instance->spi, c);
  188. avr_isp_spi_sw_txrx(instance->spi, d);
  189. return res == 0x53;
  190. }
  191. static void avr_isp_prog_end_pmode(AvrIspProg* instance) {
  192. furi_assert(instance);
  193. if(instance->pmode) {
  194. avr_isp_prog_reset_target(instance, false);
  195. // We're about to take the target out of reset
  196. // so configure SPI pins as input
  197. if(instance->spi) avr_isp_spi_sw_free(instance->spi);
  198. instance->spi = NULL;
  199. }
  200. instance->pmode = false;
  201. }
  202. static bool avr_isp_prog_start_pmode(AvrIspProg* instance, AvrIspSpiSwSpeed spi_speed) {
  203. furi_assert(instance);
  204. // Reset target before driving PIN_SCK or PIN_MOSI
  205. // SPI.begin() will configure SS as output,
  206. // so SPI master mode is selected.
  207. // We have defined RESET as pin 10,
  208. // which for many arduino's is not the SS pin.
  209. // So we have to configure RESET as output here,
  210. // (reset_target() first sets the correct level)
  211. if(instance->spi) avr_isp_spi_sw_free(instance->spi);
  212. instance->spi = avr_isp_spi_sw_init(spi_speed);
  213. avr_isp_prog_reset_target(instance, true);
  214. // See avr datasheets, chapter "SERIAL_PRG Programming Algorithm":
  215. // Pulse RESET after PIN_SCK is low:
  216. avr_isp_spi_sw_sck_set(instance->spi, false);
  217. // discharge PIN_SCK, value arbitrally chosen
  218. furi_delay_ms(20);
  219. avr_isp_prog_reset_target(instance, false);
  220. // Pulse must be minimum 2 target CPU speed cycles
  221. // so 100 usec is ok for CPU speeds above 20KHz
  222. furi_delay_ms(1);
  223. avr_isp_prog_reset_target(instance, true);
  224. // Send the enable programming command:
  225. // datasheet: must be > 20 msec
  226. furi_delay_ms(50);
  227. if(avr_isp_prog_set_pmode(instance, AVR_ISP_SET_PMODE)) {
  228. instance->pmode = true;
  229. return true;
  230. }
  231. return false;
  232. }
  233. static AvrIspProgSignature avr_isp_prog_check_signature(AvrIspProg* instance) {
  234. furi_assert(instance);
  235. AvrIspProgSignature signature;
  236. signature.vendor = avr_isp_prog_spi_transaction(instance, AVR_ISP_READ_VENDOR);
  237. signature.part_family = avr_isp_prog_spi_transaction(instance, AVR_ISP_READ_PART_FAMILY);
  238. signature.part_number = avr_isp_prog_spi_transaction(instance, AVR_ISP_READ_PART_NUMBER);
  239. return signature;
  240. }
  241. static bool avr_isp_prog_auto_set_spi_speed_start_pmode(AvrIspProg* instance) {
  242. AvrIspSpiSwSpeed spi_speed[] = {
  243. AvrIspSpiSwSpeed1Mhz,
  244. AvrIspSpiSwSpeed400Khz,
  245. AvrIspSpiSwSpeed250Khz,
  246. AvrIspSpiSwSpeed125Khz,
  247. AvrIspSpiSwSpeed60Khz,
  248. AvrIspSpiSwSpeed40Khz,
  249. AvrIspSpiSwSpeed20Khz,
  250. AvrIspSpiSwSpeed10Khz,
  251. AvrIspSpiSwSpeed5Khz,
  252. AvrIspSpiSwSpeed1Khz,
  253. };
  254. for(uint8_t i = 0; i < COUNT_OF(spi_speed); i++) {
  255. if(avr_isp_prog_start_pmode(instance, spi_speed[i])) {
  256. AvrIspProgSignature sig = avr_isp_prog_check_signature(instance);
  257. AvrIspProgSignature sig_examination = avr_isp_prog_check_signature(instance); //-V656
  258. uint8_t y = 0;
  259. while(y < 8) {
  260. if(memcmp(
  261. (uint8_t*)&sig, (uint8_t*)&sig_examination, sizeof(AvrIspProgSignature)) !=
  262. 0)
  263. break;
  264. sig_examination = avr_isp_prog_check_signature(instance);
  265. y++;
  266. }
  267. if(y == 8) {
  268. if(spi_speed[i] > AvrIspSpiSwSpeed1Mhz) {
  269. if(i < (COUNT_OF(spi_speed) - 1)) {
  270. avr_isp_prog_end_pmode(instance);
  271. i++;
  272. return avr_isp_prog_start_pmode(instance, spi_speed[i]);
  273. }
  274. }
  275. return true;
  276. }
  277. }
  278. }
  279. if(instance->spi) {
  280. avr_isp_spi_sw_free(instance->spi);
  281. instance->spi = NULL;
  282. }
  283. return false;
  284. }
  285. static void avr_isp_prog_universal(AvrIspProg* instance) {
  286. furi_assert(instance);
  287. uint8_t data;
  288. avr_isp_prog_fill(instance, 4);
  289. data = avr_isp_prog_spi_transaction(
  290. instance, instance->buff[0], instance->buff[1], instance->buff[2], instance->buff[3]);
  291. avr_isp_prog_breply(instance, data);
  292. }
  293. static void avr_isp_prog_commit(AvrIspProg* instance, uint16_t addr, uint8_t data) {
  294. furi_assert(instance);
  295. avr_isp_prog_spi_transaction(instance, AVR_ISP_COMMIT(addr));
  296. /* polling flash */
  297. if(data == 0xFF) {
  298. furi_delay_ms(5);
  299. } else {
  300. /* polling flash */
  301. uint32_t starttime = furi_get_tick();
  302. while((furi_get_tick() - starttime) < 30) {
  303. if(avr_isp_prog_spi_transaction(instance, AVR_ISP_READ_FLASH_HI(addr)) != 0xFF) {
  304. break;
  305. };
  306. }
  307. }
  308. }
  309. static uint16_t avr_isp_prog_current_page(AvrIspProg* instance) {
  310. furi_assert(instance);
  311. uint16_t page = 0;
  312. switch(instance->cfg->pagesize) {
  313. case 32:
  314. page = instance->addr & 0xFFFFFFF0;
  315. break;
  316. case 64:
  317. page = instance->addr & 0xFFFFFFE0;
  318. break;
  319. case 128:
  320. page = instance->addr & 0xFFFFFFC0;
  321. break;
  322. case 256:
  323. page = instance->addr & 0xFFFFFF80;
  324. break;
  325. default:
  326. page = instance->addr;
  327. break;
  328. }
  329. return page;
  330. }
  331. static uint8_t avr_isp_prog_write_flash_pages(AvrIspProg* instance, size_t length) {
  332. furi_assert(instance);
  333. size_t x = 0;
  334. uint16_t page = avr_isp_prog_current_page(instance);
  335. while(x < length) {
  336. if(page != avr_isp_prog_current_page(instance)) {
  337. --x;
  338. avr_isp_prog_commit(instance, page, instance->buff[x++]);
  339. page = avr_isp_prog_current_page(instance);
  340. }
  341. avr_isp_prog_spi_transaction(
  342. instance, AVR_ISP_WRITE_FLASH_LO(instance->addr, instance->buff[x++]));
  343. avr_isp_prog_spi_transaction(
  344. instance, AVR_ISP_WRITE_FLASH_HI(instance->addr, instance->buff[x++]));
  345. instance->addr++;
  346. }
  347. avr_isp_prog_commit(instance, page, instance->buff[--x]);
  348. return STK_OK;
  349. }
  350. static void avr_isp_prog_write_flash(AvrIspProg* instance, size_t length) {
  351. furi_assert(instance);
  352. avr_isp_prog_fill(instance, length);
  353. if(avr_isp_prog_getch(instance) == CRC_EOP) {
  354. avr_isp_prog_tx_ch(instance, STK_INSYNC);
  355. avr_isp_prog_tx_ch(instance, avr_isp_prog_write_flash_pages(instance, length));
  356. } else {
  357. instance->error++;
  358. avr_isp_prog_tx_ch(instance, STK_NOSYNC);
  359. }
  360. }
  361. // write (length) bytes, (start) is a byte address
  362. static uint8_t
  363. avr_isp_prog_write_eeprom_chunk(AvrIspProg* instance, uint16_t start, uint16_t length) {
  364. furi_assert(instance);
  365. // this writes byte-by-byte,
  366. // page writing may be faster (4 bytes at a time)
  367. avr_isp_prog_fill(instance, length);
  368. for(uint16_t x = 0; x < length; x++) {
  369. uint16_t addr = start + x;
  370. avr_isp_prog_spi_transaction(instance, AVR_ISP_WRITE_EEPROM(addr, instance->buff[x]));
  371. furi_delay_ms(10);
  372. }
  373. return STK_OK;
  374. }
  375. static uint8_t avr_isp_prog_write_eeprom(AvrIspProg* instance, size_t length) {
  376. furi_assert(instance);
  377. // here is a word address, get the byte address
  378. uint16_t start = instance->addr * 2;
  379. uint16_t remaining = length;
  380. if(length > instance->cfg->eepromsize) {
  381. instance->error++;
  382. return STK_FAILED;
  383. }
  384. while(remaining > AVR_ISP_EECHUNK) {
  385. avr_isp_prog_write_eeprom_chunk(instance, start, AVR_ISP_EECHUNK);
  386. start += AVR_ISP_EECHUNK;
  387. remaining -= AVR_ISP_EECHUNK;
  388. }
  389. avr_isp_prog_write_eeprom_chunk(instance, start, remaining);
  390. return STK_OK;
  391. }
  392. static void avr_isp_prog_program_page(AvrIspProg* instance) {
  393. furi_assert(instance);
  394. uint8_t result = STK_FAILED;
  395. uint16_t length = avr_isp_prog_getch(instance) << 8 | avr_isp_prog_getch(instance);
  396. uint8_t memtype = avr_isp_prog_getch(instance);
  397. // flash memory @addr, (length) bytes
  398. if(memtype == STK_SET_FLASH_TYPE) {
  399. avr_isp_prog_write_flash(instance, length);
  400. return;
  401. }
  402. if(memtype == STK_SET_EEPROM_TYPE) {
  403. result = avr_isp_prog_write_eeprom(instance, length);
  404. if(avr_isp_prog_getch(instance) == CRC_EOP) {
  405. avr_isp_prog_tx_ch(instance, STK_INSYNC);
  406. avr_isp_prog_tx_ch(instance, result);
  407. } else {
  408. instance->error++;
  409. avr_isp_prog_tx_ch(instance, STK_NOSYNC);
  410. }
  411. return;
  412. }
  413. avr_isp_prog_tx_ch(instance, STK_FAILED);
  414. return;
  415. }
  416. static uint8_t avr_isp_prog_flash_read_page(AvrIspProg* instance, uint16_t length) {
  417. furi_assert(instance);
  418. for(uint16_t x = 0; x < length; x += 2) {
  419. avr_isp_prog_tx_ch(
  420. instance,
  421. avr_isp_prog_spi_transaction(instance, AVR_ISP_READ_FLASH_LO(instance->addr)));
  422. avr_isp_prog_tx_ch(
  423. instance,
  424. avr_isp_prog_spi_transaction(instance, AVR_ISP_READ_FLASH_HI(instance->addr)));
  425. instance->addr++;
  426. }
  427. return STK_OK;
  428. }
  429. static uint8_t avr_isp_prog_eeprom_read_page(AvrIspProg* instance, uint16_t length) {
  430. furi_assert(instance);
  431. // here again we have a word address
  432. uint16_t start = instance->addr * 2;
  433. for(uint16_t x = 0; x < length; x++) {
  434. uint16_t addr = start + x;
  435. avr_isp_prog_tx_ch(
  436. instance, avr_isp_prog_spi_transaction(instance, AVR_ISP_READ_EEPROM(addr)));
  437. }
  438. return STK_OK;
  439. }
  440. static void avr_isp_prog_read_page(AvrIspProg* instance) {
  441. furi_assert(instance);
  442. uint8_t result = STK_FAILED;
  443. uint16_t length = avr_isp_prog_getch(instance) << 8 | avr_isp_prog_getch(instance);
  444. uint8_t memtype = avr_isp_prog_getch(instance);
  445. if(avr_isp_prog_getch(instance) != CRC_EOP) {
  446. instance->error++;
  447. avr_isp_prog_tx_ch(instance, STK_NOSYNC);
  448. return;
  449. }
  450. avr_isp_prog_tx_ch(instance, STK_INSYNC);
  451. if(memtype == STK_SET_FLASH_TYPE) result = avr_isp_prog_flash_read_page(instance, length);
  452. if(memtype == STK_SET_EEPROM_TYPE) result = avr_isp_prog_eeprom_read_page(instance, length);
  453. avr_isp_prog_tx_ch(instance, result);
  454. }
  455. static void avr_isp_prog_read_signature(AvrIspProg* instance) {
  456. furi_assert(instance);
  457. if(avr_isp_prog_getch(instance) != CRC_EOP) {
  458. instance->error++;
  459. avr_isp_prog_tx_ch(instance, STK_NOSYNC);
  460. return;
  461. }
  462. avr_isp_prog_tx_ch(instance, STK_INSYNC);
  463. avr_isp_prog_tx_ch(instance, avr_isp_prog_spi_transaction(instance, AVR_ISP_READ_VENDOR));
  464. avr_isp_prog_tx_ch(instance, avr_isp_prog_spi_transaction(instance, AVR_ISP_READ_PART_FAMILY));
  465. avr_isp_prog_tx_ch(instance, avr_isp_prog_spi_transaction(instance, AVR_ISP_READ_PART_NUMBER));
  466. avr_isp_prog_tx_ch(instance, STK_OK);
  467. }
  468. void avr_isp_prog_avrisp(AvrIspProg* instance) {
  469. furi_assert(instance);
  470. uint8_t ch = avr_isp_prog_getch(instance);
  471. switch(ch) {
  472. case STK_GET_SYNC:
  473. FURI_LOG_D(TAG, "cmd STK_GET_SYNC");
  474. instance->error = 0;
  475. avr_isp_prog_empty_reply(instance);
  476. break;
  477. case STK_GET_SIGN_ON:
  478. FURI_LOG_D(TAG, "cmd STK_GET_SIGN_ON");
  479. if(avr_isp_prog_getch(instance) == CRC_EOP) {
  480. avr_isp_prog_tx_ch(instance, STK_INSYNC);
  481. avr_isp_prog_tx_ch(instance, 'A');
  482. avr_isp_prog_tx_ch(instance, 'V');
  483. avr_isp_prog_tx_ch(instance, 'R');
  484. avr_isp_prog_tx_ch(instance, ' ');
  485. avr_isp_prog_tx_ch(instance, 'I');
  486. avr_isp_prog_tx_ch(instance, 'S');
  487. avr_isp_prog_tx_ch(instance, 'P');
  488. avr_isp_prog_tx_ch(instance, STK_OK);
  489. } else {
  490. instance->error++;
  491. avr_isp_prog_tx_ch(instance, STK_NOSYNC);
  492. }
  493. break;
  494. case STK_GET_PARAMETER:
  495. FURI_LOG_D(TAG, "cmd STK_GET_PARAMETER");
  496. avr_isp_prog_get_version(instance, avr_isp_prog_getch(instance));
  497. break;
  498. case STK_SET_DEVICE:
  499. FURI_LOG_D(TAG, "cmd STK_SET_DEVICE");
  500. avr_isp_prog_fill(instance, 20);
  501. avr_isp_prog_set_cfg(instance);
  502. avr_isp_prog_empty_reply(instance);
  503. break;
  504. case STK_SET_DEVICE_EXT: // ignore for now
  505. FURI_LOG_D(TAG, "cmd STK_SET_DEVICE_EXT");
  506. avr_isp_prog_fill(instance, 5);
  507. avr_isp_prog_empty_reply(instance);
  508. break;
  509. case STK_ENTER_PROGMODE:
  510. FURI_LOG_D(TAG, "cmd STK_ENTER_PROGMODE");
  511. if(!instance->pmode) avr_isp_prog_auto_set_spi_speed_start_pmode(instance);
  512. avr_isp_prog_empty_reply(instance);
  513. break;
  514. case STK_LOAD_ADDRESS:
  515. FURI_LOG_D(TAG, "cmd STK_LOAD_ADDRESS");
  516. instance->addr = avr_isp_prog_getch(instance) | avr_isp_prog_getch(instance) << 8;
  517. avr_isp_prog_empty_reply(instance);
  518. break;
  519. case STK_PROG_FLASH: // ignore for now
  520. FURI_LOG_D(TAG, "cmd STK_PROG_FLASH");
  521. avr_isp_prog_getch(instance);
  522. avr_isp_prog_getch(instance);
  523. avr_isp_prog_empty_reply(instance);
  524. break;
  525. case STK_PROG_DATA: // ignore for now
  526. FURI_LOG_D(TAG, "cmd STK_PROG_DATA");
  527. avr_isp_prog_getch(instance);
  528. avr_isp_prog_empty_reply(instance);
  529. break;
  530. case STK_PROG_PAGE:
  531. FURI_LOG_D(TAG, "cmd STK_PROG_PAGE");
  532. avr_isp_prog_program_page(instance);
  533. break;
  534. case STK_READ_PAGE:
  535. FURI_LOG_D(TAG, "cmd STK_READ_PAGE");
  536. avr_isp_prog_read_page(instance);
  537. break;
  538. case STK_UNIVERSAL:
  539. FURI_LOG_D(TAG, "cmd STK_UNIVERSAL");
  540. avr_isp_prog_universal(instance);
  541. break;
  542. case STK_LEAVE_PROGMODE:
  543. FURI_LOG_D(TAG, "cmd STK_LEAVE_PROGMODE");
  544. instance->error = 0;
  545. if(instance->pmode) avr_isp_prog_end_pmode(instance);
  546. avr_isp_prog_empty_reply(instance);
  547. break;
  548. case STK_READ_SIGN:
  549. FURI_LOG_D(TAG, "cmd STK_READ_SIGN");
  550. avr_isp_prog_read_signature(instance);
  551. break;
  552. // expecting a command, not CRC_EOP
  553. // this is how we can get back in sync
  554. case CRC_EOP:
  555. FURI_LOG_D(TAG, "cmd CRC_EOP");
  556. instance->error++;
  557. avr_isp_prog_tx_ch(instance, STK_NOSYNC);
  558. break;
  559. // anything else we will return STK_UNKNOWN
  560. default:
  561. FURI_LOG_D(TAG, "cmd STK_ERROR_CMD");
  562. instance->error++;
  563. if(avr_isp_prog_getch(instance) == CRC_EOP)
  564. avr_isp_prog_tx_ch(instance, STK_UNKNOWN);
  565. else
  566. avr_isp_prog_tx_ch(instance, STK_NOSYNC);
  567. }
  568. if(instance->callback) {
  569. instance->callback(instance->context);
  570. }
  571. }