📄 ser270.c
字号:
/*
DM270 ARM Evaluation Software
(c)Texas Instruments 2003
*/
/**
\file ser270.c
\brief Serial Interface Related APIs
*/
#include <ser270.h>
#include <clkc270.h>
#include <intc270.h>
#define SER_BIT_RATE( ARM_CLK, bitrate ) ( (ARM_CLK)/((bitrate)*2) - 1)
static STATUS SER0_sendData( char *dataAddress, Uint32 dataSize );
static STATUS SER1_sendData( char *dataAddress, Uint32 dataSize );
static STATUS SER0_recvData( char *dataAddress, Uint32 dataSize );
static STATUS SER1_recvData( char *dataAddress, Uint32 dataSize );
/**
\brief Configure serial interface
Configures serial interface 'serialID' with configuration data 'serialConfig' \n
After serial configuration, \n
Use SER_sendData() to send data from DM270 to peripheral. \n
Use SER_recvData() to recieve data from peripheral to DM270 \n
\param serialID serial interface ID, 0:SER_0, 1:SER_1
\param serialConfig configuration data
\return if success, E_PASS, else error code
\see SER_ConfigData
*/
STATUS SER_setConfig( Uint16 serialID, SER_ConfigData *serialConfig ) {
STATUS status=E_PASS;
switch(serialID) {
case SER_0:
// disable serial port 0
SP0_RSET( SIOEN0, 0);
SP0_FSET( SIOMODE0, RATE, SER_BIT_RATE( CLKC_getClockValue(CLK_ARM), serialConfig->bitRate) );
SP0_FSET( SIOMODE0, SCLKM, serialConfig->clockMode == SER_IDLE_CLK_HIGH ? 0 : 1 );
SP0_FSET( SIOMODE0, MSB, serialConfig->lsbFirst == TRUE ? 0 : 1 );
SP0_FSET( SIOMODE0, MSSEL, serialConfig->slaveOperation == TRUE ? 1 : 0 );
INTC_setIntAsIRQ(INT_SER0);
break;
case SER_1:
// disable serial port 0
SP1_RSET( SIOEN1, 0);
SP1_FSET( SIOMODE1, RATE, SER_BIT_RATE( CLKC_getClockValue(CLK_ARM), serialConfig->bitRate) );
SP1_FSET( SIOMODE1, SCLKM, serialConfig->clockMode == SER_IDLE_CLK_HIGH ? 0 : 1 );
SP1_FSET( SIOMODE1, MSB, serialConfig->lsbFirst == TRUE ? 0 : 1 );
SP1_FSET( SIOMODE1, MSSEL, serialConfig->slaveOperation == TRUE ? 1 : 0 );
INTC_setIntAsIRQ(INT_SER1);
break;
default:
status=E_INVALID_INPUT;
break;
}
return status;
}
/**
\brief Send data over serial interface
Transmits data over serial interface 'serialID' to a externally connected peripheral \n
Make sure serial interface 0 or 1 is configured using SER_setConfig(), before using this API
\param serialID Serial Interface ID, 0:SER_0, 1:SER_1
\param dataAddress Source data address
\param dataSize Size of data to be transmitted
\return if success, E_PASS, else error code
*/
STATUS SER_sendData( Uint16 serialID, char *dataAddress, Uint32 dataSize) {
STATUS status=E_PASS;
if(dataSize==0)
return E_PASS;
if(dataAddress==NULL)
return E_INVALID_INPUT;
switch(serialID) {
case SER_0:
SER0_sendData(dataAddress, dataSize);
break;
case SER_1:
SER1_sendData(dataAddress, dataSize);
break;
default:
status=E_INVALID_INPUT;
break;
}
return status;
}
/**
\brief Enable/Disable serial interface
\param serialID Serial Interface ID, 0:SER_0, 1:SER_1
\param enable TRUE: enable, FALSE: disable
\return if success, \c E_PASS, else error code
*/
STATUS SER_enable( Uint16 serialID, BOOL enable ) {
STATUS status=E_PASS;
switch(serialID) {
case SER_0:
SP0_FSET( SIOEN0, SIOEN, enable == TRUE ? 1 : 0);
break;
case SER_1:
SP1_FSET( SIOEN1, SIOEN, enable == TRUE ? 1 : 0);
break;
default:
status=E_INVALID_INPUT;
break;
}
return status;
}
/**
\brief Send one byte of data over serial interface
Make sure serial interface is enabled by using SER_enable() \n
After data transmission is over, use SER_enable() to disable serial interface
\param serialID Serial Interface ID, 0:SER_0, 1:SER_1
\param byte data byte to be sent using serialID
\return if success, \c E_PASS, else error code
*/
STATUS SER_sendByte( Uint16 serialID, Uint8 byte ) {
STATUS status=E_PASS;
switch(serialID) {
case SER_0:
SP0_RSET( TXDATA0, byte );
// Wait for the Serial Tx done
while( INTC_getIntIRQStatus(INT_SER0) )
;
INTC_clearIRQ(INT_SER0);
break;
case SER_1:
SP1_RSET( TXDATA1, byte );
// Wait for the Serial Tx done
while( INTC_getIntIRQStatus(INT_SER1) )
;
INTC_clearIRQ(INT_SER1);
break;
default:
status=E_INVALID_INPUT;
break;
}
return status;
}
static STATUS SER0_sendData( char *dataAddress, Uint32 dataSize ) {
SP0_FSET( SIOEN0, SIOEN, 1 );
while (dataSize--) {
SP0_RSET( TXDATA0, *dataAddress++ ); // R/W, Tx data
// Wait for the Serial Tx done
while( INTC_getIntIRQStatus(INT_SER0) )
;
INTC_clearIRQ(INT_SER0);
}
SP0_FSET( SIOEN0, SIOEN, 0 );
return E_PASS;
}
static STATUS SER1_sendData( char *dataAddress, Uint32 dataSize ) {
SP1_FSET( SIOEN1, SIOEN, 1 );
while (dataSize--) {
SP1_RSET( TXDATA1, *dataAddress++ ); // R/W, Tx data
// Wait for the Serial Tx done
while( INTC_getIntIRQStatus(INT_SER1) )
;
INTC_clearIRQ(INT_SER1);
}
SP1_FSET( SIOEN1, SIOEN, 0 );
return E_PASS;
}
/**
\brief Receive data over serial interface
Receives data over serial interface 'serialID' from a externally connected peripheral \n
Make sure serial interface 0 or 1 is configured using SER_setConfig(), before using this API
\param serialID Serial Interface ID, 0:SER_0, 1:SER_1
\param dataAddress Destination data address
\param dataSize Size of data to be received
\return if success, E_PASS, else error code
*/
STATUS SER_recvData( Uint16 serialID, char *dataAddress, Uint32 dataSize) {
STATUS status=E_PASS;
if(dataSize==0)
return E_PASS;
if(dataAddress==NULL)
return E_INVALID_INPUT;
switch(serialID) {
case SER_0:
SER0_recvData(dataAddress, dataSize);
break;
case SER_1:
SER1_recvData(dataAddress, dataSize);
break;
default:
status=E_INVALID_INPUT;
break;
}
return status;
}
static STATUS SER0_recvData( char *dataAddress, Uint32 dataSize ) {
SP0_FSET( SIOEN0, SIOEN, 1 );
while (dataSize--) {
SP0_RSET( TXDATA0, 0xFF );
// Wait for the Serial Tx done
while ( SP0_FGET( RXDATA0, XMIT ) )
;
// read data
*dataAddress++ = SP0_FGET( RXDATA0, RXD ); // R/W, Tx data
}
SP0_FSET( SIOEN0, SIOEN, 0 );
return E_PASS;
}
static STATUS SER1_recvData( char *dataAddress, Uint32 dataSize ) {
SP1_FSET( SIOEN1, SIOEN, 1 );
while (dataSize--) {
SP1_RSET( TXDATA1, 0xFF );
// Wait for the Serial Tx done
while ( SP1_FGET( RXDATA1, XMIT ) )
;
// read data
*dataAddress++ = SP1_FGET( RXDATA1, RXD ); // R/W, Tx data
}
SP1_FSET( SIOEN1, SIOEN, 0 );
return E_PASS;
}
/**
\brief Configure DMA for serial interface 0
\param serialDmaConfig Serial Interface 0, DMA configuration parameters
\return if success, E_PASS, else error code
\see SER_DmaConfig
*/
STATUS SER_dmaConfig( SER_DmaConfig *serialDmaConfig) {
STATUS status=E_PASS;
Uint32 addr;
SP0_FSET( DMAMODE0, PRM, serialDmaConfig->byteOrder);
SP0_FSET( DMAMODE0, DIR, serialDmaConfig->direction);
if( serialDmaConfig->size & 0x1 )
status = E_INVALID_INPUT;
SP0_FSET( DMAMODE0, TRSZ, serialDmaConfig->size );
addr = (Uint32)serialDmaConfig->address - SDRAM_MEMORY_BASE;
if( addr & 0x1 )
status = E_INVALID_INPUT;
SP0_RSET( DMASTADL0, addr );
SP0_RSET( DMASTADH0, addr >> 16);
return status;
}
/**
\brief Start DMA operation
Starts serial interface 0 DMA operation \n
DMA operation must be configured by using SER_dmaConfig(), before using this API \n
Also SDRAM DMA channel must be selected by using SDRC_selectDmaChannel(), before using this API
\return if success, E_PASS, else error code
*/
static Uint8 dmaChannel0;
STATUS SER_dmaStart() {
// enable serial interface
SER_enable( SER_0, TRUE);
// select DMA channel for serial interface
dmaChannel0 = SDRC_FGET( REFCTL, SDMA1);
SDRC_FSET( REFCTL, SDMA1, 1);
SP0_RSET( DMATRG0, 1);
return E_PASS;
}
/**
\brief Wait for DMA to complete
Wait for serial interface 0 DMA operation to complete \n
DMA operation is started using SER_dmaStart()
\param timeout DMA operation completion timeout
\warning paramter 'timeout' is not used in current implemetation, hence always pass 0
\return if success, E_PASS, else error code
*/
STATUS SER_dmaWait( Uint32 timeout ) {
STATUS status=E_PASS;
if(timeout!=0) {
// Wait for the Serial Rx/Tx done
while( INTC_getIntIRQStatus(INT_SER0) && timeout)
timeout--;
if(timeout==0)
status=E_TIMEOUT;
} else {
// Wait for the Serial Rx/Tx done
while( INTC_getIntIRQStatus(INT_SER0) )
;
}
INTC_clearIRQ(INT_SER0);
// disable serial interface
SER_enable( SER_0, FALSE);
// set DMA channel to old value
SDRC_FSET( REFCTL, SDMA1, dmaChannel0 );
return status;
}
/**
\brief Get DMA transfer remaning byte count
Returns serial interface 0, DMA transfer remaining byte count
\return count in units of bytes
*/
Uint16 SER_getDmaCount() {
return SP0_FGET( DMASTAT0, REM );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -