예제 #1
0
/**************************************************************************//**
* @brief    Writes data after the last occupied location and returns the updated
* 			value for the last occupied location
*
* @param	data	is the pointer to the data that will be written to the flash
* @param	length	is the length of the data that will be written to the flash
*
* @return   \b flash_write_count 	is the last occupied location
******************************************************************************/
unsigned int
flash_write_wear_level(unsigned int *data, unsigned int length)
{

	unsigned int ii, index;
	unsigned int flash_write_count;

	flash_read_data(&flash_write_count, 0 ,1);
	switch(flash_write_count){
	// the case of a un-initialized array, brandnew device
	case 0xFFFF:
		flash_write_count = 1;
		flash_write_data(&flash_write_count, 0 ,1);
		flash_write_data(data, 1 ,length);
		break;
		// the case of having reached 50000 writes, reset the counter to 1
	case 0xC350:
		flash_write_count = 1;
		flash_erase_segment(0, SIZE_OF_STORAGE_ARRAY);
		flash_write_data(&flash_write_count, 0 ,1);
		flash_write_data(data, 1 ,length);
		break;
		// Normal operation, find the end of the current array, store new data
	default:
		// search the array for the end of the flash storage array, look for 0xFFFF
		for(ii=0;ii<SIZE_OF_STORAGE_ARRAY;ii=ii+length+1)
		{
			flash_read_data(&flash_write_count, ii ,1);
			if(flash_write_count == 0xFFFF)
			{
				flash_read_data(&flash_write_count, 0 ,1);
				index = ii;
				ii = SIZE_OF_STORAGE_ARRAY;
			}
		}
		// before writing to segment, check to see if we are out of bound
		if(index+length+1 > SIZE_OF_STORAGE_ARRAY )
		{
			// if we have reached the end, delete the entire array, increment counter and restart
			flash_read_data(&flash_write_count, 0 ,1);
			flash_erase_segment(0, SIZE_OF_STORAGE_ARRAY);
			flash_write_count++;
			flash_write_data(&flash_write_count, 0 ,1);
			flash_write_data(data, 1 ,length);
		} else
		{
			// Normal write to Flash array
			flash_write_data(&flash_write_count, index ,1);
			flash_write_data(data, index+1 ,length);
		}
		break;
	}
	return flash_write_count;
}
예제 #2
0
파일: db.c 프로젝트: github4f/doorlock
// *************************************************************************************************
// @fn          db_clear
// @brief       Clear the dataabase
// @param       none
// @return      none
// *************************************************************************************************
void db_clear(void)
{
	u8 i;
	for (i = 0; i < MAX_TABLES; ++i)
	{
		memset(&tables[i], 0, sizeof(db_table_t));
		flash_erase_segment((u8*)tables_in_flash[i]);
	}
	memset(&info, 0, sizeof(db_info_t));
	flash_erase_segment((u8*)info_in_flash);
}
예제 #3
0
파일: db.c 프로젝트: github4f/doorlock
// *************************************************************************************************
// @fn          db_save
// @brief       save a encryption key for a door
// @param       id, key
// @return      status, 0 = success, 1 = db full
// *************************************************************************************************
u8 db_save(u16 id, u8 key[16])
{
	u8 i, j;
	u8 empty_found = 0, empty_i = 0, empty_j = 0;
	
	// first find if the record already exists
	for (i = 0; i < MAX_TABLES; ++i)
	{
		for (j = 0; j < RECORDS_PER_TABLE; ++j)
		{
			if (tables[i].records[j].id == id)
			{
				// found it
				// erase
				flash_erase_segment((u8*)tables_in_flash[i]);
				
				// update RAM first
				memcpy(tables[i].records[j].key, key, 16);
				
				// calculat new crc
				tables[i].crc = crc_compute((u8*)&tables[i],  RECORDS_PER_TABLE * sizeof(db_record_t));
				
				// write only one segment
				flash_write_segment((u8*)tables_in_flash[i], (u8*)(&tables[i]));
				return 0;
			}
			else if (!empty_found && !tables[i].records[j].id)
			{
				empty_i = i;
				empty_j = j;
				empty_found = 1;
			}
		}
	}
	
	// is database all full?
	if (!empty_found) return 1;
	
	// erase
	flash_erase_segment((u8*)tables_in_flash[empty_i]);
	
	// write to a new slot
	tables[empty_i].records[empty_j].id = id;
	memcpy(tables[empty_i].records[empty_j].key, key, 16);
	
	// calculat new crc
	tables[empty_i].crc = crc_compute((u8*)&tables[empty_i],  RECORDS_PER_TABLE * sizeof(db_record_t));
	
	// write only one segment
	flash_write_segment((u8*)tables_in_flash[empty_i], (u8*)(&tables[empty_i]));
	
	return 0;
}
예제 #4
0
파일: main.c 프로젝트: PaulMougel/msp430
/* returns 1 if the id was expected and set, 0 otherwise */
static void set_node_id(unsigned char id)
{
    TIMER_ID_INPUT = UINT_MAX;
    if(flash_write_byte((unsigned char *) NODE_ID_LOCATION, id) != 0)
    {
        flash_erase_segment((unsigned int *) NODE_ID_LOCATION);
        flash_write_byte((unsigned char *) NODE_ID_LOCATION, id);
    }
    node_id = id;
    printf("this node id is now 0x%02X\r\n", id);
}
예제 #5
0
파일: db.c 프로젝트: github4f/doorlock
u16 db_id(void)
{
	if (info.id && info.id != 0xFFFFu)
		return info.id;

	info.id = 0;
	while (!info.id || info.id == 0xFFFFu)
	{
		info.id ^= TA0R;
		info.id ^= crc_compute((u8*)&sDate,  sizeof(struct date));
		info.id ^= crc_compute((u8*)&sTime,  sizeof(struct time));
		info.id ^= crc_compute((u8*)&sBatt,  sizeof(struct batt));
	}

	flash_erase_segment((u8*)info_in_flash);
	info.crc = crc_compute((u8*)&info,  sizeof(db_info_t) - 2);
	flash_write_segment((u8*)info_in_flash, (u8*)(&info));
	return info.id;
}