SSC configure with DMA in at32uc3a

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

I have application for receiving data from master ARM device through dma controller and SSC controller in at32uc3a0512 with atmel studio6. I got guidance from this site http://www.ultimaserial.com/avr_lwip_tips3.html and i configured my device as follows,

1. data size = 16bit,
2. clock received at receiver clock pin(external sclk),
3. channel length =32,
4. data reception starts, when reception of rising RX-frame sync,

For above format, i configure my device as shown below:

#define SSC_DATA_BITS		16	//Bits
#define SSC_FRAME_BITS		16  //Bits
#define SSC_DATA_NO_FRAME	16  //Word
#define SSC_PERIOD_SIZE		256 //Bits
#define PDCA_TRANS_COUNT	32

volatile avr32_ssc_t *ssc = &AVR32_SSC
ssc->rcmr = (AVR32_SSC_RCMR_CKS_RK_PIN				<< AVR32_SSC_RCMR_CKS_OFFSET |
				AVR32_SSC_RCMR_CKO_INPUT_ONLY			<< AVR32_SSC_RCMR_CKO_OFFSET |
				0										<< AVR32_SSC_RCMR_CKI_OFFSET |
				AVR32_SSC_RCMR_CKG_NONE					<< AVR32_SSC_RCMR_CKG_OFFSET |
				AVR32_SSC_RCMR_START_DETECT_RISING_RF  	<< AVR32_SSC_RCMR_START_OFFSET |
				0										<< AVR32_SSC_RCMR_STOP_OFFSET |
				0										<< AVR32_SSC_RCMR_STTDLY_OFFSET |
				0										<< AVR32_SSC_RCMR_PERIOD_OFFSET );
										  
	ssc->rfmr = ((SSC_DATA_BITS - 1)					<< AVR32_SSC_RFMR_DATLEN_OFFSET |
				 0										<< AVR32_SSC_RFMR_MSBF_OFFSET |

(SSC_DATA_NO_FRAME - 1)				
                                << AVR32_SSC_RFMR_DATNB_OFFSET | 
				 0										<< AVR32_SSC_RFMR_FSLEN_OFFSET |
				 AVR32_SSC_RFMR_FSOS_INPUT_ONLY			<< AVR32_SSC_RFMR_FSOS_OFFSET |
				 0										<< AVR32_SSC_RFMR_FSEDGE_OFFSET |
				 0										<< AVR32_SSC_RFMR_FSLENHI_OFFSET);

ssc->cr = AVR32_SSC_CR_RXEN_MASK | AVR32_SSC_CR_TXDIS_MASK;

//pdca config
Disable_global_interrupt();
	pdca_channel_options_t ssc_dma =
	{
		.addr = (void *) dma_buf,
		.size = PDCA_TRANS_COUNT,
		.r_addr = NULL,
		.r_size = 0,
		.pid = SSC_RX_PID,
		.transfer_size = PDCA_TRANSFER_SIZE_HALF_WORD
	};
	
	pdca_init_channel(PDCA_SSC_CHANNEL, &ssc_dma);
	INTC_init_interrupts();
	INTC_register_interrupt(dma_ssc_rxdata, PDCA_INT_NO, AVR32_INTC_INT1);
	Enable_global_interrupt();

//Starts the dma transfer
void ssc_io()
{
	pdca_enable_interrupt_transfer_complete(PDCA_SSC_CHANNEL);
	volatile avr32_pdca_channel_t* get_rx = pdca_get_handler(PDCA_SSC_CHANNEL);
	get_rx->cr = AVR32_PDCA_TEN_MASK;
	while(!(ssc->sr & AVR32_SSC_SR_RXSYN_MASK));
	while(!(get_rx->isr & AVR32_PDCA_ISR_TRC_MASK));
	pdca_load_channel(PDCA_SSC_CHANNEL, &dma_buf, PDCA_TRANS_COUNT);
}

//interrupt handler for dma controller 
__attribute__ ((_interrupt_)) void dma_ssc_rxdata()
{
	int16_t i;
	Disable_global_interrupt();
	i = pdca_get_channel_status(PDCA_SSC_CHANNEL);
	if(i)
	print_dbg("\n\rtransfer enabled");
	pdca_disable_interrupt_transfer_complete(PDCA_SSC_CHANNEL);
	for(i=0;i<512;i++);
	pdca_disable(PDCA_SSC_CHANNEL);		
	for(i=0; i

When i calling ssc_io(); function it waits to detect receive frame sync, if it receives frame sync it enables the dma transfer for receiving data. As soon as transfer complete interrupt occur it stops a transfer and displays the received data's.

The actual problem is received data is only FF. i don't know where to correct my config, please anyone tell me rectifying this problem.