Missing DMA interrupt?

1 post / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi, All!

I tried to use 3 DMA channels simultaneously:
- CH0 for read data from port (PLD);
- CH1 for write data to USI in SPI mode (SD-card);
- CH2 for read data from USI is SPI mode (SD-card).

I use interrupt for process end of transactions. When I use only CH0 it works fine. When I use only CH1/CH2 it works fine too. When CH0 and CH1/CH2 is used synchronuosly -- it works fine. But if interrupt from CH0 arrived when transaction CH1/CH2 is in progress, then interrupt from CH1/CH2 will missed.

Can anyone say anything about this? Did anyone faced with similar?

OS_ISR( DMA_CH2_vect )
{
	extern unsigned char SD_USI_thread;

	DMA.CH2.CTRLB = DMA_CH_TRNIF_bm;
	DMA.INTFLAGS = DMA_CH2TRNIF_bm;

	Thread_Activate( SD_USI_thread );
} // DMA_CH2_vect



OS_ISR( DMA_CH0_vect )
{
	DMA.CH0.CTRLB = DMA_CH_TRNIF_bm;
	DMA.INTFLAGS = DMA_CH0TRNIF_bm;

	// move ring pointer
	extern unsigned char * addr;
	extern unsigned char raw_data_ring[];

	if ( addr == raw_data_ring )
		addr = RAW_RING_END;
	addr -= sizeof( matrix_data_t );

	Semaphore_Up( RAW_TEL_Semaphore );
} // DMA_CH0_vect


OS_ISR( PORTD_INT0_vect )
{
	extern unsigned char * addr;

	DMA.CH0.CTRLA = DMA_CH_ENABLE_bm | DMA_CH_BURSTLEN_1BYTE_gc;
	DMA.CH0.ADDRCTRL = DMA_CH_SRCRELOAD_NONE_gc | DMA_CH_SRCDIR_INC_gc
		| DMA_CH_DESTRELOAD_NONE_gc | DMA_CH_DESTDIR_INC_gc;

	DMA.CH0.TRFCNT = sizeof( matrix_data_t );
	DMA.CH0.REPCNT = 1;
	DMA.CH0.SRCADDR0 = (unsigned char)(PLM_START);
	DMA.CH0.SRCADDR1 = (unsigned char)(PLM_START >> 8);
	DMA.CH0.SRCADDR2 = (unsigned char)(PLM_START >> 16);
	DMA.CH0.DESTADDR0 = (unsigned char)(addr);
	DMA.CH0.DESTADDR1 = (unsigned char)(addr >> 8);
	DMA.CH0.DESTADDR2 = 0;

	DMA.CH0.CTRLB = DMA_CH_TRNIF_bm
		| DMA_CH_ERRINTLVL_OFF_gc | DMA_CH_TRNINTLVL_MED_gc;

	DMA.CH0.CTRLA = DMA_CH_ENABLE_bm | DMA_CH_BURSTLEN_1BYTE_gc
		| DMA_CH_TRFREQ_bm;
} // PORTD_INT0_vect

Ilya