I just set a few breakpoints to asm("nop") instructions.
However, I changed the code, so that PDB is directly triggering DMA15, which then sets the ADC SC1A register. The ADC is set to software trigger mode. DMA14 should then read the value of ADC´s RA register as soon as the CoCo bit is set.
So far DMA15 seems to do its job and I can the the SC1A register updated properly, but the ADC does not start the conversion. I set the ADC interrupt, but it is never triggered, because the ADC does not finish any conversion.
//---PDB--------------------------------------------------------------------------------------------
#define PDB_MOD_VALUE 32000 // counter running at 48MHz = 667us -> 1.5kHz
#define PDB_DLY_VALUE ( PDB_MOD_VALUE )
// pdb runs off BUS clock frequency
void config_pdb( void )
{
SIM_SCGC6 |= SIM_SCGC6_PDB_MASK ; // enable PDB clock
PDB0_SC = 0
| PDB_SC_LDMOD( 0 ) // registers updated when PDB counter reaches MOD or trigger event
| PDB_SC_PRESCALER( 0 ) // highest speed
| PDB_SC_TRGSEL( 15 ) // select software trigger
| PDB_SC_PDBEN_MASK // enable the PDB
| PDB_SC_MULT( 0 ) // highest speed
| PDB_SC_CONT_MASK // continuous mode
| PDB_SC_DMAEN_MASK;
PDB0_MOD = PDB_MOD_MOD( PDB_MOD_VALUE ); // counter resets at this value
PDB0_CH0C1 = 0
| PDB_C1_EN( 0 ) // channel 0, pre-trigger/trigger 0 enable (ADC0)
| PDB_C1_TOS( 0 ); // channel 0, pre_trigger/trigger 0 delayed (not bypassed)
PDB0_CH0DLY0 = PDB_DLY_DLY( PDB_DLY_VALUE ); // delay = 666uS
PDB0_SC |= PDB_SC_LDOK_MASK; // load registers with written values
}
void pdb_trigger( void )
{
PDB0_SC |= PDB_SC_SWTRIG_MASK; // software trigger
}
//----DMA-------------------------------------------------------------------------------------------
#define DMA_SIZE_8BIT 0
#define DMA_SIZE_16BIT 1
#define AD_LOOP_LEN 1
#define RAM_BUF_LEN 511
#define CH1 0x5A // 26
#define CH2 0x5B // 27
#define CH3 0x5D // 29
static volatile uint16_t adc_result_buffer[ RAM_BUF_LEN ] = { 0 }; // SRAM buffer
static const uint8_t sram_adc_conf[3] = { CH1,
CH2,
CH3 };
void configDMA( void )
{
SIM_SCGC7 |= SIM_SCGC7_DMA_MASK; // enable DMA clock
SIM_SCGC6 |= SIM_SCGC6_DMAMUX_MASK ; // enable DMAMUX clocking
// DMA channel 15 --> selects ADC input channel
DMA_CSR( 15 ) &= ~DMA_CSR_DONE_MASK;
DMA_SADDR( 15 ) = DMA_SADDR_SADDR( (uint32_t)&sram_adc_conf[ 0 ] );
DMA_DADDR( 15 ) = DMA_DADDR_DADDR( &ADC0_SC1A );
DMA_SOFF( 15 ) = 0x01;
DMA_DOFF( 15 ) = 0x00;
DMA_ATTR( 15 ) = 0
| DMA_ATTR_SSIZE( DMA_SIZE_8BIT )
| DMA_ATTR_DSIZE( DMA_SIZE_8BIT );
DMA_NBYTES_MLNO( 15 ) = 0x01;
DMA_CITER_ELINKNO( 15 ) = 0
| 0x03; // 3 channels
DMA_SLAST( 15 ) = DMA_SLAST_SLAST( -3 );
DMA_DLAST_SGA( 15 ) = 0;
DMA_CSR( 15 ) = 0;
DMA_BITER_ELINKNO( 15 ) = 0
| 0x03;
// DMA channel 14 --> gets triggered by CoCo of ADC and writes result to array
DMA_CSR( 14 ) &= ~DMA_CSR_DONE_MASK;
DMA_SADDR( 14 ) = (uint32_t)&ADC0_RA;
DMA_DADDR( 14 ) = DMA_DADDR_DADDR( &adc_result_buffer[ 0 ] );
DMA_SOFF( 14 ) = 0x00;
DMA_DOFF( 14 ) = 0x02;
DMA_ATTR( 14 ) = 0
| DMA_ATTR_SSIZE( DMA_SIZE_16BIT )
| DMA_ATTR_DSIZE( DMA_SIZE_16BIT );
DMA_NBYTES_MLNO( 14 ) = 0x02;
DMA_CITER_ELINKNO( 14 ) = 0
| 0x01;
DMA_SLAST( 14 ) = 0;
DMA_DLAST_SGA( 14 ) = 0;
DMA_CSR( 14 ) = 0;
DMA_BITER_ELINKNO( 14 ) = 0
| 0x01;
DMAMUX_CHCFG15 = DMAMUX_CHCFG14 = 0;
DMAMUX_CHCFG15 = 0
| DMAMUX_CHCFG_ENBL_MASK // enable DMA channel
| DMAMUX_CHCFG_SOURCE( 58 ); // PDB
DMAMUX_CHCFG14 = 0
| DMAMUX_CHCFG_ENBL_MASK // enable DMA channel
| DMAMUX_CHCFG_SOURCE( 40 ); // ADC0
DMA_ERQ = 0
| DMA_ERQ_ERQ15_MASK // enable DMA on hardware service request
| DMA_ERQ_ERQ14_MASK;
}
//----ADC-------------------------------------------------------------------------------------------------------------------------------
void config_adc( void )
{
ADC1_SC1A = 0
| 0x1F; // ADC1 module disabled
SIM_SCGC6 |= SIM_SCGC6_ADC0_MASK; // enable ADC0 clock
ADC0_CFG1 = 0
| ADC_CFG1_ADIV( 3 ) // CLK / 8 = 96MHz / 8 = 12MHz
| ADC_CFG1_ADLSMP_MASK // long sample time
| ADC_CFG1_MODE( 3 ) // 16bit conversion
| ADC_CFG1_ADICLK( 3 ), // Asynchronous clock
ADC0_CFG2 = 0
| ADC_CFG2_ADLSTS( 0 ); // default longest sample time
ADC0_SC2 = 0
| ADC_SC2_REFSEL( 0 ) // default voltage reference
| ADC_SC2_DMAEN_MASK; // DMA enabled
ADC0_SC2 &= ~ADC_SC2_ADTRG_MASK;
ADC0_SC3 = 0;
}
//----Init()-------------------------------------------------------------------------------------------------------------------------------
int ADC_DMA_PDB_init( void )
{
config_adc();
configDMA();
config_pdb();
pdb_trigger();
return 0;
}