本帖最后由 wopt 于 2015-3-11 18:42 编辑
2.8 McBSP
以McBSP实现UART为例。
McBSP概述
TM320C55x提供了可以与其他C55x、编解码器以及其他设备直接通信的多通道缓冲串口(McBSP)。
McBSP重要特性:
- 全速双工通信。
- 双缓存发送和三缓存接收数据寄存器,以支持连续传送。
- 收和发使用独立的帧和时钟。
- 直接与多媒体数字信号编解码器的工业标准接口,以及有模拟接口和与串行ADC/DAC的接口。
- 外部变速时钟发生器,内部可编程时钟发生器。
- 多通道收发,通道数达128。
- 字宽可选: 8, 12, 16, 20, 24, and 32 bits
- U-Law and A-Law 压缩与扩展
- 帧信号与时钟信号极性可编程
- 直接与下列格式接口
- T1/E1 framers
- MVIP switching compatible and ST-BUS compliant devices including:
1) MVIP framers
2) H.100 framers
3) SCSA framers
- IOM-2 compliant devices
- AC97 compliant devices
- IIS compliant devices
- SPI_ devices
McBSP控制寄存器
串口控制寄存器(SPCR1 和 SPCR2)
- SPCR1设置McBSP串口的数字环回模式(DLB)、 接收符号扩展和调整方式(RJUST)、Clock Stop模式(RINTM and XINTM)、接收中断模式和硬仿真模式(FREE and SOFT)。
- DX引脚延时开关(DXENA)
- 检测接收和发送操作状态(RSYNCERR, XSYNCERR, RFULL, XEMPTY, RRDY, XRDY)
- McBSP复位选项(RRST, XRST, FRST, GRST)
配置McBSP接收/发送器时的三步骤:
- 置McBSP接收/发送器为复位状态
- 配置McBSP接收/发送器寄存器
- 开启McBSP接收/发送器
接收控制寄存器(RCR1 和 RCR2)
- Specify one or two phases for each frame of receive data (RPHASE),确定接收数据每一帧是一个阶段还是两个阶段。
- Define two parameters for phase 1 and (if necessary) phase 2: the serial word length (RWDLEN1, RWDLEN2) and the number of words (RFRLEN1, RFRLEN2),定义阶段的字长和帧长。
- Choose a receive companding mode, if any (RCOMPAND),选择压扩模式。
- Enable or disable the receive frame-sync ignore function (RFIG),接收帧同步忽略方法,形象化的描述在TI官方手册McBSP的11.2章节中。
- Choose a receive data delay (RDATDLY),接收数据延时。
发送控制寄存器(XCR1 和 XCR2)
- Specify one or two phases for each frame of transmit data (XPHASE)
- Define two parameters for phase 1 and (if necessary) phase 2: the serial word length (XWDLEN1, XWDLEN2) and the number of words
- (XFRLEN1, XFRLEN2)
- Choose a transmit companding mode, if any (XCOMPAND)
- Enable or disable the transmit frame-sync ignore function (XFIG)
- Choose a transmit data delay (XDATDLY)
ps..我好懒啊,翻译都不好好写,嘿嘿。
采样率发生器寄存器(SRGR1 和 SRGR2)
- Select the input clock source for the sample rate generator (CLKSM, in conjunction with the SCLKME bit of PCR)
- Divide down the frequency of CLKG (CLKGDV),分频产生波特率,参考文档中的采样率发生器原理框图。
- Select whether internally-generated transmit frame-sync pulse are driven by FSG or by activity in the transmitter (FSGM).
- Specify the width of frame-sync pulses on FSG (FWID) and specify the period between those pulses (FPER),设置帧正脉冲宽度。
When an external source (via the CLKS, CLKR, or CLKX pin) provides the input clock source for the sample rate generator(外部时钟源):
- If the CLKS pin provides the input clock, the CLKSP bit in SRGR2 allows you to select whether the rising edge or the falling edge of CLKS triggers CLKG and FSG. If the CLKX/CLKR pin is used instead of the CLKS pin, the polarity of the input clock is selected with CLKXP/CLKRP of PCR.
- The GSYNC bit of SRGR2 allows you to make CLKG synchronized to an external frame-sync signal on the FSR pin, so that CLKG is kept in phase with the input clock.
引脚控制寄存器(PCR)
PCR设置McBSP传输帧同步模式、接收帧同步模式、发送时钟模式、接收时钟模式、发送帧同步信号的极性、接收帧同步信号的极性、发送时钟极性、接收时钟极性,并给出CLKS、DX、DR脚的状态。此外PCR还定义发送和接收部分在复位时相应引脚是否配置为通用 I/O。
- XIOEN和RIOEN = 0表示DX,FSX,CLKX,DR,FSR,CLKR,CLKS都配置为串口而非通用I/O引脚。
- FSXM = 1表示发送帧同步由采样率发生器产生(请参考SRGR2寄存器的FSGM位)。
- FSRM = 0 表示接收帧同步由外部提供。
- CLKXM = 1 表示发送时钟由内部采样率发生器产生。
- CLKRM = 0 表示接收时钟由外部提供,同样因为CLKRM与CLKXM连在一起。
- FSXP = 1 表示发送帧同步低有效。
- FSRP = 1 表示接收帧同步低有效。
- CLKXP = 1 表示CLKX的上升沿发送数据 。
- CLKRP = 0 表示CLKR的下降沿接收数据。
还有多通道控制寄存器,哎!算了,整个我觉得没必要复制然后翻译上来,自己看更能理解。
Multichannel Buffered Serial Port (McBSP) Reference Guide.pdf
(1.26 MB)
参考例程
/*---------main_mcbsp1.c---------
* In this example, the MCBSP is configured in digital loopback
* mode, with 32 bit data transfer, in multi-frame mode, using
* sample rate generator to sync frames
*/
#include <csl.h>
#include <csl_mcbsp.h>
#include <csl_irq.h>
//---------Global constants---------
#define N 10
//---------Global data definition---------
MCBSP_Config ConfigLoopBack32= {
MCBSP_SPCR1_RMK(
MCBSP_SPCR1_DLB_ON, /* 数字回环使能 DLB = 1b */
MCBSP_SPCR1_RJUST_RZF, /* 接收数据符号扩展和调整方式 RJUST = 00b */
MCBSP_SPCR1_CLKSTP_DISABLE, /* 时钟停止模式 CLKSTP = 00b or 01b */
MCBSP_SPCR1_DXENA_NA, /* DX延时模式使能 DXENA = 0b */
MCBSP_SPCR1_ABIS_DISABLE, /* 5509A无 ABIS = 0 */
MCBSP_SPCR1_RINTM_RRDY, /* 接收终端模式 RINTM = 00b */
0, /* 接收帧同步错误标志 RSYNCERR = 0b */
MCBSP_SPCR1_RRST_DISABLE /* 接收器复位 RRST = 0b */
),
MCBSP_SPCR2_RMK(
MCBSP_SPCR2_FREE_NO, /* 自由运行 FREE = 0b */
MCBSP_SPCR2_SOFT_NO, /* 软调试 SOFT = 0b */
MCBSP_SPCR2_FRST_RESET, /* 帧同步逻辑复位 FRST = 0b */
MCBSP_SPCR2_GRST_RESET, /* 采样率发生器复位 GRST = 0b */
MCBSP_SPCR2_XINTM_XRDY, /* 发送中断复位 XINTM = 0b */
0, /* 发送帧同步错误标志 XSYNCERR = 0b */
MCBSP_SPCR2_XRST_DISABLE /* 发送器复位 XRST = 0b */
),
MCBSP_RCR1_RMK(
MCBSP_RCR1_RFRLEN1_OF(0), /* 接收阶段1的帧长 RFRLEN1 = 0 */
MCBSP_RCR1_RWDLEN1_32BIT /* 接收阶段1的字长 RWDLEN1 = 101b */
),
MCBSP_RCR2_RMK(
MCBSP_RCR2_RPHASE_SINGLE, /* 接收帧的阶段数 RPHASE = 0 */
MCBSP_RCR2_RFRLEN2_OF(0), /* 接收阶段2的帧长 RFRLEN2 = 0 */
MCBSP_RCR2_RWDLEN2_8BIT, /* 接收阶段2的字长 RWDLEN2 = 000b */
MCBSP_RCR2_RCOMPAND_MSB, /* 接收数据压扩模式 RCOMPAND = 0 */
MCBSP_RCR2_RFIG_YES, /* 忽略不期望的接收帧同步信号 RFIG = 0 */
MCBSP_RCR2_RDATDLY_2BIT /* 接收数据延时 RDATDLY = 0 */
),
MCBSP_XCR1_RMK(
MCBSP_XCR1_XFRLEN1_OF(0), /* 发送阶段1的帧长 XFRLEN1 = 0 */
MCBSP_XCR1_XWDLEN1_32BIT /* 发送阶段1的字长 XWDLEN1 = 5 */
),
MCBSP_XCR2_RMK(
MCBSP_XCR2_XPHASE_SINGLE, /* 发送帧的阶段数 XPHASE = 0 */
MCBSP_XCR2_XFRLEN2_OF(0), /* 发送阶段2的帧长 XFRLEN2 = 0 */
MCBSP_XCR2_XWDLEN2_8BIT, /* 发送阶段2的字长 XWDLEN2 = 0 */
MCBSP_XCR2_XCOMPAND_MSB, /* 发送数据压扩模式 XCOMPAND = 0 */
MCBSP_XCR2_XFIG_YES, /* 忽略不期望的发送帧同步信号 XFIG = 0 */
MCBSP_XCR2_XDATDLY_2BIT /* 发送数据延时 XDATDLY = 0 */
),
MCBSP_SRGR1_RMK(
MCBSP_SRGR1_FWID_OF(1), /* 帧同步信号 FSG的脉冲宽度 FWID = 1 */
MCBSP_SRGR1_CLKGDV_OF(103) /* 输出时钟信号 CLKG的分频值 CLKGDV = 103 */
), /* CLKG frequency = (12MHz) / (103 + 1) */
MCBSP_SRGR2_RMK(
MCBSP_SRGR2_GSYNC_FREE, /* 时钟同步模式 FREE = 0 */
MCBSP_SRGR2_CLKSP_RISING, /* CLKS引脚极性 CLKSP = 0 */
MCBSP_SRGR2_CLKSM_INTERNAL, /* 采样率发生器时钟源选择 CLKSM = 1 */
MCBSP_SRGR2_FSGM_DXR2XSR, /* 采样率发生器发送帧同步模式 FSGM = 0 */
MCBSP_SRGR2_FPER_OF(15) /* FSG信号帧同步周期 FPER = 0 */
),
MCBSP_MCR1_DEFAULT,
MCBSP_MCR2_DEFAULT,
MCBSP_PCR_RMK(
MCBSP_PCR_IDLEEN_RESET, /* 省电模式 IDLEEN = 0 */
MCBSP_PCR_XIOEN_SP, /* 发送GPIO使能 XIOEN = 0 */
MCBSP_PCR_RIOEN_SP, /* 接收GPIO使能 RIOEN = 0 */
MCBSP_PCR_FSXM_INTERNAL, /* 发送帧同步模式 FSXM = 1 */
MCBSP_PCR_FSRM_EXTERNAL, /* 接收帧同步模式 FSRM = 0 */
MCBSP_PCR_CLKXM_OUTPUT, /* 发送时钟模式 CLKXM = 1 */
MCBSP_PCR_CLKRM_INPUT, /* 接收时钟模式 CLKRM = 0 */
MCBSP_PCR_SCLKME_NO, /* 采样率发生器时钟源模式 SCLKME = 0 */
0, /* DX引脚上的电平 DXSTAT = 0 */
MCBSP_PCR_FSXP_ACTIVEHIGH, /* 发送帧同步极性 FSXP = 0 */
MCBSP_PCR_FSRP_ACTIVEHIGH, /* 接收帧同步极性 FSRP = 0 */
MCBSP_PCR_CLKXP_RISING, /* 发送时钟极性 CLKXP = 0 */
MCBSP_PCR_CLKRP_FALLING /* 接收时钟极性 CLKRP = 0 */
),
MCBSP_RCERA_DEFAULT,
MCBSP_RCERB_DEFAULT,
MCBSP_RCERC_DEFAULT,
MCBSP_RCERD_DEFAULT,
MCBSP_RCERE_DEFAULT,
MCBSP_RCERF_DEFAULT,
MCBSP_RCERG_DEFAULT,
MCBSP_RCERH_DEFAULT,
MCBSP_XCERA_DEFAULT,
MCBSP_XCERB_DEFAULT,
MCBSP_XCERC_DEFAULT,
MCBSP_XCERD_DEFAULT,
MCBSP_XCERE_DEFAULT,
MCBSP_XCERF_DEFAULT,
MCBSP_XCERG_DEFAULT,
MCBSP_XCERH_DEFAULT
};
/* Define a MCBSP_Handle object to be used with MCBSP_open function */
MCBSP_Handle mhMcbsp;
Uint32 xmt[N], rcv[N];
volatile Uint16 XfrCnt = 0;
Uint16 err = 0;
Uint16 old_intm;
Uint16 rcvEventId, xmtEventId;
//---------Function prototypes---------
/* Reference start of interrupt vector table */
/* This symbol is defined in file, vectors.s55 */
extern void VECSTART(void);
// Interrupt Service Routine Prototypes
interrupt void writeIsr(void);
interrupt void readIsr(void);
void taskFxn(void);
//---------main routine---------
void main(void)
{
Uint16 i;
/* Initialize CSL library - This is REQUIRED !!! */
CSL_init();
/* Set IVPD/IVPH to start of interrupt vector location */
IRQ_setVecs((Uint32)(&VECSTART));
for (i = 0; i <= N - 1; i++) {
xmt[i] = ((Uint32)i << 17) + i;
rcv[i] = 0;
}
/* Call function to effect transfer */
taskFxn();
}
void taskFxn(void)
{
Uint16 i;
old_intm = IRQ_globalDisable();
/* Open MCBSP Port 0 and set registers to their power on defaults */
mhMcbsp = MCBSP_open(MCBSP_PORT0, MCBSP_OPEN_RESET);
/* Get EventId's associated with MCBSP Port 0 receive and transmit */
/* The event Id's are used to communicate with the CSL interrupt */
/* module functions. */
rcvEventId = MCBSP_getRcvEventId(mhMcbsp);
xmtEventId = MCBSP_getXmtEventId(mhMcbsp);
/* Clear any pending receive or transmit interrupts */
IRQ_clear(rcvEventId);
IRQ_clear(xmtEventId);
/* Place address of interrupt service routines at */
/* associated vector location */
IRQ_plug(rcvEventId, &readIsr);
IRQ_plug(xmtEventId, &writeIsr);
/* Write values from configuration structure to MCBSP control regs */
MCBSP_config(mhMcbsp, &ConfigLoopBack32);
/* Enable the MCBSP receive and transmit interrupts */
IRQ_enable(rcvEventId);
IRQ_enable(xmtEventId);
/* Start Sample Rate Generator and Frame Sync */
MCBSP_start(mhMcbsp,
MCBSP_SRGR_START | MCBSP_SRGR_FRAMESYNC,
0x300
);
/* Enable MCBSP transmit and receive */
MCBSP_start(mhMcbsp,
MCBSP_RCV_START | MCBSP_XMIT_START,
0
);
/* Prime MCBSP transmit */
while(!MCBSP_xrdy(mhMcbsp)){
;
}
MCBSP_write32(mhMcbsp,xmt[XfrCnt]);
/* Enable all masked interrupts */
IRQ_globalEnable();
/* Wait for transfer of data */
while (XfrCnt < N) {
;
}
/*------------------------------------------*\
* Compare values
\*------------------------------------------*/
for(i = 0; i < N; i++){
if (rcv[i] != xmt[i]){
++err;
break;
}
}
/* Restore old value of INTM */
IRQ_globalRestore(old_intm);
/* We're done with MCBSP, so close it */
MCBSP_close(mhMcbsp);
}
interrupt void writeIsr(void)
{
/*
* Disable this ISR's interrupt before the write to the McBSP
* since another interrupt will be generated as soon as the write
* completes, which happens very quickly due to the loopback to
* the McBSP receive.
*/
IRQ_disable(xmtEventId);
MCBSP_write32(mhMcbsp,xmt[XfrCnt]);
}
interrupt void readIsr(void)
{
rcv[XfrCnt] = MCBSP_read32(mhMcbsp);
++XfrCnt;
if (XfrCnt == N) {
IRQ_disable(rcvEventId);
IRQ_disable(xmtEventId);
MCBSP_reset(mhMcbsp);
}
else {
IRQ_enable(xmtEventId);
}
}
发送10个32bit数据。
|