Esempio n. 1
0
unsigned char BlockLoad(unsigned int size, unsigned char mem)
{
	if(!over_size_flag) // Check for file size to be less than maximum pages that can be programmed
	{
		if(mem == 'F')
		{
			// Flash memory type.
			for (uint16_t i = 0; i < size; ++i)
			{
				pageBuffer[i+2] = recchar();
			}
			return '\r'; // Report programming OK
		}
		else
		{
			// Invalid memory type?
			return '?';
		}
	}
	else
	{
		over_size_flag=0;
		return '?';
	}
}
Esempio n. 2
0
int main(void)
{
    unsigned char val;
   
    inituart(); // Initialize UART.

    /* Main loop */
    for(;;)
    {
        val = recchar(); // Wait for command character.
	 
        // Check autoincrement status.
        if(val=='a')
        {
            sendchar('Y'); // Yes, we do autoincrement.
        }
   }
} // end: main
Esempio n. 3
0
int main(void)
{
   ADDR_T address = 0;
   unsigned int temp_int=0;
   unsigned char val;
   
   /* Initialization */    
   void (*funcptr)( void ) = 0x0000; // Set up function pointer to RESET vector.
   
   PMIC_SetVectorLocationToBoot();
   
   
   eeprom_disable_mapping();
   
   PROGPORT |= (1<<PROG_NO); // Enable pull-up on PROG_NO line on PROGPORT.
   
   /* Branch to bootloader or application code? */
   if( /*!(PROGPIN & (1<<PROG_NO))*/1 ) // If PROGPIN is pulled low, enter programmingmode.
   {
      initbootuart(); // Initialize UART.

      /* Main loop */
      for(;;)
      {
	 
	 val = recchar(); // Wait for command character.
	 
	 // Check autoincrement status.
	 if(val=='a')
	 {
	    sendchar('Y'); // Yes, we do autoincrement.
	 }
	 
	 // Set address (2 bytes).
	 else if(val == 'A')
	 { // NOTE: Flash addresses are given in words, not bytes.                                            
	    address = recchar();
	    address <<=  8;
	    address |= recchar(); // Read address high and low byte.
	    sendchar('\r'); // Send OK back.
	 }

	 // Set extended address (3 bytes).
	 else if(val == 'H')
	 { // NOTE: Flash addresses are given in words, not bytes.                                            
	    address = (uint32_t)recchar() << 16;
	    address |= (uint16_t)recchar() << 8;
	    address |= recchar();
	    sendchar('\r'); // Send OK back.
	 }

	 // Chip erase.
	 else if(val=='e')
	 {
	    for(address = 0; address < APP_END; address += PAGESIZE)
	    { // NOTE: Here we use address as a byte-address, not word-address, for convenience.
	       nvm_wait_until_ready();
#ifdef __ICCAVR__
#pragma diag_suppress=Pe1053 // Suppress warning for conversion from long-type address to flash ptr.
#endif
	       EraseApplicationPage( address );
#ifdef __ICCAVR__
#pragma diag_default=Pe1053 // Back to default.
#endif
	    }
	    nvm_eeprom_erase_all();
	    sendchar('\r'); // Send OK back.
	 }
	 
#ifndef REMOVE_BLOCK_SUPPORT

	 // Check block load support.
	 else if(val=='b')
	 {
	    sendchar('Y'); // Report block load supported.
	    sendchar((BLOCKSIZE>>8) & 0xFF); // MSB first.
	    sendchar(BLOCKSIZE&0xFF); // Report BLOCKSIZE (bytes).
	 }
	 
	 // Start block load.
	 else if(val=='B')
Esempio n. 4
0
	 }
	 
#ifndef REMOVE_BLOCK_SUPPORT

	 // Check block load support.
	 else if(val=='b')
	 {
	    sendchar('Y'); // Report block load supported.
	    sendchar((BLOCKSIZE>>8) & 0xFF); // MSB first.
	    sendchar(BLOCKSIZE&0xFF); // Report BLOCKSIZE (bytes).
	 }
	 
	 // Start block load.
	 else if(val=='B')
	 {
	    temp_int = ((uint16_t)recchar()<<8) | recchar(); // Get block size.
	    val = recchar(); // Get memtype.
	    sendchar( BlockLoad(temp_int, val, address) ); // Block load.				
	 }	    
	 // Start block read.
	 else if(val=='g')
	 {
	    temp_int = ((uint16_t)recchar()<<8) | recchar(); // Get block size.
	    val = recchar(); // Get memtype
	    BlockRead(temp_int, val, address); // Block read
	 }		
#endif /* REMOVE_BLOCK_SUPPORT */
	 
#ifndef REMOVE_FLASH_BYTE_SUPPORT            
	 // Read program memory.
	 else if(val=='R')
Esempio n. 5
0
int main(void)
{
    address_t       address = 0;
    address_t       eraseAddress = 0;	
	unsigned char   msgParseState;
    unsigned int    i = 0;
    unsigned char   checksum = 0;
    unsigned char   seqNum = 0;
    unsigned int    msgLength = 0;
    unsigned char   msgBuffer[285];
    unsigned char   c, *p;
	
	/*
	 * Branch to bootloader or application code ?
	 */	
	PROG_PORT &= ~(1<<PROG_PIN);
#ifndef REMOVE_PROG_PIN_PULLUP
	PROG_PORT |= (1<<PROG_PIN);		// Enable internal pullup
	asm volatile ("nop");           // wait until port has changed	 
#endif
	for (uint8_t i=0;i<100;i++)
		asm volatile ("nop");

	if(!(PROG_IN & (1<<PROG_PIN)))  
	{
		uint8_t leave_progmode = 0;
		    
#ifndef REMOVE_BOOTLOADER_LED
        /* PROG_PIN pulled low, indicate with LED that bootloader is active */
        PROGLED_DDR  |= (1<<PROGLED_PIN);
        PROGLED_PORT &= ~(1<<PROGLED_PIN);
#endif

		#ifdef CAN_DEBUGGER_V2
		PORTF = (1<<PF4)|(1<<PF3);
		DDRF = (1<<PF7)|(1<<PF6)|(1<<PF4)|(1<<PF3);
		#endif
		
        /*
         * Init UART
         * set baudrate and enable USART receiver and transmiter without interrupts 
         */
		#ifdef	CAN_DEBUGGER_V2
		DDRG = (1<<RD)|(1<<WR);
		PORTG = (1<<RD);
		
		DDRE &= ~((1<<USB_RXF)|(1<<USB_TXE));
		PORTE |= (1<<USB_RXF)|(1<<USB_TXE);
		
		DDRA = 0;
		PORTA = 0xff;
		#else
#if UART_BAUDRATE_DOUBLE_SPEED
        UART_STATUS_REG   |=  (1 <<UART_DOUBLE_SPEED);
#endif         
        UART_BAUD_RATE_LOW = UART_BAUD_SELECT(BAUDRATE,F_CPU);
        UART_CONTROL_REG   = (1 << UART_ENABLE_RECEIVER) | (1 << UART_ENABLE_TRANSMITTER); 
        #endif
        
        /* main loop */
        for(;;)                             
        {   
            /*
             * Collect received bytes to a complete message
             */            
            msgParseState = ST_START;
	        while ( msgParseState != ST_PROCESS )
	        {
           		c = recchar();
                switch (msgParseState)
                {
                case ST_START:
				    if( c == MESSAGE_START )
				    {
					    msgParseState = ST_GET_SEQ_NUM;
					    checksum = MESSAGE_START^0;
				    }
				    break;
				    
				case ST_GET_SEQ_NUM:
                    if ( (c == 1) || (c == seqNum) )
                    {
				        seqNum = c;
				        msgParseState = ST_MSG_SIZE_1;
				        checksum ^= c;
                    }
                    else
                    {
                        msgParseState = ST_START;
                    }
			        break;
			        
			    case ST_MSG_SIZE_1:			    
				    msgLength = c<<8;
				    msgParseState = ST_MSG_SIZE_2;
				    checksum ^= c;
				    break;
				    
			    case ST_MSG_SIZE_2:			
				    msgLength |= c;
				    msgParseState = ST_GET_TOKEN;
				    checksum ^= c;
				    break;
			    
			    case ST_GET_TOKEN:
			        if ( c == TOKEN )
				    {
					    msgParseState = ST_GET_DATA;
					    checksum ^= c;
					    i = 0;
				    }
				    else
				    {
				        msgParseState = ST_START;
				    }
				    break;
			    
			    case ST_GET_DATA:			        
				    msgBuffer[i++] = c;
				    checksum ^= c;
				    if ( i == msgLength )
				    {
					    msgParseState = ST_GET_CHECK;
				    }
				    break;
				
			    case ST_GET_CHECK:
				    if( c == checksum )
				    {
					    msgParseState = ST_PROCESS;					    
				    }
				    else
				    {
				        msgParseState = ST_START;
				    }
				    break;
				}//switch
			}//while(msgParseState)
			
			/*
			 * Now process the STK500 commands, see Atmel Appnote AVR068
			 */
			
	        switch (msgBuffer[0])
	        {
#ifndef REMOVE_CMD_SPI_MULTI
			case CMD_SPI_MULTI:
				{
	                unsigned char answerByte = 0;

                    // only Read Signature Bytes implemented, return dummy value for other instructions
					if ( msgBuffer[4]== 0x30 )
					{						
						unsigned char signatureIndex = msgBuffer[6];						

						if ( signatureIndex == 0 )
							answerByte = (SIGNATURE_BYTES >>16) & 0x000000FF;
						else if ( signatureIndex == 1 )
							answerByte = (SIGNATURE_BYTES >> 8) & 0x000000FF;
						else
							answerByte = SIGNATURE_BYTES & 0x000000FF;
					}					
    				msgLength = 7;
					msgBuffer[1] = STATUS_CMD_OK;
					msgBuffer[2] = 0;					
					msgBuffer[3] = msgBuffer[4];  // Instruction Byte 1
					msgBuffer[4] = msgBuffer[5];  // Instruction Byte 2
					msgBuffer[5] = answerByte;	                
					msgBuffer[6] = STATUS_CMD_OK;
				}
Esempio n. 6
0
int main(void)
{
 
	unsigned  tempi;
	char val;
    uint8_t sw1,sw2;
	
	#ifdef START_POWERSAVE
	char OK = 1;    
	#endif
    
	cli();
	
	MCUCR = (1<<IVCE);       
	MCUCR = (1<<IVSEL);             //move interruptvectors to the Boot sector    
 
	USART_Init(UART_BAUD_SELECT(BAUDRATE,XTAL),UARTSINGLE); 	// single speed
	// USART_Init(UART_BAUD_SELECT(BAUDRATE/2,XTAL),UARTDOUBLE);  // double speed
	d7segment_init();
	



	

#if defined(START_POWERSAVE)
	/* 
		This is an adoption of the Butterfly Bootloader startup-sequence.
		It may look a little strange but separating the login-loop from
		the main parser-loop gives a lot a possibilities (timeout, sleep-modes
	    etc.).
	*/		
 
	
	for(;OK;)
	{
		if((BLPIN1 & (1<<BLPNUM1)) || (BLPIN2 & (1<<BLPNUM2)))	 // Either one of two switch press still go app mode 
		{  
			// jump to main app if pin is not grounded
			BLPORT1 &= ~(1<<BLPNUM1);  // set to default
			MCUCR = (1<<IVCE); 
			MCUCR = (0<<IVSEL);      // move interruptvectors to the Application sector
			jump_to_app();			 // Jump to application sector
		}
		else
		{	
			val = recchar();
		
			if( val == 0x1B ) /* ESC */
	        {				// AVRPROG connection
				while (val != 'S')	// Wait for signon 
				{
					val = recchar();
				}
				send_boot();					// Report signon
				OK = 0;
			}
			else
				sendchar('?');
	        }
		// Power-Save code here
	}
	
#elif defined(START_SIMPLE)
 

   sw1 = _7SEGMENT_SW1_IN_PORT & _7SEGMENT_SW1; 
   sw2 = _7SEGMENT_SW2_IN_PORT & _7SEGMENT_SW2; 
   
    if ((sw1) ) //&&  (!sw2)) // SW1, SW2 Press
//	if((BLPIN1 & (1<<BLPNUM1)) || (BLPIN2 & (1<<BLPNUM2))) 
	{  
// jump to main app if pin is  grounded
//		BLPORT1 &= ~(1<<BLPNUM1);  		// set to default  ??
//		BLPORT2 &= ~(1<<BLPNUM2);  		// set to default  ??
		MCUCR = (1<<IVCE); 
		MCUCR = (0<<IVSEL);             //move interruptvectors to the Application sector

		d7segment_display(_7SEGMENT_C_P,1);
		jump_to_app();					// Jump to application sector
	}
	
	#elif defined(START_BOOTICE)
	#warning "BOOTICE mode - no startup-condition"

	#else
	#error "Select START_ condition for bootloader in main.c"
	#endif

  
	
    for(;;)                             
    {   
	    d7segment_display(_7SEGMENT_C_B,1);
		val=recchar();
         
        if(val=='a')                         //Autoincrement?
        {
          sendchar('Y');					  //Autoincrement is quicker
        }
 
        else if(val=='A')                    //write address 
        {
			address=recchar();                //read address 8 MSB
			address=(address<<8)|recchar();
			
			address=address<<1;               // !! convert from word address to byte address
			sendchar('\r');
        }
        
        else if(val=='b')
		{									// Buffer load support
			sendchar('Y');					// Report buffer load supported
			sendchar((UART_RX_BUFFER_SIZE >> 8) & 0xFF);
											// Report buffer size in bytes
			sendchar(UART_RX_BUFFER_SIZE & 0xFF);
		}

		else if(val=='B')					// Start buffer load
Esempio n. 7
0
			
			address=address<<1;               // !! convert from word address to byte address
			sendchar('\r');
        }
        
        else if(val=='b')
		{									// Buffer load support
			sendchar('Y');					// Report buffer load supported
			sendchar((UART_RX_BUFFER_SIZE >> 8) & 0xFF);
											// Report buffer size in bytes
			sendchar(UART_RX_BUFFER_SIZE & 0xFF);
		}

		else if(val=='B')					// Start buffer load
		{
			tempi = recchar() << 8;			// Load high byte of buffersize
			tempi |= recchar();				// Load low byte of buffersize
			val = recchar();				// Load memory type ('E' or 'F')
			sendchar (BufferLoad(tempi,val));
											// Start downloading of buffer
		}
		
		else if(val == 'g')					// Block read
		{
			tempi = (recchar() << 8) | recchar();

			val = recchar();				// Get memtype
			BlockRead(tempi,val);			// Perform the block read
		}		

        else if(val=='e')                   //Chip erase 
Esempio n. 8
0
int stk_receive(unsigned char *msg, int size)
{
    address_t       address = 0;
    address_t       eraseAddress = 0;	
    unsigned char   msgParseState;
    unsigned int    i = 0;
    unsigned char   checksum = 0;
    unsigned char   seqNum = 0;
    unsigned int    msgLength = 0;
    unsigned char   msgBuffer[285];
    unsigned char   c, *p;
    unsigned char   isLeave = 0;
    char            timeout;
    int             j = 0;

    /* main loop */
    while(!isLeave)                             
      {
	/*
	 * Collect received bytes to a complete message
	 */
	msgParseState = ST_START;
	while ( msgParseState != ST_PROCESS )
	  {
	    c = recchar(&timeout, msg, size, j++);
	    if (timeout)
	      goto skip_to_main_program;
	    //sendchar(c);	  
	    switch (msgParseState)
	      {
	      case ST_START:
		if ( c == MESSAGE_START )
		  {
		    msgParseState = ST_GET_SEQ_NUM;
		    checksum = MESSAGE_START^0;
		  }
		break;
		
	      case ST_GET_SEQ_NUM:
#define _FIX_ISSUE_505_
#ifdef _FIX_ISSUE_505_
		seqNum = c;
		msgParseState = ST_MSG_SIZE_1;
		checksum ^= c;
#else
		if ( (c == 1) || (c == seqNum) )
		  {
		    seqNum = c;
		    msgParseState = ST_MSG_SIZE_1;
		    checksum ^= c;
		  }
		else
		  {
		    msgParseState = ST_START;
		  }
#endif
		break;
		
	      case ST_MSG_SIZE_1:
		msgLength = c<<8;
		msgParseState = ST_MSG_SIZE_2;
		checksum ^= c;
		break;
		
	      case ST_MSG_SIZE_2:
		msgLength |= c;
		msgParseState = ST_GET_TOKEN;
		checksum ^= c;
		break;
		
	      case ST_GET_TOKEN:
		if ( c == TOKEN )
		  {
		    msgParseState = ST_GET_DATA;
		    checksum ^= c;
		    i = 0;
		  }
		else
		  {
		    msgParseState = ST_START;
		  }
		break;
		
	      case ST_GET_DATA:
		msgBuffer[i++] = c;
		checksum ^= c;
		if (i == msgLength )
		  {
		    msgParseState = ST_GET_CHECK;
		  }
		break;
		
	      case ST_GET_CHECK:
		if ( c == checksum )
		  {
		    msgParseState = ST_PROCESS;
		  }
		else
		  {
		    msgParseState = ST_START;
		  }
		break;
	      }//switch
	  }//while(msgParseState)
	
	/*
	 * Now process the STK500 commands, see Atmel Appnote AVR068
	 */
	
	switch (msgBuffer[0])
	  {
#ifndef REMOVE_CMD_SPI_MULTI
	  case CMD_SPI_MULTI:
	    {
	      unsigned char answerByte = 0;
	      
	      // only Read Signature Bytes implemented, return dummy value for other instructions
	      if ( msgBuffer[4]== 0x30 )
		{						
		  unsigned char signatureIndex = msgBuffer[6];						
		  
		  if ( signatureIndex == 0 )
		    answerByte = (SIGNATURE_BYTES >>16) & 0x000000FF;
		  else if ( signatureIndex == 1 )
		    answerByte = (SIGNATURE_BYTES >> 8) & 0x000000FF;
		  else
		    answerByte = SIGNATURE_BYTES & 0x000000FF;
		}					
	      msgLength = 7;
	      msgBuffer[1] = STATUS_CMD_OK;
	      msgBuffer[2] = 0;					
	      msgBuffer[3] = msgBuffer[4];  // Instruction Byte 1
	      msgBuffer[4] = msgBuffer[5];  // Instruction Byte 2
	      msgBuffer[5] = answerByte;	                
	      msgBuffer[6] = STATUS_CMD_OK;
	    }
C_TASK void main(void)
{
    ADDR_T address;
    unsigned int temp_int;
    unsigned char val;


    /* Initialization */    
    void (*funcptr)( void ) = 0x0000; // Set up function pointer to RESET vector.
    PROGPORT |= (1<<PROG_NO); // Enable pull-up on PROG_NO line on PROGPORT.
    initbootuart(); // Initialize UART.
    DDRB |= _BV(PB0); //status LED


    /* Branch to bootloader or application code? */
    if( !(PROGPIN & (1<<PROG_NO)) ) // If PROGPIN is pulled low, enter programmingmode.
    {
        PORTB |= _BV(PB0); //set the status led ON
        /* Main loop */
        for(;;)
        {
            val=recchar(); // Wait for command character.

            // Check autoincrement status.
            if(val=='a')
            {
                sendchar('Y'); // Yes, we do autoincrement.
            }


            // Set address.
            else if(val=='A') // Set address...
            { // NOTE: Flash addresses are given in words, not bytes.                                            
                address=(recchar()<<8) | recchar(); // Read address high and low byte.
                sendchar('\r'); // Send OK back.
            }

            
            // Chip erase.
            else if(val=='e')
            {
                for(address = 0; address < APP_END;address += PAGESIZE)
                { // NOTE: Here we use address as a byte-address, not word-address, for convenience.
                    _WAIT_FOR_SPM();        
#ifdef __ICCAVR__
#pragma diag_suppress=Pe1053 // Suppress warning for conversion from long-type address to flash ptr.
#endif
                    _PAGE_ERASE( address );
#ifdef __ICCAVR__
#pragma diag_default=Pe1053 // Back to default.
#endif
                }
          
                sendchar('\r'); // Send OK back.
            }
            
#ifndef REMOVE_BLOCK_SUPPORT
            // Check block load support.
            else if(val=='b')
		    {
    			sendchar('Y'); // Report block load supported.
    			sendchar((BLOCKSIZE>>8) & 0xFF); // MSB first.
    			sendchar(BLOCKSIZE&0xFF); // Report BLOCKSIZE (bytes).
    		}


            // Start block load.
    		else if(val=='B')
Esempio n. 10
0
// ---------------------------------------------------------
// CMailToHandler::HandleUrlEmbeddedL()
// ---------------------------------------------------------
//
void CMailToHandler::HandleUrlEmbeddedL()
	{
	CLOG_ENTERFN( "CMailToHandler::HandleUrlEmbeddedL()" );

    //TPtrC path = iParsedUrl->Des();

	iTelService = CBrowserTelService::NewL();
	iTelService->AddObserver( this );

	TPtrC recipient = GetField( KMailto );
	TPtrC subject = GetField( KSubject );
	TPtrC msgBody = GetField( KBody );
	TPtrC cC = GetField( KCc );
    TPtrC tO = GetField( KTo );
    TPtrC bCC = GetField( KBcc );

    HBufC* rec = ChangeSeparationLC( recipient );
    HBufC* ccrec = ChangeSeparationLC( cC );
    HBufC* torec = ChangeSeparationLC( tO );
    HBufC* bccrec = ChangeSeparationLC( bCC );

    HBufC* allrec = HBufC::NewLC( ccrec->Length() +
                                  torec->Length() +
                                  bccrec->Length() + 3*KComma().Length() );
    if( ccrec->Length() != 0 )
        {
        if( allrec->Length() != 0 )
            {
            allrec->Des().Append( KComma() );
            }
        allrec->Des().Append( ccrec->Des() );
        }
    if( torec->Length() != 0 )
        {
        if( allrec->Length() != 0 )
            {
            allrec->Des().Append( KComma() );
            }
        allrec->Des().Append( torec->Des() );
        }
    if( bccrec->Length() != 0 )
        {
        if( allrec->Length() != 0 )
            {
            allrec->Des().Append( KComma() );
            }
        allrec->Des().Append( bccrec->Des() );
        }

    if( rec->Length() > 0 )
        {
        TChar ch1('?');
        TChar ch2('&');
        TChar recchar((*rec)[ rec->Length() - 1]);
        if( recchar == ch1 )
            {
            rec->Des().SetLength(rec->Length() - 1);
            }
        TChar recchar2((*rec)[ rec->Length() - 1]);
        if( recchar2 == ch2 )
            {
            rec->Des().SetLength(rec->Length() - 1);
            }
        }

    if( allrec->Length() > 0 )
        {
        TChar ch1('?');
        TChar ch2('&');
        TChar allrecchar1( (*allrec)[ allrec->Length() - 1] );
        if( allrecchar1 == ch1 )
            {
            allrec->Des().SetLength(allrec->Length() - 1);
            }
        TChar allrecchar2( (*allrec)[ allrec->Length() - 1] );
        if( allrecchar2 == ch2 )
            {
            allrec->Des().SetLength(allrec->Length() - 1);
            }
        }

 	TRAPD( err, iTelService->SendEmailMessageL( rec->Des(), allrec->Des(), subject, msgBody, ETrue) );

    CleanupStack::PopAndDestroy( 5 ); // rec, ccrec, torec, bccrec, allrec

    NotifyClient();

    ErrorHandlerL( err );

	CLOG_LEAVEFN( "CMailToHandler::HandleUrlEmbeddedL()" );
	}
int main(void)
{

/*  Initialise hardware timers and ports. All start off as inputs */
/*  PD0 is RxD
    PD1 is TxD */
/** PORTB is set as outputs on bits 0,3,4 to set controls.
    The SPI output ports SCK and MOSI stay as inputs until ready to program.
    Set the Ports PB0-2 as outputs and set high to turn off all LEDs
    PB0 = programming mode LED
    PB3 = programming completed LED (and serial comms switch over)
    PB4 = programming active LED (and reset out)
    PB5 = MOSI
    PB6 = MISO
    PB7 = SCK */

    sbi(ACSR,7);                                        // Turn off Analogue Comparator
    initbootuart();           	                        // Initialize UART.
    uint8_t sigByte1=0;                                 // Target Definition defaults
    uint8_t sigByte2=0;
    uint8_t sigByte3=0;
    uint8_t fuseBits=0;
    uint8_t highFuseBits=0;
    uint8_t extendedFuseBits=0;
    uint8_t lockBits=0;

/*---------------------------------------------------------------------------*/
/* Main loop. We exit this only with an "E" command. */
    {
        for(;;)
        {
            command=recchar();                          // Loop and wait for command character.

/** 'a' Check autoincrement status.
This allows a block of data to be uploaded to consecutive addresses without
specifying the address each time */
            if (command=='a')
            {
                sendchar('Y');                          // Yes, we will autoincrement.
            }

/** 'A' Set address.
This is stored and incremented for each upload/download.
NOTE: Flash addresses are given as word addresses, not byte addresses. */
            else if (command=='A')                       // Set address
            {
                address = (recchar()<<8);               // Set address high byte first.
                address |= recchar();                   // Then low byte.
                sendchar('\r');                         // Send OK back.
            }

/** 'b' Check block load support. This returns the allowed block size.
We will not buffer anything so we will use the FLASH page size to limit
the programmer's blocks to those that will fit the target's page. This then avoids
the long delay when the page is committed, that may cause incoming data to be lost.
This should not be called before the P command is executed, and the target device
characteristics obtained. The fPageSize characteristic should be non zero.*/
           else if (command=='b')
            {
                uint16_t blockLength = ((uint16_t)fPageSize<<1);
                if (fPageSize > 0) sendchar('Y');       // Report block load supported.
                else sendchar('N');
                sendchar(high(blockLength));            // MSB first.
                sendchar(low(blockLength));             // Report FLASH pagesize (bytes).
            }

/** 'p' Get programmer type. This returns just 'S' for serial. */
            else if (command=='p')
            {
                sendchar('S');                          // Answer 'SERIAL'.
            }

/** 'S' Return programmer identifier. Always 7 digits. We call it AVRSPRG */
            else if (command=='S')
            {
                sendchar('A');
                sendchar('V');                          // ID always 7 characters.
                sendchar('R');
                sendchar('S');
                sendchar('P');
                sendchar('R');
                sendchar('G');
            }

/** 'V' Return software version. */
            else if (command=='V')
            {
                sendchar('0');
                sendchar('0');
            }

/** 't' Return supported device codes. This returns a list of devices that can be programmed.
This is only used by AVRPROG so we will not use it - we work with signature bytes instead. */
            else if(command=='t')
            {
                sendchar( 0 );                          // Send list terminator.
            }

/** 'x' Set LED. */
            else if ((command=='x') || (command=='y') || (command=='T'))
            {
//                if (command=='x') sbi(PORTB,LED);
//                else if (command=='y') cbi(PORTB,LED);
                recchar();                              // Discard sent value
                sendchar('\r');                         // Send OK back.
            }

/** 'P' Enter programming mode.
This starts the programming of the device. Pulse the reset line high while SCK is low.
Send the command and ensure that the echoed second byte is correct, otherwise redo.
With this we get the device signature and search the table for its characteristics.
A timeout is provided in case the device doesn't respond. This will allow fall through
to an ultimate error response.
The reset line is held low until programming mode is exited. */
            else if (command=='P')
            {
                outb(DDRB,(inb(DDRB) | 0xB9));          // Setup SPI output ports
                outb(PORTB,(inb(PORTB) | 0xB9));        // SCK and MOSI high, and LEDs off
                uint8_t retry = 10;
                uint8_t result = 0;
                while ((result != 0x53) && (retry-- > 0))
                {
                    cbi(PORTB,SCK);                     // Set serial clock low
                    sbi(PORTB,RESET);                   // Pulse reset line off
                    _delay_us(100);                     // Delay to let CPU know that programming will occur
                    cbi(PORTB,RESET);                   // Pulse reset line on
                    _delay_us(25000);                   // 25ms delay
                    writeCommand(0xAC,0x53,0x00,0x00);  // "Start programming" command
                    result=buffer[2];
                }
/** Once we are in programming mode, grab the signature bytes and extract all information
about the target device such as its memory sizes, page sizes and capabilities. */
                writeCommand(0x30,0x00,0x00,0x00);
                sigByte1 = buffer[3];
                writeCommand(0x30,0x00,0x01,0x00);
                sigByte2 = buffer[3];
                writeCommand(0x30,0x00,0x02,0x00);      // Signature Bytes
                sigByte3 = buffer[3];
/* Check for device support. If the first signature byte is not 1E, then the device is
either not an Atmel device, is locked, or is not responding.*/
                uint8_t found=FALSE;                    // Indicates if the target device is supported
                uint8_t partNo = 0;
                if (sigByte1 == 0x1E)
                {
                    while ((partNo < NUMPARTS) && (! found))
                    {
                        found = ((part[partNo][0] == sigByte2) && (part[partNo][1] == sigByte3));
                        partNo++;
                    }
                }
                if (found)
                {
                    partNo--;
                    sendchar('\r');
                    fPageSize = part[partNo][2];
                    ePageSize = part[partNo][3];
                    canCheckBusy = part[partNo][4];
                    lfCapability = part[partNo][5];
                    buffer[3] = 0;                      // In case we cannot read these
                    if (lfCapability & 0x08) writeCommand(0x50,0x08,0x00,0x00);  // Read Extended Fuse Bits
                    extendedFuseBits = buffer[3];
                    if (lfCapability & 0x04) writeCommand(0x58,0x08,0x00,0x00);  // Read High Fuse Bits
                    highFuseBits = buffer[3];
                    if (lfCapability & 0x02) writeCommand(0x50,0x00,0x00,0x00);  // Read Fuse Bits
                    fuseBits = buffer[3];
                    if (lfCapability & 0x01) writeCommand(0x58,0x00,0x00,0x00);  // Read Lock Bits
                    lockBits = buffer[3];
                }
                else                                    // Not found?
                {
                    sbi(PORTB,RESET);                   // Lift reset line
                    sendchar('?');                      // Device cannot be programmed
                    outb(DDRB,(inb(DDRB) & ~0xA0));     // Set SPI ports to inputs
                }
            }

/** 'L' Leave programming mode. */
            else if(command=='L')
            {
                sbi(PORTB,RESET);                       // Turn reset line off
                sendchar('\r');                         // Answer OK.
                outb(DDRB,(inb(DDRB) & ~0xA0));         // Set SPI ports to inputs
            }

/** 'e' Chip erase.
This requires several ms. Ensure that the command has finished before acknowledging. */
            else if (command=='e')
            {
                writeCommand(0xAC,0x80,0x00,0x00);      // Erase command
                pollDelay(FALSE);
                sendchar('\r');                         // Send OK back.
            }

/** 'R' Read program memory */
            else if (command=='R')
            {
/** Send high byte, then low byte of flash word.
Send each byte from the address specified (note address variable is modified).*/
                lsbAddress = low(address);
                msbAddress = high(address);
                writeCommand(0x28,msbAddress,lsbAddress,0x00);  // Read high byte
                sendchar(buffer[3]);
                writeCommand(0x20,msbAddress,lsbAddress,0x00);  // Read low byte
                sendchar(buffer[3]);
                address++;                              // Auto-advance to next Flash word.
            }

/** 'c' Write to program memory page buffer, low byte.
NOTE: Always use this command before sending the high byte. It is written to the
page but the address is not incremented.*/
            else if (command=='c')
            {
                received = recchar();
                writeCommand(0x40,0x00,address & 0x7F,received);    // Low byte
                sendchar('\r');                         // Send OK back.
            }

/** 'C' Write to program memory page buffer, high byte.
This will cause the word to be written to the page and the address incremented. It is
the responsibility of the user to issue a page write command.*/
            else if (command=='C')
            {
                received = recchar();
                writeCommand(0x48,0x00,address & 0x7F,received);    // High Byte
                address++;                              // Auto-advance to next Flash word.
                sendchar('\r');                         // Send OK back.
            }

/** 'm' Issue Page Write. This writes the target device page buffer to the Flash.
The address is that of the page, with the lower bits masked out.
This requires several ms. Ensure that the command has finished before acknowledging.
We could check for end of memory here but that would require storing the Flash capacity
for each device. The calling program will know in any case if it has overstepped.*/
            else if (command== 'm')
            {
                writeCommand(0x4C,(address>>8) & 0x7F,address & 0xE0,0x00);  // Write Page
                pollDelay(TRUE);                        // Short delay
                sendchar('\r');                         // Send OK back.
            }
/** 'D' Write EEPROM memory
This writes the byte directly to the EEPROM at the specified address.
This requires several ms. Ensure that the command has finished before acknowledging.*/
            else if (command == 'D')
            {
                lsbAddress = low(address);
                msbAddress = high(address);
                writeCommand(0xC0,msbAddress,lsbAddress,recchar());     // EEPROM byte
                address++;                              // Auto-advance to next EEPROM byte.
                pollDelay(FALSE);                       // Long delay
                sendchar('\r');                         // Send OK back.
            }

/** 'd' Read EEPROM memory */
            else if (command == 'd')
            {
                lsbAddress = low(address);
                msbAddress = high(address);
                writeCommand(0xA0,msbAddress,lsbAddress, 0x00);
                sendchar(buffer[3]);
                address++;                              // Auto-advance to next EEPROM byte.
            }

/** 'B' Start block load.
 The address must have already been set otherwise it will be undefined. */
            else if (command=='B')
            {
                tempInt = (recchar()<<8);               // Get block size high byte first.
                tempInt |= recchar();                   // Low Byte.
                sendchar(BlockLoad(tempInt,recchar(),&address));  // Block load.
            }

/** 'g' Start block read.
 The address must have already been set otherwise it will be undefined.*/
            else if (command=='g')
            {
                tempInt = (recchar()<<8);               // Get block size high byte first.
                tempInt |= recchar();                   // Low Byte.
                command = recchar();                    // Get memory type
                BlockRead(tempInt,command,&address);    // Block read
            }
/** 'r' Read lock bits. */
            else if (command=='r')
            {
                sendchar(lockBits);
            }

/** 'l' Write lockbits. */
            else if (command=='l')
            {
                if (lfCapability & 0x10) writeCommand(0xAC,0xE0,0x00,recchar());
                sendchar('\r');                         // Send OK back.
            }

/** 'F' Read fuse bits. */
            else if (command=='F')
            {
                sendchar(fuseBits);
            }

/** 'f' Write fuse bits. */
            else if (command=='f')
            {
                if (lfCapability & 0x20) writeCommand(0xAC,0xA0,0x00,recchar()); // Fuse byte
                sendchar('\r');                         // Send OK back.
            }

/** 'N' Read high fuse bits. */
            else if (command=='N')
            {
                sendchar(highFuseBits);
            }

/** 'n' Write high fuse bits. */
            else if (command=='n')
            {
                if (lfCapability & 0x40) writeCommand(0xAC,0xA8,0x00,recchar()); // High Fuse byte
                sendchar('\r');                         // Send OK back.
            }

/** 'Q' Read extended fuse bits. */
            else if (command=='Q')
            {
                sendchar(extendedFuseBits);
            }

/** 'q' Write extended fuse bits. */
            else if (command=='q')
            {
                if (lfCapability & 0x80) writeCommand(0xAC,0xA4,0x00,recchar()); // Extended Fuse byte
                sendchar('\r');                         // Send OK back.
            }

/** 's' Return signature bytes. Sent Most Significant Byte first. */
            else if (command=='s')
            {
                sendchar(sigByte3);
                sendchar(sigByte2);
                sendchar(sigByte1);
            }

/** 'E' Exit bootloader.
At this command we enter serial passthrough and don't return from it until a
hardware reset occurs.
At the same time we should lift the reset from the target. Spin endlessly so we
don't interpret serial data, and wait for our own hard reset.*/
            else if (command=='E')
            {
                sendchar('\r');
                sbi(PORTB,RESET);                       // Pulse reset line off
                cbi(PORTB,PASSTHROUGH);                 // Change to serial passthrough
                outb(DDRB,(inb(DDRB) & ~0xA0));         // Set SPI ports to inputs
                for (;;);                    // Spin endlessly
            }

/** The last command to accept is ESC (synchronization).
This is used to abort any command by filling in remaining parameters, after which
it is simply ignored.
Otherwise, the command is not recognized and a "?" is returned.*/
            else if (command!=0x1b) sendchar('?');       // If not ESC, then it is unrecognized
        }
Esempio n. 12
0
int main(void){
	unsigned int temp_int;
	unsigned char val = 0;

	CTS_DDR_REG |= (1<<CTS_PIN);	// set to output
	CTS_PORT_REG |= (1<<CTS_PIN);	// set high

	RTS_DDR_REG &= ~(1<<CTS_PIN);	// set to input
	RTS_PORT_REG |= (1<<CTS_PIN);	// enable pull-up
	
	mod_led_init();

	InitTWI();
	
	initbootuart(); // Initialize UART.

	/* Main loop */
	while(true)
	{
		val = recchar(); // Wait for command character.

		switch(val) {
			case 'P':
			case 'L':
			case 'E':
				sendchar('\r');
				break;
		
			// Read lock byte -> execute command
			case 'r':
				switch(command_char) {
					case 'a':
						// NOT SUPPORTED in new code.
						read_and_send( TWI_CMD_AVERSION );
						break;

					case 'b':
						// NOT SUPPORTED in new code.
						read_and_send( TWI_CMD_BVERSION );
						break;

					case 'd':
						// Read CRCHI
						sendchar(CRC_HI);
						break;

					case 'e':
						// Read CRCLO
						sendchar(CRC_LO);
						break;

					case 'f':
						// Status condition
						// NOT SUPPORTED in new code.
						read_and_send(TWI_CMD_GETERRCONDN);
						break;

					default:
						sendchar(0xFF);
						break;
				}
				break;

			case 'l':
				// Write lock byte -> load command. NOT SUPPORTED in new code.
				// NOTE: This looks like a hijacked command to do a CRC check.
				command_char = recchar();
#if 0
				if( command_char == 'c' )
				{
					send_command( TWI_CMD_CRCCHECK );
					read_from_slave();
					CRC_HI= statusCode;
					read_from_slave();
					CRC_LO = statusCode;
				}
#endif
				sendchar('\r');
				break;

			case 'N':
				// Read high fuse bits -> BVERSION
				read_and_send( TWI_CMD_BVERSION );
				break;

			case 'F':
				// Low Fuse Bits -> AVERSION
				read_and_send( TWI_CMD_AVERSION );
				break;

			case	'a':
				sendchar('Y'); // Yes, we do auto-increment.
				break;

			case 'A':
				addr =(recchar()<<8) | recchar(); // Read address high and low byte.
				if(addr > MAX__APP_ADDR) over_size_flag = 1;
				//+ 15mar17 ndp - send address to Slave.
				slaveCmdBuff[0] = CMD_RECV_ADRS;
				slaveCmdBuff[1] = (uint8_t)((addr>>8) & 0x00FF);				// AH
				slaveCmdBuff[2] = (uint8_t)(addr & 0x00FF);						// AL
				(void) MasterTransmit( SLAVE_ADDRESS, slaveCmdBuff, 3 );
				//-
				sendchar('\r'); // Send OK back.
				break;

			case 'e':
				// Chip erase.	NOT SUPPORTED in new code.
#if 0
				runApp[0] =  TWI_CMD_ERASEFLASH;
				runApp[1] =  TWI_CMD_ERASEFLASH;
				get_slave_status();
				success = MasterTransmit( SLAVE_ADDRESS, runApp, 2 );
#endif
				sendchar('\r'); // Send OK back.
				break;
		
			case 'b':
				// Check block load support.
				sendchar('Y'); // Report block load supported.
				sendchar((BLOCKSIZE>>8) & 0xFF); // MSB first.
				sendchar(BLOCKSIZE&0xFF); // Report BLOCKSIZE (bytes).
				over_size_flag = 0;		// ndp 1-29-2017 fix
				break;
		
			case 'B':
				// Start block load.
				temp_int = (recchar()<<8) | recchar();	// Get block size.
				val = recchar();						// Get memtype.
				sendchar( BlockLoad(temp_int, val) );	// Block load.
// mod_led_toggle(4);			// Need a short delay here.
			 	pageBuffer[0] = CMD_RECV_DATA;					// Address was sent in 'A' command service.
				pageBuffer[1] = (uint8_t)(temp_int & 0x00FF);	// NL..Only block size less than 256 supported.
				// NOTE: Always sends PAGE_SIZE even if less data received from Host.
				success = MasterTransmit( SLAVE_ADDRESS, pageBuffer, pageBuffer[1]+2 );

				break;
		
			case 'S':
				// Return programmer identifier.
				sendchar('A'); // Return 'AVRBOOT'.
				sendchar('V'); // Software identifier (aka programmer signature) is always 7 characters.
				sendchar('R');
				sendchar('B');
				sendchar('O');
				sendchar('O');
				sendchar('T');
				reps =0;
				break;
		
			case 'V':
				// Return software version.
				// NOTE: TODO Should implement in new code.
//				send_command(TWI_CMD_EXECUTEAPP);
				// Disable bootloader mode for slave
				sendchar('2');
				sendchar('0');
				break;

			case 's':
				// Return signature bytes [for the Target device ATtiny85].
				slaveCmdBuff[0] = CMD_GET_SIG;
				(void) MasterTransmit( SLAVE_ADDRESS, slaveCmdBuff, 1 );
 mod_led_toggle(200);			// Need a short delay here to let Slave set up data.
				(void) MasterReceive( SLAVE_ADDRESS, slaveCmdBuff, 3 );
				sendchar( slaveCmdBuff[2] );
				sendchar( slaveCmdBuff[1] );
				sendchar( slaveCmdBuff[0] );
				break;
		
			/* Add missing command .. ndp 01-29-2017
			 * Return Flash Data.
			 *
			 * TODO: Need to read from Slave.
			 */
			case 'g':
 				temp_int = (recchar()<<8) | recchar();	// Get block size.
				val = recchar();						// Get mem type.
				// NOTE: Address was sent in 'A' command process.
				slaveCmdBuff[0] = CMD_GET_DATA;
				slaveCmdBuff[1] = (uint8_t)(temp_int & 0x00FF);
				(void) MasterTransmit( SLAVE_ADDRESS, slaveCmdBuff, 2 );
 mod_led_toggle(200);			// Need a short delay here to let Slave set up data.
				(void) MasterReceive( SLAVE_ADDRESS, pageBuffer, (temp_int & 0x00FF) );

				for(int i=0; i<temp_int; ++i)
				{
					sendchar( pageBuffer[i] );
				}
				break;

			default:
				if(val != 0x1b) {                  // If not ESC, then it is unrecognized...
					sendchar('?');
				}
				break;
		} // end: switch()
	} // end: while(true)
} // end: main