Advertisement
Guest User

Untitled

a guest
Nov 30th, 2014
154
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 12.21 KB | None | 0 0
  1. #define FUNC_READ 1
  2. #define FUNC_WRITE 1
  3.  
  4. #define OPTIBOOT_MAJVER 6
  5. #define OPTIBOOT_MINVER 2
  6.  
  7. /*
  8.  * OPTIBOOT_CUSTOMVER should be defined (by the makefile) for custom edits
  9.  * of optiboot.  That way you don't wind up with very different code that
  10.  * matches the version number of a "released" optiboot.
  11.  */
  12.  
  13. #if !defined(OPTIBOOT_CUSTOMVER)
  14. #define OPTIBOOT_CUSTOMVER 0
  15. #endif
  16.  
  17. unsigned const int __attribute__((section(".version")))
  18. optiboot_version = 256*(OPTIBOOT_MAJVER + OPTIBOOT_CUSTOMVER) + OPTIBOOT_MINVER;
  19.  
  20.  
  21. #include <inttypes.h>
  22. #include <avr/io.h>
  23. #include <avr/pgmspace.h>
  24. #include <avr/eeprom.h>
  25. #include <util/delay.h>
  26.  
  27. /*
  28.  * Note that we use our own version of "boot.h"
  29.  * <avr/boot.h> uses sts instructions, but this version uses out instructions
  30.  * This saves cycles and program memory.  Sorry for the name overlap.
  31.  */
  32. #include "boot.h"
  33. #include "spi.h"
  34. #include "nrf24l01.h"
  35.  
  36.  
  37. // We don't use <avr/wdt.h> as those routines have interrupt overhead we don't need.
  38.  
  39. /*
  40.  * pin_defs.h
  41.  * This contains most of the rather ugly defines that implement our
  42.  * ability to use UART=n and LED=D3, and some avr family bit name differences.
  43.  */
  44. #include "pin_defs.h"
  45.  
  46. /*
  47.  * stk500.h contains the constant definitions for the stk500v1 comm protocol
  48.  */
  49. #include "stk500.h"
  50.  
  51. #ifndef LED_START_FLASHES
  52. #define LED_START_FLASHES 0
  53. #endif
  54.  
  55. /* set the UART baud rate defaults */
  56. #ifndef BAUD_RATE
  57. #if F_CPU >= 8000000L
  58. #define BAUD_RATE   115200L // Highest rate Avrdude win32 will support
  59. #elsif F_CPU >= 1000000L
  60. #define BAUD_RATE   9600L   // 19200 also supported, but with significant error
  61. #elsif F_CPU >= 128000L
  62. #define BAUD_RATE   4800L   // Good for 128kHz internal RC
  63. #else
  64. #define BAUD_RATE 1200L     // Good even at 32768Hz
  65. #endif
  66. #endif
  67.  
  68. #ifndef UART
  69. #define UART 0
  70. #endif
  71.  
  72. #define BAUD_SETTING (( (F_CPU + BAUD_RATE * 4L) / ((BAUD_RATE * 8L))) - 1 )
  73. #define BAUD_ACTUAL (F_CPU/(8 * ((BAUD_SETTING)+1)))
  74. #define BAUD_ERROR (( 100*(BAUD_RATE - BAUD_ACTUAL) ) / BAUD_RATE)
  75.  
  76. #if BAUD_ERROR >= 5
  77. #error BAUD_RATE error greater than 5%
  78. #elif BAUD_ERROR <= -5
  79. #error BAUD_RATE error greater than -5%
  80. #elif BAUD_ERROR >= 2
  81. #warning BAUD_RATE error greater than 2%
  82. #elif BAUD_ERROR <= -2
  83. #warning BAUD_RATE error greater than -2%
  84. #endif
  85.  
  86. #if (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 > 250
  87. #error Unachievable baud rate (too slow) BAUD_RATE
  88. #endif // baud rate slow check
  89. #if (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 < 3
  90. #if BAUD_ERROR != 0 // permit high bitrates (ie 1Mbps@16MHz) if error is zero
  91. #error Unachievable baud rate (too fast) BAUD_RATE
  92. #endif
  93. #endif // baud rate fastn check
  94.  
  95. /* Watchdog settings */
  96. #define WATCHDOG_OFF    (0)
  97. #define WATCHDOG_16MS   (_BV(WDE))
  98. #define WATCHDOG_32MS   (_BV(WDP0) | _BV(WDE))
  99. #define WATCHDOG_64MS   (_BV(WDP1) | _BV(WDE))
  100. #define WATCHDOG_125MS  (_BV(WDP1) | _BV(WDP0) | _BV(WDE))
  101. #define WATCHDOG_250MS  (_BV(WDP2) | _BV(WDE))
  102. #define WATCHDOG_500MS  (_BV(WDP2) | _BV(WDP0) | _BV(WDE))
  103. #define WATCHDOG_1S     (_BV(WDP2) | _BV(WDP1) | _BV(WDE))
  104. #define WATCHDOG_2S     (_BV(WDP2) | _BV(WDP1) | _BV(WDP0) | _BV(WDE))
  105. #ifndef __AVR_ATmega8__
  106. #define WATCHDOG_4S     (_BV(WDP3) | _BV(WDE))
  107. #define WATCHDOG_8S     (_BV(WDP3) | _BV(WDP0) | _BV(WDE))
  108. #endif
  109.  
  110.  
  111. /*
  112.  * We can never load flash with more than 1 page at a time, so we can save
  113.  * some code space on parts with smaller pagesize by using a smaller int.
  114.  */
  115. #if SPM_PAGESIZE > 255
  116. typedef uint16_t pagelen_t ;
  117. #define GETLENGTH(len) len = getch()<<8; len |= getch()
  118. #else
  119. typedef uint8_t pagelen_t;
  120. #define GETLENGTH(len) (void) getch() /* skip high byte */; len = getch()
  121. #endif
  122.  
  123.  
  124. /* Function Prototypes
  125.  * The main() function is in init9, which removes the interrupt vector table
  126.  * we don't need. It is also 'OS_main', which means the compiler does not
  127.  * generate any entry or exit code itself (but unlike 'naked', it doesn't
  128.  * supress some compile-time options we want.)
  129.  */
  130.  
  131. int main(void) __attribute__ ((OS_main)) __attribute__ ((section (".init0")));
  132.  
  133.  
  134. void __attribute__((noinline)) putch(char);
  135. uint8_t __attribute__((noinline)) getch(void);
  136. void __attribute__((noinline)) verifySpace();
  137. void __attribute__((noinline)) watchdogConfig(uint8_t x);
  138.  
  139. static inline void getNch(uint8_t);
  140. static inline void flash_led(uint8_t);
  141. static inline void watchdogReset();
  142. static inline void writebuffer(int8_t memtype, uint8_t *mybuff,
  143.         uint16_t address, pagelen_t len);
  144. static inline void read_mem(uint8_t memtype,
  145.         uint16_t address, pagelen_t len);
  146.  
  147. #ifdef SOFT_UART
  148. void uartDelay() __attribute__ ((naked));
  149. #endif
  150. void appStart(uint8_t rstFlags) __attribute__ ((naked));
  151.  
  152. /*
  153.  * RAMSTART should be self-explanatory.  It's bigger on parts with a
  154.  * lot of peripheral registers.  Let 0x100 be the default
  155.  * Note that RAMSTART (for optiboot) need not be exactly at the start of RAM.
  156.  */
  157. #if !defined(RAMSTART)  // newer versions of gcc avr-libc define RAMSTART
  158. #define RAMSTART 0x100
  159. #if defined (__AVR_ATmega644P__)
  160. // correct for a bug in avr-libc
  161. #undef SIGNATURE_2
  162. #define SIGNATURE_2 0x0A
  163. #elif defined(__AVR_ATmega1280__)
  164. #undef RAMSTART
  165. #define RAMSTART (0x200)
  166. #endif
  167. #endif
  168.  
  169. /* C zero initialises all global variables. However, that requires */
  170. /* These definitions are NOT zero initialised, but that doesn't matter */
  171. /* This allows us to drop the zero init code, saving us memory */
  172. #define buff    ((uint8_t*)(RAMSTART))
  173. #ifdef VIRTUAL_BOOT_PARTITION
  174. #define rstVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+4))
  175. #define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
  176. #endif
  177.  
  178.  
  179. // XXX broken!!
  180. static inline void uart_puts(char *buf)
  181. {
  182.     char *p = buf;
  183.     while(1) {
  184.         putch(*p);
  185.         if (*p == 0)
  186.             break;
  187.         p++;
  188.     }
  189. }
  190.  
  191. /* main program starts here */
  192. int main(void) {
  193.     uint8_t ch;
  194.     uint8_t addrtx0[NRF24L01_ADDRSIZE] = NRF24L01_ADDRP0;
  195.     char *p;
  196.     static const char *str = "hello";
  197.  
  198.     /*
  199.      * Making these local and in registers prevents the need for initializing
  200.      * them, and also saves space because code no longer stores to memory.
  201.      * (initializing address keeps the compiler happy, but isn't really
  202.      *  necessary, and uses 4 bytes of flash.)
  203.      */
  204.     register uint16_t address = 0;
  205.     register pagelen_t  length;
  206.  
  207.     // After the zero init loop, this is the first code to run.
  208.     //
  209.     // This code makes the following assumptions:
  210.     //  No interrupts will execute
  211.     //  SP points to RAMEND
  212.     //  r1 contains zero
  213.     //
  214.     // If not, uncomment the following instructions:
  215.     // cli();
  216.     asm volatile ("clr __zero_reg__");
  217. #if defined(__AVR_ATmega8__) || defined (__AVR_ATmega32__)
  218.     SP=RAMEND;  // This is done by hardware reset
  219. #endif
  220.  
  221.     /*
  222.      * modified Adaboot no-wait mod.
  223.      * Pass the reset reason to app.  Also, it appears that an Uno poweron
  224.      * can leave multiple reset flags set; we only want the bootloader to
  225.      * run on an 'external reset only' status
  226.      */
  227.     ch = MCUSR;
  228.     MCUSR = 0;
  229.     if (ch & (_BV(WDRF) | _BV(BORF) | _BV(PORF)))
  230.         appStart(ch);
  231.  
  232. #if LED_START_FLASHES > 0
  233.     // Set up Timer 1 for timeout counter
  234.     TCCR1B = _BV(CS12) | _BV(CS10); // div 1024
  235. #endif
  236.  
  237. #ifndef SOFT_UART
  238. #if defined(__AVR_ATmega8__) || defined (__AVR_ATmega32__)
  239.     UCSRA = _BV(U2X); //Double speed mode USART
  240.     UCSRB = _BV(RXEN) | _BV(TXEN);  // enable Rx & Tx
  241.     UCSRC = _BV(URSEL) | _BV(UCSZ1) | _BV(UCSZ0);  // config USART; 8N1
  242.     UBRRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
  243. #else
  244.     UART_SRA = _BV(U2X0); //Double speed mode USART0
  245.     UART_SRB = _BV(RXEN0) | _BV(TXEN0);
  246.     UART_SRC = _BV(UCSZ00) | _BV(UCSZ01);
  247.     UART_SRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
  248. #endif
  249. #endif
  250.  
  251.     // Set up watchdog to trigger after 500ms
  252.     watchdogConfig(WATCHDOG_2S);
  253.     //watchdogConfig(WATCHDOG_OFF);
  254.  
  255. #if (LED_START_FLASHES > 0) || defined(LED_DATA_FLASH)
  256.     /* Set LED pin as output */
  257.     LED_DDR |= _BV(LED);
  258. #endif
  259.  
  260. #ifdef SOFT_UART
  261.     /* Set TX pin as output */
  262.     UART_DDR |= _BV(UART_TX_BIT);
  263. #endif
  264.  
  265. #if LED_START_FLASHES > 0
  266.     /* Flash onboard LED to signal entering of bootloader */
  267.     flash_led(LED_START_FLASHES * 2);
  268. #endif
  269.  
  270.     putch('-');
  271.     uart_puts(str);
  272.     uart_puts("blaa");
  273.  
  274.     for(;;) {
  275.         uint8_t pipe = 0;
  276.         if(nrf24l01_readready(&pipe))
  277.             nrf24l01_read(bufferin);
  278.         _delay_ms(10);
  279.     }*/
  280.  
  281.     /* Forever loop: exits by causing WDT reset */
  282.     for (;;) {
  283.         /* get character from UART */
  284.         ch = getch();
  285.  
  286.         if(ch == STK_GET_PARAMETER) {
  287.             unsigned char which = getch();
  288.             verifySpace();
  289.             /*
  290.              * Send optiboot version as "SW version"
  291.              * Note that the references to memory are optimized away.
  292.              */
  293.             if (which == 0x82) {
  294.                 putch(optiboot_version & 0xFF);
  295.             } else if (which == 0x81) {
  296.                 putch(optiboot_version >> 8);
  297.             } else {
  298.                 /*
  299.                  * GET PARAMETER returns a generic 0x03 reply for
  300.                  * other parameters - enough to keep Avrdude happy
  301.                  */
  302.                 putch(0x03);
  303.             }
  304.         }
  305.         else if(ch == STK_SET_DEVICE) {
  306.             // SET DEVICE is ignored
  307.             getNch(20);
  308.         }
  309.         else if(ch == STK_SET_DEVICE_EXT) {
  310.             // SET DEVICE EXT is ignored
  311.             getNch(5);
  312.         }
  313.         else if(ch == STK_LOAD_ADDRESS) {
  314.             // LOAD ADDRESS
  315.             uint16_t newAddress;
  316.             newAddress = getch();
  317.             newAddress = (newAddress & 0xff) | (getch() << 8);
  318. #ifdef RAMPZ
  319.             // Transfer top bit to RAMPZ
  320.             RAMPZ = (newAddress & 0x8000) ? 1 : 0;
  321. #endif
  322.             newAddress += newAddress; // Convert from word address to byte address
  323.             address = newAddress;
  324.             verifySpace();
  325.         }
  326.         else if(ch == STK_UNIVERSAL) {
  327.             // UNIVERSAL command is ignored
  328.             getNch(4);
  329.             putch(0x00);
  330.         }
  331.         /* Write memory, length is big endian and is in bytes */
  332.         else if(ch == STK_PROG_PAGE) {
  333.             // PROGRAM PAGE - we support flash programming only, not EEPROM
  334.             uint8_t desttype;
  335.             uint8_t *bufPtr;
  336.             pagelen_t savelength;
  337.  
  338.             GETLENGTH(length);
  339.             savelength = length;
  340.             desttype = getch();
  341.  
  342.             // read a page worth of contents
  343.             bufPtr = buff;
  344.             do *bufPtr++ = getch();
  345.             while (--length);
  346.  
  347.             // Read command terminator, start reply
  348.             verifySpace();
  349.  
  350. #ifdef VIRTUAL_BOOT_PARTITION
  351.             if ((uint16_t)(void*)address == 0) {
  352.                 // This is the reset vector page. We need to live-patch the code so the
  353.                 // bootloader runs.
  354.                 //
  355.                 // Move RESET vector to WDT vector
  356.                 uint16_t vect = buff[0] | (buff[1]<<8);
  357.                 rstVect = vect;
  358.                 wdtVect = buff[8] | (buff[9]<<8);
  359.                 vect -= 4; // Instruction is a relative jump (rjmp), so recalculate.
  360.                 buff[8] = vect & 0xff;
  361.                 buff[9] = vect >> 8;
  362.  
  363.                 // Add jump to bootloader at RESET vector
  364.                 buff[0] = 0x7f;
  365.                 buff[1] = 0xce; // rjmp 0x1d00 instruction
  366.             }
  367. #endif
  368.  
  369.             writebuffer(desttype, buff, address, savelength);
  370.  
  371.  
  372.         }
  373.         /* Read memory block mode, length is big endian.  */
  374.         else if(ch == STK_READ_PAGE) {
  375.             uint8_t desttype;
  376.             GETLENGTH(length);
  377.  
  378.             desttype = getch();
  379.  
  380.             verifySpace();
  381.  
  382.             read_mem(desttype, address, length);
  383.         }
  384.  
  385.         /* Get device signature bytes  */
  386.         else if(ch == STK_READ_SIGN) {
  387.             // READ SIGN - return what Avrdude wants to hear
  388.             verifySpace();
  389.             putch(SIGNATURE_0);
  390.             putch(SIGNATURE_1);
  391.             putch(SIGNATURE_2);
  392.         }
  393.         else if (ch == STK_LEAVE_PROGMODE) { /* 'Q' */
  394.             // Adaboot no-wait mod
  395.             watchdogConfig(WATCHDOG_16MS);
  396.             verifySpace();
  397.         }
  398.         else {
  399.             // This covers the response to commands like STK_ENTER_PROGMODE
  400.             verifySpace();
  401.         }
  402.         putch(STK_OK);
  403.     }
  404. }
  405.  
  406. void putch(char ch) {
  407.     while (!(UART_SRA & _BV(UDRE0)));
  408.     UART_UDR = ch;
  409. }
  410.  
  411. uint8_t getch(void) {
  412.     uint8_t ch;
  413.  
  414. #ifdef LED_DATA_FLASH
  415. #if defined(__AVR_ATmega8__) || defined (__AVR_ATmega32__)
  416.     LED_PORT ^= _BV(LED);
  417. #else
  418.     LED_PIN |= _BV(LED);
  419. #endif
  420. #endif
  421.  
  422.     while(!(UART_SRA & _BV(RXC0)))
  423.         ;
  424.     if (!(UART_SRA & _BV(FE0))) {
  425.         /*
  426.          * A Framing Error indicates (probably) that something is talking
  427.          * to us at the wrong bit rate.  Assume that this is because it
  428.          * expects to be talking to the application, and DON'T reset the
  429.          * watchdog.  This should cause the bootloader to abort and run
  430.          * the application "soon", if it keeps happening.  (Note that we
  431.          * don't care that an invalid char is returned...)
  432.          */
  433.         watchdogReset();
  434.     }
  435.  
  436.     ch = UART_UDR;
  437.  
  438. #ifdef LED_DATA_FLASH
  439. #if defined(__AVR_ATmega8__) || defined (__AVR_ATmega32__)
  440.     LED_PORT ^= _BV(LED);
  441. #else
  442.     LED_PIN |= _BV(LED);
  443. #endif
  444. #endif
  445.  
  446.     return ch;
  447. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement