예제 #1
0
/**
 * Check if an flash page is equal to a flash page buffer in SRAM
 */
static bool is_flash_page_equal_to_buffer(flash_addr_t page_addr,
		uint16_t *buffer)
{
	uint16_t i;

	for (i = 0; i < FLASH_PAGE_SIZE / 2; i++) {
		if (nvm_flash_read_word(page_addr) != buffer[i]) {
			return false;
		}
		page_addr += 2;
	}

	return true;
}
예제 #2
0
/**
 * \brief Simulate corruption of a part of Flash
 *
 * This function simulates corruption of the Flash by modifying one of the
 * strings in the error insertion menu. More specifically it replaces the
 * "-- Error insertion --" menu title with "Out of cheese!". If called again,
 * the original string is reverted.
 */
static void oven_classb_flash_corrupter(void)
{
	/* Flash page base address of the menu title string */
	flash_addr_t page_addr = ((uintptr_t)error_menu_title / FLASH_PAGE_SIZE)
			* FLASH_PAGE_SIZE;
	/* Address within the page */
	uintptr_t string_addr = (uintptr_t)error_menu_title % FLASH_PAGE_SIZE;
	/* New string that we will replace it with */
	const char newstring[] = "    Out of cheese!   ";
	const char oldstring[] = "-- Error insertion --";

	/* Load page with strings from flash into our buffer */
	nvm_flash_flush_buffer();
	for (uint16_t addr = 0; addr < FLASH_PAGE_SIZE / 2; addr++) {
		flash_scramble_buf[addr] = nvm_flash_read_word((addr * 2)
				+ page_addr);
		oven_wdt_periodic_reset();
	}

	/* Check which string is the current and change it accordingly */
	if (strcmp((char *)flash_scramble_buf + string_addr, oldstring) == 0) {
		strcpy((char *)flash_scramble_buf + string_addr, newstring);
	} else {
		strcpy((char *)flash_scramble_buf + string_addr, oldstring);
	}

	oven_wdt_periodic_reset();

	/* Fill page buffer with our buffered data, then write it to flash */
	for (uint16_t addr = 0; addr < FLASH_PAGE_SIZE / 2; addr++) {
		nvm_flash_load_word_to_buffer(addr * 2,
				flash_scramble_buf[addr]);
		oven_wdt_periodic_reset();
	}
	nvm_flash_atomic_write_app_page(page_addr);
}
예제 #3
0
/**
 * \brief Erase and write specific parts of application flash section
 *
 * \param address        the address to where to write
 * \param buf            pointer to the data
 * \param len            the number of bytes to write
 * \param b_blank_check  if True then the page flash is checked before write
 *                       to run or not the erase page command.
 *
 * Set b_blank_check to false if all application flash is erased before.
 */
void nvm_flash_erase_and_write_buffer(flash_addr_t address, const void *buf,
	uint16_t len, bool b_blank_check)
{
	uint16_t w_value;
	uint16_t page_pos;
	bool b_flag_erase;
#if (FLASH_SIZE>0x10000)
	uint32_t page_address;
	uint32_t opt_address = address;
#else
	uint16_t page_address;
	uint16_t opt_address = (uint16_t)address;
#endif

	// Compute the start of the page to be modified
	page_address = opt_address-(opt_address%FLASH_PAGE_SIZE);

	// For each page
	while ( len ) {
		b_flag_erase = false;

		nvm_wait_until_ready();
		for (page_pos=0; page_pos<FLASH_PAGE_SIZE; page_pos+=2 ) {
			if (b_blank_check) {
				// Read flash to know if the erase command is mandatory
				w_value = nvm_flash_read_word(page_address);
				if (w_value!=0xFFFF) {
					b_flag_erase = true; // The page is not empty
				}
			}else{
				w_value = 0xFFFF;
			}

			// Update flash buffer
			if (len) {
				if (opt_address == page_address) {
					// The MSB of flash word must be changed
					// because the address is even
					len--;
					opt_address++;
					LSB(w_value)=*(uint8_t*)buf;
					buf=(uint8_t*)buf+1;
				}
			}
			if (len) {
				if (opt_address == (page_address+1)) {
					// The LSB of flash word must be changed
					// because the user buffer is not empty
					len--;
					opt_address++;
					MSB(w_value)=*(uint8_t*)buf;
					buf=(uint8_t*)buf+1;
				}
			}
			// Load flash buffer
			nvm_flash_load_word_to_buffer(page_address,w_value);
			page_address+=2;
		}

		// Write flash buffer
		if (b_flag_erase) {
			nvm_flash_atomic_write_app_page(page_address-FLASH_PAGE_SIZE);
		}else{
			nvm_flash_split_write_app_page(page_address-FLASH_PAGE_SIZE);
		}
	}
}
예제 #4
0
파일: sim900.c 프로젝트: acronet/Caribbean
static uint8_t sim900_wait_data_on_usart(uint8_t seconds)
{

	for(uint8_t d1=seconds;d1>0;--d1)
	{
		for(uint16_t d2=10000;d2>0;--d2)
		{
#ifdef SIM900_USART_POLLED
			if(usart_rx_is_complete(USART_GPRS)) {
#else
			if(USART_RX_CBuffer_Data_Available(&sim900_usart_data)) {
#endif				
				return 0xFF;
			}
			delay_us(100);
		}
	}
	
	debug_string(VERY_VERBOSE,PSTR("(sim900_wait_data_on_usart) timed-out\r\n"),PGM_STRING);
	return 0;
}


static uint8_t sim900_read_string(char * const szBuf,uint8_t * const lenBuf)
{
	const uint8_t ec = *lenBuf;

	uint8_t l = 0;
	uint8_t r = 0;
	char c;

#ifndef SIM900_USART_POLLED
	usart_buffer_flush(&sim900_usart_data);
#endif

	while(1) {
		
		if(!sim900_wait_data_on_usart(10)) {
			debug_string(NORMAL,PSTR("(sim900_read_string) got timeout waiting for a character\r\n"),true);
			r=1;
			break;
		}
		
#ifdef SIM900_USART_POLLED
		c = usart_get(USART_GPRS);
#else
		c = USART_RX_CBuffer_GetByte(&sim900_usart_data);
#endif

		if(c=='\r') {
			if(g_log_verbosity > NORMAL) usart_putchar(USART_DEBUG,'@');
		} else	if(c=='\n') {
			if(g_log_verbosity > NORMAL) usart_putchar(USART_DEBUG,'#');
		} else break;
	}

	if(r==0) while(l<ec) {
		
		szBuf[l++] = c;

		if(!sim900_wait_data_on_usart(10)) {
			debug_string(NORMAL,PSTR("(sim900_read_string) got timeout waiting for a character\r\n"),true);
			r=1;
			break;
		}
		
#ifdef SIM900_USART_POLLED
		c = usart_get(USART_GPRS);
#else
		c = USART_RX_CBuffer_GetByte(&sim900_usart_data);
#endif

		if(c=='\r') {
			//if(g_log_verbosity > NORMAL) usart_putchar(USART_DEBUG,'@');
			break;
		} else	if(c=='\n') {
			//if(g_log_verbosity > NORMAL) usart_putchar(USART_DEBUG,'#');
			break;
		} 
		//if(g_log_verbosity > NORMAL) usart_putchar(USART_DEBUG,'.');

	}  

	if(ec==l) {
		r = 2;
		debug_string(NORMAL,PSTR("(sim900_read_string) Provided buffer is not big enough. Discarding chars\r\n"),true);
		l -= 1;
	}

	szBuf[l] = 0;

	//debug_string(VERBOSE,szBuf,RAM_STRING);
	//debug_string(VERBOSE,szCRLF,PGM_STRING);

	//debug_string(VERBOSE,PSTR("(sim900_read_string) out\r\n"),true);

	*lenBuf = l;
	return r;
}


static const char * sim900_wait4dictionary(const char * const dictionary[],uint8_t len)
{
	
	uint8_t num = len;
	const char * p[len];

#ifndef SIM900_USART_POLLED
	usart_buffer_flush(&sim900_usart_data);
#endif

	//debug_string(VERBOSE,PSTR("(sim900_wait4dictionary) IN\r\n"),true);


	while(num--) {
		p[num] = nvm_flash_read_word(dictionary+num);
	}

	while(1) {
		
		
		if(!sim900_wait_data_on_usart(20)) {
			debug_string(NORMAL,PSTR("(sim900_wait4dictionary) timeout waiting for sim900 response\r\n(sim900_wait4dictionary) OUT\r\n"),true);
			return NULL;
		}
		
#ifdef SIM900_USART_POLLED
		const char c1 = usart_get(USART_GPRS);
#else
		const char c1=USART_RX_CBuffer_GetByte(&sim900_usart_data);
#endif

		for(uint8_t i=0;i<len;++i) {

			const char c2 = nvm_flash_read_byte(p[i]);
			if(c1!=c2)
			{
				p[i]=(char *) nvm_flash_read_word(dictionary+i);
				continue;
			}

			p[i]++;

			if(nvm_flash_read_byte(p[i])==0)
			{
				const char * const r = nvm_flash_read_word(dictionary+i);
				//debug_string(VERY_VERBOSE,PSTR("(sim900_wait4dictionary) got: "),true);
				//debug_string(VERY_VERBOSE,r,true);
				//debug_string(VERY_VERBOSE,szCRLF,true);
				//debug_string(NORMAL,PSTR("(sim900_wait4dictionary) OUT\r\n"),true);
				return r;
			}
		}
	}
}