Succ-U-Bus

Discussions of any related software

Moderator: Related software moderators

Re: Succ-U-Bus

Postby Ken Forgettable » Mon Sep 28, 2009 5:18 pm

elrules wrote:After 5 pages of thread I still have not ucking idea of what Succ-u-bus is

Could you explain without retorical words what is your project about?
;)
> You are playing the drums and decide to use MCT to change a setting.
MCT asks if you want to use the latest firmware.
> You carry on playing the drums.

As the man says: it's pretty simple really.
... it's another bootloader 8-)
Last edited by Ken Forgettable on Tue Dec 29, 2009 12:41 am, edited 1 time in total.
Ken Forgettable
 
Posts: 402
Joined: Tue Jan 06, 2009 5:04 pm

Re: Succ-U-Bus

Postby elrules » Tue Sep 29, 2009 1:54 pm

Ok, so you want to program a new bootloader and maybe some changes to MCT, right? to make it easier and more platform independent the process of updating the firmware
elrules
 
Posts: 629
Joined: Thu Nov 29, 2007 4:51 pm
Location: Murcia, Spain, Europe, The World

Re: Succ-U-Bus

Postby Ken Forgettable » Wed Sep 30, 2009 10:13 am

elrules wrote:Ok, so you want to program a new bootloader and maybe some changes to MCT, right? to make it easier and more platform independent the process of updating the firmware
Yes. I'm going to use the MCT v1.81 R22 sources.
Ken Forgettable
 
Posts: 402
Joined: Tue Jan 06, 2009 5:04 pm

Re: Succ-U-Bus

Postby elrules » Wed Sep 30, 2009 3:29 pm

It is going to be an open-source project, right?

Tell us when you have found a solution to the updating problems ;)
elrules
 
Posts: 629
Joined: Thu Nov 29, 2007 4:51 pm
Location: Murcia, Spain, Europe, The World

Re: Succ-U-Bus

Postby Ken Forgettable » Thu Oct 08, 2009 9:16 am

elrules wrote:It is going to be an open-source project, right?
If anyone is interested in testing I can post a diff to the MCT v1.81 R22 sources, but you'll need to install the new bootloader and use my test app' firmware - which can do WDT resets :P
Last edited by Ken Forgettable on Tue Dec 29, 2009 12:41 am, edited 1 time in total.
Ken Forgettable
 
Posts: 402
Joined: Tue Jan 06, 2009 5:04 pm

Re: Succ-U-Bus

Postby Ken Forgettable » Sat Oct 10, 2009 1:26 am

Stick this in yer pipe and smoke it.
Code: Select all
/* -> c.Succ-U-Bus
 *
 * Status:      Beta
 * Copyright:   (c) 2009, Ken Forgettable
 * Version:      see version[] below
 * Date:      090929
 * Purpose:
 * Headless Megadrum AVR bootloader for ATmega32 (?), ATmega324p and ATmega644p.
 *
 * Built with:
 *    AVR Studio   4.16.628 
 *   GUI Version   4, 16, 0, 626
 *                           
 *   Plugins:
 *      AvrPluginAvrAsmObject   1, 0, 0, 47
 *      AvrPluginavrgccplugin   1, 0, 0, 10
 *                           
 *      using WinAVR-20081205
 *
 *   Add to project config [All files]
 *      -fno-inline-small-functions
 *      -fno-inline-functions
 *
 * NB. Build and simulate for ATmega644P at 16MHz as the code size is largest.
 *
 * 090622 - Test: compiled to 324p @16MHz - ok
 * 090703 - Beta: compiled to 324p @16MHz - ok at 1694prog, 800data
 * 090924 - prettyfied, tidied globals, added version string - 1812prog, 798data
 */

/****************************** Includes ******************************
 */
#include <avr/wdt.h>         //iomxx4.h
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <avr/boot.h>
const char version[] PROGMEM = "Succ-U-Bus v0.37";


/****************************** Definitions ***************************
 */
 #ifndef F_CPU
/* prevent compiler error by supplying a default */
# error "F_CPU not defined in project options"
// # define F_CPU 16000000UL
#endif
 
 
 
 
 #define UART_BAUD_HIGH   UBRR0H
 #define UART_BAUD_LOW   UBRR0L
 #define UART_STATUS   UCSR0A
 #define UART_TXREADY   UDRE0
#define UART_RXREADY   RXC0
 #define UART_CTRL      UCSR0B
 #define UART_CTRL_DATA   ((1<<TXEN0) | (1<<RXEN0))
 #define UART_CTRL2      UCSR0C
 #define UART_CTRL2_DATA   ((1<<UCSZ01) | (1<<UCSZ00))  //asynchronus internal clocking (not XCK0)
 #define UART_DATA      UDR0

#define TIFRn TIFR1


#define PORT_MIDILED   PORTC
#define DDR_MIDILED      DDRC
#define MIDILED_PIN      0b00100000


//#define T_START         ((0<<CS12) | (0<<CS11) | (1<<CS10))      //freq = clock
//#define T_START         ((1<<CS12) | (0<<CS11) | (0<<CS10))      //freq = clock / 256
#define T_START   ((1<<CS12) | (0<<CS11) | (1<<CS10))               //freq = clock / 1024
#define T_STOP   ((0<<CS12) | (0<<CS11) | (0<<CS10))               //stop


#define BIT_SET(ADDRESS,BIT) (ADDRESS |= (1<<BIT))
#define BIT_CLR(ADDRESS,BIT) (ADDRESS &= ~(1<<BIT))
#define BIT_CHECK(ADDRESS,BIT) (ADDRESS & (1<<BIT))


#define   ZAPPED (uint32_t) 0x0000940c         //little edian - this is JMP 0x0000 in the reset vector

#define SYX_ERASE      0xf7417ff0   //little edian
#define SYX_FIRMWARE   0xf7407ff0   //little edian
#define SYX_SOX         0xF0
#define SYX_EOX         0xF7

#define FLASH_PAGESIZE 0x100                              //largest (ATmega644) SPM_PAGESIZE

#define ERR_NORECEPTION   0x01   //unused (as no error if page == 0 hasn't been written)
#define ERR_TOOBIG      0x02
#define ERR_PARITY      0x04
#define ERR_TIMEOUT      0x08
#define ERR_CONTIG      0x10
#define ERR_WRITING      0x20
#define ERR_ANDMASK      0x3f   //NB. flash is assumed empty if err is reported as 0x7F

/****************************** Globals ********************************
 */
uint8_t err;                                          //global error accumulator

uint8_t spmData_index;
uint8_t spmData[FLASH_PAGESIZE];

uint16_t sysexData_index;
uint8_t sysexData[(FLASH_PAGESIZE * 2) + 16];                  //largest SysEx payload (hex record)

uint8_t sysexMsg_index;
uint8_t sysexMsg[4];
uint32_t * sysexMsg_ptr = (uint32_t *) &sysexMsg;               //SysEx type store

uint8_t semaphor_device = 0;                              //semaphors get dumped in ram after
uint8_t semaphor_baud;                                    //a succesful update and are thus
uint8_t semaphor_adcs;                                    //available to new app FW...FIXME

//uint8_t ee_calced __attribute__((section(".eeprom")));
//uint8_t ee_actual __attribute__((section(".eeprom")));

//volatile uint16_t crap;


/****************************** Functions *******************************
 * .text section - usual code section.
 * All initial sections are prepended to this area therefore
 * relocating .text to a different address will also relocate the
 * previous sections too.
 *
 * Relocate to Bootloader address with
 * Project->Configuration Options->Memory Settings
 * Add Memory Segment:   Memory Type   - Flash
 *                  Name      - .text
 *                  Address (1024 words) - (((FLASHEND + 1) - (BOOTSIZE * 2)) / 2)
 *                  Atmega32 and ATmega324p = 0x3c00, BOOTSZ1 = Set, BOOTSZ0 = Clr
 *                               ATmega644p = 0x7c00, BOOTSZ1 = Clr, BOOTSZ0 = Set
 */


/*----------------------------- sendByte -----------------------------
 * Description:      Sends data
 *
 * Parameters:      data to send
 * Returns:         void
 * Other Info:
 *               waits until transmission is possible
 */
static void sendByte(uint8_t data) {
   loop_until_bit_is_set(UART_STATUS, UART_TXREADY);            //Wait for empty transmit buffer and

   UART_DATA = data;                                    //stuff data into UART TX buffer
}



/*----------------------------- kill_wdt -----------------------------
 * Description:      Turns off WDT
 *
 * Parameters:      void
 * Returns:         void
 * Other Info:
 *               Turns off global interrupts too
 */
static void kill_wdt(void) {
   cli();
   wdt_reset();
   MCUSR &= ~(1<<WDRF);                                 //Need to clear WDT flag for some reason!
   WDTCSR |= (1<<WDCE) | (1<<WDE);                           //Enable WDT change (don't change prescaler)
   WDTCSR = 0x00;                                       //Turn off WDT
}



/*----------------------------- calc_MHz -----------------------------
 * Description:      Determines external crystal speed
 *
 * Parameters:      void
 * Returns:         A magic number
 * Other Info:
 *               calc xtal speed from relationship between 128Khz watchdog and Timer1 cycle count
 *               prescalar = F_CPU (MHz) / Max size of counter
 *               ie: (for timer1 @ 16MHz) (16 * 1000000) / 65536 = 244. Choose nearest prescalar of 256
 *               well!
 *               12MHz = 0x2dc6
 *               16MHz = 0x3d09
 *               20MHz = 0x4c48
 *               24MHz = 0x5b8d
 *               + execution time + upward temp drift of wdt source
 */
uint8_t calc_MHz(void) {
uint8_t baud_magic;

   kill_wdt();                                          //clear current/pending wdt resets

   WDTCSR |= (1<<WDCE) | (1<<WDE);                           //Enable update
   WDTCSR = (1<<WDIF) | (1<<WDIE) | (1<<WDE) |   (0<<WDP3) | (1<<WDP2) | (0<<WDP1) | (1<<WDP1);
                                                   //Interrupt (no reset) with 0.5sec timeout

   TCNT1 = 0x00;                                       //zero timer counter
   TIFR1 = (1<<OCF1B);                                    //clear timer overflow flag
   TCCR1B = T_START;                                    //enable timer

   sei();

   while ((TCCR1B & T_START) != 0) {
      //wait until wdt interrupt has stopped the timer
   };

   kill_wdt();                                          //clear current/pending wdt resets

   baud_magic = (TCNT1 >> 12);                              //get top nibble
   baud_magic += 1;                                    //adjust for multiplication
   baud_magic = (baud_magic << 3);                           //derive XTAL speed * 2
   baud_magic -= 1;                                    //adjust value for UBRR0L


   return baud_magic;
}



/*----------------------------- UARTinit -----------------------------
 * Description:      Configure UART
 *
 * Parameters:      void
 * Returns:         void
 * Other Info:
 *               Uses asyncronus 8,1,n at 31250 baud
 *               1MHz   -   1
 *               12MHz   -   23
 *               16MHz   -   31
 *               20MHz   -   39
 *               24MHz   -   47
 *               It's just ((xtal speed in MHz) * 2) - 1
 *               therefore only ever need need to write to UBRR0L
 */
static void UARTinit(void) {
   UART_CTRL2 = UART_CTRL2_DATA;                           //async' 8,1,n

   UART_BAUD_LOW = 31; //calc_MHz();                        //at 31250 baud
   UART_BAUD_HIGH = 0;

   UART_CTRL = UART_CTRL_DATA;                              //can now enable TX and RX (with RX ISR)
   
//   _delay_ms(5);   //measure TX line high (idle) here

}



/*----------------------------- force_wdt_reset ----------------------
 * Description:      Causes mCU reset using WDT
 *
 * Parameters:      void
 * Returns:         void
 * Other Info:
 */
static void force_wdt_reset(void) {
   kill_wdt();                                          //Clear current/pending wdt resets

   WDTCSR |= (1<<WDCE) | (1<<WDE);                           //Enable update
   WDTCSR = (1<<WDIF) | (0<<WDIE) | (1<<WDE) |   (0<<WDP3) | (0<<WDP2) | (0<<WDP1) | (1<<WDP1);
                                                   //Reset with 32ms timeout

   for (;;) {
      //hang about for reset
   }
}



/*----------------------------- enter_app_fw -------------------------
 * Description:      Function pointer to jump to the applicaion reset vector
 *
 * Parameters:      void
 * Returns:         void - never returning
 * Other Info:      
 */
static void (*enter_app_fw)(void) = 0x0000;



/***********************************************************************
 * Initial sections begin here.
 * All initial sections are prepended to the .text area therefore
 * relocating .text to a different address will also relocate these
 * sections too.
 *
 * See * Functions * description above for relocation.
 */
/*
void __endOfVectors (void) __attribute__ ((naked)) __attribute__ ((section (".vectors")));
void __endOfVectors(void)
{   
//dummy declaration to find address of end of vector table
}*/



/*-----------------------------  -----------------------------
 * Description:      
 *
 * Parameters:      void
 * Returns:         void
 * Other Info:
 */
ISR(BADISR_vect) {
   //Just in case!
}



/*-----------------------------  -----------------------------
 * Description:      
 *
 * Parameters:      void
 * Returns:         void
 * Other Info:
 */
ISR(WDT_vect) {                                          //_VECTOR(8)

   TCCR1B = 0;                                          //stop timer
}



/*-----------------------------  -----------------------------
 * Description:      
 *
 * Parameters:      void
 * Returns:         void
 * Other Info:
 */
ISR(USART0_RX_vect) {
uint8_t sysexData_byte;
   
   sysexData_byte = UART_DATA;                              //get the data

   if (sysexMsg_index < 3) {                              //first 3 bytes should be SysEx but
      if ((sysexMsg[0] == SYX_SOX) || (sysexData_byte == SYX_SOX)) {
         sysexMsg[sysexMsg_index++] = sysexData_byte;         //start buffering only with SYX_SOX

         TCNT1 = 0x00;                                 //increase timeout
      }

   } else {
      if (sysexData_byte == SYX_EOX) {                     //only end buffering at SYX_EOX
         sysexMsg[sysexMsg_index++] = sysexData_byte;         //done - save the end of SysEx and

         TCCR1B = 0;                                    //stop the timer

      } else {                                       //this is the data
         if (sysexData_index < sizeof(sysexData)) {
            sysexData[sysexData_index++] = sysexData_byte;      //buffer the payload

//         } else {
//            err.to_big = 1;                              //flag buffer overrun - trailing crap?!
         }
      }
   }
}



/*-----------------------------  -----------------------------
 * Description:      
 *
 * Parameters:      void
 * Returns:         void
 * Other Info:
 */
static void try_reception(void) {
   sysexData_index = sysexMsg_index = sysexMsg[0] = 0;            //initialise indecies

   BIT_SET(UART_CTRL, RXCIE0);                              //Enable UART RX ISR p.184

   if (calc_MHz() >= UART_BAUD_LOW) {                        //reception must finnish before time out
      err |= ERR_TIMEOUT;                                 //flag timeout
   }

   BIT_CLR(UART_CTRL, RXCIE0);                              //Disable UART RX ISR
}



/*-----------------------------  -----------------------------
 * Description:      
 *
 * Parameters:      void
 * Returns:         void
 * Other Info:
 */
//true - needs update, false - assumed ok
uint8_t isFW_bad(void) {
uint8_t update = 0;
uint32_t resetVec = pgm_read_dword(0x0000);

   if ((resetVec == 0xffffffff) || (resetVec == ZAPPED)) {         //if assumed empty or marked as bad
      update = pgm_read_byte(0x04);                        //get error code (or 0xff - empty)

   } else {
      if (resetVec == 0) {                              //also check if erased
         update = 2;
      }
   }

   return update;
}



/*-----------------------------  -----------------------------
 * Description:      
 *
 * Parameters:      void
 * Returns:         void
 * Other Info:
 * The bootloader is normally entered by the following condition priorities:
 *    1. An External reset (ie ATmega RESET pin grounded - for debugging etc).
 *    2. ANY condition where the app flash is deemed invalid.
 *
 * If non of the above are met then app FW is entered assuming JTAG, Brownout
 * or Power on reset has occured.
 *
 * As a watchdog reset in the app FW should only occur because of coding error
 * or other unhandled time outs - it's reasonable for the bootloader to want
 * new (working) app FW on board, and because JTAG resets are passed to the
 * app FW, there should not be a problem debugging.
 *
 * So, this bootloader insists on running with the mCU in a known state and
 * uses a watchdog reset to achieve this ;¬/
 *    3. The prefered watchdog reset (App' FW or bootloader can initiate this).
 */
uint8_t rst_action(uint8_t type) {
//uint16_t resetVec;
uint8_t tmp = 0;

   if ((type & (1<<WDRF)) != (1<<WDRF)) {                     //Not in the prefered entry condition so
      if ((type & (1<<EXTRF)) != (1<<EXTRF)) {               //If not a manual request and
         tmp = isFW_bad();                              //if app FW is invalid then entry condition 2 is met

      } else {
         tmp = 1;                                    //entry condition 1 met
      }
   
   
      if (tmp == 0) {                                    //Entry conditions still not fully defined?
         kill_wdt();
         MCUCR = (1<<JTD) | (1<<IVCE);                     //Enable change of JTAG and vectors
         MCUCR = 0;                                    //restore entry conditions (PUD disabled)
         MCUSR = type;                                 
         PORT_MIDILED = DDR_MIDILED = 0;                     //restore to default tristate
         enter_app_fw();                                 //Assume JTAG, Brownout or Power on so enter the app FW...
         
      } else {
         force_wdt_reset();                              //try to force the prefered entry condition 3
      }

   } else {

      kill_wdt();                                       //clear current/pending wdt resets
      tmp = 3;                                       //entry condition 3 met
   }

   //Now the mcu is in known condition 3 (with nothing pending)
   return tmp;
}



/*-----------------------------  -----------------------------
 * Description:      
 *
 * Parameters:      void
 * Returns:         void
 * Other Info:
 */
uint8_t lowNibble2asciihex(uint8_t byte) {
uint8_t val;

   val = byte & 0x0f;
   if (val > 9) {
      val += 7;
   }
   val += 0x30;

   return val;
}



/*-----------------------------  -----------------------------
 * Description:      
 *
 * Parameters:      void
 * Returns:         void
 * Other Info:
 */
uint8_t sysexData2spmData(uint16_t index) {
uint8_t tmp;
uint8_t val;

   tmp = sysexData[index];
   tmp -= 0x30;
   if (tmp > 9) {
      tmp -= 7;
   }
   val = tmp<<4;

   tmp = sysexData[++index];
   tmp -= 0x30;
   if (tmp > 9) {
      tmp -= 7;
   }
   val |= tmp;

   return val;
}



/*-----------------------------  -----------------------------
 * Description:      
 *
 * Parameters:      void
 * Returns:         void
 * Other Info:
 */
static void sysexData_checksum(void) {
uint16_t tmp;
uint8_t i;
uint8_t parity;

   sysexData_index = parity = 0;

   if (sysexData[sysexData_index++] == 0x3a) {                  //hex record start
      tmp = sysexData2spmData(sysexData_index) + 4;            //entire record length

      for (i = 0; i <= tmp; i++) {
         parity += sysexData2spmData(sysexData_index);         //calc' parity
         sysexData_index += 2;
      }

   } else {
      parity = 1;
   }

   if (parity) {
      err |= ERR_PARITY;                                 //flag error
   }
}



/*-----------------------------  -----------------------------
 * Description:      
 *
 * Parameters:      void
 * Returns:         void
 * Other Info:
 */
static void sysexData_checkaddr(uint16_t wanted) {
uint16_t have;

   have = (sysexData2spmData(3) << 8);
   have |= sysexData2spmData(5);                        //get hex record address

   if (((have - wanted) != 0)) {                        //check for contiguous data!
      err |= ERR_CONTIG;                              //flag error
   }
}



/*-----------------------------  -----------------------------
 * Description:      
 *
 * Parameters:      void
 * Returns:         void
 * Other Info:
 */
/*
//ok static uint8_t pod[] = ":01000002??FF";
//ok volatile uint8_t pod[] = ":0100000069FF";
//ok static uint8_t pod[] = ":044AC0000895FFCF87";
//ok static uint8_t pod[] = ":00000001FF";
//static uint8_t pod[] = ":0A4B3400021F3F5F7F9FBFDFFF00FD";
//static uint8_t pod[] = ":100100004B69636B00486948617442004869486103";
//static uint8_t pod[] = ":FF010000112233445566778899AABBCCDDEEFF84";
static uint8_t pod[] = ":100000000C94CA030C94E7030C94E7030C94E703E5";
//static uint8_t pod[] = ":100020000C94E7030C94E7030C94E7030C94E703A8";
uint8_t test() {
uint16_t tmp;

   sysexData[1] = pod[1];
   sysexData[2] = pod[2];
   tmp = (sysexData2spmData(1) << 1) + 12;

   for (sysexData_index = 0; sysexData_index <= tmp; sysexData_index++) {
      sysexData[sysexData_index] = pod[sysexData_index];
   }

   return 1;
}
*/



/*----------------------------- spm_topup -----------------------------
 * Description:      Stuffs SPM page buffer with intel HEX data records
 *
 * Parameters:      void
 * Returns:         0 - when SPM page buffer is ready to write
 *               1 - when more data is needed
 * Other Info:
 *records fill spm page until it is full or an end of file record is recieved.
 *if there is remaining data from a record which crossed the spm page boundry then a
 *second call will stuff this into the now fresh spm page buffer.
 */
static void spm_topup(void) {
uint8_t   record_length = sysexData2spmData(1);
uint8_t payload = 9;

   if (record_length > 0) {                              //any data?
      sysexData_index = payload;                           //point to payload

      do {                                          //bung the payload into spm buffer
         spmData[spmData_index] = sysexData2spmData(sysexData_index);

         spmData_index++;                              //will wrap to zero on completion
         sysexData_index += 2;
         record_length--;
      } while (spmData_index && record_length);

      sysexData[1] = lowNibble2asciihex(record_length>>4);      //modify the record length for
      sysexData[2] = lowNibble2asciihex(record_length);         //next topup

      while (record_length--) {                           //adjust the data buffer too
         sysexData[payload++] = sysexData[sysexData_index++];
         sysexData[payload++] = sysexData[sysexData_index++];
      }

   } else {                                          //assume eof if zero lemgth and
      while (spmData_index) {                              //fill remaining for potential md5 checksumming!
         spmData[spmData_index++] = 0xff;
      }

   }
}



/*----------------------------- fud -----------------------------
 * Description:      write flash data without fear
 *
 * Parameters:      index_p - flash page number
 * Returns:         void
 * Other Info:
 * Page size is inferred from device ID signature byte
 * (All parts have 256 pages)
 * 32   -   0x02, (64   words)
 * 324   -   0x08, (64   words)
 * 644   -   0x0A, (128words)1742,832
 */
static void fud(uint8_t index_p) {
uint16_t pageBoundry = index_p << 8;   //index_p << 7; //small devices
uint16_t i;

   boot_spm_interrupt_disable();
   boot_rww_enable_safe();         // Re-enable the RWW section
   cli();

   boot_page_erase_safe(pageBoundry);                        //erase flash page when ready

    for(i = 0; i < FLASH_PAGESIZE; i+=2) {
        boot_page_fill_safe(pageBoundry + i, ((spmData[i+1] << 8) + spmData[i]));
    }
   
   boot_page_write_safe(pageBoundry);                        //write page when ready
   boot_spm_busy_wait();                                 //hang around till completed
}



/*-----------------------------  -----------------------------
 * Description:      
 *
 * Parameters:      void
 * Returns:         void
 * Other Info:
 */
void verify(uint8_t index_p) {
uint16_t pageBoundry = index_p << 8;   //index_p << 7; //small devices
uint8_t i = 0;

   for(i = 0; i < FLASH_PAGESIZE; i++) {
        if (pgm_read_byte(pageBoundry + i) != spmData[i]) {
         err |= ERR_WRITING;                              //flag error
      }
    }
}



/*-----------------------------  -----------------------------
 * Description:      
 *
 * Parameters:      void
 * Returns:         void
 * Other Info:
 */
void sendRpt(uint8_t rpt) {
   sendByte(0xF0);                                    //SysEx SOX
   sendByte(0x7F);                                    //Succ-U-Bus Sysex ID
   sendByte(0x41);                                    //Succ-U-Bus *** request erase SysEx
   sendByte(semaphor_device);                           //data - Device ID
   sendByte((semaphor_baud + 1) >> 1);                     //data - Device crystal speed (base 10)
   sendByte(semaphor_adcs);                           //data - Device input channels (base 10)
   sendByte(rpt & 0x7F);                              //send error code
   sendByte(0xF7);
}



/*----------------------------- main -----------------------------
 * Description:      Megadrum AVR bootloader for ATmega324p and ATmega644p.
 *
 * Parameters:      void
 * Returns:            0 - Never returning.
 * Other Info:
 * Relocated from the usual program .text section (Fourth section)
 * to .init9 to ensure it is run before other program code.
 */
int main(void) {
uint8_t rst_status;
uint8_t page;
uint16_t addr;
uint8_t   record_type;
//uint16_t SuccUBus = (uint16_t) __endOfVectors >> 8;
uint8_t SuccUBus = 256 - 8;


   rst_status = MCUSR;
   err = addr =0;

   MCUCR = (1<<JTD) | (1<<IVCE);                              //Enable change of JTAG and vectors
   MCUCR = (1<<JTD) | (1<<IVSEL);                              //JTAG off and vectors to bootloader

   rst_action(rst_status);

   DDR_MIDILED = DDR_MIDILED | MIDILED_PIN;                     //With JTAG off we can now turn on MIDI LED
   PORT_MIDILED = (PORT_MIDILED | MIDILED_PIN) ^MIDILED_PIN;

   //With vectors available we can now calc' and initialise the UART (and the UART RX ISR)
   UARTinit();

   semaphor_device   = boot_signature_byte_get(0x04) & 0x7f;
   semaphor_baud = UART_BAUD_LOW  & 0x7f;
   semaphor_adcs = 32 & 0x7f;                                 //FIXME

   if (semaphor_device != 0x0A) {                              //32K parts have 16 pages in 1K
      SuccUBus -= 8;
   }

   sendRpt(isFW_bad());                                    //Send Ready/Status message

   try_reception();

   if (!err && (*sysexMsg_ptr == SYX_ERASE)) {                     //if Erase syx recieved then request hex line
      spmData_index = 0;                                    //will auto wrap
      page = addr = 0;

      do {
         record_type   = 1;                                 //expect nothing!

         sendByte(0xF0);                                    //SysEx SOX
         sendByte(0x7F);                                    //Succ-U-Bus Sysex ID
         sendByte(0x40);                                    //Succ-U-Bus *** request firmware SysEx
//         sendByte(lowNibble2asciihex(addr >> 12));
//         sendByte(lowNibble2asciihex(addr >> 8));
//         sendByte(lowNibble2asciihex(addr >> 4));
//         sendByte(lowNibble2asciihex(addr));
         sendByte(0xF7);                                    //SysEx EOX

         try_reception();

         if (!err && (*sysexMsg_ptr == SYX_FIRMWARE)) {            //if firmware syx recieved
            sysexData_checksum();

            if (!err) {
               record_type   = sysexData2spmData(7);               //valid record so get record type

               if (record_type == 0) {
                  sysexData_checkaddr(addr);

                  if (!err && (page >= SuccUBus)) {            //will this FW fit?
                     err |= ERR_TOOBIG;                     //flag error
                  }
               }

               if (record_type == 0 || record_type == 1) {      //process eof and data records only
                  addr += sysexData2spmData(1);            //grab next hex record address before it gets mangled
                  spm_topup();                        //covert and buffer hex payload

                  if (spmData_index == 0) {               //wait for enough data to do a page write
                     fud(page);                        //write flash page
//                     verify(page);
                     page++;                           //page write ok so prepare for more data
                     spm_topup();                     //process any remaining data
                  }
               }
            }
         }

      } while (!err && (record_type != 1));


      if (err || record_type != 1) {                           //something is wrong
         if (page) {                                       //if the flash could have been altered then
            spmData[0] = (uint8_t) (ZAPPED >> 0);                  //zap the power on vector
            spmData[1] = (uint8_t) (ZAPPED >> 8);
            spmData[2] = (uint8_t) (ZAPPED >> 16);
            spmData[3] = (uint8_t) (ZAPPED >> 24);

            spmData[4] = err;                              //and record the failiure error

            fud(0);                                       //try to overwrite the vectors

         }

         sendRpt(err);
      }

   } //end of request erase SysEx


   PORT_MIDILED = (PORT_MIDILED | MIDILED_PIN) ^MIDILED_PIN;         //use it or loose it!

   rst_action(0); //run again

//   rst_action(rst_status & ((1<<JTRF) + (1<<BORF) + (1<<PORF)));      //either enter FW app or reboot ;¬B

}
Ken Forgettable
 
Posts: 402
Joined: Tue Jan 06, 2009 5:04 pm

Re: Succ-U-Bus

Postby davem » Tue Oct 13, 2009 8:10 pm

Ken,

Would you like testers for this, how stable is it? I'm quite intrigued by the idea of a totally headless unit, would be nice to automagically update firmware through MCT. Just have to figure out a way to flash the Atmega using a Mac :)

Dave
davem
 
Posts: 71
Joined: Sun Jun 14, 2009 9:51 pm

Re: Succ-U-Bus

Postby Ken Forgettable » Wed Oct 14, 2009 9:04 pm

davem wrote:how stable is it?
Seems stable enough to catch various cockups I've made over the last few weeks.
I'll get the MCT hack here next week for you - want a bit more time at the v3&4 bootloaders...

Thanks for the interest, I used AVR Studio you know :roll:
Ken Forgettable
 
Posts: 402
Joined: Tue Jan 06, 2009 5:04 pm

Re: Succ-U-Bus

Postby Ken Forgettable » Fri Oct 16, 2009 8:01 pm

Here's an idea of what's happening (this is JAVA on XP - no MidiPort).
Options.png

This is the first run Setup...
MCT sends a 'request id' through the available ports to get the config' from Succ-U-Bus.
Here we have avoided the power up and key pressing (and associated hardware).

Then you can go automatic or provide hints like:
Open.png


From the bootloader code above you will see that any transmission errors or internal flashing errors should get caught and the firmware is disabled. NB. the failiure code is saved and can thus be reported on subsequent update attempts.

I had to stuff in a save and rotate for the logs too ;)
You do not have the required permissions to view the files attached to this post.
Ken Forgettable
 
Posts: 402
Joined: Tue Jan 06, 2009 5:04 pm

Re: Succ-U-Bus

Postby Pete Predictable » Fri Oct 23, 2009 12:00 am

Dear Ken Forgettable,

You say pure Java MCT code can update Dmitris firmware if I use this AVR sucUbus is installed.
You say I don't need the buttons or LCD to do it either.

Why here is no one bothered then???

It is because you are pissed and mad :lol:
Pete Predictable
 
Posts: 18
Joined: Wed Oct 21, 2009 1:04 pm

PreviousNext

Return to Related Software

Who is online

Users browsing this forum: No registered users and 24 guests