static real ginvae(arglist *al) /* like ginv, but enrolling At_reset and At_exit */ { static int nginv; AmplExports *ae = al->AE; if (AEInext < AEIlast) { AEInext->n = ++nginv; AEInext->ae = ae; at_reset(At_reset, AEInext); at_exit(At_end, AEInext++); } return ginv(al); }
/** * Initializes an at_info struct for use with the AT system. * @param ati The at_info structure to initialize. * @param sb The serial_buffer to use for tx/rx. Data is kept in the buffer * and is referenced until the command completes. Then its gone. * @return true if the parameters were acceptable, false otherwise. */ bool at_info_init(struct at_info *ati, struct serial_buffer *sb) { if (!ati || !sb) { pr_error("[at] Bad init parameter\r\n"); return false; } /* Clear everything. We don't know where at_info has been */ memset(ati, 0, sizeof(*ati)); ati->sb = sb; at_configure_device(ati, AT_DEFAULT_QP_MS, AT_DEFAULT_DELIMETER, AT_DEV_CFG_FLAG_NONE); /* Reset the state machine, and now we are ready to run */ at_reset(ati); return true; }
/** * Example: * AT+ENETRAWSEND=<len> * ><data> * OK * * Send data in 2 stages. These 2 stages must be finished inside * one mutex lock. * 1. Send 'fst' string (first stage); * 2. Receving prompt, usually "<" character; * 3. Send data (second stage) in 'len' length. */ static int at_send_data_2stage(const char *fst, const char *data, uint32_t len, char *rsp, uint32_t rsplen/*, at_send_t t*/) { int ret = 0; if (at._mode != ASYN) { LOGE(MODULE_NAME, "Operation not supported in non asyn mode"); return -1; } if ((ret = at_reset()) != 0){ LOGE(MODULE_NAME, "There is something wrong with atparser and reset fail\n"); return -1; } at_task_t *tsk = (at_task_t *)aos_malloc(sizeof(at_task_t)); if (NULL == tsk) { LOGE(MODULE_NAME, "tsk buffer allocating failed"); return -1; } if ((ret = aos_sem_new(&tsk->smpr, 0)) != 0) { LOGE(MODULE_NAME, "failed to allocate semaphore"); goto end; } LOGD(MODULE_NAME, "at 2stage task created: %d, smpr: %d", (uint32_t)tsk, (uint32_t)&tsk->smpr); tsk->rsp = rsp; tsk->rsp_offset = 0; tsk->rsp_len = rsplen; /* The 2 stages should be inside one mutex lock*/ /* Mutex context begin*/ aos_mutex_lock(&at._mutex, AOS_WAIT_FOREVER); LOGD(MODULE_NAME, "%s: at lock got", __func__); slist_add_tail(&tsk->next, &at.task_l); // uart operation should be inside mutex lock if ((ret = hal_uart_send(&at._uart, (void *)fst, strlen(fst), at._timeout)) != 0) { aos_mutex_unlock(&at._mutex); LOGE(MODULE_NAME, "uart send 2stage prefix failed"); goto end; } LOGD(MODULE_NAME, "Sending 2stage prefix %s", fst); if ((ret = hal_uart_send(&at._uart, (void *)at._send_delimiter, strlen(at._send_delimiter), at._timeout)) != 0) { aos_mutex_unlock(&at._mutex); LOGE(MODULE_NAME, "uart send delimiter failed"); goto end; } LOGD(MODULE_NAME, "Sending delimiter %s", at._send_delimiter); if ((ret = hal_uart_send(&at._uart, (void *)data, len, at._timeout)) != 0) { aos_mutex_unlock(&at._mutex); LOGE(MODULE_NAME, "uart send 2stage data failed"); goto end; } LOGD(MODULE_NAME, "Sending 2stage data %s", data); if ((ret = hal_uart_send(&at._uart, (void *)at._send_delimiter, strlen(at._send_delimiter), at._timeout)) != 0) { aos_mutex_unlock(&at._mutex); LOGE(MODULE_NAME, "uart send delimiter failed"); goto end; } LOGD(MODULE_NAME, "Sending delimiter %s", at._send_delimiter); aos_mutex_unlock(&at._mutex); LOGD(MODULE_NAME, "%s: at lock released", __func__); /* Mutex context end*/ if ((ret = aos_sem_wait(&tsk->smpr, AOS_WAIT_FOREVER)) != 0) { LOGE(MODULE_NAME, "sem_wait failed"); goto end; } LOGD(MODULE_NAME, "sem_wait succeed."); end: aos_mutex_lock(&at._mutex, AOS_WAIT_FOREVER); slist_del(&tsk->next, &at.task_l); aos_mutex_unlock(&at._mutex); if (aos_sem_is_valid(&tsk->smpr)) aos_sem_free(&tsk->smpr); if (tsk) aos_free(tsk); return ret; }
static int at_send_raw(const char *command, char *rsp, uint32_t rsplen) { int ret = 0; if (at._mode != ASYN) { LOGE(MODULE_NAME, "Operation not supported in non asyn mode"); return -1; } if ((ret = at_reset()) != 0){ LOGE(MODULE_NAME, "There is something wrong with atparser and reset fail\n"); return -1; } at_task_t *tsk = (at_task_t *)aos_malloc(sizeof(at_task_t)); if (NULL == tsk) { LOGE(MODULE_NAME, "tsk buffer allocating failed"); return -1; } if ((ret = aos_sem_new(&tsk->smpr, 0)) != 0) { LOGE(MODULE_NAME, "failed to allocate semaphore"); goto end; } LOGD(MODULE_NAME, "at task created: %d, smpr: %d", (uint32_t)tsk, (uint32_t)&tsk->smpr); tsk->rsp = rsp; tsk->rsp_offset = 0; tsk->rsp_len = rsplen; aos_mutex_lock(&at._mutex, AOS_WAIT_FOREVER); slist_add_tail(&tsk->next, &at.task_l); // uart operation should be inside mutex lock if ((ret = hal_uart_send(&at._uart, (void *)command, strlen(command), at._timeout)) != 0) { aos_mutex_unlock(&at._mutex); LOGE(MODULE_NAME, "uart send command failed"); goto end; } LOGD(MODULE_NAME, "Sending command %s", command); if ((ret = hal_uart_send(&at._uart, (void *)at._send_delimiter, strlen(at._send_delimiter), at._timeout)) != 0) { aos_mutex_unlock(&at._mutex); LOGE(MODULE_NAME, "uart send delimiter failed"); goto end; } LOGD(MODULE_NAME, "Sending delimiter %s", at._send_delimiter); aos_mutex_unlock(&at._mutex); if ((ret = aos_sem_wait(&tsk->smpr, AOS_WAIT_FOREVER)) != 0) { LOGE(MODULE_NAME, "sem_wait failed"); goto end; } LOGD(MODULE_NAME, "sem_wait succeed."); end: aos_mutex_lock(&at._mutex, AOS_WAIT_FOREVER); slist_del(&tsk->next, &at.task_l); aos_mutex_unlock(&at._mutex); if (aos_sem_is_valid(&tsk->smpr)) { aos_sem_free(&tsk->smpr); } if (tsk) { aos_free(tsk); } return ret; }
void ther_at_handle(char *cmd_buf, uint8 len, char *ret_buf, uint8 *ret_len) { char *p; *ret_len = 0; /* check cmd end */ if (cmd_buf[len - 1] != '\n') { print(LOG_DBG, "cmd end with %c, should be \\n \n", cmd_buf[len - 1]); return; } /* overwrite \n with \0 */ cmd_buf[len - 1] = '\0'; len--; // print(LOG_DBG, "get cmd <%s>, len %d\n", cmd_buf, len); if (strncmp(cmd_buf, AT_CMD, strlen(AT_CMD))) { at_help(); return; } /* AT */ if (strcmp(cmd_buf, AT_CMD) == 0) { *ret_len = sprintf((char *)ret_buf, "%s\n", "OK"); } else if (strcmp(cmd_buf, AT_TEST) == 0) { *ret_len = at_test(ret_buf); } else if (strcmp(cmd_buf, AT_ALIVE) == 0) { /* AT+MODE=x */ } else if (strncmp((char *)cmd_buf, AT_MODE, strlen(AT_MODE)) == 0) { p = cmd_buf + strlen(AT_MODE); if (*p == '1') { *ret_len = at_enter_cal_mode(ret_buf); } else if (*p == '0') { *ret_len = at_exit_cal_mode(ret_buf); } else { *ret_len = sprintf((char *)ret_buf, "%s\n", "+MODE:UNKNOWN"); } /* AT+MODE */ } else if (strcmp((char *)cmd_buf, AT_MODE_Q) == 0) { *ret_len = at_get_mode(ret_buf); /* AT+RESET */ } else if (strcmp((char *)cmd_buf, AT_RESET) == 0) { *ret_len = at_reset(ret_buf); /* AT+MAC */ } else if (strcmp((char *)cmd_buf, AT_MAC) == 0) { *ret_len = at_get_mac(ret_buf); /* AT+HTW=x,x */ } else if (strncmp((char *)cmd_buf, AT_HIGH_TEMP_WARNING, strlen(AT_HIGH_TEMP_WARNING)) == 0) { uint8 warning_enabled; uint16 high_temp_threshold; p = cmd_buf + strlen(AT_HIGH_TEMP_WARNING); warning_enabled = atoi(p); if (!warning_enabled) { /* disable high temp warning */ *ret_len = at_set_htw(ret_buf, warning_enabled, 0); } else { /* enable high temp warning */ p = strstr((const char *)cmd_buf, ","); if (p) { high_temp_threshold = atoi(p + 1); *ret_len = at_set_htw(ret_buf, warning_enabled, high_temp_threshold); } else { *ret_len = sprintf((char *)ret_buf, "%s\n", "+THRESHOLD:ERROR"); } } /* AT+HTW */ } else if (strcmp((char *)cmd_buf, AT_HIGH_TEMP_WARNING_Q) == 0) { *ret_len = at_get_htw(ret_buf); /* AT+LDO=x */ } else if (strncmp((char *)cmd_buf, AT_LDO, strlen(AT_LDO)) == 0) { p = cmd_buf + strlen(AT_LDO); if (*p == '1') { *ret_len = at_set_ldo_on(ret_buf); } else if (*p == '0') { *ret_len = at_set_ldo_off(ret_buf); } else { *ret_len = sprintf((char *)ret_buf, "%s\n", "+LDO:UNKNOWN"); } /* AT+ADC0 */ } else if (strcmp((char *)cmd_buf, AT_ADC0) == 0) { *ret_len = at_get_adc(ret_buf, HAL_ADC_CHANNEL_0); /* AT+ADC1 */ } else if (strcmp((char *)cmd_buf, AT_ADC1) == 0) { *ret_len = at_get_adc(ret_buf, HAL_ADC_CHANNEL_1); /* AT+HWADC0 */ } else if (strcmp((char *)cmd_buf, AT_HWADC0) == 0) { *ret_len = at_get_hw_adc(ret_buf, HAL_ADC_CHANNEL_0); /* AT+HWADC1 */ } else if (strcmp((char *)cmd_buf, AT_HWADC1) == 0) { *ret_len = at_get_hw_adc(ret_buf, HAL_ADC_CHANNEL_1); /* AT+CH0RT */ } else if (strcmp((char *)cmd_buf, AT_CH0RT) == 0) { *ret_len = at_get_ch_Rt(ret_buf, HAL_ADC_CHANNEL_0); /* AT+CH1RT */ } else if (strcmp((char *)cmd_buf, AT_CH1RT) == 0) { *ret_len = at_get_ch_Rt(ret_buf, HAL_ADC_CHANNEL_1); /* AT+TEMP0 */ } else if (strcmp((char *)cmd_buf, AT_TEMP0) == 0) { *ret_len = at_get_ch_temp(ret_buf, HAL_ADC_CHANNEL_0); /* AT+TEMP1 */ } else if (strcmp((char *)cmd_buf, AT_TEMP1) == 0) { *ret_len = at_get_ch_temp(ret_buf, HAL_ADC_CHANNEL_1); /* AT+ADC0DELTA=x */ } else if (strncmp((char *)cmd_buf, AT_ADC0_DELTA, strlen(AT_ADC0_DELTA)) == 0) { short delta; p = cmd_buf + strlen(AT_ADC0_DELTA); delta = atoi(p); *ret_len = at_set_adc0_delta(ret_buf, delta); /* AT+ADC0DELTA */ } else if (strcmp((char *)cmd_buf, AT_ADC0_DELTA_Q) == 0) { *ret_len = at_get_adc0_delta(ret_buf); /* AT+ADC1K=x */ } else if (strncmp((char *)cmd_buf, AT_ADC1_K, strlen(AT_ADC1_K)) == 0) { float k; p = cmd_buf + strlen(AT_ADC1_K); k = atof(p); *ret_len = at_set_adc1_k(ret_buf, k); /* AT+ADC1K */ } else if (strcmp((char *)cmd_buf, AT_ADC1_K_Q) == 0) { *ret_len = at_get_adc1_k(ret_buf); /* AT+LOWTEMPCAL=x,x */ } else if (strncmp((char *)cmd_buf, AT_LOW_TEMP_CAL, strlen(AT_LOW_TEMP_CAL)) == 0) { float R_low, t_low; p = cmd_buf + strlen(AT_LOW_TEMP_CAL); R_low = atof(p); p = strstr((const char *)cmd_buf, ","); if (p) t_low = atof(p + 1); else t_low = 0; *ret_len = at_set_low_temp_cal(ret_buf, R_low, t_low); /* AT+LOWTEMPCAL */ } else if (strcmp((char *)cmd_buf, AT_LOW_TEMP_CAL_Q) == 0) { *ret_len = at_get_low_temp_cal(ret_buf); /* AT+HIGHTEMPCAL=x,x */ } else if (strncmp((char *)cmd_buf, AT_HIGH_TEMP_CAL, strlen(AT_HIGH_TEMP_CAL)) == 0) { float R_high, t_high; p = cmd_buf + strlen(AT_HIGH_TEMP_CAL); R_high = atof(p); p = strstr((const char *)cmd_buf, ","); if (p) t_high = atof(p + 1); else t_high = 0; *ret_len = at_set_high_temp_cal(ret_buf, R_high, t_high); /* AT+HIGHTEMPCAL */ } else if (strcmp((char *)cmd_buf, AT_HIGH_TEMP_CAL_Q) == 0) { *ret_len = at_get_high_temp_cal(ret_buf); /* AT+TEMPCAL=x,y */ } else if (strncmp((char *)cmd_buf, AT_TEMP_CAL, strlen(AT_TEMP_CAL)) == 0) { float B_delta, R25_delta; p = cmd_buf + strlen(AT_TEMP_CAL); B_delta = atof(p); p = strstr(cmd_buf, ","); if (p) R25_delta = atof(p + 1); else R25_delta = 0; *ret_len = at_set_temp_cal(ret_buf, B_delta, R25_delta); /* AT+TEMPCAL */ } else if (strcmp((char *)cmd_buf, AT_TEMP_CAL_Q) == 0) { *ret_len = at_get_temp_cal(ret_buf); /* AT+BATTADC */ } else if (strcmp((char *)cmd_buf, AT_BATT_ADC) == 0) { *ret_len = at_get_batt_adc(ret_buf); /* AT+BATTV */ } else if (strcmp((char *)cmd_buf, AT_BATT_VOLTAGE) == 0) { *ret_len = at_get_batt_voltage(ret_buf); /* AT+BATTP */ } else if (strcmp((char *)cmd_buf, AT_BATT_PERCENTAGE) == 0) { *ret_len = at_get_batt_percentage(ret_buf); /* AT+CONTRAST=x */ } else if (strncmp((char *)cmd_buf, AT_OLED_CONTRAST, strlen(AT_OLED_CONTRAST)) == 0) { uint8 contrast; p = cmd_buf + strlen(AT_OLED_CONTRAST); contrast = atoi(p); *ret_len = at_set_oled9639_contrast(ret_buf, contrast); /* AT+SERASE */ } else if (strcmp((char *)cmd_buf, AT_S_ERASE) == 0) { *ret_len = at_serase(ret_buf); /* AT+SRESET */ } else if (strcmp((char *)cmd_buf, AT_S_RESET) == 0) { *ret_len = at_sreset(ret_buf); /* AT+SINFO */ } else if (strcmp((char *)cmd_buf, AT_S_INFO) == 0) { *ret_len = at_sinfo(ret_buf); /* AT+SRESTORE */ } else if (strcmp((char *)cmd_buf, AT_S_RESTORE) == 0) { *ret_len = at_srestore(ret_buf); /* AT+STEST */ } else if (strcmp((char *)cmd_buf, AT_S_TEST) == 0) { *ret_len = at_stest(ret_buf); } else { at_help(); } return; }