Sending SSC sync data via PDC

Discussion around product based on ARM Cortex M3 core.

Moderators: nferre, ncollot

crwper
Posts: 19
Joined: Thu Oct 25, 2012 3:55 am

Sending SSC sync data via PDC

Sun Dec 07, 2014 2:45 am

I've been able to initialize SSC and send both regular and sync data using direct commands like this:

Code: Select all

ssc_write_sync_data(DAC_SSC_PTR, i++); // Right channel
ssc_write(DAC_SSC_PTR, 0x0000);        // Left channel
I have also been able to send regular data using the PDC. I initialize the PDC after initializing SSC as usual, like this:

Code: Select all

pdc_packet_t packet;
	
// Configure and enable interrupt of SSC
NVIC_EnableIRQ(DAC_IRQ);

// Enable PDC transfers
pdc_enable_transfer(DAC_PDC, PERIPH_PTCR_TXTEN);

// Initialize read/write counters
dac_tx_top = DAC_BUF_SIZE;
dac_tx_ptr = 0;

// Fill buffer
dac_fill_buffer();

// Initialize PDC data packet for transfer
packet.ul_addr = (uint32_t) dac_tx_buffer;
packet.ul_size = DAC_BUF_SIZE;
pdc_tx_init(DAC_PDC, &packet, &packet);

// Enable transmit interrupt
ssc_enable_interrupt(DAC_SSC_PTR, SSC_IER_ENDTX);
I then handle the ENDTX interrupt like this:

Code: Select all

void SSC_Handler(void)
{
	uint32_t status;
	pdc_packet_t packet;
	
	status = ssc_get_status(DAC_SSC_PTR);
	if (status & SSC_SR_ENDTX)
	{
		// Increment write counter
		dac_tx_top += DAC_BUF_SIZE;
		
		// Fill buffer
		dac_fill_buffer();
		
		// Set up next packet
		packet.ul_addr = (uint32_t) dac_tx_buffer;
		packet.ul_size = DAC_BUF_SIZE;
		pdc_tx_init(DAC_PDC, NULL, &packet);
	}
}
Here is the code used to fill the buffer:

Code: Select all

// PDC transfer buffer
static uint16_t dac_tx_buffer[DAC_BUF_SIZE];

static void dac_fill_buffer(void)
{
	static uint16_t i = 0, j;

	for (j = 0; j < DAC_BUF_SIZE; ++j)
	{
		dac_tx_buffer[j] = i++;
	}
}
Pretty simple stuff. This gives the following result on my logic analyzer:

Image

As you can see, the buffer is being sent on Channel 2, which is the regular data. The sync data is completely empty.

The question is: Can I use the PDC to send both regular and sync data?

Thanks for your help!

Michael
crwper
Posts: 19
Joined: Thu Oct 25, 2012 3:55 am

Re: Sending SSC sync data via PDC

Sun Dec 07, 2014 2:48 am

In case it's helpful, here is how I initialize the SSC:

Code: Select all

clock_opt_t      tx_clk_option;
data_frame_opt_t tx_data_frame_option;

// Enable DAC master clock
pmc_switch_pck_to_pllack(DAC_PCK_ID, DAC_PCK_PRES);
pmc_enable_pck(DAC_PCK_ID);

// Configure SSC
pmc_enable_periph_clk(DAC_SSC_ID);
ssc_set_clock_divider(DAC_SSC_PTR, DAC_RATE * DAC_BITS * 2, sysclk_get_cpu_hz());

tx_clk_option.ul_cks              = SSC_TCMR_CKS_MCK;
tx_clk_option.ul_cko              = SSC_TCMR_CKO_CONTINUOUS;
tx_clk_option.ul_cki              = 0;
tx_clk_option.ul_ckg              = SSC_TCMR_CKG_NONE;
tx_clk_option.ul_period           = DAC_BITS - 1;
tx_clk_option.ul_sttdly           = DAC_BITS;
tx_clk_option.ul_start_sel        = SSC_TCMR_START_RF_RISING;

tx_data_frame_option.ul_datlen    = DAC_BITS - 1;
tx_data_frame_option.ul_msbf      = SSC_TFMR_MSBF;
tx_data_frame_option.ul_datnb     = 0;
tx_data_frame_option.ul_fslen     = DAC_BITS - 1;
tx_data_frame_option.ul_fslen_ext = 0;
tx_data_frame_option.ul_fsos      = SSC_TFMR_FSOS_POSITIVE;
tx_data_frame_option.ul_fsedge    = SSC_TFMR_FSEDGE_POSITIVE;

ssc_set_td_default_level(DAC_SSC_PTR, 0);
ssc_set_transmitter(DAC_SSC_PTR, &tx_clk_option, &tx_data_frame_option);

ssc_enable_tx_frame_sync_data(DAC_SSC_PTR);
ssc_enable_tx(DAC_SSC_PTR);
As you can see, I am enabling frame sync data, but I'm not sure how to get this to work with the PDC.

Thanks again!

Michael

Return to “SAM3 Cortex-M3 MCU”

Who is online

Users browsing this forum: Google [Bot] and 1 guest