Reputation: 35
I'm creating an application with 2 ATMega16 micro controller.
The second micro should check if a password is stored in the external EEPROM then send this information to the first one. So, if there were a stored password user will be ask to log-in, else the user should set a new password and send it to the second micro to save it in the external EEPROM.
The code doesn't run in a right way; can you help me to understand what happens?
Note: all driver used are tested and all of them works correctly.
First Micro Code
#define PASSWORD_LENGTH 5
#define PASSWORD_ADDRESS 0x0311
#define HMI_READY 0
#define CONTROL_READY 1
#define IS_PASSWORD_EXIST 6
#define PASSWORD_EXISTS 7
#define PASSWORD_NOT_EXISTS 8
#include "lcd.h"
#include "keypad.h"
#include "uart.h"
void HMI_init(void) ;
void HMI_set_new_password(uint8 *a_ptrPassword) ;
void HMI_send_password(uint8 *a_ptrPass) ;
uint8 g_password[PASSWORD_LENGTH] = {0} ;
int main(void)
{
HMI_init() ;
UART_sendByte(HMI_READY) ;
LCD_clearDisplay() ;
LCD_displayString("Stuck Here : ( ") ; /*<<<<<<<<<<<<<<<<<<<<<*/
if(UART_receiveByte() == PASSWORD_NOT_EXISTS)
{
LCD_sendCommand(CLEAR_DISPLAY) ;
LCD_displayString("N O ") ;
}
else if(UART_receiveByte() == PASSWORD_EXISTS) ;
{
LCD_sendCommand(CLEAR_DISPLAY) ;
LCD_displayString("Y E S ") ;
while(1)
{
}
}
}
/* Functions Definitions */
void HMI_init(void)
{
LCD_init() ;
LCD_sendCommand(CLEAR_DISPLAY) ;
LCD_sendCommand(CURSOR_OFF) ;
LCD_displayStringRowCol(0,4,"WELCOME") ;
LCD_displayStringRowCol(1,1,"TO DOOR LOCKER") ;
UART_init();
SREG |=(1<<7) ;
}
void HMI_set_new_password(uint8 *a_ptrPassword)
{
uint8 i = 0 ;
uint8 key = 0 ;
uint8 temp_pass[PASSWORD_LENGTH] = {0} ;
uint8 confirm_flag = 0 ;
while(confirm_flag == 0)
{
i = 0 ;
LCD_sendCommand(CLEAR_DISPLAY) ;
LCD_sendCommand(CURSOR_ON) ;
LCD_displayString("SET A PASSWORD : ") ;
LCD_goToRowCol(1,0) ;
while(i<PASSWORD_LENGTH)
{
key = KeyPad_getPresssedKey() ;
if(key>=0 && key<=9)
{
a_ptrPassword[i] = key ;
LCD_displayCharacter('*') ;
i++ ;
}else
{
}
_delay_ms(2000) ;
}
LCD_sendCommand(CLEAR_DISPLAY) ;
LCD_sendCommand(CURSOR_ON) ;
LCD_displayString("REPEAT PASSWORD : ") ;
LCD_goToRowCol(1,0) ;
i = 0 ;
while(i<PASSWORD_LENGTH)
{
key = KeyPad_getPresssedKey() ;
if(key>=0 && key <=9)
{
temp_pass[i] = key ;
i++ ;
LCD_displayCharacter('*') ;
}else
{
}
_delay_ms(2000) ;
}
/* compare */
for(i = 0 ; i<PASSWORD_LENGTH ; i++)
{
if(a_ptrPassword[i] != temp_pass[i])
{
confirm_flag = 0 ;
break ;
}else{
confirm_flag = 1 ;
}
}
if(confirm_flag == 1)
{
LCD_sendCommand(CLEAR_DISPLAY) ;
LCD_displayString("CONFIRMED") ;
_delay_ms(2000) ;
}else if(confirm_flag == 0 )
{
LCD_sendCommand(CLEAR_DISPLAY) ;
LCD_displayString("NOT CONFIRMED") ;
_delay_ms(2000) ;
}
}
}
void HMI_send_password(uint8 *a_ptrPass)
{
uint8 i = 0 ;
for(i = 0 ; i<PASSWORD_LENGTH ; i++)
{
UART_sendByte(a_ptrPass[i]) ;
}
}
Second micro code
#define PASSWORD_LENGTH 5
#define PASSWORD_ADDRESS 0x0311
#define HMI_READY 0
#define CONTROL_READY 1
#define IS_PASSWORD_EXIST 6
#define PASSWORD_EXISTS 7
#define PASSWORD_NOT_EXISTS 8
#include "lcd.h"
#include "uart.h"
#include "eeprom.h"
void CONTROL_init(void) ;
uint8 CONTROL_password_exist(void) ;
void CONTROL_receive_password(uint8 *a_ptrPass) ;
void CONTROL_save_password(uint8 *a_ptrPass) ;
uint8 g_received_password[PASSWORD_LENGTH] = {0} ;
int main(void)
{
CONTROL_init() ;
if(CONTROL_password_exist() == 0)
{
while(UART_receiveByte() != HMI_READY) ;
UART_sendByte(PASSWORD_NOT_EXISTS) ;
}
else
{
while(UART_receiveByte() != HMI_READY) ;
UART_sendByte(PASSWORD_EXISTS) ;
while(1)
{
}
}
}
void CONTROL_init(void)
{
LCD_init() ;
LCD_sendCommand(CLEAR_DISPLAY) ;
LCD_sendCommand(CURSOR_OFF) ;
EEPROM_init() ;
UART_init() ;
SREG |=(1<<7) ;
}
uint8 CONTROL_password_exist(void)
{
uint8 i = 0 ;
uint8 temp = 0 ;
for(i=0 ; i<PASSWORD_LENGTH ; i++)
{
EEPROM_readByte((PASSWORD_ADDRESS+i) , &temp) ;
_delay_ms(150) ;
if(temp != 0xFF)
{
return 1 ;
}
}
return 0 ;
}
void CONTROL_receive_password(uint8 *a_ptrPass)
{
uint8 i = 0 ;
for(i = 0 ; i<PASSWORD_LENGTH ; i++)
{
a_ptrPass[i] = UART_receiveByte() ;
}
}
void CONTROL_save_password(uint8 *a_ptrPass)
{
uint8 i = 0 ;
for(i = 0 ; i<PASSWORD_LENGTH ; i++)
{
EEPROM_writeByte((PASSWORD_ADDRESS+i) , a_ptrPass[i]);
_delay_ms(150) ;
}
}
Upvotes: 0
Views: 106
Reputation: 93556
The synchronisation is poorly implemented - you have a start-up race condition. You have no guarantee that CONTROL is ready when HMI sends its single HMI_READY
byte.
The HMI should wait for a response, and if none is received in a reasonable time (a matter of milliseconds), resend the HMI_READY
:
Pseudo-code - this is just to illustrate a possible structure and logic:
// Wait for response
response = false ;
while( !response )
{
// Send or resend synchronisation byte
send( HMI_READY )
// Wait for response or timeout
start_time = now() ;
while( !response && (now() - start_time) < TIMEOUT )
{
ch = receive() ;
response = ( ch == PASSWORD_NOT_EXISTS || ch == PASSWORD_EXISTS )
}
}
if( ch == PASSWORD_NOT_EXISTS)
{
...
}
else // password exists
{
...
}
Your CONTROL may be fine, since it does wait indefinitely for HMI_READY, but might better be structured thus:
// Wait for synch byte
while( receive() == HMI_READY )
{
// wait
}
if( CONTROL_password_exist() )
{
send( PASSWORD_EXISTS )
}
else
{
send( PASSWORD_NOT_EXISTS )
}
...
In this way, it does not matter when or in what order each micro is started, each will wait for the other - synchronisation.
Upvotes: 0