⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 at_trans.c

📁 在ARM7和UC/OSII的平台上实现了GPS自动报站的功能,涉及GPS模块LEA_4S的驱动,位置速寻算法,语音芯片ISD4004的录放音驱动,LED页面管理等等.从启动代码到操作系统的移植以及到业
💻 C
字号:
/****************************************************************
**                                                              *
**  FILE         :  AT_Trans.C                                  *
**  COPYRIGHT    :  (c) 2001 .Xiamen Yaxon NetWork CO.LTD       *
**                                                              *
**                                                              *
**  By : CCH 2002.1.15                                          *
****************************************************************/
#include "includes.h"
#include "bsp.h"
#include "message.h"
#include "errtask.h"
#include "gsmtask.h"
#include "tools.h"
#include "timetask.h"
#include "at_cmd.h"
#include "at_core.h"
#include "at_trans.h"

#include "dlcs.h"
#include "phonedrv.h"
#include "ZPrint.h"



/*
********************************************************************************
*                  DEFINE CONFIG PARAMETERS
********************************************************************************
*/
#define MAX_TCB                             4

/* define TCB1 buffer size */
#define SIZE_ACKBUF_1                       20
#define SIZE_RECVBUF_1                      50

/* define TCB2 buffer size */
#define SIZE_ACKBUF_2                       20
#define SIZE_RECVBUF_2                      50

/* define TCB3 buffer size */
#define SIZE_ACKBUF_3                       20
#define SIZE_RECVBUF_3                      50

/* define timer period */
#define PERIOD_WAIT                         MILTICK, 2
#define PERIOD_TEST                         MILTICK, 2

/* define times of test send */
#define MAX_TEST                            ((OS_TICKS_PER_SEC * 4) / 2)        /* 2 = PERIOD_TEST */


/*
********************************************************************************
*                  DEFINE AT COMMAND CONTROL BLOCK STRUCTURE
********************************************************************************
*/
typedef struct {
    BOOLEAN          opened;                                            /* open status */
    BOOLEAN          echo;                                              /* echo status */
    TMR_TSK         *waittmr;                                           /* wait timer */
    TMR_TSK         *overflowtmr;                                       /* overflow timer */
    INT16U           bufsize;                                           /* receive buffer size */
    INT8U           *recvbuf;                                           /* receive buffer */
    ATCMDACK_STRUCT  atcmdack;                                          /* at command ack */
    INT8U            status;                                            /* command status */
    INT8U            ct_test;                                           /* test times */
    INT8U            overtime;                                          /* overflow time */
    INT8U            nsEC;                                              /* number of END'S characters(send) */
    INT8U            naEC;                                              /* number of END'S characters(ack) */
    INT8U            nrEC;                                              /* number of END'S characters(receive) */
    INT16U           wlen;                                              /* write length */
    INT8U           *wptr;                                              /* write position */
    INT16U           sendlen;                                           /* send data length */
    INT8U           *sendptr;                                           /* send data buffer */
    void   (* informer)(INT8U, const ATCMDACK_STRUCT *);                /* command informer */
    INT16S (* handler)(INT8U *, INT16U, ATCMDACK_STRUCT *);             /* command handler */
} TCB_STRUCT;


/*
********************************************************************************
*                  DEFINE MODULE VARIANT
********************************************************************************
*/
static TCB_STRUCT *TCB[MAX_TCB];

/* define TCB1 variants */
static TCB_STRUCT TCB1;
static INT8U ackbuf_1[SIZE_ACKBUF_1];
static INT8U recvbuf_1[SIZE_RECVBUF_1];

/* define TCB2 variants */
static TCB_STRUCT TCB2;
static INT8U ackbuf_2[SIZE_ACKBUF_2];
static INT8U recvbuf_2[SIZE_RECVBUF_2];

/* define TCB3 variants */
static TCB_STRUCT TCB3;
static INT8U ackbuf_3[SIZE_ACKBUF_3];
static INT8U recvbuf_3[SIZE_RECVBUF_3];



static void DelTCB(INT8U id, INT8U reason)
{

    if (TCB[id] == NULL) return;
    if (TCB[id]->status & ATCMD_EXIST) {
        TCB[id]->status &= ~ATCMD_EXIST;
        TCB[id]->status |=  ATCMD_WAIT;
        StartTmr(TCB[id]->waittmr, PERIOD_WAIT);
        StopTmr(TCB[id]->overflowtmr);
        if (TCB[id]->informer != 0) TCB[id]->informer(reason, &TCB[id]->atcmdack);
    }
    OSQPost(GsmTaskMsgQue, MSG_ATTRANS_FREE, 0, 0);
}

static void StartSend(INT8U id)
{
    if (TCB[id] == NULL) return;
    if ((TCB[id]->status & (ATCMD_EXIST | ATCMD_READY)) != (ATCMD_EXIST | ATCMD_READY)) return;

    if (PushDatatoDLC(id, TCB[id]->sendptr, TCB[id]->sendlen)) {
        TCB[id]->status &= ~ATCMD_READY;
        StartTmr(TCB[id]->overflowtmr, SECOND, TCB[id]->overtime);
        if (!TCB[id]->echo && TCB[id]->naEC == 0)
            DelTCB(id, AT_SUCCESS);
        if (TCB[id]->nsEC == 0)
            DelTCB(id, AT_SUCCESS);
    } else {
        StartTmr(TCB[id]->overflowtmr, PERIOD_TEST);
        if (--TCB[id]->ct_test == 0)
            ErrExit(ERR_ATTRANS_TEST);
   }
}

static void WaitTmrProc(void)
{
    INT8U id;

    id = GetCurTmrIndex();
    StopTmr(TCB[id]->waittmr);
    TCB[id]->status &= ~ATCMD_WAIT;
    OSQPost(GsmTaskMsgQue, MSG_ATTRANS_FREE, 0, 0);
}

static void OverflowTmrProc(void)
{
    INT8U id;

    id = GetCurTmrIndex();
    StopTmr(TCB[id]->overflowtmr);
    if ((TCB[id]->status & (ATCMD_EXIST | ATCMD_READY)) == (ATCMD_EXIST | ATCMD_READY)) {
        StartSend(id);
    } else {
        RecoveryATCmd(id);
        DelTCB(id, AT_OVERTIME);
    }
}

static void DiagnoseProc(void)
{
    INT8U i;

    for (i = 0; i < MAX_TCB; i++) {
        if (TCB[i] == NULL) continue;
        if ((TCB[i]->status & (ATCMD_EXIST | ATCMD_READY)) == ATCMD_EXIST) {
            if (GetTmrSwitch(TCB[i]->overflowtmr) != ON) ErrExit(ERR_ATTRANS_TMR);
        }
        if (TCB[i]->status & ATCMD_WAIT) {
            if (GetTmrSwitch(TCB[i]->waittmr) != ON) ErrExit(ERR_ATTRANS_TMR);
        }
    }
}

void InitAT_Trans(void)
{
    INT8U i;

    /* initialize TCB1 */
    {
        TCB1.recvbuf = recvbuf_1;
        TCB1.bufsize = sizeof(recvbuf_1);
        TCB1.atcmdack.ackbuf  = ackbuf_1;
        TCB1.atcmdack.bufsize = sizeof(ackbuf_1);
    }

    /* initialize TCB2 */
    {
        TCB2.recvbuf = recvbuf_2;
        TCB2.bufsize = sizeof(recvbuf_2);
        TCB2.atcmdack.ackbuf  = ackbuf_2;
        TCB2.atcmdack.bufsize = sizeof(ackbuf_2);
    }

    /* initialize TCB3 */
    {
        TCB3.recvbuf = recvbuf_3;
        TCB3.bufsize = sizeof(recvbuf_3);
        TCB3.atcmdack.ackbuf  = ackbuf_3;
        TCB3.atcmdack.bufsize = sizeof(ackbuf_3);
    }

    /* initialize TCB array */
    {
        TCB[0] = NULL;
        TCB[1] = &TCB1;
        TCB[2] = &TCB2;
        TCB[3] = &TCB3;
    }

    for (i = 0; i < MAX_TCB; i++) {
        if (TCB[i] == NULL) continue;
        TCB[i]->opened      = TRUE;
        TCB[i]->echo        = TRUE;
        TCB[i]->status      = 0;
        TCB[i]->waittmr     = CreateTimer(WaitTmrProc, i);
        TCB[i]->overflowtmr = CreateTimer(OverflowTmrProc, i);
    }
    InstallDiagProc(DiagnoseProc);                              /* install diagnose procedure */
}

BOOLEAN SendATCmd(INT8U id, ATCMDPARA_STRUCT *cmdptr, INT8U *ptr, INT16U len, void (* fp)(INT8U, const ATCMDACK_STRUCT *))
{
    if (TCB[id] == NULL) return FALSE;
    if (!TCB[id]->opened || TCB[id]->status & ATCMD_EXIST) return FALSE;

    TCB[id]->status    = cmdptr->status;
    if (TCB[id]->status & ATCMD_INSANT) {
        TCB[id]->naEC           = 1;
        TCB[id]->atcmdack.numEC = 0;
    } else {
        TCB[id]->naEC           = cmdptr->naEC;
    }
    TCB[id]->nsEC      = cmdptr->nsEC;
    TCB[id]->overtime  = cmdptr->overtime;
    TCB[id]->handler   = cmdptr->handler;

    TCB[id]->status   |= (ATCMD_EXIST | ATCMD_READY);
    TCB[id]->ct_test   = MAX_TEST;
    TCB[id]->nrEC      = 0;
    TCB[id]->wlen      = 0;
    TCB[id]->wptr      = TCB[id]->recvbuf;
    TCB[id]->sendlen   = len;
    TCB[id]->sendptr   = ptr;
    TCB[id]->informer  = fp;

    OSQPost(GsmTaskMsgQue, MSG_ATTRANS_TSK, 0, 0);
    return TRUE;
}

void StopATCmd(INT8U id, INT8U reason)
{
    if (TCB[id] == NULL) return;
    DelTCB(id, reason);
}

void AbandonATCmd(INT8U id)
{
    if (TCB[id] == NULL) return;
    if ((TCB[id]->status & (ATCMD_EXIST | ATCMD_READY)) == ATCMD_EXIST) RecoveryATCmd(id);
    DelTCB(id, AT_ABANDON);
}

void AbandonAllATCmd(void)
{
    INT8U i;

    for (i = 0; i < MAX_TCB; i++) AbandonATCmd(i);
}

BOOLEAN CanSendATCmd(INT8U id)
{
    #if GSM_BENQ
    if((GetPhoneStatus(PHONE_COM)==PHONE_CONNECTING)&&(id==DLC_SM)) return FALSE;
    #endif
    if (TCB[id] == NULL)  return FALSE;
    if (!TCB[id]->opened) return FALSE;
    if (TCB[id]->status & (ATCMD_EXIST | ATCMD_WAIT)) return FALSE;
    else return TRUE;
}

BOOLEAN EchoOnATTrans(INT8U id)
{
    if (TCB[id] == NULL) return FALSE;
    TCB[id]->echo = TRUE;
    return TRUE;
}

BOOLEAN EchoOffATTrans(INT8U id)
{
    if (TCB[id] == NULL) return FALSE;
    TCB[id]->echo = FALSE;
    return TRUE;
}

BOOLEAN OpenATTrans(INT8U id)
{
    if (TCB[id] == NULL) return FALSE;
    TCB[id]->opened = TRUE;
    OSQPost(GsmTaskMsgQue, MSG_ATTRANS_FREE, 0, 0);
    return TRUE;
}

BOOLEAN CloseATTrans(INT8U id)
{
    if (TCB[id] == NULL) return FALSE;
    TCB[id]->opened = FALSE;
    return TRUE;
}

void CloseAllATTrans(void)
{
    INT8U i;

    for (i = 0; i < MAX_TCB; i++) CloseATTrans(i);
}

void HdlATCmdTrans(void)
{
    INT8U i;

    for (i = 0; i < MAX_TCB; i++) StartSend(i);
}

BOOLEAN HdlATCmdAck(INT8U id, INT8U *sptr, INT16U len)
{
    INT8U  nsEC;
    INT16S hdlres;

    if (TCB[id] == NULL || len <= 3) return FALSE;
    if ((TCB[id]->status & (ATCMD_EXIST | ATCMD_READY)) == ATCMD_EXIST) {
        if (TCB[id]->echo && TCB[id]->nsEC == 1 && TCB[id]->nrEC == 0) {
           /* if (!SearchDataInMem(sptr, len, TCB[id]->sendptr, TCB[id]->sendlen))
                return FALSE; */
        }
        TCB[id]->nrEC++;
        if (TCB[id]->echo && TCB[id]->nrEC <= TCB[id]->nsEC) {
            if (TCB[id]->nrEC == TCB[id]->nsEC && TCB[id]->naEC == 0)
            {
              DelTCB(id, AT_SUCCESS);
            }
        } else {
            TCB[id]->atcmdack.numEC++;
            if (TCB[id]->status & ATCMD_INSANT) {
                if (TCB[id]->handler == 0) {
                    DelTCB(id, AT_FAILURE);
                } else {
                    if ((hdlres = TCB[id]->handler(sptr, len, &TCB[id]->atcmdack)) != -1)
                        DelTCB(id, hdlres);
                }
            } else {
                if ((TCB[id]->wlen + len) > TCB[id]->bufsize) {
                    DelTCB(id, AT_FAILURE);
                    return TRUE;
                }

                memcpy(TCB[id]->wptr, sptr, len);
                TCB[id]->wptr += len;
                TCB[id]->wlen += len;

                if (TCB[id]->echo) nsEC = TCB[id]->nsEC;
                else nsEC = 0;
                if (TCB[id]->nrEC == (nsEC + TCB[id]->naEC)) {
                    if (TCB[id]->handler == 0)
                        DelTCB(id, AT_FAILURE);
                    else
                        DelTCB(id, TCB[id]->handler(TCB[id]->recvbuf, TCB[id]->wlen, &TCB[id]->atcmdack));
                }
            }
        }
        return TRUE;
    } else {
        return FALSE;
    }
}

BOOLEAN SuspendATRecv(INT8U id)
{
    if (TCB[id] == NULL) return FALSE;
    if ((TCB[id]->status & (ATCMD_EXIST | ATCMD_SUSPENDRECV)) == (ATCMD_EXIST | ATCMD_SUSPENDRECV))
        return TRUE;
    else
        return FALSE;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -