Is cpu_irq_save required when setting up the pdca(dma)

Go To Last Post
4 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi,

i noticed that the ASF function "pdca_init_channel" calls this  two functions cpu_irq_save and cpu_irq_restore.

They just save and disable the interrupts but what bad could happen if a interrupt interrupts while setting up the registers of the pdca. Is this actually needed?

 

uint32_t pdca_init_channel(uint8_t pdca_ch_number,
		const pdca_channel_options_t *opt)
{
	/* get the correct channel pointer */
	volatile avr32_pdca_channel_t *pdca_channel = pdca_get_handler(
			pdca_ch_number);

	pdca_disable_interrupt_transfer_complete(pdca_ch_number);
	pdca_disable_interrupt_reload_counter_zero(pdca_ch_number);

	irqflags_t flags = cpu_irq_save();

	pdca_channel->mar = (uint32_t)opt->addr;
	pdca_channel->tcr = opt->size;
	pdca_channel->psr = opt->pid;
	pdca_channel->marr = (uint32_t)opt->r_addr;
	pdca_channel->tcrr = opt->r_size;
	pdca_channel->mr =
#if (AVR32_PDCA_H_VERSION >= 120)
			opt->etrig << AVR32_PDCA_ETRIG_OFFSET |
#endif
			opt->transfer_size << AVR32_PDCA_SIZE_OFFSET;
	pdca_channel->cr = AVR32_PDCA_ECLR_MASK;
	pdca_channel->isr;

	cpu_irq_restore(flags);

	return PDCA_SUCCESS;
}

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It's just common sense to disable interrupts when configuring any peripheral as you don't want it to go off half clocked. In fact the usual thing is to leave interrupts off until all peripherals are configured. But if done in a modular fashion where you cannot know where in the sequence a particular peripheral might be initialized then the best you can do is switch off then on for each one. So I'm guessing you'll find this modular library probably follows the same pattern for all peripherals.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
go off half clocked

I saw what you did there. laugh

Letting the smoke out since 1978

 

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Im still not sure if I understand this correctly. If I init the pdca(dma) for example I assume it is disabled and only after the init I would set the enable bit in the control register. So i should not go off half clocked or am I missing something?

Same for the pwm_init it would only make sense to disable the interrupt when the pwm is enabled right? So as long I disable all modules before configuren them I would be fine?

int pwm_init(const pwm_opt_t *opt)
{
  volatile avr32_pwm_t *pwm = &AVR32_PWM;
  bool global_interrupt_enabled = Is_global_interrupt_enabled();

  if (opt == 0 ) // Null pointer.
    return PWM_INVALID_INPUT;

  // Disable interrupt.
  if (global_interrupt_enabled) Disable_global_interrupt();
  pwm->idr = ((1 << (AVR32_PWM_LINES_MSB + 1)) - 1) << AVR32_PWM_IDR_CHID0_OFFSET;
  pwm->isr;
  if (global_interrupt_enabled) Enable_global_interrupt();