/*************************************************************************
* File Name: sim800L.c
* create by: doucheng
* Date First Issued : 2014-05-30
* Description : This file contains the op code of sim800L
* basicly AT cmd of sim800L
* using usart1 on armfly board
* sim800L work in non transparent mode
* modified by doucheng
* date: 2014/05/30
* ver: v 0.1
*
**************************************************************************/
//std lib
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
//modem driver
#include "sim800L.h"
//rt thread lib
#include <rtthread.h>
#include <rtdevice.h>
#include "platform.h"
struct rt_semaphore sim800L_lock; //lock for sim800L OP
#define sim800L_LOCK() rt_sem_take(&sim800L_lock,RT_WAITING_FOREVER)
#define sim800L_UNLOCK() rt_sem_release(&sim800L_lock)
//default ip & port
char default_remoteIPADDR[] = "202.105.21.213";
char default_remotedomain[] = "inforstack.wicp.net";
char default_remotePORT[] = "32824";
char default_connTYPE[] = "TCP";
rt_sim800L_device * sim800L;
void sim800L_set_attribute(char* attribute, char* content);
//<CR><LF><response><CR><LF>
// /r /n response /r /n
// 0D 0A response 0D 0A
rt_uint8_t GetCommLineStatus(void)
{
return sim800L->CommLineStatus;
}
void SetCommLineStatus(SIM800L_Status_TypeDef status)
{
sim800L->CommLineStatus = status;
}
//AT response are send to msg queue
//call by rt_thread_sim800L_rx_entry
//parse "RING","CLOSED" response and send event seperately
//return err code
rt_err_t SendATResp(char* at_resp_msg)
{
rt_err_t ret;
RT_ASSERT(sim800L->AT_resp_MQ != RT_NULL);
if(rt_strncmp( (char*)(at_resp_msg), "CLOSED", 6)==0){
ret = rt_event_send(sim800L->ATResp_event, CLOSED);
SetCommLineStatus(IN_DISCONNECT);
}
else if(rt_strncmp( (char*)(at_resp_msg), "RING", 4)==0){
if(GetCommLineStatus() != IN_CALL)
ret = rt_event_send(sim800L->ATResp_event, RING);
}
else if(rt_strncmp( (char*)(at_resp_msg), "NORMAL POWER DOWN", 17)==0){
ret = rt_event_send(sim800L->ATResp_event, POWER_DOWN);
}
else{
ret = rt_strlen((char*)at_resp_msg) + 1 ;
*(at_resp_msg + ret ) = '0';
ret = rt_mq_send(sim800L->AT_resp_MQ, at_resp_msg, ret);
// RT_DEBUG_LOG(DEBUG_GPRS,("write response mq\"%s\",left %d\r\n",at_resp_msg,sim800L->AT_resp_MQ->entry));
}
if(ret == -RT_EFULL){
RT_DEBUG_LOG(DEBUG_GPRS,("AT response MQ is full\r\n"));
}
return ret;
}
//AT response in msg queue are captured by thread call this function
//must call by a thread
//will block thread for max_tout
//return length of response string
static rt_int8_t WaitATResp(char* get_resp_str,char *response , rt_uint32_t max_tout )
{
char ATResp_buff[SIM800L_AT_RESP_MQ_MSG_SIZE];
rt_err_t err = RT_ERROR;
rt_err_t ret;
rt_err_t retry = 0;
rt_memset(ATResp_buff, 0, sizeof(ATResp_buff));
RT_ASSERT(sim800L->AT_resp_MQ != RT_NULL);
if(response == RT_NULL){
return RT_EOK ;
}
do{
ret = rt_mq_recv(sim800L->AT_resp_MQ, ATResp_buff, SIM800L_AT_RESP_MQ_MSG_SIZE, 1);
// RT_DEBUG_LOG(DEBUG_GPRS,("read response mq\"%s\",left %d\r\n",ATResp_buff,sim800L->AT_resp_MQ->entry));
if( ret == RT_EOK ) {
sim800L->at_retry_times = 0 ;
if(strstr(ATResp_buff,response)){
if(get_resp_str != RT_NULL){
rt_strncpy((char*)get_resp_str, (char*)ATResp_buff, rt_strlen((char*)ATResp_buff));
}
RT_DEBUG_LOG(DEBUG_GPRS,("RECV_AT[%s]\r\n",(char *)ATResp_buff));
err = RT_EOK ;
}
}
else {
sleep(max_tout>>3);
if(retry++ > 8){
RT_DEBUG_LOG(DEBUG_GPRS,("AT response failed\r\n"));
sim800L->at_retry_times++ ;
err = RT_ERROR ;
break ;
}
}
}while(err != RT_EOK);
while(sim800L->AT_resp_MQ->entry > 0){
rt_mq_recv(sim800L->AT_resp_MQ, ATResp_buff, SIM800L_AT_RESP_MQ_MSG_SIZE, max_tout);
}
return err;
}
rt_err_t rt_sim800L_open(void)
{
return RT_EOK;
}
rt_err_t rt_sim800L_close(void)
{
return RT_EOK;
}
rt_size_t rt_sim800L_read(void* buffer)
{
return RT_EOK;
}
/********************************************
* This function write ATcmd to sim800L *
* @return the byte number of sim800L sent. *
********************************************/
rt_size_t rt_sim800L_write(const void* buffer)
{
rt_size_t write_len;
rt_size_t size =strlen(buffer);
sim800L_LOCK();
write_len = rt_device_write(sim800L->device, 0, buffer, size);
sim800L_UNLOCK();
RT_DEBUG_LOG(DEBUG_GPRS,("AT_SEND[%s]\r\n",buffer));
return write_len;
}
/********************************************
* This function read ipdata from sim800L *
* block type, use it in app thread *
* paras: ip data buffer pointer *
* @return the byte number of sim800L read *
********************************************/
rt_size_t sim800L_readDATA(void* buffer,rt_int32_t time)
{
rt_uint8_t* buf = (rt_uint8_t*)buffer;
if(rt_sem_take(sim800L->frame_sem, time)== RT_EOK){
if( rt_mq_recv(sim800L->cmd_gprs_main_MQ, buf, SIM800L_cmd_gprs_main_MQ_MSG_SIZE, time<<1) == RT_EOK ) {
RT_DEBUG_LOG(DEBUG_GPRS,("read ipdata mq\"%s\",left %d\r\n",buf,sim800L->cmd_gprs_main_MQ->entry));
return rt_strlen((char *)buf);
}
}
return 0;
}
rt_err_t send_sem_main(void)
{
return rt_sem_release(sim800L->cmd_main_gprs_sem);
}
rt_err_t send_cmd_to_main(char *buffer,rt_size_t len )
{
rt_mq_send(sim800L->cmd_gprs_main_MQ,buffer,len);
rt_sem_release(sim800L->cmd_main_gprs_sem);
return RT_EOK ;
}
rt_err_t sim800l_send_atcmd(const void* write_buffer,const void* read_buffer,const void* wait_buffer,rt_uint32_t timeout)
{
rt_err_t err = RT_ERROR ;
rt_sim800L_write(write_buffer);
err = WaitATResp((char *)read_buffer,(char *)wait_buffer,timeout) ;
if (err ==RT_EOK){
// RT_DEBUG_LOG(DEBUG_GPRS,("AT OK\r\n"));
err = RT_EOK; //failed
}
else if (err ==RT_ERROR){
// RT_DEBUG_LOG(DEBUG_GPRS,("AT ERROR\r\n"));
err = RT_ERROR; //failed
}
else if (err ==RT_ETIMEOUT){
RT_DEBUG_LOG(DEBUG_GPRS,("AT TIMEOUT\r\n"));
err = RT_ETIMEOUT; //timeout
}
return err;
}
/********************************************
* This function power off to sim800L *
* non transparent mode *
* @return the byte number of sim800L sent. *
********************************************/
rt_err_t Gprs_Off_cmd(void)
{
return sim800l_send_atcmd("AT+CPOWD=1\r\n",RT_NULL,RT_NULL,RT_TICK_PER_SECOND);
}
/********************************************
* This function echo sim800L *
* non transparent mode *
* @return the byte number of sim800L sent. *
********************************************/
rt_err_t rt_sim800l_set_echo(void)
{
rt_uint8_t retry = 0 ;
rt_err_t err = RT_ERROR ;
do{
err = sim800l_send_atcmd("ATE0\r\n",RT_NULL,"OK",RT_TICK_PER_SECOND>>3);
if(retry++ > 2){
err = RT_ETIMEOUT ;
break ;
}
}while(err != RT_EOK);
return err ;
}
/********************************************
* This function send ipdata to sim800L *
* non transparent mode *
* @return the byte number of sim800L sent. *
********************************************/
rt_err_t rt_sim800l_check_sim(void)
{
rt_uint8_t retry = 0 ;
rt_err_t err = RT_ERROR ;
char CMDresp[SIM800L_AT_RESP_MQ_MSG_SIZE];
do{
err = sim800l_send_atcmd("AT+CPIN?\r\n",CMDresp,"+CPIN:",RT_TICK_PER_SECOND);
if(strstr(CMDresp,"+CPIN: READY")== 0){
SetCommLineStatus(IN_NO_SIM);
break ;
}
if(retry++ > 2){
err = RT_ETIMEOUT ;
break ;
}
}while(err != RT_EOK);
return err ;
}
/********************************************
* This function send ipdata to sim800
SIM800L GPRS
5星 · 超过95%的资源 需积分: 35 34 浏览量
2015-03-18
10:57:34
上传
评论 1
收藏 10KB RAR 举报
tianqing324
- 粉丝: 0
- 资源: 5
- 1
- 2
前往页