Advertisement
Guest User

BootYocto.c

a guest
Mar 4th, 2017
220
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 7.78 KB | None | 0 0
  1. /**********************************************************/
  2. /* Midi Bootloader for Atmel megaAVR Controllers          */
  3. /* Pour Yocto                                             */
  4. /* Laurent Lecatelier                                     */
  5. /**********************************************************/
  6.  
  7. /* some includes */
  8. #include <inttypes.h>
  9. #include <avr/io.h>
  10. #include <avr/pgmspace.h>
  11. #include <avr/interrupt.h>
  12. #include <avr/wdt.h>
  13. #include <util/delay.h>
  14.  
  15. #include <avr/eeprom.h>
  16. #include <avr/boot.h>
  17.  
  18. #define MAX_ERROR_COUNT 5
  19. #define NUM_LED_FLASHES 2
  20.  
  21.  
  22. #ifndef BAUD_RATE
  23. #define BAUD_RATE   31250
  24. #endif
  25.  
  26.  
  27. /* SW_MAJOR and MINOR needs to be updated from time to time to avoid warning message from AVR Studio */
  28. /* never allow AVR Studio to do an update !!!! */
  29. #define HW_VER   0x01
  30. #define SW_MAJOR 0x01
  31. #define SW_MINOR 0x10
  32.  
  33.  
  34.  
  35. #define LED_DDR  DDRB
  36. #define LED_PORT PORTB
  37. #define LED_PIN  PINB
  38. #define LED      PINB0
  39.  
  40.  
  41. /* define various device id's */
  42. /* manufacturer byte is always the same */
  43. #define SIG1    0x1E    // Yep, Atmel is the only manufacturer of AVR micros.  Single source :(
  44. #define SIG2    0x97
  45. #define SIG3    0x05
  46.  
  47.  
  48. #define MATCHING_HEADER 0
  49. #define READING_COMMAND 2
  50. #define READING_DATA 3
  51.  
  52.  
  53.  
  54.  
  55. /* function prototypes */
  56. void putch(char);
  57. char getch(void);
  58. void flash_led(uint8_t);
  59. void shiftOut_SRIO(uint8_t value);
  60. uint8_t shiftIn_SRIO(void) ;
  61. uint8_t Button_Step_Read(void) ;
  62. void Midiloop(void);
  63. void LedStep(uint16_t value);
  64. void boot_program_page (uint32_t page, uint8_t *buf);
  65.  
  66.  
  67. /* some variables */
  68. union address_union
  69. {
  70.   uint16_t word;
  71.   uint8_t  byte[2];
  72. } address;
  73.  
  74. union length_union
  75. {
  76.   uint16_t word;
  77.   uint8_t  byte[2];
  78. } length;
  79.  
  80. struct flags_struct
  81. {
  82.   unsigned eeprom : 1;
  83.   unsigned rampz  : 1;
  84. } flags;
  85.  
  86.  
  87. const uint8_t sysex_header[] = {
  88.   0xf0,  // <SysEx>
  89.   0x7d,  // Non commercial
  90.   0x08, 0x08,  // Product ID  Yocto 0808
  91.   0x02, // Nb Oct Cmd
  92. };
  93.  
  94.  
  95. uint32_t page = 0;
  96. uint8_t rx_buffer[ 2 * (SPM_PAGESIZE + 1)];
  97.  
  98.  
  99. uint8_t buff[256];
  100. uint8_t address_high;
  101.  
  102. uint8_t pagesz=0x80;
  103.  
  104. uint8_t i;
  105. uint8_t bootuart = 0;
  106.  
  107. uint8_t error_count = 0;
  108.  
  109. void (*app_start)(void) = 0x00000;
  110.  
  111.  
  112.  
  113.  
  114. /* main program starts here */
  115. int main(void)
  116. {
  117.   uint8_t ch;
  118.  
  119.   ch = MCUSR;
  120.   MCUSR = 0;
  121.   WDTCSR |= _BV(WDCE) | _BV(WDE);
  122.   WDTCSR = 0;
  123.  
  124. /*
  125.   if (! (ch &  _BV(EXTRF))) // if its a not an external reset...
  126.       app_start();  // skip bootloader
  127.  */
  128.  
  129.     bootuart = 2;
  130.  
  131.   // Programmation de Serial 1     
  132.  
  133.     UBRR1L = (uint8_t)(F_CPU/(BAUD_RATE*16L)-1);
  134.     UBRR1H = (F_CPU/(BAUD_RATE*16L)-1) >> 8;
  135.     UCSR1A = 0x00;
  136.     UCSR1C = 0x06;
  137.     UCSR1B = _BV(TXEN1)|_BV(RXEN1);
  138.  
  139.   // Port B Pour lire les touches et emettre les Led
  140.  
  141.   DDRB =  0b10111111;
  142.  
  143.   // Test du flash des 16 boutons
  144.  
  145.  
  146.  
  147.   if ( Button_Step_Read() == 0b10101 ) // On appuie au boot sur le bouton 1+3+5
  148.   {
  149.         flash_led(NUM_LED_FLASHES);
  150.        
  151. //      LedStep(SPM_PAGESIZE);
  152. //      _delay_ms(300);
  153.    
  154.         Midiloop();
  155.  
  156.         flash_led(NUM_LED_FLASHES);
  157.  
  158.  }
  159.    
  160.   app_start();
  161.  
  162.   return 0;
  163. }
  164.  
  165.  
  166. void putch(char ch)
  167. {
  168.     while (!(UCSR1A & _BV(UDRE1)));
  169.     UDR1 = ch;
  170. }
  171.  
  172.  
  173. char getch(void)
  174. {
  175.   uint32_t count = 0;
  176.   while(!(UCSR1A & _BV(RXC1)))
  177.   {
  178.       /* 20060803 DojoCorp:: Addon coming from the previous Bootloader*/
  179.       /* HACKME:: here is a good place to count times*/
  180.       count++;
  181.       if (count > MAX_TIME_COUNT)
  182.         app_start();
  183.   }
  184.   return UDR1;
  185. }
  186.  
  187.  
  188.  
  189. void flash_led(uint8_t count)
  190. {
  191.   while (count--)
  192.   {
  193.     PORTB &= ~(1 << 4 );
  194.     shiftOut_SRIO(0xFF);
  195.     shiftOut_SRIO(0xFF);
  196.     PORTB |= ( 1 << 4 );
  197.  
  198.     _delay_ms(100);
  199.    
  200.     PORTB &= ~(1 << 4 );
  201.     shiftOut_SRIO(0);
  202.     shiftOut_SRIO(0);
  203.     PORTB |= ( 1 << 4 );
  204.    
  205.     _delay_ms(100);
  206.  
  207.   }
  208. }
  209.  
  210.  
  211. uint8_t shiftIn_SRIO(void)
  212. {
  213.     uint8_t value = 0;
  214.     uint8_t i = 0;
  215.     while (i < 8 ) {
  216.         value |= (  ( ( PINB & 0b01000000 ) >> 6 ) << (7-i) );//value |  (digitalRead(6) << (7-i));
  217.         PORTB |= (1<<7);//digitalWrite(7, HIGH);
  218.         PORTB &= ~(1<<7);// digitalWrite(7, LOW);
  219.         i++;
  220.     }
  221.     return value;
  222. }
  223.  
  224. void shiftOut_SRIO(uint8_t value)
  225. {
  226.     uint8_t i;
  227.     uint8_t mask=0x80;
  228.  
  229.     for (i = 0; i < 8; i++)  
  230.     {
  231.         if ( ( value & mask ) == mask )
  232.             PORTB |= (1<<5);
  233.         else
  234.             PORTB &= ~(1<<5);
  235.         PORTB |=  (1<<7) ;
  236.         PORTB &= ~(1<<7) ;
  237.         mask>>=1;
  238.     }
  239.  
  240. }
  241.  
  242. uint8_t Button_Step_Read(void)
  243. {
  244.   uint8_t firstbyte;
  245.   PORTB |= (1<<3);
  246.   firstbyte = shiftIn_SRIO();
  247.   PORTB &= ~(1<<3);
  248.   return firstbyte;
  249. }  
  250.  
  251.  
  252. void LedStep(uint16_t value)
  253. {
  254.     PORTB &= ~(1 << 4 );
  255.     shiftOut_SRIO( value >> 8 );
  256.     shiftOut_SRIO( value & 0xFF );
  257.     PORTB |= ( 1 << 4 );
  258. }
  259.  
  260.  
  261. void boot_program_page (uint32_t page, uint8_t *buf)
  262. {
  263.     uint16_t i;
  264.     uint8_t sreg;
  265.  
  266.     // Disable interrupts.
  267.  
  268.     sreg = SREG;
  269.     cli();
  270.  
  271.     eeprom_busy_wait ();
  272.  
  273.     boot_page_erase (page);
  274.     boot_spm_busy_wait ();      // Wait until the memory is erased.
  275.  
  276.     for (i=0; i<SPM_PAGESIZE; i+=2)
  277.     {
  278.         // Set up little-endian word.
  279.  
  280.         uint16_t w =  buf[i] | (buf[i + 1] << 8);
  281.    
  282.         boot_page_fill (page + i, w);
  283.     }
  284.  
  285.     boot_page_write (page);     // Store buffer in flash page.
  286.     boot_spm_busy_wait();       // Wait until the memory is written.
  287.  
  288.     // Reenable RWW-section again. We need this if we want to jump back
  289.     // to the application after bootloading.
  290.  
  291.     boot_rww_enable ();
  292.  
  293.     // Re-enable interrupts (if they were ever enabled).
  294.  
  295.     SREG = sreg;
  296. }
  297.  
  298. void Midiloop(void) {
  299.  
  300.   uint8_t byte;
  301.   uint16_t bytes_read = 0;
  302.   uint16_t rx_buffer_index =0;
  303.   uint8_t state = MATCHING_HEADER;
  304.   uint8_t checksum = 0;
  305.   uint8_t sysex_commands[2];
  306.   uint16_t progress_counter = 0;
  307.  
  308.   page = 0;
  309.  
  310.  
  311.   while (1) {
  312.  
  313.     byte = getch();
  314.     // In case we see a realtime message in the stream, safely ignore it.
  315.     if (byte > 0xf0 && byte != 0xf7) {
  316.       continue;
  317.     }
  318.  
  319.     switch (state) {
  320.       case MATCHING_HEADER:
  321.         if (byte == sysex_header[bytes_read]) {
  322.           ++bytes_read;
  323.           if (bytes_read == sizeof(sysex_header)) {
  324.             bytes_read = 0;
  325.             state = READING_COMMAND;
  326.           }
  327.         } else {
  328.           bytes_read = 0;
  329.         }
  330.         break;
  331.        
  332.  
  333.       case READING_COMMAND:
  334.         if (byte < 0x80) {
  335.           sysex_commands[bytes_read++] = byte;
  336.           if (bytes_read == 2) {
  337.             bytes_read = 0;
  338.             rx_buffer_index = 0;
  339.             checksum = 0;
  340.             state = READING_DATA;
  341.              ++progress_counter;
  342.             LedStep(progress_counter);
  343.          }
  344.         } else {
  345.              state = MATCHING_HEADER;
  346.              progress_counter=0;
  347.              LedStep(progress_counter);
  348.              bytes_read = 0;
  349.         }
  350.         break;
  351.  
  352.       case READING_DATA:
  353.         if (byte < 0x80) {
  354.           if (bytes_read & 1) {
  355.             rx_buffer[rx_buffer_index] |= byte & 0xf;
  356.             if (rx_buffer_index < SPM_PAGESIZE ) {
  357.               checksum += rx_buffer[rx_buffer_index];
  358.             }
  359.             ++rx_buffer_index;
  360.           } else {
  361.             rx_buffer[rx_buffer_index] = (byte << 4);
  362.           }
  363.           ++bytes_read;
  364.         } else if (byte == 0xf7) {
  365.           if (sysex_commands[0] == 0x7f &&
  366.               sysex_commands[1] == 0x00 &&
  367.               bytes_read == 0) {
  368.             // Reset.
  369.             return;
  370.           } else if (rx_buffer_index == SPM_PAGESIZE + 1 &&
  371.                      sysex_commands[0] == 0x7e &&
  372.                      sysex_commands[1] == 0x00 &&
  373.                     rx_buffer[rx_buffer_index - 1] == checksum) {
  374.             // Block write.
  375.             boot_program_page(page,rx_buffer);
  376.             page += SPM_PAGESIZE;
  377.             ++progress_counter;
  378.             LedStep(progress_counter);
  379.           }
  380.           state = MATCHING_HEADER;
  381.           bytes_read = 0;
  382.         }
  383.         break;
  384.     }
  385.   }
  386. }
  387.  
  388. /* end of file BootYocto.c */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement