Example #1
0
/***************************************************************************//**
 * @brief
 *   Output the #AT_results of an AT command.
 *
 * @param[in] result
 *   The AT_results_t result to output.
 ******************************************************************************/
void AT_PrintResult(int8_t result)
{
	if (result != AT_NOTHING) {
		AT_last = AT_buffer;
		AT_buffer[0] = '\0';
	}
	if (AT_quietResult == true) {
		return;
	}
	switch (result) {
	case AT_NOTHING:
		break;

	case AT_OK:
		if (AT_verbose) {
			AT_printf("OK\r\n");
		} else {
			AT_printf("0\r");
		}
		break;

	case AT_ERROR:
		if (AT_verbose) {
			AT_printf("ERROR\r\n");
		} else {
			AT_printf("4\r");
		}
		break;

	default:
		break;
	}
}
Example #2
0
/***************************************************************************//**
 * @brief
 *   Parser AT extension function for user.
 *
 * @param[in] token
 *   The token to parse.
 *
 * @return
 *   The parse result.
 ******************************************************************************/
static int8_t user_parse(uint8_t token)
{
	int8_t result = AT_OK;
	int value;

	switch (token) {

	case AT_USER_LED:
		if (AT_argc == 1) {
			value = AT_atoll(AT_argv[0]);
			if (value == 1) {

				// Turn on the LED
				GPIO_PinOutSet(LED_PORT, LED_BIT);
			} else if (value == 0) {

				// Turn off the LED
				GPIO_PinOutClear(LED_PORT, LED_BIT);
			} else {
				result = AT_ERROR;
			}
		} else {
			result = AT_ERROR;
		}
		break;

	case AT_USER_TEMPERATURE:
		if (AT_argc == 0) {
		   value = TD_MEASURE_TemperatureExtended();
		   AT_printf("%d.%d\r\n", value / 10, value % 10);
		} else {
			result = AT_ERROR;
		}
		break;

	case AT_USER_VOLTAGE:
		if (AT_argc == 0) {
		   value = TD_MEASURE_VoltageExtended();
		   AT_printf("%d.%03d\r\n", value / 1000, value % 1000);
		} else {
			result = AT_ERROR;
		}
		break;

	default:
		result = AT_NOTHING;
		break;
	}
	return result;
}
Example #3
0
/***************************************************************************//**
 * @brief
 *   Help AT extension function for user.
 ******************************************************************************/
static void user_help(void)
{
	AT_printf(
		"$L   => Turn on/off the LED\r\n"
		"$T   => Read the temperature\r\n"
		"$V   => Read the voltage\r\n");
};
Example #4
0
/***************************************************************************//**
 * @brief
 *   Help AT extension function for TD Sensor Send.
 ******************************************************************************/
static void sensor_send_help(void)
{
	AT_printf(
		"AT$DP= => Data phone\r\n"
		"AT$EB => Boot event\r\n"
		"AT$EC= => Connection event\r\n"
		"AT$ER= => RSSI event\r\n"
		"AT$ES= => Switch event\r\n"
		"AT$ET= => Temperature event\r\n"
		"AT$EV= => Battery event\r\n"
		"AT$KA => Keep-Alive\r\n"
		"AT$RAW= => Raw frame\r\n"
		"AT$REG => Register frame\r\n"
		"AT$SSMS= => Service SMS\r\n"
		"AT$STWT= => Service Tweet\r\n"
	);
}
Example #5
0
/***************************************************************************//**
 * @brief
 *   AT command parser.
 *
 * @details
 *   This function is the main AT parser function to call when a new input
 *   character is received from the main idle loop.
 *
 *   It will perform lexical analysis, argument collection and call the piece of
 *   code in charge of handling the corresponding AT command.
 *
 * @param[in] c
 *   The new character to parse.
 ******************************************************************************/
void AT_Parse(char c)
{
	uint32_t x, y;
	int extension, i;
	char td_serial[13];

#if defined(__ICCARM__)
	extern unsigned char CSTACK$$Base;
	extern unsigned char CSTACK$$Limit;
	unsigned char *memptr;
#elif defined(__GNUC__)
	extern unsigned char __end;
	extern unsigned char __cs3_region_end_ram;
	unsigned char *memptr;
#endif

	uint8_t token = AT_PARSE;
	int8_t result = AT_OK, extension_result = AT_PARSE;
	uint8_t echo, verbosity, quiet_result, extended_result, banner;
	TD_DEVICE device = {0, 0, 0, 0, 0};
	TD_DEVICE_EXT device_ext = {
		1,
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
	};

	for (extension = 0; extension < AT_EXTENSION_NUMBER; extension++) {
		if (AT_extension[extension] == 0) {
			break;
		}
		if (AT_extension[extension]->tokenize != 0) {
			token = AT_extension[extension]->tokenize(c);
			if (token == AT_ESCAPE) {
				return;
			}
			if (token > AT_BASE_LAST) {
				break;
			}
		}
	}
	if (AT_echo) {
		switch (AT_state) {
		case AT_A:
			if (c == 'A' || c == 'a') {
				tfp_printf("%c", c);
			}
			break;

		case AT_AT:
			if (c == 'T' || c == 't' || c == '/') {
				tfp_printf("%c", c);
			} else {
				tfp_printf("\b \b");
			}
			break;

		default:
			if (c == '\b' || c == 0x7f) {
				if (AT_last > &AT_buffer[2]) {
					tfp_printf("\b \b");
				}
			} else if (c == '\r' || c == '\n') {
				tfp_printf("\r");
			} else {
				tfp_printf("%c", c);
			}
			break;
		}
	}
	if (token == AT_PARSE) {
		token = AT_Tokenize(c, &extension);
	}
	if (token > AT_BASE_LAST && extension < AT_EXTENSION_NUMBER && AT_extension[extension]->parse != 0) {
		extension_result = AT_extension[extension]->parse(token);
		if (extension_result != AT_NOTHING) {
			AT_PrintResult(extension_result);
		}
		return;
	}
	switch (token) {
	case AT_PARSE:
		result = AT_NOTHING;
		break;

	case AT_UNKNOWN:
		result = AT_ERROR;
		break;

	case AT:
		break;

	case AT_DISPLAY_CONFIG:
		for (extension = 0; extension < AT_EXTENSION_NUMBER; extension++) {
			if (AT_extension[extension] == 0) {
				break;
			}
			if (AT_extension[extension]->status != 0) {
				AT_extension[extension]->status(false);
			}
		}
		AT_printf("%s\r\n", CONFIG_MANUFACTURER);
		tfp_printf("Hardware Version: %s\r\n", CONFIG_HARDWARE_VERSION);
		tfp_printf("Software Version: %s\r\n", CONFIG_SOFTWARE_VERSION);
		TD_FLASH_DeviceRead(&device);
		tfp_printf("S/N: %08X\r\n", device.Serial);
		if (TD_FLASH_DeviceReadExtended(&device, &device_ext) == true) {
			for (i = 0; i < 12; i++) {
				td_serial[i] = device_ext.TDSerial[i];
			}
			td_serial[12] = '\0';
			if (td_serial[0] != '?') {
				tfp_printf("TDID: %12s\r\n", td_serial);
			}
		}
		tfp_printf("ACTIVE PROFILE\r\n");
		tfp_printf("E%d V%d Q%d",
				   AT_echo,
				   AT_verbose,
				   AT_quietResult);
		tfp_printf(" X%d S200:%d",
				   AT_extended,
				   AT_banner
				  );
		for (extension = 0; extension < AT_EXTENSION_NUMBER; extension++) {
			if (AT_extension[extension] == 0) {
				break;
			}
			if (AT_extension[extension]->status != 0) {
				AT_extension[extension]->status(true);
			}
		}
		tfp_printf("\r\n");
		break;

	case AT_FACTORY:
		AT_verbose = true;
		AT_extended = true;
		AT_echo = true;
		AT_quietResult = false;
		AT_banner = AT_FORCE_BANNER ? true : false;
		for (extension = 0; extension < AT_EXTENSION_NUMBER; extension++) {
			if (AT_extension[extension] == 0) {
				break;
			}
			if (AT_extension[extension]->init != 0) {
				AT_extension[extension]->init();
			}
		}
		break;

	case AT_GET_BANNER:
		if (AT_argc == 0) {
			AT_printf("%d\r\n", AT_banner);
		} else {
			result = AT_ERROR;
		}
		break;

	case AT_HARDWARE_REV:
		if (AT_argc == 0) {
			AT_printf("%s\r\n", CONFIG_HARDWARE_VERSION);
		} else {
			result = AT_ERROR;
		}
		break;

	case AT_HELP:
		if (AT_argc == 0) {
			AT_printf("%s", AT_help);
			for (extension = 0; extension < AT_EXTENSION_NUMBER; extension++) {
				if (AT_extension[extension] == 0) {
					break;
				}
				if (AT_extension[extension]->help != 0) {
					AT_extension[extension]->help();
				}
			}
		} else {
			result = AT_ERROR;
		}
		break;

	case AT_MANUFACTURER:
		if (AT_argc == 0) {
			AT_printf("%s\r\n", CONFIG_MANUFACTURER);
		} else {
			result = AT_ERROR;
		}
		break;

	case AT_PRODUCT_REV:
		if (AT_argc == 0) {
			if (TD_FLASH_DeviceRead(&device)) {
				AT_printf("%02X\r\n", device.ProdResult);
			} else {
				result = AT_ERROR;
			}
		} else {
			result = AT_ERROR;
		}
		break;

	case AT_QUERY_BANNER:
		if (AT_argc != 0) {
			result = AT_ERROR;
		} else {
			AT_printf("0..1\r\n");
		}
		break;

	case AT_RELEASE_DATE:
		if (AT_argc == 0) {
			AT_printf("%s\r\n", CONFIG_RELEASE_DATE);
		} else {
			result = AT_ERROR;
		}
		break;

	case AT_RESET:
		if (AT_argc == 0) {
			AT_PrintResult(result);
			TD_RTC_Delay(T100MS);
			NVIC_SystemReset();
		} else {
			result = AT_ERROR;
		}
		break;

	case AT_SERIAL_NUMBER:
		if (AT_argc == 0) {
			TD_FLASH_DeviceRead(&device);
			AT_printf("%04X\r\n", device.Serial);
			if (TD_FLASH_DeviceReadExtended(&device, &device_ext) == true) {
				for (i = 0; i < 12; i++) {
					td_serial[i] = device_ext.TDSerial[i];
				}
				td_serial[12] = '\0';
				tfp_printf("TDID: %12s\r\n", td_serial);
			}
		} else {
			result = AT_ERROR;
		}
		break;

	case AT_SET_BANNER:
		if (AT_argc == 1) {
			banner = AT_atoll(AT_argv[0]);
			if (banner > 1) {
				result = AT_ERROR;
			} else {
				AT_banner = banner;
			}
		} else {
			result = AT_ERROR;
		}
		break;

	case AT_SET_ECHO:
		if (AT_argc == 0) {
			AT_echo = false;
		} else if (AT_argc == 1) {
			echo = AT_atoll(AT_argv[0]);
			if (echo < 2) {
				AT_echo = echo ? true : false;
			} else {
				result = AT_ERROR;
			}
		} else {
			result = AT_ERROR;
		}
		break;

	case AT_SET_EXTENDED_RESULTS:
		if (AT_argc == 0) {
			AT_extended = true;
		} else if (AT_argc == 1) {
			extended_result = AT_atoll(AT_argv[0]);
			if (extended_result < 2) {
				AT_extended =  extended_result ? true : false;
			} else {
				result = AT_ERROR;
			}
		} else {
			result = AT_ERROR;
		}
		break;

	case AT_SET_QUIET:
		if (AT_argc == 0) {
			AT_quietResult = true;
		} else if (AT_argc == 1) {
			quiet_result = AT_atoll(AT_argv[0]);
			if (quiet_result < 2) {
				AT_quietResult = quiet_result ? true : false;
			} else {
				result = AT_ERROR;
			}
		} else {
			result = AT_ERROR;
		}
		break;

	case AT_SET_VERBOSITY:
		if (AT_argc == 0) {
			AT_verbose =  true;
		} else if (AT_argc == 1) {
			verbosity = AT_atoll(AT_argv[0]);
			if (verbosity < 2) {
				AT_verbose = verbosity ? true : false;
			} else {
				result = AT_ERROR;
			}
		} else {
			result = AT_ERROR;
		}
		break;

	case AT_SOFTWARE_REV:
		if (AT_argc == 0) {
			AT_printf("%s\r\n", CONFIG_SOFTWARE_VERSION);
		} else {
			result = AT_ERROR;
		}
		break;

#if defined(__ICCARM__)
	case AT_FREE_STACK:
		memptr = &CSTACK$$Base;
		while (memptr < &CSTACK$$Limit) {
			if (*memptr++ != 0xCD) {
				break;
			}
		}
		AT_printf("Free Stack: %d bytes", memptr - &CSTACK$$Base);
		break;
#elif defined(__GNUC__)
	case AT_FREE_STACK:
		memptr = &__end;
		while (memptr < &__cs3_region_end_ram) {
			if (*memptr++ != 0xCD) {
				break;
			}
		}
		AT_printf("Free Stack: %d bytes", memptr - &__end);
		break;
#endif

	case AT_UNIQUE_ID:
		if (AT_argc == 0) {
			x = DEVINFO->UNIQUEH;
			y = DEVINFO->UNIQUEL;
			AT_printf("%08X%08X\r\n", x, y);
		} else {
			result = AT_ERROR;
		}
		break;

	case AT_WRITE_CONFIG:
		if (AT_argc == 0) {
			AT_SavePersistBuffer();
			TD_FLASH_WriteVariables();
		} else {
			result = AT_ERROR;
		}
		break;

	default:
		result = AT_ERROR;
		break;
	}
	AT_PrintResult(result);
}
Example #6
0
/***************************************************************************//**
 * @brief
 *   Initialize the AT command parser.
 ******************************************************************************/
void AT_Init(void)
{
	int i;
	uint8_t extension_read, *persist_pointer;
	uint16_t persist_size = 1;

	for (i = 0; i < AT_BUFFER_SIZE; i++) {
		AT_buffer[i] = '\0';
	}
	for (i = 0; i < AT_BUFFER_SIZE; i++) {
		AT_previousCommand[i] = '\0';
	}
	for (i = 0; i < AT_MAX_ARGS; i++) {
		AT_argv[i] = 0;
	}
	AT_argc = 0;
	AT_last = &AT_buffer[0];
	AT_state = AT_A;
	AT_verbose = true;
	AT_extended = true;
	AT_echo = true;
	AT_quietResult = false;
	AT_banner = AT_FORCE_BANNER ? true : false;

	// Find out how many persistent bytes are required by extensions
	for (i = 0; i < AT_EXTENSION_NUMBER; i++) {
		if (AT_extension[i] == 0) {
			break;
		}
		if (AT_extension[i]->init != 0) {
			AT_extension[i]->init();
		}
		if (AT_extension[i]->persist != 0) {
			persist_size += AT_extension[i]->persist(false, 0, 0);
		}
	}
	if (persist_size > AT_PERSIST_SIZE) {
		persist_size = AT_PERSIST_SIZE;
	}
	/* Read persist data. If not available, create them. After that AT_persist_buffer is correctly filled */
	if (!TD_FLASH_DeclareVariable((uint8_t *) AT_persist_buffer, AT_PERSIST_SIZE, 0)) {
		AT_SavePersistBuffer();
	}

	// Read persistent data
	persist_pointer = AT_persist_buffer;
	AT_echo = (*persist_pointer & 0x01) ? true : false;
	AT_verbose = (*persist_pointer & 0x02) ? true : false;
	AT_quietResult = (*persist_pointer & 0x04) ? true : false;
	AT_extended = (*persist_pointer & 0x08) ? true : false;
	AT_banner  = (*persist_pointer & 0x10) ? true : false;
	persist_pointer++;

	// Pass persistent data to each extension
	for (i = 0; i < AT_EXTENSION_NUMBER; i++) {
		if (AT_extension[i] == 0) {
			break;
		}
		if (AT_extension[i]->persist != 0) {
			extension_read = AT_extension[i]->persist(false, persist_pointer, persist_size);
			persist_pointer += extension_read;
			persist_size -= extension_read;
		}
	}

	if (AT_verbose == true && AT_quietResult == false && AT_banner == true) {
		AT_printf("^SYSSTART\r\n");
	}
}