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.

635 lines
15KB

  1. /***************************************************************************
  2. * Copyright (C) 10/2014 by Olaf Rempel *
  3. * razzor@kopf-tisch.de *
  4. * *
  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; version 2 of the License, *
  8. * *
  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. * *
  14. * You should have received a copy of the GNU General Public License *
  15. * along with this program; if not, write to the *
  16. * Free Software Foundation, Inc., *
  17. * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
  18. ***************************************************************************/
  19. #include <avr/io.h>
  20. #include <avr/interrupt.h>
  21. #include <avr/boot.h>
  22. #include <avr/pgmspace.h>
  23. #include <avr/wdt.h>
  24. /* *********************************************************************** */
  25. #if defined(CONFIG_ispprog)
  26. /*
  27. * using ATmega16 @7.3728MHz:
  28. * Fuse H: 0xDA (512 words bootloader, jtag disabled)
  29. * Fuse L: 0xFF (ext. Crystal)
  30. */
  31. #define F_CPU 7372800
  32. #define BAUDRATE 19200
  33. #define DEVCODE 0x74
  34. /* 100 * 10ms => 1000ms */
  35. //#define TIMEOUT 100
  36. /* enter bootloader if PIND3 is high */
  37. #define ISP_DDR DDRD
  38. #define ISP_PIN PIND
  39. #define ISP_PORT PORTD
  40. #define ISP_NUM PIND3
  41. #define ISP_POL 1
  42. /* low active led on PORTB3 */
  43. #define LED_DDR DDRB
  44. #define LED_PORT PORTB
  45. #define LED_NUM PORTB3
  46. #define LED_POL 0
  47. /* *********************************************************************** */
  48. #elif defined(CONFIG_flightctrl)
  49. /*
  50. * using ATmega644P @20MHz:
  51. * Fuse E: 0xFD (2.7V BOD)
  52. * Fuse H: 0xDC (1024 words bootloader)
  53. * Fuse L: 0xFF (ext. Crystal)
  54. */
  55. #define F_CPU 20000000
  56. #define BAUDRATE 57600
  57. #define DEVCODE 0x74 /* mega16 devcode */
  58. /* 100 * 10ms => 1000ms */
  59. #define TIMEOUT 100
  60. /* enter bootloader if PIND3 is high */
  61. //#define ISP_DDR DDRD
  62. //#define ISP_PIN PIND
  63. //#define ISP_PORT PORTD
  64. //#define ISP_NUM PIND3
  65. //#define ISP_POL 1
  66. /* high active led on PORTB1 */
  67. #define LED_DDR DDRB
  68. #define LED_PORT PORTB
  69. #define LED_NUM PORTB1
  70. #define LED_POL 1
  71. /* support special MKBL commands */
  72. #define SUPPORT_MKBL 1
  73. /* *********************************************************************** */
  74. #elif defined(CONFIG_funkstuff88)
  75. /*
  76. * using ATmega88 @8MHz:
  77. * Fuse E: 0xFD (2.7V BOD)
  78. * Fuse H: 0xDD (512 words bootloader)
  79. * Fuse L: 0xE2 (internal osc)
  80. */
  81. #define F_CPU 8000000
  82. #define BAUDRATE 19200
  83. #define DEVCODE 0x76 /* mega8 devcode */
  84. /* 100 * 10ms => 1000ms */
  85. #define TIMEOUT 100
  86. /* enter bootloader if PIND3 is high */
  87. //#define ISP_DDR DDRD
  88. //#define ISP_PIN PIND
  89. //#define ISP_PORT PORTD
  90. //#define ISP_NUM PIND3
  91. //#define ISP_POL 1
  92. /* low active led on PORTD6 */
  93. #define LED_DDR DDRD
  94. #define LED_PORT PORTD
  95. #define LED_NUM PORTD6
  96. #define LED_POL 0
  97. /* *********************************************************************** */
  98. #elif defined(CONFIG_funkstuff168)
  99. /*
  100. * using ATmega168 @16MHz:
  101. * Fuse E: 0xFD (2.7V BOD)
  102. * Fuse H: 0xDD (512 words bootloader)
  103. * Fuse L: 0xFF (external crystal)
  104. */
  105. #define F_CPU 16000000
  106. #define BAUDRATE 19200
  107. #define DEVCODE 0x74 /* mega16 devcode */
  108. /* 100 * 10ms => 1000ms */
  109. #define TIMEOUT 100
  110. /* enter bootloader if PIND3 is high */
  111. //#define ISP_DDR DDRD
  112. //#define ISP_PIN PIND
  113. //#define ISP_PORT PORTD
  114. //#define ISP_NUM PIND3
  115. //#define ISP_POL 1
  116. /* low active led on PORTD6 */
  117. #define LED_DDR DDRD
  118. #define LED_PORT PORTD
  119. #define LED_NUM PORTD6
  120. #define LED_POL 0
  121. /* *********************************************************************** */
  122. #elif defined(CONFIG_ispprog2)
  123. /*
  124. * using ATmega328P @8MHz:
  125. * Fuse E: 0xFD (2.7V BOD)
  126. * Fuse H: 0xDC (512 words bootloader)
  127. * Fuse L: 0xE2 (internal osc)
  128. */
  129. #define F_CPU 8000000
  130. #define BAUDRATE 19200
  131. #define DEVCODE 0x72 /* mega32 devcode */
  132. /* 100 * 10ms => 1000ms */
  133. //#define TIMEOUT 100
  134. /* enter bootloader if PINB1 is low */
  135. #define ISP_DDR DDRB
  136. #define ISP_PIN PINB
  137. #define ISP_PORT PORTB
  138. #define ISP_NUM PINB1
  139. #define ISP_POL 0
  140. /* high active led on PORTB0 */
  141. #define LED_DDR DDRB
  142. #define LED_PORT PORTB
  143. #define LED_NUM PORTB0
  144. #define LED_POL 1
  145. /* *********************************************************************** */
  146. #elif defined(CONFIG_avrnetio)
  147. /*
  148. * using ATmega644 @16MHz:
  149. * Fuse E: 0xFD (2.7V BOD)
  150. * Fuse H: 0xDC (1024 words bootloader)
  151. * Fuse L: 0xD7 (ext. Crystal)
  152. */
  153. #define F_CPU 16000000
  154. #define BAUDRATE 38400
  155. #define DEVCODE 0x74 /* mega16 devcode */
  156. /* 100 * 10ms => 1000ms */
  157. #define TIMEOUT 100
  158. /* enter bootloader if PINB1 is low */
  159. #define ISP_DDR DDRB
  160. #define ISP_PIN PINB
  161. #define ISP_PORT PORTB
  162. #define ISP_NUM PINB1
  163. #define ISP_POL 0
  164. /* *********************************************************************** */
  165. #elif defined(CONFIG_funkbridge)
  166. /*
  167. * using ATmega328P @16MHz:
  168. * Fuse E: 0xFD (2.7V BOD)
  169. * Fuse H: 0xDC (512 words bootloader)
  170. * Fuse L: 0xFF (external crystal)
  171. */
  172. #define F_CPU 16000000
  173. #define BAUDRATE 19200
  174. #define DEVCODE 0x72 /* mega32 devcode */
  175. /* 100 * 10ms => 1000ms */
  176. #define TIMEOUT 100
  177. /* enter bootloader if PINB1 is low */
  178. //#define ISP_DDR DDRB
  179. //#define ISP_PIN PINB
  180. //#define ISP_PORT PORTB
  181. //#define ISP_NUM PINB1
  182. //#define ISP_POL 0
  183. /* high active led on PORTD4 */
  184. #define LED_DDR DDRD
  185. #define LED_PORT PORTD
  186. #define LED_NUM PORTD4
  187. #define LED_POL 1
  188. /* *********************************************************************** */
  189. #else
  190. #error "unknown CONFIG"
  191. #endif
  192. /* *********************************************************************** */
  193. /* needs F_CPU */
  194. #include <util/delay.h>
  195. #define UART_CALC_BAUDRATE(baudRate) ((uint32_t)(F_CPU) / ((uint32_t)(baudRate)*16) -1)
  196. #if defined(ISP_NUM)
  197. #if (ISP_POL == 0)
  198. #define ISP_INIT() { ISP_DDR &= ~(1<<ISP_NUM); ISP_PORT |= (1<<ISP_NUM); }
  199. #define ISP_CHECK() (ISP_PIN & (1<<ISP_NUM))
  200. #else
  201. #define ISP_INIT() { ISP_DDR &= ~(1<<ISP_NUM); ISP_PORT &= ~(1<<ISP_NUM); }
  202. #define ISP_CHECK() !(ISP_PIN & (1<<ISP_NUM))
  203. #endif
  204. #endif /* defined(ISP_NUM) */
  205. #if defined(LED_NUM)
  206. #define LED_INIT() LED_DDR |= (1<<LED_NUM);
  207. #if (LED_POL == 0)
  208. #define LED_ON() LED_PORT &= ~(1<<LED_NUM)
  209. #define LED_OFF() LED_PORT |= (1<<LED_NUM)
  210. #else
  211. #define LED_ON() LED_PORT |= (1<<LED_NUM)
  212. #define LED_OFF() LED_PORT &= ~(1<<LED_NUM)
  213. #endif
  214. #else
  215. #define LED_INIT()
  216. #define LED_ON()
  217. #define LED_OFF()
  218. #endif /* defined(LED_NUM) */
  219. static uint8_t page_buf[SPM_PAGESIZE];
  220. register uint16_t address asm("r2");
  221. #if defined(__AVR_ATmega16__)
  222. static void uartinit(void)
  223. {
  224. /* Set baud rate */
  225. UBRRH = (UART_CALC_BAUDRATE(BAUDRATE)>>8) & 0xFF;
  226. UBRRL = (UART_CALC_BAUDRATE(BAUDRATE) & 0xFF);
  227. /* enable usart with 8n1 */
  228. UCSRB = (1<<TXEN) | (1<<RXEN);
  229. UCSRC = (1<<URSEL) | (1<<UCSZ1) | (1<<UCSZ0);
  230. } /* uartinit */
  231. static void sendchar(uint8_t data)
  232. {
  233. loop_until_bit_is_set(UCSRA, UDRE);
  234. UDR = data;
  235. } /* sendchar */
  236. static uint8_t recvchar(void)
  237. {
  238. loop_until_bit_is_set(UCSRA, RXC);
  239. return UDR;
  240. } /* recvchar */
  241. #if defined(TIMEOUT)
  242. static uint8_t recvcheck(void)
  243. {
  244. return (UCSRA & (1<<RXC));
  245. } /* recvcheck */
  246. #endif /* defined(TIMEOUT) */
  247. #else
  248. static void uartinit(void)
  249. {
  250. /* set baudrate */
  251. UBRR0H = (UART_CALC_BAUDRATE(BAUDRATE)>>8) & 0xFF;
  252. UBRR0L = (UART_CALC_BAUDRATE(BAUDRATE) & 0xFF);
  253. /* USART: rx/tx enable, 8n1 */
  254. UCSR0B = (1<<TXEN0) | (1<<RXEN0);
  255. UCSR0C = (1<<UCSZ01) | (1<<UCSZ00);
  256. } /* uartinit */
  257. static void sendchar(uint8_t data)
  258. {
  259. loop_until_bit_is_set(UCSR0A, UDRE0);
  260. UDR0 = data;
  261. } /* sendchar */
  262. static uint8_t recvchar(void)
  263. {
  264. loop_until_bit_is_set(UCSR0A, RXC0);
  265. return UDR0;
  266. } /* recvchar */
  267. #if defined(TIMEOUT)
  268. static uint8_t recvcheck(void)
  269. {
  270. return (UCSR0A & (1<<RXC0));
  271. } /* recvcheck */
  272. #endif /* defined(TIMEOUT) */
  273. #endif
  274. static void eraseFlash(void)
  275. {
  276. address = 0;
  277. while (address < BOOTLOADER_START) {
  278. boot_page_erase(address);
  279. boot_spm_busy_wait();
  280. address += SPM_PAGESIZE;
  281. }
  282. boot_rww_enable();
  283. } /* eraseFlash */
  284. static void writeFlashPage(uint16_t size)
  285. {
  286. uint16_t pagestart = address;
  287. uint8_t *tmp = page_buf;
  288. do {
  289. uint16_t data;
  290. data = *tmp++;
  291. data |= (*tmp++ << 8);
  292. boot_page_fill(address, data);
  293. address += 2;
  294. size -= 2;
  295. } while (size);
  296. boot_page_write(pagestart);
  297. boot_spm_busy_wait();
  298. boot_rww_enable();
  299. } /* writeFlashPage */
  300. static void writeEEpromPage(uint16_t size)
  301. {
  302. uint8_t *tmp = page_buf;
  303. do {
  304. EEARL = address;
  305. EEARH = (address >> 8);
  306. EEDR = *tmp++;
  307. address++;
  308. #if defined(__AVR_ATmega16__)
  309. EECR |= (1<<EEMWE);
  310. EECR |= (1<<EEWE);
  311. #else
  312. EECR |= (1<<EEMPE);
  313. EECR |= (1<<EEPE);
  314. #endif
  315. eeprom_busy_wait();
  316. size--;
  317. } while (size);
  318. } /* writeEEpromPage */
  319. static void readSendFlashPage(uint16_t size)
  320. {
  321. do {
  322. sendchar(pgm_read_byte_near(address++));
  323. size--;
  324. } while (size);
  325. } /* readSendFlashPage */
  326. static void readSendEEpromPage(uint16_t size)
  327. {
  328. do {
  329. EEARL = address;
  330. EEARH = (address >> 8);
  331. EECR |= (1<<EERE);
  332. address++;
  333. sendchar(EEDR);
  334. size--;
  335. } while (size);
  336. } /* readSendEEpromPage */
  337. #if defined(__AVR_ATmega88__) || \
  338. defined(__AVR_ATmega168__) || \
  339. defined(__AVR_ATmega328P__) || \
  340. defined(__AVR_ATmega644__) || \
  341. defined(__AVR_ATmega644P__)
  342. /*
  343. * For newer devices the watchdog timer remains active even after a
  344. * system reset. So disable it as soon as possible.
  345. * automagically called on startup
  346. */
  347. void disable_wdt_timer(void) __attribute__((naked, section(".init3")));
  348. void disable_wdt_timer(void)
  349. {
  350. MCUSR = 0;
  351. WDTCSR = (1<<WDCE) | (1<<WDE);
  352. WDTCSR = (0<<WDE);
  353. }
  354. #endif
  355. #if defined(ISP_NUM) || defined(TIMEOUT)
  356. static void (*jump_to_app)(void) __attribute__ ((noreturn)) = 0x0000;
  357. #endif
  358. int main(void) __attribute__ ((noreturn));
  359. int main(void)
  360. {
  361. #if defined(ISP_NUM)
  362. /* set as input, enable pullup/pulldown */
  363. ISP_INIT();
  364. {
  365. volatile uint8_t wait = 0;
  366. while (--wait);
  367. }
  368. /* check if bootloader is not selected */
  369. if (ISP_CHECK()) {
  370. jump_to_app();
  371. }
  372. #endif /* defined(ISP_NUM) */
  373. #if defined(LED_NUM)
  374. LED_DDR |= (1<<LED_NUM);
  375. #endif /* defined(LED_NUM) */
  376. #if defined(OSCCAL_VALUE)
  377. OSCCAL = OSCCAL_VALUE;
  378. #endif /* defined(OSCCAL_VALUE) */
  379. /* initalize UART */
  380. uartinit();
  381. uint8_t val = 0x1B;
  382. #if defined(TIMEOUT)
  383. uint8_t prev = 0x00;
  384. uint8_t boot_timeout = TIMEOUT;
  385. while (1) {
  386. if (recvcheck()) {
  387. val = recvchar();
  388. #if defined(SUPPORT_MKBL)
  389. if ((prev == 0x1B) && (val == 0xAA || val == 'S')) {
  390. break;
  391. }
  392. #else
  393. if ((prev == 0x1B) && (val == 'S')) {
  394. break;
  395. }
  396. #endif /* defined(SUPPORT_MKBL) */
  397. prev = val;
  398. }
  399. _delay_ms(10);
  400. boot_timeout--;
  401. if (boot_timeout == 0x00) {
  402. LED_OFF();
  403. jump_to_app();
  404. }
  405. #if defined(LED_NUM)
  406. if (!(boot_timeout & 0x03)) {
  407. LED_PORT ^= (1<<LED_NUM);
  408. }
  409. #endif /* defined(LED_NUM) */
  410. }
  411. #endif /* defined(TIMEOUT) */
  412. /* turn on LED */
  413. LED_ON();
  414. while (1) {
  415. uint8_t response = 0xFF;
  416. /* Autoincrement? */
  417. if (val == 'a') {
  418. response = 'Y';
  419. /* write address: flash:words, eeprom:bytes */
  420. } else if (val == 'A') {
  421. address = (recvchar() << 8);
  422. address |= recvchar();
  423. response = '\r';
  424. /* Buffer load support */
  425. } else if (val == 'b') {
  426. sendchar('Y');
  427. sendchar((SPM_PAGESIZE >> 8) & 0xFF);
  428. response = SPM_PAGESIZE & 0xFF;
  429. /* Start buffer load */
  430. } else if (val == 'B') {
  431. uint16_t size;
  432. uint16_t count;
  433. uint8_t *data = page_buf;
  434. size = (recvchar() << 8);
  435. size |= recvchar();
  436. val = recvchar();
  437. for (count = 0; count < SPM_PAGESIZE; count++) {
  438. *data++ = (count < size) ? recvchar() : 0xFF;
  439. }
  440. if ((val == 'F') && (address < (BOOTLOADER_START >> 1))) {
  441. address <<= 1;
  442. writeFlashPage(size);
  443. address >>= 1;
  444. response = '\r';
  445. } else if ((val == 'E') && (address < E2END)) {
  446. writeEEpromPage(size);
  447. response = '\r';
  448. } else {
  449. response = 0x00;
  450. }
  451. /* Block read */
  452. } else if (val == 'g') {
  453. uint16_t size;
  454. size = (recvchar() << 8);
  455. size |= recvchar();
  456. val = recvchar();
  457. if (val == 'F') {
  458. address <<= 1;
  459. readSendFlashPage(size);
  460. address >>= 1;
  461. } else if (val == 'E') {
  462. readSendEEpromPage(size);
  463. }
  464. /* Chip erase */
  465. } else if (val == 'e') {
  466. eraseFlash();
  467. response = '\r';
  468. /* Exit upgrade */
  469. } else if (val == 'E') {
  470. wdt_enable(WDTO_250MS);
  471. response = '\r';
  472. /* Enter/Leave programming mode */
  473. } else if ((val == 'P') || (val == 'L')) {
  474. response = '\r';
  475. /* return programmer type: serial */
  476. } else if (val == 'p') {
  477. response = 'S';
  478. /* Return device type */
  479. } else if (val == 't') {
  480. sendchar(DEVCODE);
  481. response = 0x00;
  482. /* Clear and set LED ignored */
  483. } else if ((val == 'x') || (val == 'y')) {
  484. recvchar();
  485. response = '\r';
  486. /* Set device */
  487. } else if (val == 'T') {
  488. response = (recvchar() == DEVCODE) ? '\r' : 0x00;
  489. /* Return software identifier */
  490. } else if (val == 'S') {
  491. sendchar('A');
  492. sendchar('V');
  493. sendchar('R');
  494. sendchar('B');
  495. sendchar('O');
  496. sendchar('O');
  497. response = 'T';
  498. #if defined(SUPPORT_MKBL)
  499. } else if (val == 0xAA) {
  500. sendchar('M');
  501. sendchar('K');
  502. sendchar('B');
  503. response = 'L';
  504. #endif /* defined(SUPPORT_MKBL) */
  505. /* Return Software/Hardware Version */
  506. } else if ((val == 'V') || (val == 'v')) {
  507. sendchar('0');
  508. response = '8';
  509. /* Return Signature Bytes */
  510. } else if (val == 's') {
  511. sendchar(SIGNATURE_2);
  512. sendchar(SIGNATURE_1);
  513. response = SIGNATURE_0;
  514. } else if (val != 0x1B) {
  515. response = '?';
  516. }
  517. if (response != 0xFF) {
  518. sendchar(response);
  519. }
  520. val = recvchar();
  521. }
  522. }