Esempio n. 1
0
/**
 * Change current media selection
 * \param media Media to select
 */
void media_select(enum media_types media)
{
	if (media_selection == media) {
		return;
	}
	media_dbgp("media select: %s\r\n", media_get_type_str(media));
	if (media_connected) {
		media_disconnect();
	}
	media_selection = media;
}
Esempio n. 2
0
/**
 * Boot information edit
 * \param info Pointer to region information block
 */
static void _app_info_edit(struct regions_info *info)
{
	uint32_t i, input_size = 1, input_flags = DBGIN_ECHO_ON;
	uint8_t menu = 0;
	bool wait_input = false;
	int rc;
	ioport_set_pin_dir(DBG_INFO_EDIT_TRIGGER_PIN, IOPORT_DIR_INPUT);
	if (!DBG_INFO_EDIT_TRIGGER_PIN_ACTIVE
			== ioport_get_pin_level(DBG_INFO_EDIT_TRIGGER_PIN)) {
		return;
	}

	while (1) {
		if (wait_input) {
			rc = _app_dbg_input(input_buf, input_size, input_flags);
			switch (menu) {
			case 1: /* Select boot mode */
				if (input_buf[0] >= '0' &&
						input_buf[0] <
						('0' + TRIGGER_NUM_MAX)) {
					int new_trig = input_buf[0] - '0';
					dbg_print("\r\n");
					dbg_print(
							"- Trigger: %d, %s -> %d, %s\r\n",
							(int)info->trigger,
							trigger_get_mode_str((
								enum
								trigger_modes)
							info
							->trigger),
							new_trig,
							trigger_get_mode_str((
								enum
								trigger_modes)
							new_trig));
					info->trigger = input_buf[0] - '0';
					/* Return to default menu */
					menu = 0;
					wait_input = false;
				} else {
					/* Invalid input, wait another */
					dbg_putchar(BS);
				}

				break;

			case 2: /* Change boot file */
				dbg_print("\r\n");
				if (-1 != rc) {
					dbg_print("- Set file: %s\r\n",
							input_buf);
					strcpy(info->boot_file_name,
							(char *)input_buf);
				}

				/* Return to default menu */
				menu = 0;
				wait_input = false;
				break;

			default: /* Main menu */
				switch (input_buf[0]) {
				/* Switch to menu */
				case '1':
				case '2':
					dbg_print("\r\n");
					menu = input_buf[0] - '0';
					wait_input = false;
					break;

				/* Show regions info */
				case 'i':
				case 'I':
					dbg_print("\r\n");
					_app_show_regions_info(info);
					wait_input = false;
					break;

				/* Load regions info */
				case 'l':
				case 'L':
					region_info_read((void *)INFO_ADDR(
							true), info);
					dbg_print("\r\n- Info loaded\r\n");
					_app_show_regions_info(info);
					wait_input = false;
					break;

				/* Save regions info */
				case 's':
				case 'S':
					_app_save_regions_info(info, true);
					dbg_print("\r\n- Info saved\r\n");
					_app_show_regions_info(info);
					wait_input = false;
					break;

				/* Quit edit */
				case 'q':
				case 'Q':
					dbg_print("\r\n");
					return;

				default: /* Invalid input, wait another */
					dbg_putchar(BS);
				}
			}
		}

		switch (menu) {
		case 1: /* Select trigger mode */
			for (i = 0; i < TRIGGER_NUM_MAX; i++) {
				dbg_print("= %u: %s\r\n", (unsigned)i,
						trigger_get_mode_str((enum
						trigger_modes)i));
			}
			dbg_print("= Current boot mode: %d, %s\r\n",
					(int)info->trigger,
					trigger_get_mode_str((enum trigger_modes)
					info->trigger));
			dbg_print("> New mode:");
			input_size = 1;
			input_flags = DBGIN_ECHO_ON | DBGIN_NUM_ONLY;
			break;

		case 2: /* Change boot file */
			dbg_print("==== Available List ====\r\n");
			for (i = 0; i < MEDIA_NUM_MAX; i++) {
				dbg_print(" - In #%u, %s\r\n", (unsigned)i,
						media_get_type_str((enum
						media_types)i));
				media_select((enum media_types)i);
				media_scan_files(false);
			}
			dbg_print("= Current file: %s\r\n",
					info->boot_file_name);
			dbg_print("> New file:");
			input_size = 13;
			input_flags = DBGIN_ECHO_ON | DBGIN_WANT_ESC |
					DBGIN_WANT_CR;
			break;

		default:
			dbg_print("\r\n==== Info Edit ====\r\n");
			dbg_print(" - 1: Change boot mode\r\n");
			dbg_print(" - 2: Change boot file\r\n");
			dbg_print(" - i: Show regions information\r\n");
			dbg_print(" - l: Load/restore boot information\r\n");
			dbg_print(" - s: Save boot information\r\n");
			dbg_print(" - q: quit edit\r\n");
			input_size = 1;
			input_flags = DBGIN_ECHO_ON;
		}
		wait_input = true;
	}
}
Esempio n. 3
0
/**
 * Receive new firmware
 *
 * \param info Regions information struct
 * \param no_partition Use single partition, do not split memory to app + buff
 *
 * \return received firmware size
 */
static uint32_t _app_load(struct regions_info *info, bool no_partition)
{
	void *addr, *info_addr;
	uint32_t *p_sign, *p_len;
	uint32_t rx_size;
	uint32_t target_region;
	uint32_t i = 0, flags = 0xFF;
	if (info->boot_region != 0 && info->boot_region != 1) {
		dbg_print("bl: Boot region information (%d) invalid\r\n",
				(int)info->boot_region);
		return 0;
	}

	/* Wait media connection */
	i = 0;
	while (i < MEDIA_NUM_MAX) {
		media_select((enum media_types)i);
		if (media_connect()) {
			dbg_print("bl: Source media %s is ready\r\n",
					media_get_type_str((enum media_types)i));
			break;
		} else if (flags & (1 << i)) {
			flags &= ~(1 << i);
			dbg_print("bl: Source media %s not ready\r\n",
					media_get_type_str((enum media_types)i));
		}

		i++;
	}
	target_region = no_partition ? info->boot_region : (!info->boot_region);

	addr      = (void *)APP_START(target_region);
	info_addr = (void *)INFO_ADDR(false);
	dbg_print("bl: Load to %x, info @ %x\r\n", (unsigned)addr,
			(unsigned)info_addr);

	dbg_print("bl: Unlock download buffer & info area ...\r\n");
	memory_unlock(addr, (void *)((uint32_t)addr + APP_CODE_SIZE - 1));
	memory_unlock(info_addr, (void *)((uint32_t)info_addr + INFO_SIZE - 1));
	dbg_print("bl: Unlock download buffer & info area done\r\n");

	dbg_print("bl: Erase download buffer & info area ...\r\n");
	memory_erase(     addr, APP_CODE_SIZE);
	memory_erase(info_addr, INFO_SIZE);
	dbg_print("bl: Erase download buffer & info area done\r\n");

#ifdef DBG_USE_LED
	_app_led_blink(50, 4);
	_app_led_on(DBG_LED_PIN);
#endif

	/* Clear SW force boot trigger */
#ifdef TRIGGER_USE_FLAG
	info->trigger = TRIGGER_BOOT;
#endif
	p_sign = &info->signature[target_region];
	p_len  = &info->length[target_region];
	rx_size = media_load_file(addr, APP_SIZE,
			(uint8_t *)app_mem_block_buf, MEM_BLOCK_SIZE,
			_app_save_block);
	if (rx_size) {
		*p_sign = region_signature(addr, rx_size);
		*p_len  = rx_size;
	} else {
		*p_sign = 0;
		*p_len  = 0;
	}

	/* Save region information */
	region_info_write(info_addr, info);

	dbg_print("bl: Lock download buffer & info area ...\r\n");
	memory_lock(addr, (void *)((uint32_t)addr + APP_CODE_SIZE - 1));
	memory_lock(info_addr, (void *)((uint32_t)info_addr + INFO_SIZE - 1));
	dbg_print("bl: Lock download buffer & info area done\r\n");

#ifdef DBG_USE_LED
	_app_led_off(DBG_LED_PIN);
#endif

#if DUMP_ENABLE
	_dump_data("Downloaded APP:\r\n", addr, rx_size, true);
	_dump_data("INFO:\r\n", info_addr, INFO_SIZE, true);
#endif
	return rx_size;
}