void receive_at_command(void)
{

unsigned char received_bytes = 0;
unsigned char rx_char_buffer = 0;
unsigned char x = 0;
#if defined BOOTLOCK_BIT_SET_SUPPORT && BOOTLOCK_BIT_SET_SUPPORT == 1
unsigned char blb = 0;
unsigned char lock_bits = 0;
#endif
#if defined VERSION_INFO_NEEDED && VERSION_INFO_NEEDED == 1
unsigned int eep_address = 0;
#endif

while(memory_to_write == 0)
    {
      x=_UDR_;
      x=_UDR_;
      sput_str(prompt);
       do{
             received_bytes = 0;
             //uart_rx_timeout = UART_TIMEOUT_ABS_MAX_VALUE;
             rx_char_buffer = sget_char();
             if(rx_char_buffer){ sput_char(rx_char_buffer); }

             if( rx_char_buffer == 'A' || rx_char_buffer == 'a' )
               {
                  rx_char_buffer = sget_char();
                  if(rx_char_buffer){ sput_char(rx_char_buffer); }
                  if( rx_char_buffer == 'T' || rx_char_buffer == 't' )
                   {
                      while(1)
                          {
                             rx_char_buffer = sget_char();
                             sput_char(rx_char_buffer);
                             if(received_bytes > 10 )
                              {
                                received_bytes = 0xff;
                                sput_str(error_message);
                                break;
                              }
                             if(rx_char_buffer == '\r' || rx_char_buffer == '\n')
                              {
                                 x_buffer[received_bytes] = '\0';
                                 break;
                              }
                             x_buffer[received_bytes++] = rx_char_buffer;
                             if(rx_char_buffer == 0) { received_bytes = 0; break; }
                          }
                   }

               }else if( rx_char_buffer == '\n' || rx_char_buffer == '\r' ) { sput_str(prompt); }

           }while(received_bytes == 0 ); // end of "while(1)" loop

       if(received_bytes == 0Xff){ continue; }
       strupr((char*)x_buffer);
       memory_to_write = 0;
       switch(x_buffer[0])
            {
               case('W'):  switch(x_buffer[1])
                                {
                                   case('F'):  memory_to_write = 1;  break;
                                   case('E'):  memory_to_write = 2;  break;
#if defined BOOTLOCK_BIT_SET_SUPPORT && BOOTLOCK_BIT_SET_SUPPORT == 1
                                   case('B'):  blb = 7; lock_bits = 0xFF;
                                               for(x=2; x<=9; x++)
                                                 {
                                                     rx_char_buffer = x_buffer[x];
                                                     if(rx_char_buffer == '0'){ lock_bits &= (~(1<<blb)); }
                                                     blb--;
                                                 }
                                               x_buffer[10] = '\0';
                                               utoa(lock_bits,(char*)x_buffer, 2);
                                               sput_str((char*)x_buffer);
                                               sput_str("Y/N");
                                               rx_char_buffer = sget_char();
                                               if(rx_char_buffer == 'Y' || rx_char_buffer == 'y')
                                                {
                                                   boot_lock_bits_set(~lock_bits);
                                                   sput_str(success_message);
                                                }else{ sput_str("Aborted");  }
                                               break;
#endif
                                   default  :  sput_str(error_message); break;
                                }
                           break;

#if defined BOOTLOCK_BIT_READ_SUPPORT && BOOTLOCK_BIT_READ_SUPPORT == 1
              case('R'):  switch(x_buffer[1])
                               {
                                  case('B'): utoa(boot_lock_fuse_bits_get(GET_LOCK_BITS), (char*)x_buffer, 2);
                                             sput_str((char*)x_buffer);
                                             break;

                                  case('L'): utoa(boot_lock_fuse_bits_get(GET_LOW_FUSE_BITS), (char*)x_buffer, 2);
                                             sput_str((char*)x_buffer);
                                             break;

                                  case('H'): utoa(boot_lock_fuse_bits_get(GET_HIGH_FUSE_BITS), (char*)x_buffer, 2);
                                             sput_str((char*)x_buffer);
                                             break;

                                  case('E'): utoa(boot_lock_fuse_bits_get(GET_EXTENDED_FUSE_BITS), (char*)x_buffer, 2);
                                             sput_str((char*)x_buffer);
                                             break;

                                  default  : sput_str(error_message); break;

                               }

                           break;

#endif //END of #if defined BOOTLOCK_BIT_READ_SUPPORT && BOOTLOCK_BIT_READ_SUPPORT == 1
              case('I'):
#if defined VERSION_INFO_NEEDED && VERSION_INFO_NEEDED == 1
                           sput_char('\r'); sput_char('\n');
                           eep_address = (E2END - 31);
                           while(eep_address <= E2END)
                               {
                                  x = eeprom_read_byte((unsigned char*)eep_address++);
                                  if(x < 0xff && x > 0){ sput_char(x); }
                               }
#endif
                           sput_str("BootLoader V3.2\r\nChris Efstathiou 2009");
                           break;

              default  :   sput_str(error_message);
                           break;

            }

    }//end of "while(memory_to_write == 0)" loop.

return;
}
__attribute__((__noreturn__)) void main(void)
{

#if (FLASHEND > 0xFFFFUL)
unsigned long flash_address = 0;
#else
unsigned int  flash_address = 0;
#endif
#if SPM_PAGESIZE > 128
unsigned int  x=0, y=0;
#else
unsigned char  x=0, y=0;
#endif
unsigned char high_byte_buffer = 0, low_byte_buffer = 0, packet_resend_required = 0;
unsigned char packet_number = 0, error_counter = 0, memory_full = 0;
unsigned int received_bytes = 0, address_buffer = 0, eeprom_address = 0, crc16 = 0, crc_buffer = 0;

EXTRA_STARTUP_COMMANDS();
ENABLE_LEVEL_PIN();
UART_TIMEOUT_ENABLE();
sget_char(); // Dummy receive used as a 200 ms delay as the UART is not yet enabled.
if( ((PIN_REG(CHECK_LEVEL_PORT) & (1 << CHECK_LEVEL_PIN))) ){ EXTRA_EXIT_COMMANDS(); asm("jmp 0x0000"); }

/* Initialization commands */
// Setup the UART
_UCSRA_ = 0;
// Enable the UART to receive/transmit and enable UART pins
_UCSRB_ = ( (1 << _RXEN_)|(1 << _TXEN_) );
// Set UART to receive and transmit 8 bits per character, 1 stop bit with no parity.
_UCSRC_ = ( USEURSEL | (1 << _UCSZ1_) | (1 << _UCSZ0_) );
// Set baudrate.
_UBRRH_ = BAUDREG/256;
_UBRRL_ = BAUDREG%256;
// Turn on the pull up resistor of the UART rx pin.
DDR_REG(UART_PORT) &= (~(1<<UART_RX_PIN));
PORT_REG(UART_PORT) |= (1<<UART_RX_PIN);
// Make the UART Txd pin an output.
DDR_REG(UART_PORT) |= (1<<UART_TX_PIN);
// Enable the LED indication.
ENABLE_LED();
#if INTIALIZATION_DELAY > 0
sget_char();
#endif
/* MAIN BOOTLOADER LOOP */
while(1)
    {
       // START THE STANDARD 128 BYTE PACKET X MODEM CRC FILE DOWNLOAD
       // I tried to follow the crc X modem protocol as faithfully as i could
       LED_ON();
       flash_address = 0;
       eeprom_address = 0;
       packet_number = 0;
       error_counter = 0;
       received_bytes = 0;
       memory_to_write = 0;
       memory_full = 0;
       UART_TIMEOUT_DISABLE(); //Disable uart receive timeout.
       receive_at_command();
       sput_str("START THE X MODEM TRANSFER\r\n");
       UART_TIMEOUT_ENABLE(); //Enable the UART timeout.

       do{
            sput_char(XMODEM_NCG);
         }while(sget_char() != XMODEM_SOH);

       // DOWNLOAD AND VERIFY ONE PACKET AT A TIME UNTILL THE BUFFER IS FULL. The buffer is equal to SPM_PAGESIZE.
       /*------------------------------------------------------------------------------------------------------*/
       do{
           crc16 = 0;
#if BOOTLOADER_SAVE_CODE_SIZE == 1
           sget_char();
           sget_char();
#elif BOOTLOADER_SAVE_CODE_SIZE == 0
           packet_number++;
           packet_resend_required = 0;
           high_byte_buffer =  sget_char();     //get X modem packet number
           low_byte_buffer  =  sget_char();
           // Examine the packet number.
           if( (high_byte_buffer + low_byte_buffer) != 255 ) { packet_resend_required = (1<<2); }
           if( high_byte_buffer == (packet_number-1) ) { packet_resend_required |= (1<<1); }
           if(high_byte_buffer != packet_number) { packet_resend_required |= (1<<0); }
#endif
           // Now receive the packet data and perform the crc16 check.

           for(x = X_MODEM_PACKET_LENGTH; x > 0; x--)
             {
                x_buffer[received_bytes] = sget_char();
                crc16 = ( crc16 ^ ((unsigned int)x_buffer[received_bytes] << 8) );
                for(y = 8; y > 0; y--)
                  {
                     crc_buffer = crc16 << 1;
                     if(crc16 & 0x8000) { crc_buffer = crc_buffer ^ 0x1021; }
                     crc16 = crc_buffer;
                  }
                received_bytes++;
             }
           high_byte_buffer = sget_char();         //get X modem CRC16
           low_byte_buffer  = sget_char();
#if BOOTLOADER_SAVE_CODE_SIZE == 0
           if( (high_byte_buffer != (crc16 / 256))||(low_byte_buffer != (crc16 % 256)) ){ packet_resend_required |= (1<<3); }
           // Now we must see if the packet was received ok or if not, what went wrong.
           if(packet_resend_required > 0)
            {
               error_counter++;
               packet_number--;  // Packet number is decremented.
               received_bytes -= X_MODEM_PACKET_LENGTH;
               if( packet_resend_required >= (1<<2) )
                {
                   sput_char(XMODEM_NAK);

                 }else if(packet_resend_required >= (1<<1) )
                        {
                           sput_char(XMODEM_ACK);

                        }else{
                               goto XMODEM_FAILED;
                              } // end of "if( packet_resend_required >= (1<<2) )" statement.
#elif BOOTLOADER_SAVE_CODE_SIZE == 1
           if( (high_byte_buffer != (crc16 / 256))||(low_byte_buffer != (crc16 % 256)) )
            {
               goto XMODEM_FAILED;

#endif
            }else{  // "if(packet_resend_required > 0)" statement.
                   if(memory_to_write == 1)
                    {
                       x = 0;
                       while( received_bytes >= SPM_PAGESIZE )
                           {
                              if(flash_address <= (BOOTLOADER_MEM_START-SPM_PAGESIZE) )
                               {
                                  address_buffer = x; // Store the x_buffer position for the verification process.
                                  y=0;
                                  do{
                                       boot_page_fill_safe( y, x_buffer[x] | (x_buffer[x+1] << 8) );
                                       x+=2; //BYTE COUNTER UP TO "received_bytes"
                                       y+=2; //BYTE COUNTER UP TO SPM_PAGESIZE
                                    }while(y < SPM_PAGESIZE);
                                  boot_page_erase_safe(flash_address);      //erase one Flash page
                                  boot_page_write_safe(flash_address);      //write buffer to one Flash page
                                  boot_rww_enable_safe();
                                  y=0;
                                  do{
                                      if( pgm_read_byte(flash_address+y) != x_buffer[address_buffer+y] ){ goto XMODEM_FAILED; }
                                      y++;
                                    }while(y < SPM_PAGESIZE);
                                  flash_address += SPM_PAGESIZE;
                                  received_bytes -= SPM_PAGESIZE;

                               }else{ memory_full = 1; goto XMODEM_FAILED; }
                           }

                    }else if(memory_to_write == 2)
                           {
                             for(x=0; x < X_MODEM_PACKET_LENGTH; x++)
                               {
                                  if(eeprom_address <= E2END)
                                   {
                                      eeprom_write_byte((unsigned char*)eeprom_address, x_buffer[x]);
                                      if(eeprom_read_byte((unsigned char*)eeprom_address) != x_buffer[x]){ goto XMODEM_FAILED; }
                                      eeprom_address++;

                                   }else{ memory_full = 1;  }
                               }
                             received_bytes = 0;
                           }
                   sput_char(XMODEM_ACK);
                   //error_counter =0;
                 }// end of "if(packet_resend_required > 0){...}else{...}" statement

           if(error_counter >= 10){ goto XMODEM_FAILED; }  //Standard X modem max errors is 10, abort update.

         }while(sget_char() != XMODEM_EOT); // End of do{}while loop
/*----------------------------------------------------------------------------------------------------------*/
       // The flash or Eeprom is written so it is time to exit.
       // exit the X modem transfer.
       sput_char(XMODEM_NAK);
       if(sget_char() == XMODEM_EOT)
        {
           sput_char(XMODEM_ACK);
           error_counter = 0;
        }
       else{
             // If the transfer failed send the X modem cancel character 10 times as per X modem specifications.
XMODEM_FAILED:
               y=0;
               do{
                    sput_char(XMODEM_CAN);
                    y++;

                 }while( y<10);
               error_counter = 1;

           }

       _UCSRB_ &= (~ (1 << _RXEN_));
       UART_TIMEOUT_1S();
       sget_char();   //dummy receive. It is used as delay.
       _UCSRB_ |= (1 << _RXEN_);
       if(memory_full)
        {
           sput_str("Error memory full");

        }else if(error_counter)
               {
                  sput_str(error_message);

               }else{
                       sput_str(update_success_message);
                    }
       //(*((void(*)(void))(BOOTLOADER_MEM_START)))();

    } // END of while(1) main loop.


}
int main(void)
{
    char buffer[7];
    
	DDRA=0xF0;						//SET DATA DIRECTION REGISTER
									//SET 1 for OUTPUT PORT
									//SET 0 FOR INPUT PORT
									//PA.4, PA.5, PA.6 AND PA.7 ARE OUTPUT
									//ALL OTHERS ARE INPUT
									
	DDRB=0XFB;						//SET DATA DIRECTION REGISTER
									//SET 1 for OUTPUT PORT
									//SET 0 FOR INPUT PORT
									//PB.2 IS  INPUT
									//ALL OTHERS ARE OUTPUT
	
	DDRD=0XF1;						//SET DATA DIRECTION REGISTER
									//SET 1 for OUTPUT PORT
									//SET 0 FOR INPUT PORT
									//PD.1, PD.2 AND PD.3 ARE INPUT
									//ALL OTHERS ARE OUTPUT

	sbi(PORTA,4);					//LED1 ON (INDICATION FOR READY TO USE)
	
	
	sbi(PORTB,2);					//ENABLE PULL UP FOR SWITCH INT2
	sbi(PORTD,1);					//ENABLE PULL UP FOR SW1
	sbi(PORTD,2);					//ENABLE PULL UP FOR SWITCH INT0
	sbi(PORTD,3);					//ENABLE PULL UP FOR SWITCH INT1
	
    /*
     *  Initialize UART library, pass baudrate and AVR cpu clock
     *  with the macro 
     *  UART_BAUD_SELECT() (normal speed mode )
     *  or 
     *  UART_BAUD_SELECT_DOUBLE_SPEED() ( double speed mode)
     */
    uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) ); 
    
    /*
     * now enable interrupt, since UART library is interrupt controlled
     */
    sei();
    
    /*
     * Transmit string from program memory to UART
     */
    uart_puts_P("\r\n\nSample code made by Robokits India for ROBOGRID. ");
	uart_puts_P("\r\n\nVisit Us at www.robokits.org. ");
	uart_puts_P("\r\n\nSample code for eeprom writing and reading.");
	
	uint8_t num;
	uint8_t *ead;

	num=0;
	ead = 0;

	do
	{                   
		eeprom_write_byte(ead++, num);  
		num++; 		
	} while (num != 255);
		
	uart_puts_P("\r\n EEPROM written. Now read content from EEPROM\n\r");  		
		
	num = 0;
		
	for (ead = 0; num != 255; ead++)
	{
		num = eeprom_read_byte(ead);     
		itoa(num, buffer, 10);   // convert interger into string (decimal format)    
		uart_puts(buffer);        // and transmit string to UART
		uart_puts_P("  ");  	  
	}
	return(0);
}
//************************************************************************
boolean	ATS_Test_EEPROM(void)
{
boolean		passedOK;
uint8_t 	dataByte;
uint8_t		dataByteRead;
uint16_t	dataWord;
uint16_t	dataWordRead;
uint32_t	dataLongWord;
uint32_t	dataLongWordRead;
int			addressPtr;
char		reportString[48];

	passedOK		=	true;
	//*	test BYTE read/write
	addressPtr		=	random(E2END);
	dataByte		=	0x5A;
	eeprom_write_byte((uint8_t *)addressPtr, dataByte);
	dataByteRead	=	eeprom_read_byte((uint8_t *)addressPtr);

	sprintf(reportString, "EEPROM_byte_rw  (addr= 0x%04X)", addressPtr);
	if (dataByteRead == dataByte)
	{
		ATS_PrintTestStatus(reportString, PASSED);
	}
	else
	{
		ATS_PrintTestStatus(reportString, FAILED);
		passedOK		=	false;
	}


	//*	test WORD read/write
	addressPtr		=	random(E2END);
	dataWord		=	0xA55A;
	eeprom_write_word((uint16_t *)addressPtr, dataWord);
	dataWordRead	=	eeprom_read_word((uint16_t *)addressPtr);

	sprintf(reportString, "EEPROM_word_rw  (addr= 0x%04X)", addressPtr);
	if (dataWordRead == dataWord)
	{
		ATS_PrintTestStatus(reportString, PASSED);
	}
	else
	{
		ATS_PrintTestStatus(reportString, FAILED);
		passedOK		=	false;
	}


	//*	test Long WORD read/write
	addressPtr		=	random(E2END);
	dataLongWord	=	0x5AA5A55A;
	eeprom_write_dword((uint32_t *)addressPtr, dataLongWord);
	dataLongWordRead	=	eeprom_read_dword((uint32_t *)addressPtr);

	sprintf(reportString, "EEPROM_dword_rw (addr= 0x%04X)", addressPtr);
	if (dataLongWordRead == dataLongWord)
	{
		ATS_PrintTestStatus(reportString, PASSED);
	}
	else
	{
		ATS_PrintTestStatus(reportString, FAILED);
		passedOK		=	false;
	}


	return(passedOK);
}
Beispiel #5
0
/*-----------------------------------------------------------------------------
*  process received bus telegrams
*/
static void ProcessBus(void) {

   uint8_t     ret;
   TBusMsgType msgType;
   uint8_t     i;
   uint8_t     *p;
   bool        msgForMe = false;
   uint8_t     flags;

   uint8_t         old_osccal;
   static uint8_t  sOsccal = 0;
   uint16_t        startCnt;
   uint16_t        stopCnt;
   uint16_t        clocks;
   uint16_t        diff;
   uint16_t        seqLen;
   static int      sCount = 0;
   static uint16_t sMinDiff = 0xffff;
   static uint8_t  sMinOsccal = 0;
   uint8_t         osccal_corr;
   
   ret = BusCheck();

   if (ret == BUS_MSG_OK) {
      msgType = spRxBusMsg->type; 
      switch (msgType) {  
         case eBusDevReqReboot:
         case eBusDevReqInfo:
         case eBusDevReqSetAddr:
         case eBusDevReqEepromRead:
         case eBusDevReqEepromWrite:
         case eBusDevReqDoClockCalib:
            if (spRxBusMsg->msg.devBus.receiverAddr == MY_ADDR) {
               msgForMe = true;
            }
            break;
         default:
            break;
      }
      if (msgForMe == false) {
         return;
      }

      switch (msgType) {  
         case eBusDevReqReboot:
            /* reset controller with watchdog */    
            /* set watchdog timeout to shortest value (14 ms) */                     
            cli();
            wdt_enable(WDTO_15MS);
            /* wait for reset */
            while (1);
            break;   
         case eBusDevReqInfo:
            sTxBusMsg.type = eBusDevRespInfo;  
            sTxBusMsg.senderAddr = MY_ADDR; 
            sTxBusMsg.msg.devBus.receiverAddr = spRxBusMsg->senderAddr;
            sTxBusMsg.msg.devBus.x.devResp.info.devType = eBusDevTypeSw8Cal;
            strncpy((char *)(sTxBusMsg.msg.devBus.x.devResp.info.version),
               version, BUS_DEV_INFO_VERSION_LEN); 
            sTxBusMsg.msg.devBus.x.devResp.info.version[BUS_DEV_INFO_VERSION_LEN - 1] = '\0';
            BusSend(&sTxBusMsg);  
            break;
         case eBusDevReqSetAddr:
            sTxBusMsg.senderAddr = MY_ADDR; 
            sTxBusMsg.type = eBusDevRespSetAddr;  
            sTxBusMsg.msg.devBus.receiverAddr = spRxBusMsg->senderAddr;
            p = &(spRxBusMsg->msg.devBus.x.devReq.setAddr.addr);
            eeprom_write_byte((uint8_t *)MODUL_ADDRESS, *p);
            BusSend(&sTxBusMsg);  
            break;
         case eBusDevReqEepromRead:
            sTxBusMsg.senderAddr = MY_ADDR; 
            sTxBusMsg.type = eBusDevRespEepromRead;
            sTxBusMsg.msg.devBus.receiverAddr = spRxBusMsg->senderAddr;
            sTxBusMsg.msg.devBus.x.devResp.readEeprom.data = 
               eeprom_read_byte((const uint8_t *)spRxBusMsg->msg.devBus.x.devReq.readEeprom.addr);
            BusSend(&sTxBusMsg);  
            break;
         case eBusDevReqEepromWrite:
            sTxBusMsg.senderAddr = MY_ADDR; 
            sTxBusMsg.type = eBusDevRespEepromWrite;
            sTxBusMsg.msg.devBus.receiverAddr = spRxBusMsg->senderAddr;
            p = &(spRxBusMsg->msg.devBus.x.devReq.writeEeprom.data);
            eeprom_write_byte((uint8_t *)spRxBusMsg->msg.devBus.x.devReq.readEeprom.addr, *p);
            BusSend(&sTxBusMsg);  
            break;
         case eBusDevReqDoClockCalib:
            if (spRxBusMsg->msg.devBus.x.devReq.doClockCalib.command == eBusDoClockCalibInit) {
                sCount = 0;
                sOsccal = 0;
                sMinDiff = 0xffff;
            } else if (sCount > MAX_CAL_TEL) {
                sTxBusMsg.msg.devBus.x.devResp.doClockCalib.state = eBusDoClockCalibStateError;
                sTxBusMsg.senderAddr = MY_ADDR; 
                sTxBusMsg.type = eBusDevRespDoClockCalib;
                sTxBusMsg.msg.devBus.receiverAddr = spRxBusMsg->senderAddr;
                BusSend(&sTxBusMsg);
                break;
            }

            flags = DISABLE_INT;

            BUS_TRANSCEIVER_POWER_UP;
            PORTB = 0;

            /* 8 bytes 0x00: 8 * (1 start bit + 8 data bits) + 7 stop bits  */
            seqLen = 8 * 1000000 * 9 / 9600 + 7 * 1000000 * 1 / 9600; /* = 8229 us */
            old_osccal = OSCCAL;

            ExitComm();
            InitTimer1();

            TCCR1B = (1 << ICES1) | TIMER1_PRESCALER;

            OSCCAL = sOsccal;
            NOP_10;
            
            for (i = 0; i < 8; i++) {
                startCnt = Synchronize();
                stopCnt = ClkMeasure();
                
                clocks = stopCnt - startCnt;
                if (clocks > seqLen) {
                    diff = clocks - seqLen;
                } else {
                    diff = seqLen - clocks;
                }
                if (diff < sMinDiff) {
                    sMinDiff = diff;
                    sMinOsccal = OSCCAL;
                }
                OSCCAL++;
                NOP_4;
            }

            BUS_TRANSCEIVER_POWER_DOWN;

            InitTimer1();
            InitComm();
            sOsccal = OSCCAL;
            OSCCAL = old_osccal;

            RESTORE_INT(flags);

            if (sCount < MAX_CAL_TEL) { 
                sTxBusMsg.msg.devBus.x.devResp.doClockCalib.state = eBusDoClockCalibStateContiune;
                sCount++;
            } else {
                sTxBusMsg.msg.devBus.x.devResp.doClockCalib.state = eBusDoClockCalibStateSuccess;
                /* save the osccal correction value to eeprom */
                osccal_corr = eeprom_read_byte((const uint8_t *)OSCCAL_CORR);
                osccal_corr += sMinOsccal - old_osccal;
                eeprom_write_byte((uint8_t *)OSCCAL_CORR, osccal_corr);
                OSCCAL = sMinOsccal;
                NOP_10;
            }
            sTxBusMsg.senderAddr = MY_ADDR; 
            sTxBusMsg.type = eBusDevRespDoClockCalib;
            sTxBusMsg.msg.devBus.receiverAddr = spRxBusMsg->senderAddr;
            BusSend(&sTxBusMsg);  
            break;
         default:
            break;
      }   
   }
}
Beispiel #6
0
/* read recieved byte   */
uint8_t spi_get_rx()
{
    return eeprom_read_byte(&SPI_RX);
}
Beispiel #7
0
static uint8_t get_txpower_from_eeprom(void)
{
	return eeprom_read_byte(&eemem_txpower);
}
Beispiel #8
0
void steno_init() {
  if (!eeconfig_is_enabled()) {
    eeconfig_init();
  }
  mode = eeprom_read_byte(EECONFIG_STENOMODE);
}
Beispiel #9
0
uint8 MDP_IsWatchdogEnable() {
	if (isWatchdogEnabled == 255) {
		isWatchdogEnabled = eeprom_read_byte((uint8_t*) WATCHDOG_ENABLE_VALUE);
	}
	return isWatchdogEnabled;
}
Beispiel #10
0
/*! \fn     usbProcessIncoming(uint8_t* incomingData)
*   \brief  Process the incoming USB packet
*   \param  incomingData    Pointer to the packet (can be overwritten!)
*/
void usbProcessIncoming(uint8_t* incomingData)
{
    // Temp plugin return value, error by default
    uint8_t plugin_return_value = PLUGIN_BYTE_ERROR;

    // Use message structure
    usbMsg_t* msg = (usbMsg_t*)incomingData;

    // Get data len
    uint8_t datalen = msg->len;

    // Get data cmd
    uint8_t datacmd = msg->cmd;

#ifdef USB_FEATURE_PLUGIN_COMMS
    // Temp ret_type
    RET_TYPE temp_rettype;
#endif
    
#ifdef DEV_PLUGIN_COMMS
    char stack_str[10];
#endif
    // Debug comms
    // USBDEBUGPRINTF_P(PSTR("usb: rx cmd 0x%02x len %u\n"), datacmd, datalen);

    switch(datacmd)
    {
        // ping command
        case CMD_PING :
        {
            usbSendMessage(0, 6, msg);
            return;
        }

        // version command
        case CMD_VERSION :
        {
            msg->len = 3; // len + cmd + FLASH_CHIP
            msg->cmd = CMD_VERSION;
            msg->body.data[0] = FLASH_CHIP;
            msg->len += getVersion((char*)&msg->body.data[1], sizeof(msg->body.data) - 1);
            usbSendMessage(0, msg->len, msg);
            return;
        }

#ifdef USB_FEATURE_PLUGIN_COMMS
        // context command
        case CMD_CONTEXT :
        {
            if (checkTextField(msg->body.data, datalen, NODE_PARENT_SIZE_OF_SERVICE) == RETURN_NOK)
            {
                plugin_return_value = PLUGIN_BYTE_ERROR;
                USBPARSERDEBUGPRINTF_P(PSTR("setCtx: len %d too big\n"), datalen);
            }
            else if (getSmartCardInsertedUnlocked() != TRUE)
            {
                plugin_return_value = PLUGIN_BYTE_NOCARD;
                USBPARSERDEBUGPRINTF_P(PSTR("set context: no card\n"));                
            }
            else if (setCurrentContext(msg->body.data, datalen) == RETURN_OK)
            {
                plugin_return_value = PLUGIN_BYTE_OK;
                USBPARSERDEBUGPRINTF_P(PSTR("set context: \"%s\" ok\n"), msg->body.data);
            }
            else
            {
                plugin_return_value = PLUGIN_BYTE_ERROR;
                USBPARSERDEBUGPRINTF_P(PSTR("set context: \"%s\" failed\n"), msg->body.data);
            }
            break;
        }

        // get login
        case CMD_GET_LOGIN :
        {
            if (getLoginForContext((char*)incomingData) == RETURN_OK)
            {
                // Use the buffer to store the login...
                usbSendMessage(CMD_GET_LOGIN, strlen((char*)incomingData)+1, incomingData);
                USBPARSERDEBUGPRINTF_P(PSTR("get login: \"%s\"\n"),(char *)incomingData);
                return;
            }
            else
            {
                plugin_return_value = PLUGIN_BYTE_ERROR;
                USBPARSERDEBUGPRINTF_P(PSTR("get login: failed\n"));
            }
            break;
        }

        // get password
        case CMD_GET_PASSWORD :
        {
            if (getPasswordForContext((char*)incomingData) == RETURN_OK)
            {
                usbSendMessage(CMD_GET_PASSWORD, strlen((char*)incomingData)+1, incomingData);
                USBPARSERDEBUGPRINTF_P(PSTR("get pass: \"%s\"\n"),(char *)incomingData);
                return;
            }
            else
            {
                plugin_return_value = PLUGIN_BYTE_ERROR;
                USBPARSERDEBUGPRINTF_P(PSTR("get pass: failed\n"));
            }
            break;
        }

        // set login
        case CMD_SET_LOGIN :
        {
            if (checkTextField(msg->body.data, datalen, NODE_CHILD_SIZE_OF_LOGIN) == RETURN_NOK)
            {
                plugin_return_value = PLUGIN_BYTE_ERROR;
                USBPARSERDEBUGPRINTF_P(PSTR("set login: \"%s\" checkTextField failed\n"),msg->body.data);
            }
            else if (setLoginForContext(msg->body.data, datalen) == RETURN_OK)
            {
                plugin_return_value = PLUGIN_BYTE_OK;
                USBPARSERDEBUGPRINTF_P(PSTR("set login: \"%s\" ok\n"),msg->body.data);
            }
            else
            {
                plugin_return_value = PLUGIN_BYTE_ERROR;
                USBPARSERDEBUGPRINTF_P(PSTR("set login: \"%s\" failed\n"),msg->body.data);
            }
            break;
        }

        // set password
        case CMD_SET_PASSWORD :
        {
            if (checkTextField(msg->body.data, datalen, NODE_CHILD_SIZE_OF_PASSWORD) == RETURN_NOK)
            {
                plugin_return_value = PLUGIN_BYTE_ERROR;
                USBPARSERDEBUGPRINTF_P(PSTR("set pass: len %d invalid\n"), datalen);
            }
            else if (setPasswordForContext(msg->body.data, datalen) == RETURN_OK)
            {
                plugin_return_value = PLUGIN_BYTE_OK;
                USBPARSERDEBUGPRINTF_P(PSTR("set pass: \"%s\" ok\n"),msg->body.data);
            }
            else
            {
                plugin_return_value = PLUGIN_BYTE_ERROR;
                USBPARSERDEBUGPRINTF_P(PSTR("set pass: failed\n"));
            }
            break;
        }

        // check password
        case CMD_CHECK_PASSWORD :
        {
            if (checkTextField(msg->body.data, datalen, NODE_CHILD_SIZE_OF_PASSWORD) == RETURN_NOK)
            {
                plugin_return_value = PLUGIN_BYTE_ERROR;
                break;
            }
            temp_rettype = checkPasswordForContext(msg->body.data, datalen);
            if (temp_rettype == RETURN_PASS_CHECK_NOK)
            {
                plugin_return_value = PLUGIN_BYTE_ERROR;
            }
            else if(temp_rettype == RETURN_PASS_CHECK_OK)
            {
                plugin_return_value = PLUGIN_BYTE_OK;
            }
            else
            {
                plugin_return_value = PLUGIN_BYTE_NA;
            }
            break;
        }

        // set password
        case CMD_ADD_CONTEXT :
        {
            if (checkTextField(msg->body.data, datalen, NODE_PARENT_SIZE_OF_SERVICE) == RETURN_NOK)
            {
                // Check field
                plugin_return_value = PLUGIN_BYTE_ERROR;
                USBPARSERDEBUGPRINTF_P(PSTR("set context: len %d invalid\n"), datalen);
            }
            else if (addNewContext(msg->body.data, datalen) == RETURN_OK)
            {
                // We managed to add a new context
                plugin_return_value = PLUGIN_BYTE_OK;
                USBPARSERDEBUGPRINTF_P(PSTR("add context: \"%s\" ok\n"),msg->body.data);
            }
            else
            {
                // Couldn't add a new context
                plugin_return_value = PLUGIN_BYTE_ERROR;
                USBPARSERDEBUGPRINTF_P(PSTR("add context: \"%s\" failed\n"),msg->body.data);
            }
            break;
        }
#endif

#ifdef FLASH_BLOCK_IMPORT_EXPORT
        // flash export start
        case CMD_EXPORT_FLASH_START :
        {
            approveImportExportMemoryOperation(CMD_EXPORT_FLASH_START, &plugin_return_value);
            guiGetBackToCurrentScreen();
            break;
        }

        // export flash contents
        case CMD_EXPORT_FLASH :
        {
            uint8_t size = PACKET_EXPORT_SIZE;
            
            // Check that the user approved
            if (currentFlashOpUid != CMD_EXPORT_FLASH_START)
            {
                return;
            }

            //flashOpCurAddr1 is the page
            //flashOpCurAddr2 is the offset
            // Check if the export address is correct
            if (flashOpCurAddr1 >= PAGE_COUNT)
            {
                usbSendMessage(CMD_EXPORT_FLASH_END, 0, NULL);
                USBPARSERDEBUGPRINTF_P(PSTR("export: end\n"));
                currentFlashOpUid = 0;
                return;
            }

            // Check how much data we need in case we're close to the page end
            if ((BYTES_PER_PAGE - flashOpCurAddr2) < PACKET_EXPORT_SIZE)
            {
                size = (uint8_t)(BYTES_PER_PAGE - flashOpCurAddr2);
            }

            // Get a block of data and send it, increment counter
            readDataFromFlash(flashOpCurAddr1, flashOpCurAddr2, size, (void*)incomingData);
            usbSendMessage(CMD_EXPORT_FLASH, size, incomingData);
            //usbSendMessageWithRetries(CMD_EXPORT_FLASH, size, (char*)incomingData, 255);
            flashOpCurAddr2 += size;
            
            if (flashOpCurAddr2 == BYTES_PER_PAGE)
            {
                flashOpCurAddr2 = 0;
                flashOpCurAddr1++;
            }

            // Skip over the graphics address if we're in that case
            if (flashOpCurAddr1 == GRAPHIC_ZONE_PAGE_START)
            {
                flashOpCurAddr1 = GRAPHIC_ZONE_PAGE_END;
            }
            return;
        }
        
        // flash export end
        case CMD_EXPORT_FLASH_END :
        {
            currentFlashOpUid = 0;
            return;
        }

        // flash export start
        case CMD_EXPORT_EEPROM_START :
        {
            approveImportExportMemoryOperation(CMD_EXPORT_EEPROM_START, &plugin_return_value);
            guiGetBackToCurrentScreen();
            break;
        }

        // export eeprom contents
        case CMD_EXPORT_EEPROM :
        {
            uint8_t size = PACKET_EXPORT_SIZE;

            // Check that the user approved
            if (currentFlashOpUid != CMD_EXPORT_EEPROM_START)
            {
                return;
            }

            //flashOpCurAddr1 is the current eeprom address
            // Check if the export address is correct
            if (flashOpCurAddr1 >= EEPROM_SIZE)
            {
                usbSendMessage(CMD_EXPORT_EEPROM_END, 0, NULL);
                USBPARSERDEBUGPRINTF_P(PSTR("export: end\n"));
                currentFlashOpUid = 0;
                return;
            }

            // Check how much data we need
            if ((EEPROM_SIZE - flashOpCurAddr1) < PACKET_EXPORT_SIZE)
            {
                size = (uint8_t)(EEPROM_SIZE - flashOpCurAddr1);
            }

            // Get a block of data and send it, increment counter
            eeprom_read_block(incomingData, (void*)flashOpCurAddr1, size);
            usbSendMessage(CMD_EXPORT_EEPROM, size, (char*)incomingData);
            //usbSendMessageWithRetries(CMD_EXPORT_EEPROM, size, (char*)incomingData, 255);
            flashOpCurAddr1 += size;
            return;
        }
        
        // end eeprom export
        case CMD_EXPORT_EEPROM_END :
        {
            currentFlashOpUid = 0;
            return;
        }

        // import flash contents
        case CMD_IMPORT_FLASH_BEGIN :
        {
            // Check datalen for arg
            if (datalen != 1)
            {
                USBPARSERDEBUGPRINTF_P(PSTR("import: no param\n"));
                return;
            }
            
            // Ask user approval            
            approveImportExportMemoryOperation(CMD_IMPORT_FLASH_BEGIN, &plugin_return_value);

            //flashOpCurAddr1 is the page
            //flashOpCurAddr2 is the offset
            // Check what we want to write
            if (msg->body.data[0] == 0x00)
            {
                flashOpCurAddr1 = 0x0000;
                flash_import_user_space = TRUE;
            }
            else
            {
                flash_import_user_space = FALSE;
                flashOpCurAddr1 = GRAPHIC_ZONE_PAGE_START;
            }
            
            // Get back to normal screen
            guiGetBackToCurrentScreen();
            break;
        }

        // import flash contents
        case CMD_IMPORT_FLASH :
        {
            // Check if we actually approved the import, haven't gone over the flash boundaries, if we're correctly aligned page size wise
            if ((currentFlashOpUid != CMD_IMPORT_FLASH_BEGIN) || (flashOpCurAddr1 >= PAGE_COUNT) || (flashOpCurAddr2 + datalen > BYTES_PER_PAGE) || ((flash_import_user_space == FALSE) && (flashOpCurAddr1 >= GRAPHIC_ZONE_PAGE_END)))
            {
                plugin_return_value = PLUGIN_BYTE_ERROR;
                currentFlashOpUid = 0;
            }
            else
            {
                flashWriteBuffer(msg->body.data, flashOpCurAddr2, datalen);
                flashOpCurAddr2+= datalen;

                // If we just filled a page, flush it to the page
                if (flashOpCurAddr2 == BYTES_PER_PAGE)
                {
                    flashWriteBufferToPage(flashOpCurAddr1);
                    flashOpCurAddr2 = 0;
                    flashOpCurAddr1++;

                    // If we are importing user contents, skip the graphics zone
                    if ((flash_import_user_space == TRUE) && (flashOpCurAddr1 == GRAPHIC_ZONE_PAGE_START))
                    {
                        flashOpCurAddr1 = GRAPHIC_ZONE_PAGE_END;
                    }
                }
                plugin_return_value = PLUGIN_BYTE_OK;
            }
            break;
        }

        // end flash import
        case CMD_IMPORT_FLASH_END :
        {
            if ((currentFlashOpUid == CMD_IMPORT_FLASH_BEGIN) && (flashOpCurAddr2 != 0))
            {
                flashWriteBufferToPage(flashOpCurAddr1);
            }
            plugin_return_value = PLUGIN_BYTE_OK;
            currentFlashOpUid = 0;
            break;
        }

        // import flash contents
        case CMD_IMPORT_EEPROM_BEGIN :
        {
            // Ask for user confirmation
            approveImportExportMemoryOperation(CMD_IMPORT_EEPROM_BEGIN, &plugin_return_value);
            guiGetBackToCurrentScreen();
            break;
        }

        // import flash contents
        case CMD_IMPORT_EEPROM :
        {
            // flashOpCurAddr1 is the current eeprom address
            if ((currentFlashOpUid != CMD_IMPORT_EEPROM_BEGIN) || ((flashOpCurAddr1 + datalen) >= EEPROM_SIZE))
            {
                plugin_return_value = PLUGIN_BYTE_ERROR;
                currentFlashOpUid = 0;
            }
            else
            {
                eeprom_write_block((void*)msg->body.data, (void*)flashOpCurAddr1, datalen);
                flashOpCurAddr1+= datalen;
                plugin_return_value = PLUGIN_BYTE_OK;
            }
            break;
        }

        // end eeprom import
        case CMD_IMPORT_EEPROM_END :
        {
            plugin_return_value = PLUGIN_BYTE_OK;
            currentFlashOpUid = 0;
            break;
        }
#endif
#ifdef NODE_BLOCK_IMPORT_EXPORT
        // Read user profile in flash
        case CMD_START_MEMORYMGMT :
        {            
            // Check that the smartcard is unlocked
            if (getSmartCardInsertedUnlocked() == TRUE)
            {
                // If so, ask the user to approve memory management mode
                approveMemoryManagementMode(&plugin_return_value);
            }            
            break;
        }
        
        // Read starting parent
        case CMD_GET_STARTING_PARENT :
        {
            // Check that we're actually in memory management mode
            if (memoryManagementModeApproved == TRUE)
            {
                // Read starting parent
                uint16_t temp_address = getStartingParentAddress();
                
                // Send address
                usbSendMessage(CMD_GET_STARTING_PARENT, 2, (uint8_t*)&temp_address);
                
                // Return
                return;
            }
            else
            {
                plugin_return_value = PLUGIN_BYTE_ERROR;
            }
            break;            
        }
        
        // Get a free node address
        case CMD_GET_FREE_SLOT_ADDR :
        {
            // Check that we're actually in memory management mode
            if (memoryManagementModeApproved == TRUE)
            {
                uint16_t temp_address;
                
                // Scan for next free node address
                scanNodeUsage();
                
                // Store next free node address
                temp_address = getFreeNodeAddress();
                
                // Send address
                usbSendMessage(CMD_GET_FREE_SLOT_ADDR, 2, (uint8_t*)&temp_address);
                return;
            }
            else
            {
                plugin_return_value = PLUGIN_BYTE_ERROR;
            }
            break;
        }
        
        // End memory management mode
        case CMD_END_MEMORYMGMT :
        {
            // Check that we're actually in memory management mode
            if (memoryManagementModeApproved == TRUE)
            {
                // memoryManagementModeApproved is cleared when user removes his card
                guiSetCurrentScreen(SCREEN_DEFAULT_INSERTED_NLCK);
                plugin_return_value = PLUGIN_BYTE_OK;
                leaveMemoryManagementMode();
                guiGetBackToCurrentScreen();
                scanNodeUsage();
            }
            else
            {
                plugin_return_value = PLUGIN_BYTE_ERROR;
            }
            break;
        }
        
        // Read node from Flash
        case CMD_READ_FLASH_NODE :
        {
            // Check that the mode is approved & that args are supplied
            if ((memoryManagementModeApproved == TRUE) && (datalen == 2))
            {
                uint16_t* temp_uint_ptr = (uint16_t*)msg->body.data;
                uint8_t temp_buffer[NODE_SIZE];
                
                // Read node in flash & send it, ownership check is done in the function
                readNode((gNode*)temp_buffer, *temp_uint_ptr);
                usbSendMessage(CMD_READ_FLASH_NODE, NODE_SIZE, temp_buffer);
                return;
            }
            else
            {
                plugin_return_value = PLUGIN_BYTE_ERROR;
            }
            break;
        }
        
        // Set favorite
        case CMD_SET_FAVORITE :
        {
            // Check that the mode is approved & that args are supplied
            if ((memoryManagementModeApproved == TRUE) && (datalen == 5))
            {
                uint16_t* temp_par_addr = (uint16_t*)&msg->body.data[1];
                uint16_t* temp_child_addr = (uint16_t*)&msg->body.data[3];
                
                setFav(msg->body.data[0], *temp_par_addr, *temp_child_addr);
                plugin_return_value = PLUGIN_BYTE_OK;
            }
            else
            {
                plugin_return_value = PLUGIN_BYTE_ERROR;
            }
            break;            
        }
        
        // Get favorite
        case CMD_GET_FAVORITE :
        {
            // Check that the mode is approved & that args are supplied
            if ((memoryManagementModeApproved == TRUE) && (datalen == 1))
            {
                uint16_t data[2];
                readFav(msg->body.data[0], &data[0], &data[1]);
                usbSendMessage(CMD_GET_FAVORITE, 4, (void*)data);
                return;
            }
            else
            {
                plugin_return_value = PLUGIN_BYTE_ERROR;
            }
            break;
        }
        
        // Set starting parent
        case CMD_SET_STARTINGPARENT :
        {
            // Check that the mode is approved & that args are supplied
            if ((memoryManagementModeApproved == TRUE) && (datalen == 2))
            {
                uint16_t* temp_par_addr = (uint16_t*)&msg->body.data[0];
                setStartingParent(*temp_par_addr);
                plugin_return_value = PLUGIN_BYTE_OK;
            }
            else
            {
                plugin_return_value = PLUGIN_BYTE_ERROR;
            }
            break;            
        }
        
        // Set new CTR value
        case CMD_SET_CTRVALUE :
        {
            // Check that the mode is approved & that args are supplied
            if ((memoryManagementModeApproved == TRUE) && (datalen == USER_CTR_SIZE))
            {
                setProfileCtr(msg->body.data);
                plugin_return_value = PLUGIN_BYTE_OK;
            }
            else
            {
                plugin_return_value = PLUGIN_BYTE_ERROR;
            }
            break;            
        }
        
        // Get CTR value
        case CMD_GET_CTRVALUE :
        {
            // Check that the mode is approved & that args are supplied
            if (memoryManagementModeApproved == TRUE)
            {
                // Temp buffer to store CTR
                uint8_t tempCtrVal[USER_CTR_SIZE];
                
                // Read CTR value
                readProfileCtr(tempCtrVal);
                
                // Send it
                usbSendMessage(CMD_GET_CTRVALUE, USER_CTR_SIZE, tempCtrVal);
                return;
            }
            else
            {
                plugin_return_value = PLUGIN_BYTE_ERROR;
            }
            break;
        }
        
        // Add a known card to the MP, 8 first bytes is the CPZ, next 16 is the CTR nonce
        case CMD_ADD_CARD_CPZ_CTR :
        {
            // Check that the mode is approved & that args are supplied
            if ((memoryManagementModeApproved == TRUE) && (datalen == SMARTCARD_CPZ_LENGTH + AES256_CTR_LENGTH))
            {
                writeSmartCardCPZForUserId(msg->body.data, &msg->body.data[SMARTCARD_CPZ_LENGTH], getCurrentUserID());
                plugin_return_value = PLUGIN_BYTE_OK;
            }
            else
            {
                plugin_return_value = PLUGIN_BYTE_ERROR;
            }
            break;
        }
        
        // Get all the cpz ctr values for current user
        case CMD_GET_CARD_CPZ_CTR :
        {
            // Check that the mode is approved
            if (memoryManagementModeApproved == TRUE)
            {
                outputLUTEntriesForGivenUser(getCurrentUserID());
                plugin_return_value = PLUGIN_BYTE_OK;
            }
            else
            {
                plugin_return_value = PLUGIN_BYTE_ERROR;
            }
            break;            
        }
        
        // Write node in Flash
        case CMD_WRITE_FLASH_NODE : 
        {
            // First two bytes are the node address
            uint16_t* temp_node_addr_ptr = (uint16_t*)msg->body.data;
            uint16_t temp_flags;
            
            // Check that the plugin provided the address and packet #
            if ((memoryManagementModeApproved != TRUE) || (datalen != 3))
            {
                plugin_return_value = PLUGIN_BYTE_ERROR;
            } 
            else
            {                
                // If it is the first packet, store the address and load the page in the internal buffer
                if (msg->body.data[2] == 0)
                {
                    // Read the flags and check we're not overwriting someone else's data
                    readDataFromFlash(pageNumberFromAddress(*temp_node_addr_ptr), NODE_SIZE * nodeNumberFromAddress(*temp_node_addr_ptr), 2, (void*)&temp_flags);
                    
                    // Either the node belongs to us or it is invalid
                    if((getCurrentUserID() == userIdFromFlags(temp_flags)) || (validBitFromFlags(temp_flags) == NODE_VBIT_INVALID))
                    {
                        currentNodeWritten = *temp_node_addr_ptr;
                        loadPageToInternalBuffer(pageNumberFromAddress(currentNodeWritten));                        
                    }
                }
                
                // Check that the address the plugin wants to write is the one stored and that we're not writing more than we're supposed to
                if ((currentNodeWritten == *temp_node_addr_ptr) && (currentNodeWritten != NODE_ADDR_NULL) && (msg->body.data[2] * (PACKET_EXPORT_SIZE-3) + datalen < NODE_SIZE))
                {
                    // If it's the first packet, set correct user ID
                    if (msg->body.data[2] == 0)
                    {
                        userIdToFlags((uint16_t*)&(msg->body.data[3]), getCurrentUserID());
                    }
                    
                    // Fill the data at the right place
                    flashWriteBuffer(msg->body.data + 3, (NODE_SIZE * nodeNumberFromAddress(currentNodeWritten)) + (msg->body.data[2] * (PACKET_EXPORT_SIZE-3)), datalen - 3);
                    
                    // If we finished writing, flush buffer
                    if (msg->body.data[2] == (NODE_SIZE/(PACKET_EXPORT_SIZE-3)))
                    {
                        flashWriteBufferToPage(pageNumberFromAddress(currentNodeWritten));
                    }
                    
                    plugin_return_value = PLUGIN_BYTE_OK;
                }
                else
                {
                    plugin_return_value = PLUGIN_BYTE_ERROR;
                }
            }
            break;
        }
#endif

        // import media flash contents
        case CMD_IMPORT_MEDIA_START :
        {
            #ifndef DEV_PLUGIN_COMMS
                uint8_t temp_buffer[PACKET_EXPORT_SIZE];
            #endif
            
            // Set default addresses
            mediaFlashImportPage = GRAPHIC_ZONE_PAGE_START;
            mediaFlashImportOffset = 0;
            
            // No check if dev comms
            #ifdef DEV_PLUGIN_COMMS
                plugin_return_value = PLUGIN_BYTE_OK;
                mediaFlashImportApproved = TRUE;
            #else            
                // Mandatory wait for bruteforce
                userViewDelay();
                
                // Compare with our password, can be 0xFF... if not initialized
                if (datalen == PACKET_EXPORT_SIZE)
                {
                    eeprom_read_block((void*)temp_buffer, (void*)EEP_BOOT_PWD, PACKET_EXPORT_SIZE);
                    if (memcmp((void*)temp_buffer, (void*)msg->body.data, PACKET_EXPORT_SIZE) == 0)
                    {
                        plugin_return_value = PLUGIN_BYTE_OK;
                        mediaFlashImportApproved = TRUE;
                    }
                }
            #endif
            
            break;
        }

        // import media flash contents
        case CMD_IMPORT_MEDIA :
        {
            // Check if we actually approved the import, haven't gone over the flash boundaries, if we're correctly aligned page size wise
            if ((mediaFlashImportApproved == FALSE) || (mediaFlashImportPage >= GRAPHIC_ZONE_PAGE_END) || (mediaFlashImportOffset + datalen > BYTES_PER_PAGE))
            {
                plugin_return_value = PLUGIN_BYTE_ERROR;
                mediaFlashImportApproved = FALSE;
            }
            else
            {
                flashWriteBuffer(msg->body.data, mediaFlashImportOffset, datalen);
                mediaFlashImportOffset+= datalen;

                // If we just filled a page, flush it to the page
                if (mediaFlashImportOffset == BYTES_PER_PAGE)
                {
                    flashWriteBufferToPage(mediaFlashImportPage);
                    mediaFlashImportOffset = 0;
                    mediaFlashImportPage++;
                }
                plugin_return_value = PLUGIN_BYTE_OK;
            }
            break;
        }

        // end media flash import
        case CMD_IMPORT_MEDIA_END :
        {
            if ((mediaFlashImportApproved == TRUE) && (mediaFlashImportOffset != 0))
            {
                flashWriteBufferToPage(mediaFlashImportPage);
            }
            plugin_return_value = PLUGIN_BYTE_OK;
            mediaFlashImportApproved = FALSE;
            break;
        }
        
        // Set Mooltipass param
        case CMD_SET_MOOLTIPASS_PARM :
        {
            // Check that args are supplied
            if (datalen == 2)
            {
                setMooltipassParameterInEeprom(msg->body.data[0], msg->body.data[1]);
                plugin_return_value = PLUGIN_BYTE_OK;
            }
            else
            {
                plugin_return_value = PLUGIN_BYTE_ERROR;
            }
            break;
        }
        
        // Get Mooltipass param
        case CMD_GET_MOOLTIPASS_PARM :
        {
            plugin_return_value = getMooltipassParameterInEeprom(msg->body.data[0]);
            break;
        }
        
        // Reset smartcard
        case CMD_RESET_CARD :
        {
            uint16_t* temp_uint_pt = (uint16_t*)msg->body.data;
            // Check the args, check we're not authenticated, check that the card detection returns a user card, try unlocking the card with provided PIN            
            if ((datalen == 2) && (getCurrentScreen() == SCREEN_DEFAULT_INSERTED_UNKNOWN) && (mooltipassDetectedRoutine(swap16(*temp_uint_pt)) == RETURN_MOOLTIPASS_4_TRIES_LEFT))
            {
                eraseSmartCard();
                plugin_return_value = PLUGIN_BYTE_OK;
            }
            else
            {
                plugin_return_value = PLUGIN_BYTE_ERROR;                
            }
            break;
        }
        
        // Add current unknown smartcard
        case CMD_ADD_UNKNOWN_CARD :
        {
            uint16_t* temp_uint_pt = (uint16_t*)msg->body.data;
            
            // Check the args, check we're not authenticated, check that the card detection returns a user card, try unlocking the card with provided PIN
            if ((datalen == (2 + AES256_CTR_LENGTH)) && (getCurrentScreen() == SCREEN_DEFAULT_INSERTED_UNKNOWN) && (mooltipassDetectedRoutine(swap16(*temp_uint_pt)) == RETURN_MOOLTIPASS_4_TRIES_LEFT))
            {
                addNewUserForExistingCard(msg->body.data + 2);
                plugin_return_value = PLUGIN_BYTE_OK;
            }
            else
            {
                plugin_return_value = PLUGIN_BYTE_ERROR;
            }
            break;
        }
        
        // Read card login
        case CMD_READ_CARD_LOGIN :
        {
            if (getSmartCardInsertedUnlocked() == TRUE)
            {
                uint8_t temp_data[SMARTCARD_MTP_LOGIN_LENGTH/8];
                readMooltipassWebsiteLogin(temp_data);
                usbSendMessage(CMD_READ_CARD_LOGIN, sizeof(temp_data), (void*)temp_data);
                return;
            } 
            else
            {
                plugin_return_value = PLUGIN_BYTE_ERROR;
            }
            break;
        }
        
        // Read card stored password
        case CMD_READ_CARD_PASS :
        {
            if (getSmartCardInsertedUnlocked() == TRUE)
            {
                if (guiAskForConfirmation(1, (confirmationText_t*)readStoredStringToBuffer(ID_STRING_SEND_SMC_PASS)) == RETURN_OK)
                {
                    uint8_t temp_data[SMARTCARD_MTP_PASS_LENGTH/8];
                    readMooltipassWebsitePassword(temp_data);
                    usbSendMessage(CMD_READ_CARD_PASS, sizeof(temp_data), (void*)temp_data);
                    guiGetBackToCurrentScreen();
                    return;
                } 
                else
                {
                    guiGetBackToCurrentScreen();
                    plugin_return_value = PLUGIN_BYTE_ERROR;
                }
            } 
            else
            {
                plugin_return_value = PLUGIN_BYTE_ERROR;
            }
            break;
        }
        
        // Set card login
        case CMD_SET_CARD_LOGIN :
        {
            if ((checkTextField(msg->body.data, datalen, SMARTCARD_MTP_LOGIN_LENGTH/8) == RETURN_OK) && (getSmartCardInsertedUnlocked() == TRUE))
            {
                if (guiAskForConfirmation(1, (confirmationText_t*)readStoredStringToBuffer(ID_STRING_SET_SMC_LOGIN)) == RETURN_OK)
                {
                    // Temp buffer for application zone 2
                    uint8_t temp_az2[SMARTCARD_AZ_BIT_LENGTH/8];
                    
                    // Read Application Zone 2
                    readApplicationZone2(temp_az2);
                    // Erase Application Zone 2
                    eraseApplicationZone1NZone2SMC(FALSE);
                    // Write our data in the buffer at the right spot
                    memcpy(temp_az2 + (SMARTCARD_MTP_LOGIN_OFFSET/8), msg->body.data, datalen);
                    // Write the new data in the card
                    writeApplicationZone2(temp_az2);
                    
                    // Return OK
                    plugin_return_value = PLUGIN_BYTE_OK;
                } 
                else
                {
                    plugin_return_value = PLUGIN_BYTE_ERROR;
                }
                guiGetBackToCurrentScreen();
            }
            else
            {
                plugin_return_value = PLUGIN_BYTE_ERROR;
            }
            break;
        }
        
        // Set card stored password
        case CMD_SET_CARD_PASS :
        {
            if ((checkTextField(msg->body.data, datalen, SMARTCARD_MTP_PASS_LENGTH/8) == RETURN_OK) && (getSmartCardInsertedUnlocked() == TRUE))
            {
                if (guiAskForConfirmation(1, (confirmationText_t*)readStoredStringToBuffer(ID_STRING_SET_SMC_PASS)) == RETURN_OK)
                {
                    // Temp buffer for application zone 1
                    uint8_t temp_az1[SMARTCARD_AZ_BIT_LENGTH/8];
                    
                    // Read Application Zone 1
                    readApplicationZone1(temp_az1);
                    // Erase Application Zone 1
                    eraseApplicationZone1NZone2SMC(TRUE);
                    // Write our data in buffer
                    memcpy(temp_az1 + (SMARTCARD_MTP_PASS_OFFSET/8), msg->body.data, datalen);
                    // Write the new data in the card
                    writeApplicationZone1(temp_az1);
                    
                    // Return OK
                    plugin_return_value = PLUGIN_BYTE_OK;
                } 
                else
                {
                    plugin_return_value = PLUGIN_BYTE_ERROR;
                }
                guiGetBackToCurrentScreen();
            }
            else
            {
                plugin_return_value = PLUGIN_BYTE_ERROR;
            }
            break;
        }
        
        // Get 32 random bytes
        case CMD_GET_RANDOM_NUMBER :
        {
            uint8_t randomBytes[32];
            fillArrayWithRandomBytes(randomBytes, 32);
            usbSendMessage(CMD_GET_RANDOM_NUMBER, 32, randomBytes);
            return;
        }            
        
        // set password bootkey
        case CMD_SET_BOOTLOADER_PWD :
        {
            if ((eeprom_read_byte((uint8_t*)EEP_BOOT_PWD_SET) != BOOTLOADER_PWDOK_KEY) && (datalen == PACKET_EXPORT_SIZE))
            {
                eeprom_write_block((void*)msg->body.data, (void*)EEP_BOOT_PWD, PACKET_EXPORT_SIZE);
                eeprom_write_byte((uint8_t*)EEP_BOOT_PWD_SET, BOOTLOADER_PWDOK_KEY);
                plugin_return_value = PLUGIN_BYTE_OK;
            }
            else
            {
                plugin_return_value = PLUGIN_BYTE_ERROR;
            }
            break;
        }
        
        // Jump to bootloader
        case CMD_JUMP_TO_BOOTLOADER :
        {
            #ifndef DEV_PLUGIN_COMMS
                uint8_t temp_buffer[PACKET_EXPORT_SIZE];
            #endif
            
            // Mandatory wait for bruteforce
            userViewDelay();
            #ifdef DEV_PLUGIN_COMMS
                // Write "jump to bootloader" key in eeprom
                eeprom_write_word((uint16_t*)EEP_BOOTKEY_ADDR, BOOTLOADER_BOOTKEY);
                // Use WDT to reset the device
                cli();
                wdt_reset();
                wdt_clear_flag();
                wdt_change_enable();
                wdt_enable_2s();
                sei();
                while(1);
            #else
                if ((eeprom_read_byte((uint8_t*)EEP_BOOT_PWD_SET) == BOOTLOADER_PWDOK_KEY) && (datalen == PACKET_EXPORT_SIZE))
                {
                    eeprom_read_block((void*)temp_buffer, (void*)EEP_BOOT_PWD, PACKET_EXPORT_SIZE);
                    if (memcmp((void*)temp_buffer, (void*)msg->body.data, PACKET_EXPORT_SIZE) == 0)
                    {
                        // Write "jump to bootloader" key in eeprom
                        eeprom_write_word((uint16_t*)EEP_BOOTKEY_ADDR, BOOTLOADER_BOOTKEY);
                        // Use WDT to reset the device
                        cli();
                        wdt_reset();
                        wdt_clear_flag();
                        wdt_change_enable();
                        wdt_enable_2s();
                        sei();
                        while(1);
                    }
                }
            #endif
        }

        // Development commands
#ifdef  DEV_PLUGIN_COMMS
        // erase eeprom
        case CMD_ERASE_EEPROM :
        {
            eraseFlashUsersContents();
            firstTimeUserHandlingInit();
            plugin_return_value = PLUGIN_BYTE_OK;
            break;
        }

        // erase flash
        case CMD_ERASE_FLASH :
        {
            eraseFlashUsersContents();
            plugin_return_value = PLUGIN_BYTE_OK;
            break;
        }

        // erase eeprom
        case CMD_ERASE_SMC :
        {
            if (getSmartCardInsertedUnlocked() == TRUE)
            {
                eraseSmartCard();
                plugin_return_value = PLUGIN_BYTE_OK;
            }
            else
            {
                plugin_return_value = PLUGIN_BYTE_ERROR;
            }
            break;
        }

        case CMD_DRAW_BITMAP :
        {
            usbPrintf_P(PSTR("draw bitmap file %d\n"), msg->body.data[0]);
            if (msg->body.data[3] != 0)     // clear
            {
                oledWriteActiveBuffer();
                oledClear();
                oledBitmapDrawFlash(msg->body.data[1], msg->body.data[2], msg->body.data[0], 0);
            }
            else
            {
                // don't clear, overlay active screen
                oledWriteActiveBuffer();
                oledBitmapDrawFlash(msg->body.data[1], msg->body.data[2], msg->body.data[0], 0);
            }
            return;
        }
        
        case CMD_CLONE_SMARTCARD :
        {
            if (cloneSmartCardProcess(SMARTCARD_DEFAULT_PIN) == RETURN_OK)
            {
                plugin_return_value = PLUGIN_BYTE_OK;
            } 
            else
            {
                plugin_return_value = PLUGIN_BYTE_ERROR;
            }
            break;
        }

        case CMD_SET_FONT :
        {
            usbPrintf_P(PSTR("set font file %d\n"), msg->body.data[0]);
            oledSetFont(msg->body.data[0]);

            if (datalen > 1) {
                usbPrintf_P(PSTR("testing string \"%s\"\n"), (char *)&msg->body.data[1]);
                oledFlipBuffers(0,0);
                oledWriteActiveBuffer();
                oledClear();
                oledPutstr((char *)&msg->body.data[1]);
            }

            return;
        }
        case CMD_STACK_FREE:
            
            usbPutstr("Stack Free ");
            int_to_string(stackFree(),stack_str);
            usbPutstr(stack_str);
            usbPutstr(" bytes\n");
        return;
#endif

        default :   return;
    }
    usbSendMessage(datacmd, 1, &plugin_return_value);
}
Beispiel #11
0
void MDP_ProcessSetWatchdogReq(uint8 msg[], int length) {
	isWatchdogEnabled = msg[11];
	if (eeprom_read_byte((uint8_t*) WATCHDOG_ENABLE_VALUE) != isWatchdogEnabled)
		eeprom_write_byte((uint8_t*) WATCHDOG_ENABLE_VALUE, isWatchdogEnabled);
}
Beispiel #12
0
int main(void) {
    io_init();
    uint8_t input[16];
    aes128_ctx_t ks, iks;


    printf("Build Date: %s\n", build_date);
    printf("Git:        %s\n\n", build_git_sha);
    printf("  Photon DA AES\n");
    printf("-----------------\n");
    printf("ROUNDS  = %lu\n", (unsigned long) ROUNDS);
    printf("DELAY   = %lu\n", (unsigned long) DELAY);
    printf("STARTUP = %lu\n", (unsigned long) STARTUP);
    printf("-----------------\n");
    printf("SBOX:  0x%.2X\n", (unsigned int) aes_sbox);
    printf("Input: 0x%.2X\n", (unsigned int) input);
    printf("Key:   0x%.2X\n", (unsigned int) key);
    printf("-----------------\n");
#if ROUNDS == 0
    uint16_t writes = eeprom_read_word(&write_cycles);
    uint8_t byte = eeprom_read_byte(&input_byte);
    printf("write_cycles = %u\n", writes);
    printf("input_byte = 0x%.2X\n", byte);
#endif
#ifdef PHOTON
    printf("Computing S-Box only!\n");
#endif
    printf("\n");

#if STARTUP > 0
    _delay_ms(STARTUP * 1000);
#endif

#ifdef VERBOSE
    printf("Printing AES Key:\n");
    print_128(key);
    printf("\n");
#endif

    // aes128_init(const void* key, aes128_ctx_t* ctx);
    aes128_init(key, &ks);

#ifdef VERBOSE
    printf("Printing AES SBOX:\n");
    uint16_t s = 0;
    for(s=0; s < 256; s++) {
        printf("%.2X", aes_sbox[s]);
        if((s + 1) % 16 == 0)
            printf("\n");
    }
    printf("\n");
#endif

#if ROUNDS > 0
    unsigned long round = 1;
    uint8_t i=0;
    unsigned long total_rounds = 256 * ROUNDS;
    while(round <= total_rounds) {
        reset_input(input, i);
#else
    reset_input(input, byte);
    memcpy(&init,&input,sizeof(uint8_t)*16);
    printf("Input:\n");
    print_128(input);
    printf("\n");
    while(1) {
        memcpy(&input,&init,sizeof(uint8_t)*16);
#endif
        memcpy(&iks,&ks,sizeof(aes128_ctx_t));

#ifdef VERBOSE
#if ROUNDS > 0
        printf("[%6ld]: Input:\n", round);
#else
        printf("Input:\n");
#endif
        print_128(input);
        printf("\n");
#endif

        // void aes128_enc(void* buffer, aes128_ctx_t* ctx);
        aes128_enc(input, &ks);

#ifdef VERBOSE
#if ROUNDS  > 0
        printf("[%6ld]: Result:\n", round);
#else
        printf("Result:\n");
#endif

        //Result gets written back to the input
        print_128(input);
        printf("\n");
#endif

#if ROUNDS > 0
        round++;
        if ( (round - 1) % ROUNDS == 0)
            i++;
#endif
#if DELAY > 0
        _delay_ms(DELAY);
#endif
    }
#if ROUNDS  > 0
    printf("Exiting... after round %li\n", round - 1);
#endif

    return(0);
}
Beispiel #13
0
void ShowData(void) {
#ifdef WITH_ROTARY_SWITCH
show_page_1:
#endif
  lcd_clear();
  lcd_MEM2_string(VERSION_str);	// "Version x.xxk"
  lcd_line2();
  lcd_MEM2_string(R0_str);	// "R0="
  DisplayValue(eeprom_read_byte(&EE_ESR_ZEROtab[2]),-2,' ',3);
  DisplayValue(eeprom_read_byte(&EE_ESR_ZEROtab[3]),-2,' ',3);
  DisplayValue(eeprom_read_byte(&EE_ESR_ZEROtab[1]),-2,LCD_CHAR_OMEGA,3);
#ifdef FOUR_LINE_LCD
  lcd_line3();
#else
  wait_for_key_ms(MIDDLE_WAIT_TIME);
 #ifdef WITH_ROTARY_SWITCH
  if (rotary.incre > FAST_ROTATION) return;	// fast rotation ends the function
  if (rotary.count < 0) goto show_page_1;
show_page_2:
 #endif
  lcd_clear();
#endif
  /* output line 3 */
  lcd_MEM_string(RIHI); // "RiHi="
  DisplayValue(RRpinPL,-1,LCD_CHAR_OMEGA,3);
#ifdef FOUR_LINE_LCD
  lcd_line4();
#else
  lcd_line2();
#endif
  /* output line 4 */
  lcd_MEM_string(RILO); // "RiLo="
  DisplayValue(RRpinMI,-1,LCD_CHAR_OMEGA,3);

  wait_for_key_ms(MIDDLE_WAIT_TIME);
#ifdef WITH_ROTARY_SWITCH
  if (rotary.incre > FAST_ROTATION) return;	// fast rotation ends the function
 #ifdef FOUR_LINE_LCD
  if (rotary.count < 0) goto show_page_1;
 #else
  if (rotary.count < -1) goto show_page_1;
  if (rotary.count < 0) goto show_page_2;
 #endif
show_page_3:
#endif
  lcd_clear();
  lcd_MEM_string(C0_str);                       //output "C0 "
  DisplayValue(eeprom_read_byte(&c_zero_tab[5]),0,' ',3);		//output cap0 1:3
  DisplayValue(eeprom_read_byte(&c_zero_tab[6]),0,' ',3);		//output cap0 2:3
  DisplayValue(eeprom_read_byte(&c_zero_tab[2]),-12,'F',3);		//output cap0 1:2
  lcd_line2();
  lcd_space();
  lcd_space();
  lcd_space();
  DisplayValue(eeprom_read_byte(&c_zero_tab[1]),0,' ',3);		//output cap0 3:1
  DisplayValue(eeprom_read_byte(&c_zero_tab[4]),0,' ',3);		//output cap0 3:2
  DisplayValue(eeprom_read_byte(&c_zero_tab[0]),-12,'F',3);		//output cap0 2:1
#ifdef FOUR_LINE_LCD
  lcd_line3();
#else
  wait_for_key_ms(MIDDLE_WAIT_TIME);
 #ifdef WITH_ROTARY_SWITCH
  if (rotary.incre > FAST_ROTATION) return;	// fast rotation ends the function
  if (rotary.count < -2) goto show_page_1;
  if (rotary.count < -1) goto show_page_2;
  if (rotary.count < 0) goto show_page_3;
show_page_4:
 #endif
  lcd_clear();
#endif
  /* output line 7 */
  lcd_MEM2_string(REF_C_str);	// "REF_C="
  i2lcd((int16_t)eeprom_read_word((uint16_t *)(&ref_offset)));
#ifdef FOUR_LINE_LCD
  lcd_line4();
#else
  lcd_line2();
#endif
  /* output line 8 */
  lcd_MEM2_string(REF_R_str);  // "REF_R="
  i2lcd((int8_t)eeprom_read_byte((uint8_t *)(&RefDiff)));
  wait_for_key_ms(MIDDLE_WAIT_TIME);
#ifdef WITH_ROTARY_SWITCH
  if (rotary.incre > FAST_ROTATION) return;	// fast rotation ends the function
 #ifdef FOUR_LINE_LCD
  if (rotary.count < -1) goto show_page_1;
  if (rotary.count < 0) goto show_page_3;
 #else
  if (rotary.count < -3) goto show_page_1;
  if (rotary.count < -2) goto show_page_2;
  if (rotary.count < -1) goto show_page_3;
  if (rotary.count < 0) goto show_page_4;
 #endif
#endif
}
Beispiel #14
0
int main(void)
{
	uint16_t send_status_timeout = 25;
	uint32_t station_packetcounter;
	uint32_t pos;
	uint8_t button_state = 0;
	uint8_t manual_dim_direction = 0;

	// delay 1s to avoid further communication with uart or RFM12 when my programmer resets the MC after 500ms...
	_delay_ms(1000);

	util_init();
	check_eeprom_compatibility(DEVICE_TYPE_DIMMER);

	osccal_init();
	
	// read packetcounter, increase by cycle and write back
	packetcounter = eeprom_read_dword((uint32_t*)EEPROM_POS_PACKET_COUNTER) + PACKET_COUNTER_WRITE_CYCLE;
	eeprom_write_dword((uint32_t*)EEPROM_POS_PACKET_COUNTER, packetcounter);

	// read device id and write to send buffer
	device_id = eeprom_read_byte((uint8_t*)EEPROM_POS_DEVICE_ID);	
	use_pwm_translation = 1; //eeprom_read_byte((uint8_t*)EEPROM_POS_USE_PWM_TRANSLATION);	
	
	// TODO: read (saved) dimmer state from before the eventual powerloss
	/*for (i = 0; i < SWITCH_COUNT; i++)
	{
		uint16_t u16 = eeprom_read_word((uint16_t*)EEPROM_POS_SWITCH_STATE + i * 2);
		switch_state[i] = (uint8_t)(u16 & 0b1);
		switch_timeout[i] = u16 >> 1;
	}*/
	
	// read last received station packetcounter
	station_packetcounter = eeprom_read_dword((uint32_t*)EEPROM_POS_STATION_PACKET_COUNTER);

	led_blink(200, 200, 5);

#ifdef UART_DEBUG
	uart_init(false);
	UART_PUTS ("\r\n");
	UART_PUTS ("Open Home Control Dimmer V1.0 (c) Uwe Freese, www.uwe-freese.de\r\n");
	osccal_info();
	UART_PUTF ("Device ID: %u\r\n", device_id);
	UART_PUTF ("Packet counter: %lu\r\n", packetcounter);
	UART_PUTF ("Use PWM translation table: %u\r\n", use_pwm_translation);
	UART_PUTF ("Last received station packet counter: %u\r\n\r\n", station_packetcounter);
#endif

	// init AES key
	eeprom_read_block (aes_key, (uint8_t *)EEPROM_POS_AES_KEY, 32);

	rfm12_init();
	PWM_init();
	io_init();
	setPWMDutyCycle(0);
	timer0_init();

	// DEMO to measure the voltages of different PWM settings to calculate the pwm_lookup table
	/*while (42)
	{
		uint16_t i;
		
		for (i = 0; i <= 1024; i = i + 100)
		{
			UART_PUTF ("PWM value OCR1A: %u\r\n", i);
			OCR1A = i;
			led_blink(500, 6500, 1);
		}
	}*/
	
	// DEMO 0..100..0%, using the pwm_lookup table and the translation table in EEPROM.
	/*while (42)
	{
		float i;
		
		for (i = 0; i <= 100; i = i + 0.05)
		{
			led_blink(10, 10, 1);
			setPWMDutyCycle(i);
		}
		
		for (i = 99.95; i > 0; i = i - 0.05)
		{
			led_blink(10, 10, 1);
			setPWMDutyCycle(i);
		}
	}*/

	// set initial switch state
	/*for (i = 0; i < SWITCH_COUNT; i++)
	{
		switchRelais(i, switch_state[i]);
	}*/

	sei();

	// DEMO 30s
	/*animation_length = 30;
	animation_length = (uint32_t)((float)animation_length * 1000 / ANIMATION_CYCLE_MS);
	start_brightness = 0;
	end_brightness = 255;
	animation_position = 0;*/
	
	while (42)
	{
		if (rfm12_rx_status() == STATUS_COMPLETE)
		{
			uint8_t len = rfm12_rx_len();
			
			if ((len == 0) || (len % 16 != 0))
			{
				UART_PUTF("Received garbage (%u bytes not multiple of 16): ", len);
				printbytearray(bufx, len);
			}
			else // try to decrypt with all keys stored in EEPROM
			{
				memcpy(bufx, rfm12_rx_buffer(), len);
				
				//UART_PUTS("Before decryption: ");
				//printbytearray(bufx, len);
					
				aes256_decrypt_cbc(bufx, len);

				//UART_PUTS("Decrypted bytes: ");
				//printbytearray(bufx, len);

				uint32_t assumed_crc = getBuf32(len - 4);
				uint32_t actual_crc = crc32(bufx, len - 4);
				
				//UART_PUTF("Received CRC32 would be %lx\r\n", assumed_crc);
				//UART_PUTF("Re-calculated CRC32 is  %lx\r\n", actual_crc);
				
				if (assumed_crc != actual_crc)
				{
					UART_PUTS("Received garbage (CRC wrong after decryption).\r\n");
				}
				else
				{
					//UART_PUTS("CRC correct, AES key found!\r\n");
					UART_PUTS("         Received: ");
					printbytearray(bufx, len - 4);
					
					// decode command and react
					uint8_t sender = bufx[0];
					
					UART_PUTF("           Sender: %u\r\n", sender);
					
					if (sender != 0)
					{
						UART_PUTF("Packet not from base station. Ignoring (Sender ID was: %u).\r\n", sender);
					}
					else
					{
						uint32_t packcnt = getBuf32(1);

						UART_PUTF("   Packet Counter: %lu\r\n", packcnt);

						// check received counter
						if (0) //packcnt <= station_packetcounter)
						{
							UART_PUTF2("Received packet counter %lu is lower than last received counter %lu. Ignoring packet.\r\n", packcnt, station_packetcounter);
						}
						else
						{
							// write received counter
							station_packetcounter = packcnt;
							eeprom_write_dword((uint32_t*)EEPROM_POS_STATION_PACKET_COUNTER, station_packetcounter);
							
							// check command ID
							uint8_t cmd = bufx[5];

							UART_PUTF("       Command ID: %u\r\n", cmd);
							
							if (cmd != 141) // ID 141 == Dimmer Request
							{
								UART_PUTF("Received unknown command ID %u. Ignoring packet.\r\n", cmd);
							}
							else
							{
								// check device id
								uint8_t rcv_id = bufx[6];

								UART_PUTF("      Receiver ID: %u\r\n", rcv_id);
								
								if (rcv_id != device_id)
								{
									UART_PUTF("Device ID %u does not match. Ignoring packet.\r\n", rcv_id);
								}
								else
								{
									// read animation mode and parameters
									uint8_t animation_mode = bufx[7] >> 5;
									
									// TODO: Implement support for multiple dimmers (e.g. RGB)
									// uint8_t dimmer_bitmask = bufx[7] & 0b111;
									
									animation_length = getBuf16(8);
									start_brightness = bufx[10];
									end_brightness = bufx[11];

									UART_PUTF("   Animation Mode: %u\r\n", animation_mode); // TODO: Set binary mode like 00010110
									//UART_PUTF("   Dimmer Bitmask: %u\r\n", dimmer_bitmask);
									UART_PUTF("   Animation Time: %us\r\n", animation_length);
									UART_PUTF(" Start Brightness: %u\r\n", start_brightness);
									UART_PUTF("   End Brightness: %u\r\n", end_brightness);
									
									animation_length = (uint32_t)((float)animation_length * 1000 / ANIMATION_CYCLE_MS);
									animation_position = 0;
									
									/* TODO: Write to EEPROM (?)
									// write back switch state to EEPROM
									switch_state[i] = req_state;
									switch_timeout[i] = req_timeout;
									
									eeprom_write_word((uint16_t*)EEPROM_POS_SWITCH_STATE + i * 2, u16);
									
									*/
									
									// send acknowledge
									UART_PUTS("Sending ACK:\r\n");

									// set device ID (base station has ID 0 by definition)
									bufx[0] = device_id;
									
									// update packet counter
									packetcounter++;
									
									if (packetcounter % PACKET_COUNTER_WRITE_CYCLE == 0)
									{
										eeprom_write_dword((uint32_t*)0, packetcounter);
									}

									setBuf32(1, packetcounter);

									// set command ID "Generic Acknowledge"
									bufx[5] = 1;
									
									// set sender ID of request
									bufx[6] = sender;
									
									// set Packet counter of request
									setBuf32(7, station_packetcounter);

									// zero unused bytes
									bufx[11] = 0;
									
									// set CRC32
									uint32_t crc = crc32(bufx, 12);
									setBuf32(12, crc);

									// show info
									UART_PUTF("            CRC32: %lx\r\n", crc);
									uart_putstr("      Unencrypted: ");
									printbytearray(bufx, 16);

									rfm12_sendbuf();
									
									UART_PUTS("   Send encrypted: ");
									printbytearray(bufx, 16);
									UART_PUTS("\r\n");
								
									rfm12_tick();
									
									led_blink(200, 0, 1);
									
									send_status_timeout = 25;
								}
							}
						}
					}
				}
				
			}

			// tell the implementation that the buffer can be reused for the next data.
			rfm12_rx_clear();
		}

		_delay_ms(ANIMATION_UPDATE_MS);
		
		// React on button press.
		// - abort animation
		// - switch off, when brightness > 0
		// - switch on otherwise
		if (!(BUTTON_PORT & (1 << BUTTON_PIN))) // button press
		{
			if (button_state == 0)
			{
				UART_PUTS("Button pressed\r\n");
				animation_length = 0;
				animation_position = 0;
			}
			
			if (button_state < 5)
			{
				button_state++;
			}
			else // manual dimming
			{
				if (manual_dim_direction) // UP
				{
					if (current_brightness < 100)
					{
						current_brightness = (uint8_t)current_brightness / 2 * 2 + 2;
						setPWMDutyCycle(current_brightness);
					}
					else
					{
						UART_PUTS("manual dimming DOWN\r\n");
						manual_dim_direction = 0;
					}
				}
				else // DOWN
				{
					if (current_brightness > 0)
					{
						current_brightness = (((uint8_t)current_brightness - 1) / 2) * 2;
						setPWMDutyCycle(current_brightness);
					}
					else
					{
						UART_PUTS("manual dimming UP\r\n");
						manual_dim_direction = 1;
					}
				}
				
			}
		}
		else if (button_state && (BUTTON_PORT & (1 << BUTTON_PIN))) // button release
		{
			UART_PUTS("Button released\r\n");
			
			if (button_state < 5) // short button press
			{
				if (current_brightness > 0)
				{
					UART_PUTS(" -> 0%\r\n");
					setPWMDutyCycle(0);
				}
				else
				{
					UART_PUTS(" -> 100%\r\n");
					setPWMDutyCycle(100);
				}
			}
			else
			{
				// reverse dim direction
				manual_dim_direction = !manual_dim_direction;
			}
			
			button_state = 0;
		}
				
		// update brightness according animation_position, updated by timer0
		if (animation_length > 0)
		{
			pos = animation_position; // copy value to avoid that it changes in between by timer interrupt
			UART_PUTF2("%lu/%lu, ", pos, animation_length);
			
			if (pos == animation_length)
			{
				UART_PUTF("END Brightness %u%%, ", end_brightness * 100 / 255);
				setPWMDutyCycle((float)end_brightness * 100 / 255);
				animation_length = 0;
				animation_position = 0;
			}
			else
			{			
				float brightness = (start_brightness + ((float)end_brightness - start_brightness) * pos / animation_length) * 100 / 255;
				UART_PUTF("Br.%u%%, ", (uint32_t)(brightness));
				setPWMDutyCycle(brightness);
			}
		}			
		
		// send status from time to time
		if (send_status_timeout == 0)
		{
			send_status_timeout = SEND_STATUS_EVERY_SEC * (1000 / ANIMATION_UPDATE_MS);
			send_dimmer_status();
			led_blink(200, 0, 1);
		}

		rfm12_tick();
		send_status_timeout--;
		checkSwitchOff();
	}
Beispiel #15
0
/**
 * Read a single byte
 */
uint8_t EEPROMClassEx::readByte(int address)
{	
	if (!isReadOk(address+sizeof(uint8_t))) return 0;
	return eeprom_read_byte((unsigned char *) address);
}
Beispiel #16
0
int readMemByte(int position)
{
	return eeprom_read_byte(position);
}
/** Loads saved non-volatile parameter values from the EEPROM into the parameter table, as needed. */
void V2Params_LoadNonVolatileParamValues(void)
{
	/* Target RESET line polarity is a non-volatile value, retrieve current parameter value from EEPROM */
	V2Params_GetParamFromTable(PARAM_RESET_POLARITY)->ParamValue = eeprom_read_byte(&EEPROM_Reset_Polarity);
}
Beispiel #18
0
void loop(void)
{
    //if we are in playback mode
    if (playing)
    {
        // fetch the next note from the eeprom
        reading = eeprom_read_byte((uint8_t*) noteSlot);
        reading = reading * 4;
    }
    else
    {
        // fetch the next note from the probe
        reading = adc_read();
    }

    // if nothing is being pressed
    if (reading < 128)
    {
        // turn the touch LED On
        bit_clear(PORTB, LED_TOUCH);

        // Stop playing any notes we might be playing
        dontplay();

        // if we are recording
        if (recording)
        {
            // turn the REC LED on
            bit_clear(PORTB, LED_REC);
            _delay_ms(10);
            if (adc_read() == reading)
            {
                saved = 0;
            }
        }
    }
    else
    {
        // if we are recording and the note hasn't changed
        if (recording && !saved)
        {
            // crop off the top two bits to make the note fit in an 8 bit memory address
            int readingLess = reading / 4;

            // store the note in the eeprom
            eeprom_write_byte((uint8_t *) noteSlot, (uint8_t) readingLess);

            // move to the next eeprom location
            noteSlot++;

            // if the eeprom is full
            if (noteSlot > 60)
            {
                // stop recording & reset to the beginning of the recording
                recording = FALSE;
                noteSlot = 0;

                // turn the recording LED Off
                bit_set(PORTB, LED_REC);
            }
            else
            {
                // mark the current note as saved
                saved = 1;
            }
        }

        // turn the TOUCH LED off
        bit_set(PORTB, LED_TOUCH);

        // if we are recording, turn the RED LED off (why here?)
        if (recording) bit_set(PORTB, LED_REC);

        // average out the reading over a few samples to make sure it is correct
        _delay_ms(50);
        reading = reading + adc_read() + adc_read() + adc_read() / 4;

        if ((reading <= 310)) // Record button was pressed
        {
            // Toggle Recording Mode
            recording = !recording;

            // If we are finished recording
            if (!recording)
            {
                // add a '0' to the end of the recording, to make sure the playback is turned off
                noteSlot++;
                eeprom_write_byte((uint8_t *) noteSlot, (uint8_t) 0);
            }

            // reset our 'pointer' to the beginning of the eeprom
            noteSlot = 0;

            // wait for the button to be released
            while (adc_read() > 128);
        }
        else if ((reading <= 340)) // Play button was pressed
        {
            // we cant play while recording
            if (!recording)
            {
                // start playing back from the beginning of the eeprom
                playing = TRUE;
                noteSlot = 0;

                // turn on the REC LED
                bit_clear(PORTB, LED_REC);

                // wait for the button to be released
                while (adc_read() > 128);
            }
        }
        else if ((reading <= 359))
        {
            playnote(A1);
        }
        else if (reading <= 380)
        {
            playnote(AS1);
        }
        else if (reading <= 387)
        {
            playnote(B1);
        }
        else if (reading <= 402)
        {
            playnote(C1);
        }
        else if (reading <= 418)
        {
            playnote(CS1);
        }
        else if (reading <= 436)
        {
            playnote(D1);
        }
        else if (reading <= 455)
        {
            playnote(DS1);
        }
        else if (reading <= 477)
        {
            playnote(E1);
        }
        else if (reading <= 500)
        {
            playnote(F1);
        }
        else if (reading <= 525)
        {
            playnote(FS1);
        }
        else if (reading <= 554)
        {
            playnote(G1);
        }
        else if (reading <= 586)
        {
            playnote(GS1);
        }
        else if (reading <= 621)
        {
            playnote(A2);
        }
        else if (reading <= 661)
        {
            playnote(AS2);
        }
        else if (reading <= 707)
        {
            playnote(B2);
        }
        else if (reading <= 760)
        {
            playnote(C2);
        }
        else if (reading <= 821)
        {
            playnote(CS2);
        }
        else if (reading <= 892)
        {
            playnote(D2);
        }
        else if (reading <= 977)
        {
            playnote(DS2);
        }
        else if (reading > 977)
        {
            playnote(E2);
        }
    }

    if (playing)
    {
        // wait for time
        _delay_ms(200);
        dontplay();
        _delay_ms(200);
        noteSlot++;
        if (noteSlot > 60 || reading == 0)
        {
            noteSlot = 0;
            playing = FALSE;
            bit_set(PORTB, LED_REC);
        }
    }
    else
    {
        // loop quickly
        _delay_us(255);
    }
}
Beispiel #19
0
int
AP_EEPROMB::read_byte(int address)
{
	return eeprom_read_byte((const uint8_t *) address);
}
Beispiel #20
0
// This routine is called once to allow you to set up any other variables in your program
// You can use 'clock' function here.
// The loopStart parameter has the current clock value in μS
TICK_COUNT appInitSoftware(TICK_COUNT loopStart){

	act_setSpeed(&servo_0,DRIVE_SPEED_CENTER);
	act_setSpeed(&servo_1,DRIVE_SPEED_CENTER);
	act_setSpeed(&servo_2,DRIVE_SPEED_CENTER);
	act_setSpeed(&servo_3,DRIVE_SPEED_CENTER);
	act_setSpeed(&servo_4,DRIVE_SPEED_CENTER);
	act_setSpeed(&servo_5,DRIVE_SPEED_CENTER);

	// starting values for trims.
	data[RX_SERVO_0_CH] = eeprom_read_byte(&data_eeprom[RX_SERVO_0_CH]);
	data[RX_SERVO_0_CL] = eeprom_read_byte(&data_eeprom[RX_SERVO_0_CL]);
	data[RX_SERVO_1_CH] = eeprom_read_byte(&data_eeprom[RX_SERVO_1_CH]);
	data[RX_SERVO_1_CL] = eeprom_read_byte(&data_eeprom[RX_SERVO_1_CL]);
	data[RX_SERVO_2_CH] = eeprom_read_byte(&data_eeprom[RX_SERVO_2_CH]);
	data[RX_SERVO_2_CL] = eeprom_read_byte(&data_eeprom[RX_SERVO_2_CL]);
	data[RX_SERVO_3_CH] = eeprom_read_byte(&data_eeprom[RX_SERVO_3_CH]);
	data[RX_SERVO_3_CL] = eeprom_read_byte(&data_eeprom[RX_SERVO_3_CL]);
	data[RX_SERVO_4_CH] = eeprom_read_byte(&data_eeprom[RX_SERVO_4_CH]);
	data[RX_SERVO_4_CL] = eeprom_read_byte(&data_eeprom[RX_SERVO_4_CL]);
	data[RX_SERVO_0_MUL] = eeprom_read_byte(&data_eeprom[RX_SERVO_0_MUL]);
	data[RX_SERVO_1_MUL] = eeprom_read_byte(&data_eeprom[RX_SERVO_1_MUL]);
	data[RX_SERVO_2_MUL] = eeprom_read_byte(&data_eeprom[RX_SERVO_2_MUL]);
	data[RX_SERVO_3_MUL] = eeprom_read_byte(&data_eeprom[RX_SERVO_3_MUL]);
	data[RX_SERVO_4_MUL] = eeprom_read_byte(&data_eeprom[RX_SERVO_4_MUL]);


	data[RX_AUTOP_X_MUL] = eeprom_read_byte(&data_eeprom[RX_AUTOP_X_MUL]);
	data[RX_AUTOP_Y_MUL] = eeprom_read_byte(&data_eeprom[RX_AUTOP_Y_MUL]);
	data[RX_AUTOP_X_TRIM] = eeprom_read_byte(&data_eeprom[RX_AUTOP_X_TRIM]);
	data[RX_AUTOP_Y_TRIM] = eeprom_read_byte(&data_eeprom[RX_AUTOP_Y_TRIM]);

	data[RX_GYRO_X_OFFSET_L] = eeprom_read_byte(&data_eeprom[RX_GYRO_X_OFFSET_L]);
	data[RX_GYRO_X_OFFSET_H] = eeprom_read_byte(&data_eeprom[RX_GYRO_X_OFFSET_H]);
	data[RX_GYRO_Y_OFFSET_L] = eeprom_read_byte(&data_eeprom[RX_GYRO_Y_OFFSET_L]);
	data[RX_GYRO_Y_OFFSET_H] = eeprom_read_byte(&data_eeprom[RX_GYRO_Y_OFFSET_H]);



	if ((data[RX_SERVO_1_CH] < 0x60) | (data[RX_SERVO_1_CH] > 0x80)){
		reset_trims();
	}

	if ((data[RX_SERVO_3_MUL] > 137) || (data[RX_SERVO_3_MUL] < 117)){ data[RX_SERVO_3_MUL] = 127;}
	if ((data[RX_SERVO_4_MUL] > 137) || (data[RX_SERVO_4_MUL] < 117)){ data[RX_SERVO_4_MUL] = 127;}


	// initialise RF module.
	cyrf6936_Initialise_soft(&cyrf_0);
	cyrf6936_Initialise_soft(&cyrf_1);



	// enable interrupt on pin connected to cyrf6936 interrupt pin.
	cyrfIntEnable();

	frameStart=clockGetus();

	data[RX_BAT_VOLT] = a2dConvert8bit(ADC_CH_ADC0);

	AtEst1.AYZ = AtEst0.AYZ = 0x2A7FF;
	AtEst1.AXZ = AtEst1.AXZ = 0x38DFF;


	return 0; // don't pause after
}
Beispiel #21
0
int main(void)
{
        unsigned char ch;
        unsigned char prev_ch=0;
        unsigned char chr_nl=0;
        unsigned char msgparsestate;
        unsigned char cksum=0;
        unsigned char seqnum=0;
        int msglen=0;
        int i=0;
        uart_init();
        wd_init();
        LED_INIT;
        LED_OFF;
        sei();
        msgparsestate=MSG_IDLE;
	// default values:
	CONFIG_PARAM_SW_MINOR=D_CONFIG_PARAM_SW_MINOR;
	CONFIG_PARAM_SW_MAJOR=D_CONFIG_PARAM_SW_MAJOR;
        if (eeprom_read_byte((uint8_t *)EEPROM_MAGIC) == 20){
                // ok magic number matches accept values
                CONFIG_PARAM_SW_MINOR=eeprom_read_byte(EEPROM_MINOR);
                CONFIG_PARAM_SW_MAJOR=eeprom_read_byte(EEPROM_MAJOR);
        }
        while(1){
                if (msgparsestate==MSG_IDLE){
                        ch=uart_getchar(1);
                }else{
                        ch=uart_getchar(0);
                }
                // parse message according to appl. note AVR068 table 3-1:
                if (msgparsestate==MSG_IDLE && ch == MESSAGE_START){
                        msgparsestate=MSG_WAIT_SEQNUM;
                        cksum = ch^0;
                        continue;
                }
		// The special avrusb500 terminal mode.
		// Just connect a serial terminal and press enter twice.
		// Both Windows and Linux send normally \r (=0xd) as the
		// only line end character. It is however possible to configure
		// \r\n as line end in some serial terminals. Therefore we
		// must handle it.
                if (msgparsestate==MSG_IDLE && (ch == '\r'||ch == '\n')){
			i++;
			if(chr_nl ==0 && ch=='\n' && prev_ch== '\r'){
				// terminal sends \r\n for new line
				chr_nl=1;
			}
			prev_ch=ch;
			if (chr_nl){
				// wait for \r\n \r\n
				if (i==4){
					terminalmode(1);
					i=0;
				}
			}else{
				// Linux wait for \n\n
				if (i==2){
					terminalmode(0);
					i=0;
				}
			}
			continue;
		}
                if (msgparsestate==MSG_WAIT_SEQNUM){
                        seqnum=ch;
                        cksum^=ch;
                        msgparsestate=MSG_WAIT_SIZE1;
                        continue;
                }
                if (msgparsestate==MSG_WAIT_SIZE1){
                        cksum^=ch;
                        msglen=ch<<8;
                        msgparsestate=MSG_WAIT_SIZE2;
                        continue;
                }
                if (msgparsestate==MSG_WAIT_SIZE2){
                        cksum^=ch;
                        msglen|=ch;
                        msgparsestate=MSG_WAIT_TOKEN;
                        continue;
                }
                if (msgparsestate==MSG_WAIT_TOKEN){
                        cksum^=ch;
                        if (ch==TOKEN){
                                msgparsestate=MSG_WAIT_MSG;
                                i=0;
                        }else{
                                msgparsestate=MSG_IDLE;
                        }
                        continue;
                }
                if (msgparsestate==MSG_WAIT_MSG && i<msglen && i<280){
                        cksum^=ch;
                        msg_buf[i]=ch;
                        i++;
			wdt_reset(); //wd_kick();
                        if (i==msglen){
                                msgparsestate=MSG_WAIT_CKSUM;
                        }
                        continue;
                }
                if (msgparsestate==MSG_WAIT_CKSUM){
                        if (ch==cksum && msglen > 0){
                                // message correct, process it
                                wdt_reset(); //wd_kick();
                                programcmd(seqnum);
                        }else{
                                msg_buf[0] = ANSWER_CKSUM_ERROR;
                                msg_buf[1] = STATUS_CKSUM_ERROR;
                                transmit_answer(seqnum,2);
                        }
                        // no continue here, set state=MSG_IDLE
                }
                msgparsestate=MSG_IDLE;
                msglen=0;
                seqnum=0;
		prev_ch=0;
                i=0;
        }
	return(0);
}
Beispiel #22
0
/* Read byte to send */
uint8_t spi_get_tx()
{
    return eeprom_read_byte(&SPI_TX);
}
Beispiel #23
0
byte EXROMClass::read(int readPointer)
{
  return eeprom_read_byte((unsigned char *) readPointer);
}
Beispiel #24
0
void USB_ResetInterface(void)
{
	USB_INT_DisableAllInterrupts();
	USB_INT_ClearAllInterrupts();
	
	#if defined(USB_CAN_BE_HOST)
	USB_HostState   = HOST_STATE_Unattached;
	#endif
	
	#if defined(USB_CAN_BE_DEVICE)
	USB_DeviceState = DEVICE_STATE_Unattached;
	USB_ConfigurationNumber  = 0;

	#if !defined(NO_DEVICE_REMOTE_WAKEUP)
	USB_RemoteWakeupEnabled  = false;
	#endif
	
	#if !defined(NO_DEVICE_SELF_POWER)
	USB_CurrentlySelfPowered = false;
	#endif
	#endif
	
	if (!(USB_Options & USB_OPT_MANUAL_PLL))
	{
		#if defined(USB_SERIES_4_AVR)
		PLLFRQ = ((1 << PLLUSB) | (1 << PDIV3) | (1 << PDIV1));
		#endif

		USB_PLL_On();
		while (!(USB_PLL_IsReady()));
	}
	
	USB_Controller_Reset();
	
	#if defined(USB_CAN_BE_BOTH)
	if (UHWCON & (1 << UIDE))
	{
		USB_INT_Clear(USB_INT_IDTI);
		USB_INT_Enable(USB_INT_IDTI);
		USB_CurrentMode = USB_GetUSBModeFromUID();
	}
	#endif
		
	if (!(USB_Options & USB_OPT_REG_DISABLED))
	  USB_REG_On();
	else
	  USB_REG_Off();
	
	USB_CLK_Unfreeze();

	#if (defined(USB_CAN_BE_DEVICE) && (defined(USB_SERIES_4_AVR) || defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR)))
	if (USB_CurrentMode == USB_MODE_DEVICE)
	{
		if (USB_Options & USB_DEVICE_OPT_LOWSPEED)
		  USB_Device_SetLowSpeed();
		else
		  USB_Device_SetFullSpeed();
	}
	#endif
	
	#if (defined(USB_CAN_BE_DEVICE) && !defined(FIXED_CONTROL_ENDPOINT_SIZE))
	if (USB_CurrentMode == USB_MODE_DEVICE)
	{
		USB_Descriptor_Device_t* DeviceDescriptorPtr;

		if (CALLBACK_USB_GetDescriptor((DTYPE_Device << 8), 0, (void*)&DeviceDescriptorPtr) != NO_DESCRIPTOR)
		{		  
			#if defined(USE_RAM_DESCRIPTORS)
			USB_ControlEndpointSize = DeviceDescriptorPtr->Endpoint0Size;
			#elif defined(USE_EEPROM_DESCRIPTORS)
			USB_ControlEndpointSize = eeprom_read_byte(&DeviceDescriptorPtr->Endpoint0Size);
			#else
			USB_ControlEndpointSize = pgm_read_byte(&DeviceDescriptorPtr->Endpoint0Size);
			#endif
		}
	}
	#endif

	USB_Attach();
	
	#if defined(USB_DEVICE_ONLY)
	USB_INT_Clear(USB_INT_SUSPEND);
	USB_INT_Enable(USB_INT_SUSPEND);
	USB_INT_Clear(USB_INT_EORSTI);
	USB_INT_Enable(USB_INT_EORSTI);

	#if defined(USB_SERIES_4_AVR) || defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR)
	USB_INT_Enable(USB_INT_VBUS);
	#endif
	#elif defined(USB_HOST_ONLY)
	USB_Host_HostMode_On();
	
	USB_Host_VBUS_Auto_Off();
	USB_OTGPAD_Off();

	USB_Host_VBUS_Manual_Enable();
	USB_Host_VBUS_Manual_On();
	
	USB_INT_Enable(USB_INT_SRPI);
	USB_INT_Enable(USB_INT_BCERRI);
	#else
	if (USB_CurrentMode == USB_MODE_DEVICE)
	{
		USB_INT_Clear(USB_INT_SUSPEND);
		USB_INT_Enable(USB_INT_SUSPEND);
		USB_INT_Clear(USB_INT_EORSTI);
		USB_INT_Enable(USB_INT_EORSTI);

		#if defined(USB_SERIES_4_AVR) || defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR)
		USB_INT_Enable(USB_INT_VBUS);
		#endif

		#if defined(CONTROL_ONLY_DEVICE)
		UENUM = ENDPOINT_CONTROLEP;
		#endif
	}
	else if (USB_CurrentMode == USB_MODE_HOST)
	{
		USB_Host_HostMode_On();
		
		USB_Host_VBUS_Auto_Off();
		USB_OTGPAD_Off();

		USB_Host_VBUS_Manual_Enable();
		USB_Host_VBUS_Manual_On();
		
		USB_INT_Enable(USB_INT_SRPI);
		USB_INT_Enable(USB_INT_BCERRI);
	}
	#endif
}
Beispiel #25
0
int main(void) {
    uint8_t state = 0;

    PORTB = 0;
    DDRB = _BV(PB0);

	wdt_enable(WDTO_120MS);

    while (OSCCAL < 0x7D) {
        OSCCAL++;
        delay(10000);   
    }

    // Set PWM

    current_set = eeprom_read_byte((uint8_t*) &current_set_eeprom);

    OCR0A = eeprom_read_byte((uint8_t*) &pwm_value);
    //OCR0A = 1;

    TCCR0A = _BV(COM0A1) | _BV(WGM00) | _BV(WGM01);
    TCCR0B = _BV(CS00);
    TCNT0 = 0;
    TIMSK0 = 0;

    // Set ADC

    ADMUX = _BV(MUX1) | _BV(REFS0) | _BV(ADLAR);
    ADCSRA = _BV(ADEN) | _BV(ADIE) | _BV(ADPS2) | _BV(ADPS1) | _BV(ADPS0);
    DIDR0 = _BV(ADC2D) | _BV(ADC3D);

#ifdef USE_CURRENT_SENSE
    ADCSRA |= _BV(ADSC);
#endif

    sei();

//    OSCCAL = 0x7F;

	while (1) {
       	wdt_reset();

        if (OCR0A > MAX_PWM_VALUE) {
            OCR0A = MAX_PWM_VALUE;
        }
            

        // Check button state ----------

        if ((PINB & _BV(BUTTON_INC)) && (state & BUTTON_INC_ON)) {
            state &= ~(BUTTON_INC_ON);

#ifndef USE_CURRENT_SENSE
            if (OCR0A < 0xFE) {
                OCR0A++;
                eeprom_write_byte((uint8_t*) &pwm_value, OCR0A);
            }
#endif

#ifdef USE_CURRENT_SENSE
            if (current_set < MAX_CURRENT_SET) {
                current_set++;
                eeprom_write_byte((uint8_t *) &current_set_eeprom, current_set);
                eeprom_write_byte((uint8_t*) &pwm_value, OCR0A);
            }
#endif
            // INREMENT
        } 

        if (!(PINB & _BV(BUTTON_INC)) && !(state & BUTTON_INC_ON)) {
            state |= BUTTON_INC_ON;
        }

        if ((PINB & _BV(BUTTON_DEC)) && (state & BUTTON_DEC_ON)) {
            state &= ~(BUTTON_DEC_ON);

#ifndef USE_CURRENT_SENSE
            if (OCR0A > 0) {
                OCR0A--;
                eeprom_write_byte((uint8_t*) &pwm_value, OCR0A);
            }
#endif

#ifdef USE_CURRENT_SENSE
            if (current_set > 1) {
                current_set--;
                eeprom_write_byte((uint8_t *) &current_set_eeprom, current_set);
                eeprom_write_byte((uint8_t*) &pwm_value, OCR0A);
            }
#endif
            // DECREMENT
        } 

        if (!(PINB & _BV(BUTTON_DEC)) && !(state & BUTTON_DEC_ON)) {
            state |= BUTTON_DEC_ON;
        }

        // -----------------------------

        delay(10000);
	}

	return 0;
}