Part Number:AM5718Other Parts Discussed in Thread:SYSBIOS
TI的工程师,你好。
我在使用MCSPI的时候遇到了这样一个问题,在Task中使用MCSPI_transfer没有任何问题(EDMA传输),但是在Hwi或者定时器中断回调函数中调用时就无法运行了,值得注意的是,中断回调函数是可以在正常情况下使用的,运行错误日志如下:
[t=0x02abab8e] ti.sysbios.knl.Semaphore: ERROR: line 289: assertion failure: A_badContext: bad calling context. Must be called from a Task.
[ 0.058] ti.sysbios.knl.Semaphore: line 289: assertion failure: A_badContext: bad calling context. Must be called from a Task.
[ 0.058] xdc.runtime.Error.raise: terminating execution
初始化参数配置如下:
MCSPI_Handle tMcpi;
MCSPI_Params tMcSpiParams;
MCSPI_Params_init(&tMcSpiParams);
tMcSpiParams.frameFormat = SPI_POL0_PHA0;
tMcSpiParams.transferTimeout = 0xffff;
tMcSpiParams.bitRate = MCSPI_OUT_FREQ;
tMcSpiParams.dataSize = 8;
tMcSpiParams.mode = SPI_MASTER;
tMcSpiParams.transferCallbackFxn = NULL;//atCbFxn[tInstance];
tMcSpiParams.transferMode = SPI_MODE_CALLBACK;
tMcpi = MCSPI_open(tInstance, tInstance, &tMcSpiParams);
传输参数配置如下:
SPI_Transaction tTransaction;
tTransaction.status = SPI_TRANSFER_STARTED;
tTransaction.count = 20;
tTransaction.txBuf = &tmptxbuff[0];
tTransaction.rxBuf = &tmprxbuff[0];
MCSPI_transfer(tMcpi, &tTransaction);
而我查看了MCSPI_transfer的使用说明,有这样一句描述:
In SPI_MODE_CALLBACK, MCSPI_transfer() does not block task execution and calls a MCSPI_CallbackFxn. This makes the MCSPI_tranfer() safe to be used within a Task, Swi, or Hwi context. The SPI_Transaction structure must stay persistent until the MCSPI_transfer function has completed!
可是MCSPI_transfer函数为什么不能在回调函数中使用呢?
Nancy Wang:
hongyou lu 说:ti.sysbios.knl.Semaphore: ERROR: line 289: assertion failure: A_badContext: bad calling context. Must be called from a Task.
先看一下提示中的报错,是否有用到Semaphore
另外如何在HWI的回调函数中使用的?
,
hongyou lu:
感谢回复!
1、我在HWI中断回调函数中只调用了MCSPI_transfer(),当transferCallbackFxn 不为空时,EDMA回调函数中只有一个system_printf();我研究了一下MCSPI_transfer函数内部实现,看到下层调用MCSPI_transfer_v1时调用了SPI_osalPendLock(object->mutex,SemaphoreP_WAIT_FOREVER),也就是说,只要我调用了MCSPI_transfer函数,就一定会用到Semaphore,那这样就说明API说明有误了。
2、Hwi中断函数中的内容如下:
SPI_Transaction tTransaction;tTransaction.status = SPI_TRANSFER_STARTED;tTransaction.count = 20;tTransaction.txBuf = &tmptxbuff[0];tTransaction.rxBuf = &tmprxbuff[0];MCSPI_transfer(tMcpi, &tTransaction);
问题:
1、能否实现在中断中使用SPI传输?
2、如果不能在中断中使用SPI传输,那么如何才能实现高频率触发SPI传输?
,
Nancy Wang:
我在英文论坛看到一个类似的帖子,您可以在英文论坛发帖吗?建议到英文论坛咨询一下产品线专家。
e2e.ti.com/…/am3358-cannot-call-spi_transfer-in-hwi-context
,
hongyou lu:
谢谢你的回复,Nancy。
我看了这个帖子,但修改TI的源代码并不是好的解决办法,另外,我不能在英文论坛上发帖。
并且,我还测试了在一个没有延时的任务中调用MCSPI_transfer函数,并且在传输结束后控制IO口翻转,结果示波器测试出IO口翻转频率仅仅只有4khz左右,而SPI的频率为48Mhz,当我屏蔽掉这个函数后,仅仅只做IO口翻转,测试出的IO口翻转频率为600khz-1300khz左右,说明MCSPI_transfer的延时很大;
1、那么是不是无法做到高频率(100khz-200khz)触发SPI传输?
2、这样的话是不是在中断回调函数中调用就不太合理了?