S3C2416 SPI中断方式实现
来源:互联网 发布:子曰法语之言能无从乎 编辑:程序博客网 时间:2024/06/07 02:15
samsung S3C2416支持HS_SPI(高速串行外设接口),是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚,同时为PCB的布局上节省空间,提供方便,正是出于这种简单易用的特性,如今越来越多的芯片集成了这种通信协议。
将2416作为SPI主站与MCP2515通讯,s3c2416采用SPI中断方式处理发送和接收。
考虑到MCP2515spi协议,采用一问一答方式,中断处理中需严格遵循一条完整指令中的发送和接收,即发送完应马上处理需要的接收。
spi中断处理流程:
1.初始化SPI和中断
void SpiRegInit(PCAN_INFO pCan_info)
{
rCH_CFG |= (1<<5);//软件复位
rCH_CFG &= ~(1<<5);
rCH_CFG = (0<<4) | (0<<3) | (0<<2) | (0<<1) | (0<<0);
rCLK_CFG = PCLK/((2*SPICLK)+1);//时钟配置
rCLK_CFG |= (0<<9) | (1<<8);
rMODE_CFG = (rMODE_CFG & ~0x1fffffff) | TRAIL_CNT(0x3FF) | MODE_BUS_SZ_BYTE | TX_TRIG_LVL(0x1);//配置模式寄存器
//RX_TRIG_LVL(1);// | TX_TRIG_LVL(0x4);
//rSPI_INT_EN = 0;
rPACKET_CNT = 1<<16;//启用接收包数量控制
rSWAP_REG = 0;
rFB_Clk_sel = 0x3;//Feedback clock selecting register.
#if 1
SPIINT_Init();
DebugPrint("[*CH_CFG %08X]\n", rCH_CFG);
#endif
nSSHigh(); //片选寄存器inactive
}
2.发送数据申请和接收数据申请
发送数据申请
rSPI_INT_EN |= INT_TX_FIFORDY;//开启准备发送中断
接收申请
这里可以按需设置触发等级来触发接收fifo准备中断,触发等级为0~64字节
rMODE_CFG |= RX_TRIG_LVL(1); //设置接收中断触发等级
rSPI_INT_EN |= INT_TX_FIFORDY; //开启接收中断
3.中断处理发送接收
VOID __irq MCP2515_SPIINTHandler(void)
{
PMCP2515_SPIINFO pSpiInfo = &Mcp2515_spi;
DWORD pspi_data;
DWORD status, modecfg;
BYTE OperTotal;
INT i = 0;
ULONG TotalTimeOut, Count=0;
rINTMSK |= (((DWORD)0x1)<<(pSpiInfo->dwSPIINTNo-0x20));//屏蔽SPI0中断
ClearPending(1 << (pSpiInfo->dwSPIINTNo-0x20));//清除悬而未决中断源
status = rSPI_STATUS;//获取SPI状态
rPENDING_CLR |= (1<<4) | (1<<3) | (1<<2) | (1<<1);//清楚SPI中断
if (status & STUS_TX_FIFORDY)//判断发送中断
{
if(!g_bCSValid) {
MCP2515_CS_VALID;//拉低CS片选引脚
nSSLow(); //设置slave_selection_reg寄存器nssout active
g_bCSValid = TRUE;
}
OperTotal = 64 - ((status>>6) & 0x7f);
rPENDING_CLR = 0x1f;
while (i<OperTotal && GetQueToRead(&pSpiInfo->TxQue.Que, &pspi_data, (DWORD)1, FALSE))
{
rSPI_TX_DATA = *((BYTE *)pspi_data);
ChangeQueOut(&pSpiInfo->TxQue.Que, 1, FALSE);
i++;
}
TotalTimeOut = WRITE_TIME_OUT_CONSTANT*50 + (WRITE_TIME_OUT_MULTIPLIER)*(i-1);
TXDone(TotalTimeOut);//等待发送完成
rCH_CFG &= ~CH_TXCH_ON;
if (g_byReadReg)
{
rCH_CFG |= CH_RXCH_ON;
rSPI_INT_EN |= INT_RX_FIFORDY;
}
}
else if (status & STUS_RX_FIFORDY /*|| status & STUS_TRAILCNT_ZERO*/)//接收中断
{
BYTE rrtmp[5] = {0};
i = 0;
OperTotal = (status>>13) & 0x7f;//data level in RX fifo
TotalTimeOut = READ_TIME_OUT_CONSTANT*50 + (READ_TIME_OUT_MULTIPLIER)*OperTotal;
while(i<OperTotal && GetQueToWrite(&pSpiInfo->RxQue.Que, &pspi_data, 1, FALSE))
{
*((BYTE *)pspi_data) = rSPI_RX_DATA;
ChangeQueIn(&pSpiInfo->RxQue.Que, 1, FALSE);
i++;
}
rCH_CFG &= ~CH_RXCH_ON;
g_byReadReg = 0;
}
if (!g_byReadReg)
{
nSSHigh();
MCP2515_CS_INVALID;
rPACKET_CNT = 0;
rCH_CFG |= CH_SW_RST;
rCH_CFG &= ~CH_SW_RST;
//CAN_Delay(100);
DebugPrint("[<<<CS Invalid>>>]\n");
g_bCSValid = FALSE;
}
ClearPending(1 << (pSpiInfo->dwSPIINTNo-0x20));
rINTMSK &= ~(((DWORD)0x1)<<(pSpiInfo->dwSPIINTNo-0x20));//取消屏蔽
}
4.调试过程
a.当Packet_Count_reg(Ch0)= 1<<16 | (1)时,发送数据时只能发送1个字节的数据,其余数据在FIFO中发布出去。这个问题比较奇怪,不知道是我的SPI配置有问题还是S3C2416的bug?还望有知道的童鞋解释解释。
- S3C2416 SPI中断方式实现
- S3C2416 按键驱动 --中断方式
- S3C2416 TIMER 中断的使用
- 【已实现】stm32 SPI DMA中断收发
- s3c2416启动方式
- 关于 s3c2416 hspi spi linux 驱动
- s3c2416 SPI芯片是否有BUG?
- Samsung s3c6410/s3c2416 的SPI接口调试
- Samsung s3c6410/s3c2416 的SPI接口调试
- spi测试自发自收(中断通信方式)
- 【stm32f407】外部中断实现按键中断方式
- KL25_中断方式实现_ADC
- 串口中断方式实现FIFO
- Future方式中断线程实现
- S3C2416睡眠的底层实现
- ucos 中断 sprinf SPI
- 中断方式实现发送数据串口驱动
- 中断方式串口发送实现思路
- Linux查看CPU和内存使用情况
- Nginx负载均衡
- 程序“[3296] yuv_disp.exe: 本机”已退出,返回值为 -1 (0xffffffff)。 求解 谢谢 各位高手
- 麻省理工学院(MIT)研究生学习指导—— 怎样做研究生(中)
- imagebutton设置透明度
- S3C2416 SPI中断方式实现
- test
- rsync服务器配置
- ln实现文件夹的重定向
- df
- 编译时去掉msvcr100
- Oracle如何在亿级记录表中创建索引
- form data enctype
- 自定义控件集合属性的设计时支持