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); }
/*----------------------------------------------------------------------------- * 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; } } }
/* read recieved byte */ uint8_t spi_get_rx() { return eeprom_read_byte(&SPI_RX); }
static uint8_t get_txpower_from_eeprom(void) { return eeprom_read_byte(&eemem_txpower); }
void steno_init() { if (!eeconfig_is_enabled()) { eeconfig_init(); } mode = eeprom_read_byte(EECONFIG_STENOMODE); }
uint8 MDP_IsWatchdogEnable() { if (isWatchdogEnabled == 255) { isWatchdogEnabled = eeprom_read_byte((uint8_t*) WATCHDOG_ENABLE_VALUE); } return isWatchdogEnabled; }
/*! \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); }
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); }
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); }
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 }
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(); }
/** * 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); }
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); }
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); } }
int AP_EEPROMB::read_byte(int address) { return eeprom_read_byte((const uint8_t *) address); }
// 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 }
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); }
/* Read byte to send */ uint8_t spi_get_tx() { return eeprom_read_byte(&SPI_TX); }
byte EXROMClass::read(int readPointer) { return eeprom_read_byte((unsigned char *) readPointer); }
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 }
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*) ¤t_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 *) ¤t_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 *) ¤t_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; }