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

📄 ext_serial_9s12_port.c

📁 RT9S12 target document
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
 * Copyright 1994-2003 The MathWorks, Inc.
 *
 * File: ext_serial_mc9s12_port.c     $Revision.1 $
 *
 * 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
 */


/* System macros (EXT_MODE, etc.) -- generated by 'gen_cpp_req_defines_h.tlc' */
#include "cpp_req_defines.h"

#include <string.h>

#include "tmwtypes.h"

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


/***************** 9S12 SPECIFIC FUNCTIONS ***********************************/

/* Microcontroller specific and system headers */
#if MC9S12_TYPE == DP256
#include <mc9s12dp256.h>		      /* port definitions etc. */
#elif MC9S12_TYPE == C128
#include <mc9s12c128.h>			      /* port definitions etc. */
#elif MC9S12_TYPE == C32
#include <mc9s12c32.h>			      /* port definitions etc. */
#endif

#include "buffer.h"                   /* (ring)buffer macros */
#include "mc_signal.h"

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


#ifdef USE_TARGET_TIMEOUTS
#include "mc_timer.h"             /* commsTimeoutFlag */
#endif


/* ExtSerialPortDataPending... need at least 9 bytes to consider buffer contents a packet  --  fw-07-07 */
#define MIN_PACKET_SIZE  9    /* smallest packet size: ACK_PACKET (9) */
//#define MIN_PACKET_SIZE  1      /* safe assumption */


/* defined in 'ext_work.c', here used to enable a kind of communication timeout mechanism during startup */
extern int_T           volatile  startModel;



#ifdef USE_TARGET_TIMEOUTS

/* enable a kind of communication timeout mechanism during startup (core timer ISR not yet running) */
static uint32_T        ExtSerialPortDataPendingCallsCounter = 0;

/* the timeout condition is detected when 'ExtSerialPortDataPending' has been called 
 * MAX_NUM_CALLS_TO_PENDING times without the receipt of a full data telegram.
 */
#define MAX_NUM_CALLS_TO_PENDING   500

#endif /* USE_TARGET_TIMEOUTS */



/*=============*
 *   PRIVATE   *
 *=============*/

/* serial communication reception ring buffer (reception is interrupt driven -> needs a ring buffer) */
static struct myRingBuffer ExtModeComBufAdmin;
static struct myRingBuffer *ExtModeComBufPtr= &ExtModeComBufAdmin;


/* make sure we're using the right port... */
#if SCI0_COMMS == MCOM

#if TARGET_BOARD != C32BASED

#pragma CODE_SEG __NEAR_SEG NON_BANKED /* Interrupt section for this module. Placement will be in NON_BANKED area. */
__interrupt void SCI0_RX_isr(void) {

   char_T   inVal,
            sr0Reg;

   // set sertime_pin high (timing -> scope)
   #ifdef TIMING
   setSerTiPin;
   #endif

   /* read SCI0 status register */
   sr0Reg=SCI0SR1;

   /* determine cause of interrupt */
   if((sr0Reg&OR_mask)!=0) {

      /* detected an OverRun condition -> error */
      abort_LED(1);

   }
   else if((sr0Reg&RDRF_mask)!=0) {

      /* Receive Data Register Full -> fetch character and store */
      inVal=SCI0DRL;                            /* get value from register SCI0DRL */
      BufferSet(ExtModeComBufPtr, inVal);       /* write character to the (ring) buffer */

   }  

   // reset sertime_pin (timing -> scope)
   #ifdef TIMING
   clrSerTiPin;
   #endif
} /* SCI0_RX_isr */


#else /* TARGET_BOARD != C32-based */


#pragma CODE_SEG __NEAR_SEG NON_BANKED /* Interrupt section for this module. Placement will be in NON_BANKED area. */
__interrupt void SCI0_RX_isr(void) {

   char_T   inVal,
            sr0Reg;

   // set sertime_pin high (timing -> scope)
   #ifdef TIMING
   setSerTiPin;
   #endif

   /* read SCI0 status register */
   sr0Reg=SCISR1;

   /* determine cause of interrupt */
   if((sr0Reg&OR_mask)!=0) {

      /* detected an OverRun condition -> error */
      abort_LED(1);

   }
   else if((sr0Reg&RDRF_mask)!=0) {

      /* Receive Data Register Full -> fetch character and store */
      inVal=SCIDRL;                            /* get value from register SCI0DRL */
      BufferSet(ExtModeComBufPtr, inVal);       /* write character to the (ring) buffer */

   }  

   // reset sertime_pin (timing -> scope)
   #ifdef TIMING
   clrSerTiPin;
   #endif
} /* SCI0_RX_isr */


#endif /* TARGET_BOARD != C32-based */


#else /* SCI0_COMMS != MCOM -> SCI1_COMMS == MCOM (must be, otherwise this file would not have been included) */


#if TARGET_BOARD != C32BASED

#pragma CODE_SEG __NEAR_SEG NON_BANKED /* Interrupt section for this module. Placement will be in NON_BANKED area. */
__interrupt void SCI1_RX_isr(void) {

   char_T   inVal,
            sr1Reg;

   // set sertime_pin high (timing -> scope)
   #ifdef TIMING
   setSerTiPin;
   #endif

   /* read SCI1 status register */
   sr1Reg=SCI1SR1;

   /* determine cause of interrupt */
   if((sr1Reg&OR_mask)!=0) {

      /* detected an OverRun condition -> error */
      abort_LED(1);

   }
   else if((sr1Reg&RDRF_mask)!=0) {

      /* Receive Data Register Full -> fetch character and store */
      inVal=SCI1DRL;                            /* get value from register SCI1DRL */
      BufferSet(ExtModeComBufPtr, inVal);       /* write character to the (ring) buffer */

   }  

   // reset sertime_pin (timing -> scope)
   #ifdef TIMING
   clrSerTiPin;
   #endif
} /* SCI1_RX_isr */

#endif /* TARGET_BOARD != C32-based */


#endif /* SCI1_COMMS == MCOM */

#pragma CODE_SEG DEFAULT

/* ============================================================================ */



/* Function: serial_get_string =================================================
 * Abstract:
 *  Attempts to get the specified number of bytes from the reception ring buffer.  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
 *  by macro TIMEOUT, an error is returned.
 *
 *  EXT_NO_ERROR is returned on success, EXT_ERROR on failure.
 *
 */
PRIVATE boolean_T serial_get_string(char *dst, uint_T nBytesToGet, uint32_T *nBytesGot) {

   char_T      *bufPtr=dst;
   uint_T      i=0;
   uint_T      nBuf=0;
   
   #ifdef debugTARGETTIMEOUT
   uint32_T    timeoutCounter = 0;
   #endif

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


   PRINT_DEBUG_MSG_LVL5("IN\n\r");

   /* display state of communications variables on port T */
   #if COMMSTATE_ON_PTT == 1
   PTT |=  0x02;    /* 'beginning of potentially endless loop' */
   
     #ifdef debugTARGETTIMEOUT
     PTT &= ~0x04;    /* 'no timeout' */
     #endif
   
   #endif

   /* wait for enough data to arrive... up to recATTEMPTS times -- this is where this function blocks! */
   do {

      /* determine the amount of data currently stored in the reception buffer */
      nBuf=Buffercounter(ExtModeComBufPtr);
      
      #ifdef debugTARGETTIMEOUT
      if(timeoutCounter++ > 200000) {
        #if COMMSTATE_ON_PTT == 1             
        PTT |= 0x04;    /* 'timeout' */
        #endif
        
        return EXT_ERROR;
      }
      #endif
      

   }
   while(nBuf<nBytesToGet);

   #if COMMSTATE_ON_PTT == 1
   PTT&=~0x02;   /* 'end of potentially endless loop' */
   #endif

   PRINT_DEBUG_MSG_LVL5("Bytes waited for: ");
   PRINT_DEBUG_MSG_LVL5_UDec((uint16_T)nBytesToGet);
   PRINT_DEBUG_MSG_NL5;
   PRINT_DEBUG_MSG_LVL5("Bytes available: ");
   PRINT_DEBUG_MSG_LVL5_UDec((uint16_T)nBuf);
   PRINT_DEBUG_MSG_NL5;

   /*
    * the above loop guarantees that, at this stage, the required 
    * number of bytes can be read from the read buffer
    */
   for(i=0; i<nBytesToGet; i++) {

      BufferGet(ExtModeComBufPtr, *bufPtr++);

      #if DEBUG_MSG_LVL >= 4
      PRINT_DEBUG_MSG_LVL4("Data received: 0x");
      PRINT_DEBUG_MSG_LVL4_UHex((uint8_T)*(--bufPtr));
      PRINT_DEBUG_MSG_NL4;
      /* need to restore the buffer pointer */
      bufPtr++;
      #endif
   }

   /* return actual number of bytes which have been read from the reception buffer (0 or nBytesToGet) */
   *nBytesGot=(uint32_T)i;   // i = nBytesToGet (always, at this stage)


   PRINT_DEBUG_MSG_LVL5("OUT, error status: 0\n\r");

   /* return error flag */
   return EXT_NO_ERROR;

} /* end serial_get_string */



#if TARGET_BOARD != C32BASED

/* Function: serial_set_string =================================================
 * Abstract:
 *  Sets (sends) the specified number of bytes on SCI0 (or SCI1). The number of
 *  bytes sent is returned via the 'bytesWritten' parameter.
 *
 */
PRIVATE boolean_T serial_set_string(char *src, uint32_T size, uint32_T *bytesWritten) {

   uint_T      i;

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

   PRINT_DEBUG_MSG_LVL5("IN\n\r");

   PRINT_DEBUG_MSG_LVL5("Number of bytes to be sent: ");
   PRINT_DEBUG_MSG_LVL5_UDec((uint16_T)size);
   PRINT_DEBUG_MSG_NL5;

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

      /* make sure we're using the right port... */
      #if SCI0_COMMS == MCOM

      while((SCI0SR1&TDRE_mask)==0) {

      };  // wait until the end of a possibly ongoing transmission
      SCI0DRL=src[i];                // send character

      #else

      while((SCI1SR1&TDRE_mask)==0) {

      };  // wait until the end of a possibly ongoing transmission
      SCI1DRL=src[i];                // send character

      #endif

      PRINT_DEBUG_MSG_LVL4("Sending  0x");
      PRINT_DEBUG_MSG_LVL4_UHex(src[i]);
      PRINT_DEBUG_MSG_NL4;

   }

   *bytesWritten=i;


   /* return error flag */
   PRINT_DEBUG_MSG_LVL5("OUT, error status: ");
   PRINT_DEBUG_MSG_LVL5_UDec(error);
   PRINT_DEBUG_MSG_NL5;

   return EXT_NO_ERROR;

} /* end serial_set_string */


#else /* TARGET_BOARD != C32-based */

/* ... this is for C32-based targets */

/* Function: serial_set_string =================================================
 * Abstract:
 *  Sets (sends) the specified number of bytes on SCI0 (or SCI1). The number of
 *  bytes sent is returned via the 'bytesWritten' parameter.
 *
 */
PRIVATE boolean_T serial_set_string(char *src, uint32_T size, uint32_T *bytesWritten) {

   uint_T      i;

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

   PRINT_DEBUG_MSG_LVL5("IN\n\r");

   PRINT_DEBUG_MSG_LVL5("Number of bytes to be sent: ");
   PRINT_DEBUG_MSG_LVL5_UDec((uint16_T)size);
   PRINT_DEBUG_MSG_NL5;

⌨️ 快捷键说明

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