📄 ext_serial_9s12_port.c
字号:
/*
* 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 + -