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

📄 ext_serial_win32_port.c

📁 RT9S12 target document
💻 C
字号:
/*
* Copyright 1994-2003 The MathWorks, Inc.
*
* File: ext_serial_win32_port.c     $Revision: 1.1.6.3 $
*
* Abstract:
*  The External Mode Serial Port is a logical object providing a standard
*  interface between the external mode code and the physical serial port.
*  The prototypes in the 'Visible Functions' section of this file provide
*  the consistent front-end interface to external mode code.  The
*  implementations of these functions provide the back-end interface to the
*  physical serial port.  This layer of abstraction allows for minimal
*  modifications to external mode code when the physical serial port is
*  changed.
*
*     ----------------------------------
*     | Host/Target external mode code |
*     ----------------------------------
*                   / \
*                  /| |\
*                   | |
*                   | |
*                  \| |/
*                   \ /  Provides a standard, consistent interface to extmode
*     ----------------------------------
*     | External Mode Serial Port      |
*     ----------------------------------
*                   / \  Function definitions specific to physical serial port
*                  /| |\
*                   | |
*                   | |
*                  \| |/
*                   \ /
*     ----------------------------------
*     | HW/OS/Physical serial port     |
*     ----------------------------------
*
*  See also ext_serial_pkt.c.
*/

/* 
 * Adapted for rtmc9s12-Target, fw-09-7
 */


#include <string.h>

#include "tmwtypes.h"

#include "ext_types.h"
#include "ext_share.h"
#include "ext_serial_port.h"
#include "ext_serial_pkt.h"

//#include "mex.h"                       /* mexPrintf */

#include "debugMsgs.h"     /* macros PRINT_DEBUG_MSG_LVL1 to PRINT_DEBUG_MSG_LVL5,  fw-06-07 */


/***************** WIN32 SPECIFIC FUNCTIONS ***********************************/

/* avoid problem with lcc header files...  fw-06-07 */
#ifdef __LCC__
#undef EXTERN_C
#endif
#include <windows.h>
#ifdef __LCC__
#ifndef EXTERN_C
#define EXTERN_C
#endif
#endif
#include <assert.h>
#include <stdio.h>

/* This is for the lcc compiler. */
#ifndef MAXDWORD
#define MAXDWORD 0xffffffff
#endif

/*PRIVATE COMMTIMEOUTS cto_immediate = { MAXDWORD, 0, 0, 0, 0 };*/
//PRIVATE COMMTIMEOUTS cto_timeout   = { MAXDWORD, MAXDWORD, 10000, 0, 0 };
PRIVATE COMMTIMEOUTS cto_timeout= {
   100,
   100,
   100,
   0,
   0
};
PRIVATE COMMTIMEOUTS cto_blocking= {
   0,
   0,
   0,
   0,
   0
};
PRIVATE DCB          dcb;
PRIVATE HANDLE       serialHandle=INVALID_HANDLE_VALUE;

/* Function: initDCB ===========================================================
 * Abstract:
 *  Initializes the control settings for a win32 serial communications device.
 */
PRIVATE void initDCB(uint32_T baud) {

   dcb.DCBlength=sizeof(dcb);                   

   /* ---------- Serial Port Config ------- */
   dcb.BaudRate=baud;
   dcb.Parity=NOPARITY;
   dcb.fParity=0;
   dcb.StopBits=ONESTOPBIT;
   dcb.ByteSize=8;
   dcb.fOutxCtsFlow=0;
   dcb.fOutxDsrFlow=0;
   dcb.fDtrControl=DTR_CONTROL_DISABLE;
   dcb.fDsrSensitivity=0;
   dcb.fRtsControl=RTS_CONTROL_DISABLE;
   dcb.fOutX=0;
   dcb.fInX=0;

   /* ---------- Misc Parameters ---------- */
   dcb.fErrorChar=0;
   dcb.fBinary=1;
   dcb.fNull=0;
   dcb.fAbortOnError=0;
   dcb.wReserved=0;
   dcb.XonLim=2;
   dcb.XoffLim=4;
   dcb.XonChar=0x13;
   dcb.XoffChar=0x19;
   dcb.EvtChar=0;

} /* end initDCB */


/* Function: serial_get_string =================================================
 * Abstract:
 *  Attempts to get the specified number of bytes from the comm line.  The
 *  number of bytes read is returned via the 'bytesRead' parameter.  If the
 *  specified number of bytes is not read within the time out period specified
 *  in cto_timeout, an error is returned.
 *
 *  EXT_NO_ERROR is returned on success, EXT_ERROR on failure.
 */
PRIVATE boolean_T serial_get_string(char *data, uint32_T size, uint32_T *bytesRead) {

   boolean_T   error=EXT_NO_ERROR;

   // local function name... debugging only
   #if DEBUG_MSG_LVL > 0
   const char  *funct_name="serial_get_string";
   #endif

   assert(serialHandle!=NULL);

   SetCommTimeouts(serialHandle, &cto_timeout);

   if(!ReadFile(serialHandle, data, size, (unsigned long*)bytesRead, NULL)) {

      error=EXT_ERROR;
      goto EXIT_POINT;

   }

   #if DEBUG_MSG_LVL >= 5
   {
      unsigned int   i;

      PRINT_DEBUG_MSG_LVL5("0x");
      for(i=0; i<size; i++) {

         PRINT_DEBUG_MSG_LVL5_UHex((uint8_T)data[i]);
         PRINT_DEBUG_MSG_LVL5_Raw(" ");

      }
      PRINT_DEBUG_MSG_NL5;
   }
   #endif

   EXIT_POINT:return error;

} /* end serial_get_string */


/* Function: serial_set_string =================================================
 * Abstract:
 *  Sets (sends) the specified number of bytes on the comm line.  The number of
 *  bytes sent is returned via the 'bytesWritten' parameter.
 *
 *  EXT_NO_ERROR is returned on success, EXT_ERROR on failure.
 */
PRIVATE boolean_T serial_set_string(uint8_T *data, uint32_T size, uint32_T *bytesWritten) {

   boolean_T   error=EXT_NO_ERROR;
   uint32_T    k,
               myBytesWritten;

   // local function name... debugging only
   #if DEBUG_MSG_LVL > 0
   const char  *funct_name="serial_set_string";
   #endif

   assert(serialHandle!=NULL);
   assert(data!=NULL);

   #if DEBUG_MSG_LVL >= 5
   {
      uint32_T i;

      PRINT_DEBUG_MSG_LVL5("");
      for(i=0; i<size; i++) {

         PRINT_DEBUG_MSG_LVL5_Raw(" 0x");
         PRINT_DEBUG_MSG_LVL5_UHex(data[i]);

      }
      PRINT_DEBUG_MSG_NL5;
   }
   #endif

   /* 
     * The following call to WriteFile doesn't work properly (at least not when using LCC) 
     * for converted data (Filter, '^ 0x20') the host appears to send the original data, 
     * e.g. 0x3... this causes the target to misinterpret the received data and 
     * consequently 'hang'   --   fw-06-07
     */
   //   if (!WriteFile(serialHandle,data,size,(unsigned long *)bytesWritten, NULL)) {
   //        error = EXT_ERROR;
   //        goto EXIT_POINT;
   //   }

   /* working equivalent... fw-06-07 */
   PRINT_DEBUG_MSG_LVL5("Size = ");
   PRINT_DEBUG_MSG_LVL5_UDec(size);
   PRINT_DEBUG_MSG_NL5;
   *bytesWritten=0;
   for(k=0; k<size; k++) {

      if(!WriteFile(serialHandle, data++, 1L, &myBytesWritten, NULL)) {

         error=EXT_ERROR;
         goto EXIT_POINT;

      }
      *bytesWritten+=myBytesWritten;

   }
   PRINT_DEBUG_MSG_LVL5("BytesWritten = ");
   PRINT_DEBUG_MSG_LVL5_UDec(*bytesWritten);
   PRINT_DEBUG_MSG_NL5;

   EXIT_POINT:return error;

} /* end serial_set_string */


/* Function: serial_string_pending =============================================
 * Abstract:
 *  Returns, via the 'pendingBytes' arg, the number of bytes pending on the
 *  comm line.
 *
 *  EXT_NO_ERROR is returned on success, EXT_ERROR on failure.
 */
PRIVATE boolean_T serial_string_pending(int32_T *pendingBytes) {

   struct _COMSTAT   status;
   unsigned long     etat;
   boolean_T         error=EXT_NO_ERROR;

   assert(serialHandle!=NULL);

   /* Find out how much data is available. */
   if(!ClearCommError(serialHandle, &etat, &status)) {

      pendingBytes=0;
      error=EXT_ERROR;
      goto EXIT_POINT;

   }
   else {

      *pendingBytes=status.cbInQue;

   }

   EXIT_POINT:return error;

} /* end serial_string_pending */


/* Function: serial_uart_close =================================================
 * Abstract:
 *  Closes the serial port.
 *
 *  EXT_NO_ERROR is returned on success, EXT_ERROR on failure.
 */
PRIVATE boolean_T serial_uart_close(void) {

   if(serialHandle!=INVALID_HANDLE_VALUE) {

      CloseHandle(serialHandle);
      serialHandle=INVALID_HANDLE_VALUE;

   }
   assert(serialHandle==INVALID_HANDLE_VALUE);
   return EXT_NO_ERROR;

} /* end serial_uart_close */


/* Function: serial_uart_init ==================================================
 * Abstract:
 *  Opens the serial port and initializes the port, baud, and DCB settings.
 *
 *  EXT_NO_ERROR is returned on success, EXT_ERROR on failure.
 */
PRIVATE boolean_T serial_uart_init(uint16_T port, uint32_T baud) {

   boolean_T   error=EXT_NO_ERROR;
   boolean_T   closeFile=false;

   initDCB(baud);

   /* If the serial port is open, close it. */
   if(serialHandle!=INVALID_HANDLE_VALUE) {
      PRINT_DEBUG_MSG_LVL1_Raw("Serial port already open, closing...");
      error=serial_uart_close();
      if(error!=EXT_NO_ERROR) {

         goto EXIT_POINT;

      }

   }

   assert(serialHandle==INVALID_HANDLE_VALUE);

   /* Attempt to open the serial port */
   if(serialHandle==INVALID_HANDLE_VALUE) {

      char  localPortString[10];
      sprintf(localPortString, "COM%d:", port);

      serialHandle=(void*)CreateFile(localPortString, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
      if(serialHandle==INVALID_HANDLE_VALUE) {

         error=EXT_ERROR;
         goto EXIT_POINT;

      }

   }

   #ifdef ERASE
   // reset 'serialHandle' and set length of input/output buffer to 2048 bytes (each)  --  fw-06-07
   if(!SetupComm(serialHandle, 2048, 2048)) {

      closeFile=true;
      error=EXT_ERROR;
      goto EXIT_POINT;

   }
   #endif

   if(!SetCommTimeouts(serialHandle, &cto_blocking)) {

      closeFile=true;
      error=EXT_ERROR;
      goto EXIT_POINT;

   }

   if(!SetCommState(serialHandle, &dcb)) {

      closeFile=true;
      error=EXT_ERROR;
      goto EXIT_POINT;

   }

   EXIT_POINT:
   if(closeFile) {

      serial_uart_close();

   }
   return error;

} /* end serial_uart_init */


/* Function: serial_uart_clear =================================================
 * Abstract:
 *  Purges all data from the serial port.
 *
 *  EXT_NO_ERROR is returned on success, EXT_ERROR on failure.
 */
PRIVATE boolean_T serial_uart_clear(void) {

   if(serialHandle!=INVALID_HANDLE_VALUE) {
      PRINT_DEBUG_MSG_LVL1_Raw("Purging serial communications...");
      PurgeComm(serialHandle, PURGE_TXCLEAR);

   }
   return EXT_NO_ERROR;

} /* end serial_uart_clear */


/***************** VISIBLE FUNCTIONS ******************************************/

/* Function: ExtSerialPortCreate ===============================================
 * Abstract:
 *  Creates an External Mode Serial Port object.  The External Mode Serial Port
 *  is an abstraction of the physical serial port providing a standard
 *  interface for external mode code.  A pointer to the created object is
 *  returned.
 *
 */
PUBLIC ExtSerialPort * ExtSerialPortCreate(void) {

   static ExtSerialPort serialPort;
   ExtSerialPort        *portDev= &serialPort;

   /* Determine and save endianess. */
   {
      union Char2Integer_tag {

            int   IntegerMember;
            char  CharMember[sizeof(int)];

      } temp;

      temp.IntegerMember=1;
      if(temp.CharMember[0]!=1) {

         portDev->isLittleEndian=false;

      }
      else {

         portDev->isLittleEndian=true;

      }
   }

   portDev->fConnected=false;

   return portDev;

} /* end ExtSerialPortCreate */


/* Function: ExtSerialPortConnect ==============================================
 * Abstract:
 *  Performs a logical connection between the external mode code and the
 *  External Mode Serial Port object and a real connection between the External
 *  Mode Serial Port object and the physical serial port.
 *
 *  EXT_NO_ERROR is returned on success, EXT_ERROR on failure.
 */
PUBLIC boolean_T ExtSerialPortConnect(ExtSerialPort *portDev, uint16_T port, uint32_T baudRate) {

   boolean_T   error=EXT_NO_ERROR;

   if(portDev->fConnected) {

      error=EXT_ERROR;
      goto EXIT_POINT;

   }

   portDev->fConnected=true;

   error=serial_uart_init(port, baudRate);
   if(error!=EXT_NO_ERROR) {

      portDev->fConnected=false;
      goto EXIT_POINT;

   }

   EXIT_POINT:return error;

} /* end ExtSerialPortConnect */


/* Function: ExtSerialPortDisconnect ===========================================
 * Abstract:
 *  Performs a logical disconnection between the external mode code and the
 *  External Mode Serial Port object and a real disconnection between the
 *  External Mode Serial Port object and the physical serial port.
 *
 *  EXT_NO_ERROR is returned on success, EXT_ERROR on failure.
 */
PUBLIC boolean_T ExtSerialPortDisconnect(ExtSerialPort *portDev) {

   boolean_T   error=EXT_NO_ERROR;

   if(!portDev->fConnected) {
      PRINT_DEBUG_MSG_LVL1_Raw("Attempting to close serial port: Serial port already closed!");
      error=EXT_ERROR;
      goto EXIT_POINT;

   }

   portDev->fConnected=false;

   PRINT_DEBUG_MSG_LVL1_Raw("Attempting to close serial communications...");
   error=serial_uart_close();
   if(error!=EXT_NO_ERROR) {

      goto EXIT_POINT;

   }

   EXIT_POINT:return error;

} /* end ExtSerialPortDisconnect */


/* Function: ExtSerialPortClearData ============================================
 * Abstract:
 *  Discards all data from the serial port buffer
 *
 *  EXT_NO_ERROR is returned on success (which is always...)
 */
PUBLIC boolean_T ExtSerialPortClearData(void) {

   return serial_uart_clear();

} /* end ExtSerialPortClearData */



/* Function: ExtSerialPortSetData ==============================================
 * Abstract:
 *  Sets (sends) the specified number of bytes on the comm line.  The number of
 *  bytes sent is returned via the 'bytesWritten' parameter.
 *
 *  EXT_NO_ERROR is returned on success, EXT_ERROR on failure.
 */
PUBLIC boolean_T ExtSerialPortSetData(ExtSerialPort *portDev, char *data, uint32_T size, uint32_T *bytesWritten) {

   if(!portDev->fConnected) {

      return EXT_ERROR;

   }

   return serial_set_string(data, size, bytesWritten);

} /* end ExtSerialPortSetData */


/* Function: ExtSerialPortDataPending ==========================================
 * Abstract:
 *  Returns, via the 'bytesPending' arg, the number of bytes pending on the
 *  comm line.
 *
 *  EXT_NO_ERROR is returned on success, EXT_ERROR on failure.
 */
PUBLIC boolean_T ExtSerialPortDataPending(ExtSerialPort *portDev, int32_T *bytesPending) {

   if(!portDev->fConnected) {

      return EXT_ERROR;

   }

   return serial_string_pending(bytesPending);

} /* end ExtSerialPortDataPending */


/* Function: ExtSerialPortGetRawChar ===========================================
 * Abstract:
 *  Attempts to get one byte from the comm line.  The number of bytes read is
 *  returned via the 'bytesRead' parameter.
 *
 *  EXT_NO_ERROR is returned on success, EXT_ERROR on failure.
 */
PUBLIC boolean_T ExtSerialPortGetRawChar(ExtSerialPort *portDev, char *c, uint32_T *bytesRead) {

   if(!portDev->fConnected) {

      return EXT_ERROR;

   }

   return serial_get_string(c, 1, bytesRead);

} /* end ExtSerialPortGetRawChar */


/* [EOF] ext_serial_win32_port.c */

⌨️ 快捷键说明

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