完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
[解决方案] 2011/2018:问题不存在如所描述的那样。DMA传输未暂停。由于逻辑分析仪的错误触发器,我看了一个错误的数据传输。]用逻辑分析仪查看我的PIC的两个不同SPI外设的信号,我惊讶地看到,我的DMA SPI传输(写入512个字节到闪存)被CN(IOC)中断/暂停。中断服务例程,它访问另一个SPI外围设备。只需注意:传输和中断工作得很好,这只是我想优化的时机。在我看来,DMA传输的想法是在没有MPU的情况下工作(使用SPI重复的连续模式),所以我没有想到MPU中断对DMA传输有影响。它。我的意图是,DMA传输应该继续而不是等待另一个(无关的)中断。虽然我有一个模糊的理解,DMA SPI传输确实依赖于内部的中断逻辑,但我还没有找到文档中的细节的解释,尤其是我如何才能解释。观察到的行为。我必须注意中断优先级还是应该继续搜索哪个方向…这里是一些背景信息。前4个频道显示了512字节DMA SPI传输(SPI 2)的摘录,它被CN中断(底部4通道)打断。CN中断例程读取来自另一SPI外围设备(SPI 1)的数据的七个16位字,即在最后4个通道中看到的数据传输也反映中断的长度。在中断退出时,DMA继续工作。在ButtoMod中看到的图像是中断功能。这是对DMA SPI传输的SPI 2的一次初始化,这是一个函数,它实际上对512字节的附加信息进行DMA传输:嵌套中断被启用(而不是DI)。中断优先级是所有4(这是复位后的默认值,例如,πSPI2TXIP,πSPI2IP)(设置为3,对于SPI2不改变行为)在这个PIC的中断向量表中。CN中断位于γ-SPI2中断和γ-SPI2TX中断之前,即“自然优先级”F。或CN高于SPI2(第8.1章FRM)
以上来自于百度翻译 以下为原文 ["solution" 11.Jan.2018: the problem does not exist as described. The DMA transfer is NOT paused. Due to wrong trigger for the Logic Analyzer, I looked at a wrong data transfer.] Looking at the signals of two different SPI peripherals of my PIC with a logic analyzer, I was a bit astonished to see that my DMA SPI transfer (writing 512 bytes into a flash memory) is interrupted/paused by a CN (IOC) interrupt service routine, which accesses another SPI peripheral. Just to note: the transfers and interrupts work perfectly,- it's just the timing which I would like to optimize. In my mind the idea of a DMA transfer is to work without the MPU (using SPI repeated continous mode), so I did not expect an MPU interrupt to have influence on the DMA transfer, by delaying it. My intention is that the DMA transfer should continue and not wait for another (unrelated) interrupt. While I have a vague understanding that the DMA SPI transfer DOES depend on interrupt logic internally, I did not yet find an explanation of the details in the documentation, especially how can I change the observed behaviour. Do I have to pay attention to interrupt priorities or in which direction should I continue to search ... Here is some background information The top 4 channels shows an excerpt of the 512 byte DMA SPI transfer (SPI 2), which is interrupted by a CN interrupt (bottom 4 channels). The CN interrupt routine reads seven 16-bit words of data from another SPI peripheral (SPI 1), i.e. the data transfer seen in the last 4 channels also reflects the length of the interrupt. On exit of interrupt, the DMA continues to work. See image at bottom This is the interrupt function void __attribute__((interrupt, auto_psv)) _CNInterrupt(void) { if (_IOCFB10) { spiReadData16(ICM_ACCEL_XOUT_H, (WORD *) dataICM.iData, ICM_DATA_COUNT); bIcmDataReady = 1; _IOCFB10 = 0; } _CNIF = 0; // clear interrupt flag } This is some one-time initialization of SPI #2 for the DMA SPI transfer SPI2CON1bits.MODE16 = 0; // byte mode SPI2CON1bits.MSTEN = 1; //SPI Master SPI2CON1bits.CKP = 0; // Idle state for clock is a low level SPI2CON1bits.CKE = 1; SPI2CON1bits.ENHBUF = 0; SPI2STATLbits.SPIROV = 0; // clear the Receive overflow flag SPI2BRGLbits.BRG = 0; SPI2CON1bits.MCLKEN = 0; // SPIEN enabled; DISSDO disabled; MCLKEN FOSC/2; CKP Idle:Low, Active:High; // SSEN disabled;MSTEN Master; MODE16 disabled; SMP Middle; DISSCK disabled; // SPIFE Frame Sync pulse precedes;CKE Idle to Active; MODE32 disabled; // SPISIDL disabled; ENHBUF enabled; DISSDI disabled; SPI2CON1Hbits.IGNROV = 1; SPI2CON1Lbits.SPIEN = 1; // enable SPI2 peripheral and this is the function which actually does DMA transfers of 512 bytes static void dmaWrite(BYTE *pBuf, WORD wCount, WORD wMode) { DMACON = 0x0001; // DMACONbits.DMAEN = 0; DMAH= DMA_UPPER_LIMIT; DMAL= 0x0000; // CHEN enabled; DAMODE Unchanged; TRMODE One-Shot; CHREQ disabled; // RELOAD disabled; SIZE 8 bit; NULLW disabled; SAMODE Incremented; // HALFIF disabled; LOWIF disabled; HALFEN disabled; DONEIF disabled; // OVRUNIF disabled; CHSEL SPI2 Event; HIGHIF disabled; DMACH0 = 0; // SPI "repeated continous mode" DMACH0bits.TRMODE=0; // Transfer mode DMACH0bits.SAMODE=1; // Source address increment mode DMACH0bits.DAMODE=0; // dest DMACH0bits.SIZE=1; // byte DMACH0bits.NULLW=0; // null write disable DMAINT0= 0x00; IFS0bits.DMA0IF = false; _DMA0IE = 1; // enable interrupt // for CHSEL see FRM Table 5-1 DMAINT0bits.CHSEL = DMA_TRIG_SRC_SPI2_TRANSMIT; //Trig on SPI2 TX DMASRC0= (WORD) pBuf; DMADST0= (unsigned int)&SPI2BUFL; DMACNT0= wCount; _SPI2TXIF = 0; SPI2IMSKLbits.SPITBEN = 1; // interrupt if tx empty // Clearing Channel 0 Interrupt Flag; IFS0bits.DMA0IF = 0; //Enable DMA DMACONbits.DMAEN = 1; //Enable DMA Channel 0 DMACH0bits.CHEN = 1; DMACH0bits.CHREQ = 1; // note, actually the end of the DMA transfer is signalled end handled // by a DMA interrupt, not shown here } Additional information: Nested interrupts are enabled (not disabled) Interrupt priorities are all 4 (which is the default after reset, e.g. _SPI2TXIP, _SPI2IP) (setting them to 3 for SPI2 does not change the behaviour) In the interrupt vectors table for this PIC the CNInterrupt comes BEFORE the __SPI2Interrupt and __SPI2TXInterrupt, i.e. the 'natural priority' for CN is higher than for SPI2 (chapter 8.1 FRM) Attached Image(s) |
|
相关推荐
9个回答
|
|
我不认为CN中断对DMA传输有任何直接影响。但是在中断例程中,您调用SPICADATA1616()来从SPI1传输一些数据。这将暂停DMA,因为SPI1和SPI2寄存器通过相同的数据总线访问,并且CPU访问总是优先于DMA。如果修改代码,也可以使用DMA从SPI1读取数据(原因是使用另一个DMA通道)。然后,您可以使用固定的DMA优先级来提供SPI2比SPI1更高的优先级,然后SPI2传输将不间断地运行。如果有足够的时间,SPI1数据将在SPI2数据之间传输。否则SPI1数据将在SPI2传输结束后被转移。您还可以使用循环DMA优先级,然后两个传输将以“并行”方式运行。如果CPU/DMA速度不够高,SPI2传输速率可能会下降,而SPI1传输是活跃的。另一种方法是优化SpReDATA16()。例如,如果代码连续轮询SPI1寄存器,以检查数据是否可用,这也将使用DMA数据总线,并且暂停SPI2 DMA传输。因此,在SpReDATA16()程序中的一些NOP可以允许SPI2 DMA传输继续。最好的问候,Michael Brinks。
以上来自于百度翻译 以下为原文 I don't think the CN interrupt has any direct influence on the DMA transfer. However in the interrupt routine you call spiReadData16() to transfer some data from SPI1. This will pause the DMA because SPI1 and SPI2 registers are accessed through the same data bus, and CPU access always takes priority over DMA. If you modify your code to also use DMA for reading data from SPI1 (of cause using another DMA channel). Then you can use fixed DMA priority to give SPI2 higher preference than SPI1, the SPI2 transfer will then run uninterrupted. The SPI1 data will be transferred in between the SPI2 data, if there is time enough. Otherwise the SPI1 data will be transferred after the SPI2 transfer ends. You can also use round robin DMA priority, then the two transfers will run in "parallel". If the CPU/DMA speed isn't high enough, the SPI2 transfer rate may drop, while the SPI1 transfer is active. An other approach is to optimize spiReadData16(). E.g. if the code continuously polls a SPI1 register, to check if data is available, this will also use the DMA data bus, and pause SPI2 DMA transfers. So a few nops in the spiReadData16() routine could allow the SPI2 DMA transfer to continue. Best regards, Michael Brinks |
|
|
|
谢谢你的提示,我想我明白你的意思了。为了验证,我简单地注释了SPIDEL16函数,然后添加了一些虚拟延迟。因此,不再有SPI 1访问(也被逻辑分析器验证):DMA SPI 2的“暂停”仍然具有CN中断的长度,现在由被添加的延迟环路“主宰”。因此,即使您的想法是正确的,似乎也不是“暂停”DMA SPI传输的主要原因。
以上来自于百度翻译 以下为原文 Thanks for the tip, I think I got your idea. So for verification I simply commented out the spiRead16 function and then added some dummy delay. Thus there is no SPI#1 access any more (also verified with Logic Analyzer) Result: the DMA SPI#2 "pause" still has the length of the CN interrupt, now "dominated" by the added delay loop. So even if your idea is correct, it seems not to be the primary reason for the 'paused' DMA SPI transfer. void __attribute__((interrupt, auto_psv)) _CNInterrupt(void) { if (_IOCFB10) { // spiReadData16(ICM_ACCEL_XOUT_H, (WORD *) dataICM.iData, ICM_DATA_COUNT); volatile int k; for (k=0;k<250;++k) ; // approx. 100 us, just to make interrupt call longer bIcmDataReady = 1; _IOCFB10 = 0; } _CNIF = 0; // clear interrupt flag } |
|
|
|
不相信米迦勒的论点。我同意CPU在访问内存时优先于DMA,但只有当它们同时尝试访问相同的SFR(在这种情况下)时!SPI读缓冲器的实际CPU读取需要一个指令周期,但DMA看起来要比它长很多,事实上,在另一个SPI外围设备上的完全交换,包括删除和提高Cs的行,作为一个主,需要由固件来完成。我怀疑我们需要看到(经常被请求和神秘的)“短而完整的代码示例”,它展示了这个问题。有东西告诉我,其他事情正在发生……RodiMs——查看你所提供的图像,你说ISR会导致7个16位的值被交换,但是(并且我承认在这张图片中不是很清楚),看起来这7个交换前面有一个短的E。Xchange或垃圾或某种类型的,这可能是重要的吗?也许我们需要看看你调用的函数是什么?苏珊
以上来自于百度翻译 以下为原文 Not convinced by Michael's argument. I agree that the CPU has priority over the DMA for accessing memory but only when they both try to access the same SFR (in this case) at the same time! The actual CPU read of the SPI read buffer would take one instruction cycle but the DMA seems to be held up for a lot longer than that - in fact the complete exchange on the other SPI peripheral including the dropping and raising of the CS line which, as a master, needs to be done by the firmware. I suspect that we need to see the (oft requested and mythical) "short but complete code example" that exhibits the problem. Something tells me that something else is happening to cause this.... Rodims - looking at the image you have provided, you said that the ISR causes 7 16-bit values to be exchanged, but (and I admit it is not very clear in that picture) it would appear that the 7 exchanges are preceded by a shorter exchange/garbage or some sort - could that be significant? Perhaps we need to see what is in the function you call? Susan |
|
|
|
你有PIC港口双端口RAM,是你的缓冲区吗?
以上来自于百度翻译 以下为原文 Does you pic haven dual port ram and is your buffer there? |
|
|
|
在你的照片上没有100%确定…但我看不太正确。如果“02 CLK”频道显示8个时钟(一个字节,或者16个字)的“突发”,那么它就不能正常运行。如果传输512字节,则应该有512×8(4096)连续时钟,没有任何停顿。即使通过中断例程驱动“遗留”SPI,它也有一个字节/字缓冲区。所以可以创建一个恒定的时钟。一个字节等待一个被发送。PIC24具有增强的SPI,它允许通过中断(较少中断)写入字节/字块,从而产生恒定时钟。DMA将不断地给SPI缓冲器供电。没有停顿。即使存在内存冲突(1时钟周期),也不会有SPI时钟延迟,因为DMA是给缓冲器而不是输出。T Yorky
以上来自于百度翻译 以下为原文 Not 100% sure on your picture... but it doesn't look right to me. If the '02 CLK' channel is showing 'bursts' of 8 clocks (for a byte, or 16 for words) then that is not operating correctly. If you a transferring 512 bytes there should be 512 x 8 (4096) continuous clocks without any pauses. Even driving the 'legacy' SPI by interrupt routine it has a single byte/word buffer. So can create a constant clock. One byte waiting while one being transmitted. The PIC24 has the enhanced SPI which allows a block of bytes/words to be written by interrupt (less interrupts), creating a constant clock. DMA will feed the SPI buffer constantly. No pauses. Even if there is a memory conflict (1 clock cycle) there will be no SPI clock delay as the DMA is feeding the buffer not the output. T Yorky |
|
|
|
提醒:所有SPI传输(一个DMA,另一个DMA)工作完美,做他们应该做的事情。我的“问题”只是我正在放松DMA性能,因为DMA SPI传输在某种程度上被我的CN中断“暂停”。该剪辑不是为了显示SPI传输的细节,而是为了显示中断ISR的长度必须与DMA传输中暂停的长度直接相关。你看到的是一个字节的SPI“写入”到奴隶命令寄存器,接着是7个16位“读取”。请注意在迈克尔斯提示之后,我已经删除了使用第二个SPI的中断中的调用。(请参阅POST第3版中的代码更新),这仍然显示了在服务中断的CN中断期间,DMA SPI传输被暂停的相同问题,因此目前两个SPI之间没有干扰,并且记住,所有的工作都是按它的方式工作的,它只是“暂停”的DMA TRAN。SfER,这对我来说是出乎意料的。不,PIC24F GB4家族没有这个2KB双端口RAM。我的缓冲区在16 kb的RAM中,在DMA传输期间,512字节缓冲区也不应该被CPU访问/写入,-我使用双缓冲。该剪辑只显示了512字节传输被中断的位置的时间(这将发生一次以上,因为M)。Y中断发生在1千赫)。它只演示了中断时间和DMA SPI传输的“暂停”之间的相关性。因为我已经删除了POST×3中的SPILADATA16函数调用(也显示了完整的中断代码),但是问题仍然存在,这不能是两个SPI之间的冲突。SPI DMA不是为了增强SPI而初始化的,也不想使用增强模式,也因为性能原因,它引起了我很多的头痛,但是这是一个不同的和更老的帖子。对于暂停的SPI DMA操作没有变化。我仍然觉得它与DMA SPI的内部操作有关,这似乎是基于中断逻辑(不谈论ISRs)。
以上来自于百度翻译 以下为原文 As reminder: all the SPI transfers (one with DMA, the other one without) work perfectly and do what they should do. My "problem" simply is that I'm loosing DMA performance, because the DMA SPI transfer is somehow "paused" by my CN interrupt. The clip was not intended to show details of the SPI transfer, but to show that the lenght of the interrupt ISR must correlate directly to the length of the pause in the DMA transfer. What you see is a one byte SPI "Write" to the slaves command register, followed by 7 16-bit "reads". Please note that after Michaels tip I already removed the call within the interrupt which uses the second SPI. (See my code update in post #3.) This still shows the same problem that during the time of the CN interrupt beeing serviced, the DMA SPI transfer is paused. So for the moment there is NO interference between the two SPIs, and remember, everything works as it it should, its only the 'paused' DMA transfer which looks unexpected for me. No, the PIC24F GB4 family does not have this 2kb dual ported RAM. My buffer is somewhere in the 16 kB RAM And the 512 byte buffer should also not be accessed / written by the CPU during DMA transfer,- I use double buffering. The clip only shows some time around the location where the 512 byte transfer is interrupted ( which will happen more than one time, because my interrupt occurs at 1 kHz ). It should only demonstrate the correlation between interrupt time and the "pausing" of the DMA SPI transfer. Since I already removed the spiReadData16 function call in post #3 (which also shows the complete interrupt code), but the problem persists, this cannot be a conflict between the two SPIs . The SPI DMA is not initialized for Enhanced SPI SPI2CON1bits.ENHBUF = 0; I don't want to use enhanced mode also for performance reasons, it caused me a lot of headache, but that's a different and older post. [edit: I just switched to enhanced mode for a short test. No change regarding the paused SPI DMA operation] I still have the impression it has to do with the internal operation of DMA SPI, which seems to be based on interrupt logic (not talking about ISRs) // for CHSEL see FRM Table 5-1 DMAINT0bits.CHSEL = DMA_TRIG_SRC_SPI2_TRANSMIT; //Trigger on SPI2 Transmit ... _SPI2TXIF = 0; SPI2IMSKLbits.SPITBEN = 1; // interrupt if tx empty |
|
|
|
这个问题是解决的,或者是更正确的:这个问题并不像描述的那样存在。我总是触发错误的事件,它也显示了512字节的SPI传输,但是那个简单地没有DMA,所以当然它会被中断。T Yorky p让我在正确的方向,因为实际上,SPI DMA写的时钟应该是连续的配置。我没有意识到我的错误,因为我的DMA SPI确实读取了字节之间的空白(我无法摆脱),但这是另一个故事和论坛帖子。谢谢你的想法。
以上来自于百度翻译 以下为原文 Mea culpa, the bug was sitting in front of my PC. The problem is solved, or to be more correct: the problem does not exist as described. I always triggered to the wrong event which also shows a 512 byte SPI transfer, but that one simply was without DMA, so of course then it gets interrupted. T Yorky pushed me in the right direction, because indeed the clock for SPI DMA Write should be continous for my configuration. I did not realize my fault, because my DMA SPI Reads indeed do have exactly these gaps between bytes (which I could not get rid of), but that's another story and forum post. Thanks for all your ideas. |
|
|
|
苏珊是真的吗?在PIC32上,内部总线共享CPU,DMA共享总线。所以只有一个可以一次访问RAM。PC24是否不同?PIC24HJ具有双端口RAM,他说这不是。
以上来自于百度翻译 以下为原文 Susan is that true? on The PIC32 the Internal Bus is shared The CPU and the DMA share the Bus. so only one can access RAM at a time. Is the PC24 different? The PIC24HJ has dual port RAM, he says this one does not. |
|
|
|
“PIC24HJ具有双端口RAM,他说这一点没有PIC24的许多不同的味道。没有黄金规则…FJ1024可以(在文档中,但没有测试)在底部64K的任何地方做内存到内存DMA(不确定这是否包括可能附加的任何外部RAM)。
以上来自于百度翻译 以下为原文 "The PIC24HJ has dual port RAM, he says this one does not" So many different 'flavours' of PIC24. No golden rules... FJ1024 can (in documentation but not tested) do memory to memory DMA anywhere in the bottom 64K (not sure if this includes any external RAM that may be attached). |
|
|
|
只有小组成员才能发言,加入小组>>
5370 浏览 9 评论
2100 浏览 8 评论
2004 浏览 10 评论
请问是否能把一个ADC值转换成两个字节用来设置PWM占空比?
3277 浏览 3 评论
请问电源和晶体值之间有什么关系吗?PIC在正常条件下运行4MHz需要多少电压?
2312 浏览 5 评论
879浏览 1评论
768浏览 1评论
有偿咨询,关于MPLAB X IPE烧录PIC32MX所遇到的问题
706浏览 1评论
PIC Kit3出现目标设备ID(00000000)与预期的设备ID(02c20000)不匹配。是什么原因
764浏览 0评论
653浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-3-6 03:55 , Processed in 1.180710 second(s), Total 59, Slave 54 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191