SAM C21 Xplained Pro
#define CONF_PWM_MODULE LED_0_PWM4CTRL_MODULE
#define CONF_PWM_CHANNEL LED_0_PWM4CTRL_CHANNEL
#define CONF_PWM_OUTPUT LED_0_PWM4CTRL_OUTPUT
#define CONF_PWM_OUT_PIN LED_0_PWM4CTRL_PIN
#define CONF_PWM_OUT_MUX LED_0_PWM4CTRL_MUX
#define CONF_TCC_CAPTURE_CHANNEL 1
#define CONF_TCC_EVENT_GENERATOR EVSYS_ID_GEN_TCC0_MCX_0
#define CONF_TCC_EVENT_USER EVSYS_ID_USER_TCC0_MC_1
#define CONF_COMPARE_TRIGGER TCC0_DMAC_ID_OVF
Add to the main application source file, outside of any functions: uint16_t capture_values[3] = {0, 0, 0};
struct dma_resource capture_dma_resource;
COMPILER_ALIGNED(16) DmacDescriptor capture_dma_descriptor SECTION_DMAC_DESCRIPTOR;
uint16_t compare_values[3] = {
(0x1000 / 4), (0x1000 * 2 / 4), (0x1000 * 3 / 4)
};
struct dma_resource compare_dma_resource;
COMPILER_ALIGNED(16) DmacDescriptor compare_dma_descriptor SECTION_DMAC_DESCRIPTOR;
Copy-paste the following setup code to your user application: static void config_event_for_capture(void)
{
config.generator = CONF_TCC_EVENT_GENERATOR;
}
static void config_dma_for_capture(void)
{
struct dma_resource_config config;
dma_get_config_defaults(&config);
config.trigger_action = DMA_TRIGGER_ACTION_BEAT;
config.peripheral_trigger = CONF_CAPTURE_TRIGGER;
dma_allocate(&capture_dma_resource, &config);
struct dma_descriptor_config descriptor_config;
dma_descriptor_get_config_defaults(&descriptor_config);
descriptor_config.block_transfer_count = 3;
descriptor_config.beat_size = DMA_BEAT_SIZE_HWORD;
descriptor_config.step_selection = DMA_STEPSEL_SRC;
descriptor_config.src_increment_enable = false;
descriptor_config.source_address =
(uint32_t)&CONF_PWM_MODULE->CC[CONF_TCC_CAPTURE_CHANNEL];
descriptor_config.destination_address =
(uint32_t)capture_values + sizeof(capture_values);
dma_descriptor_create(&capture_dma_descriptor, &descriptor_config);
dma_add_descriptor(&capture_dma_resource, &capture_dma_descriptor);
dma_add_descriptor(&capture_dma_resource, &capture_dma_descriptor);
dma_start_transfer_job(&capture_dma_resource);
}
static void config_dma_for_wave(void)
{
struct dma_resource_config config;
dma_get_config_defaults(&config);
config.trigger_action = DMA_TRIGGER_ACTION_BEAT;
config.peripheral_trigger = CONF_COMPARE_TRIGGER;
dma_allocate(&compare_dma_resource, &config);
struct dma_descriptor_config descriptor_config;
dma_descriptor_get_config_defaults(&descriptor_config);
descriptor_config.block_transfer_count = 3;
descriptor_config.beat_size = DMA_BEAT_SIZE_HWORD;
descriptor_config.dst_increment_enable = false;
descriptor_config.source_address =
(uint32_t)compare_values + sizeof(compare_values);
#if (SAMR21) || (SAMD21) || (SAMDA1) || (SAMHA1)
descriptor_config.destination_address =
(uint32_t)&CONF_PWM_MODULE->CC[CONF_PWM_CHANNEL];
#else
descriptor_config.destination_address =
(uint32_t)&CONF_PWM_MODULE->CCBUF[CONF_PWM_CHANNEL];
#endif
dma_descriptor_create(&compare_dma_descriptor, &descriptor_config);
dma_add_descriptor(&compare_dma_resource, &compare_dma_descriptor);
dma_add_descriptor(&compare_dma_resource, &compare_dma_descriptor);
dma_start_transfer_job(&compare_dma_resource);
}
static void configure_tcc(void)
{
config_tcc.counter.period = 0x1000;
config_tcc.compare.channel_function[CONF_TCC_CAPTURE_CHANNEL] =
config_tcc.compare.match[CONF_PWM_CHANNEL] = compare_values[2];
config_tcc.pins.enable_wave_out_pin[CONF_PWM_OUTPUT] = true;
config_tcc.pins.wave_out_pin[CONF_PWM_OUTPUT] = CONF_PWM_OUT_PIN;
config_tcc.pins.wave_out_pin_mux[CONF_PWM_OUTPUT] = CONF_PWM_OUT_MUX;
tcc_init(&tcc_instance, CONF_PWM_MODULE, &config_tcc);
.input_config[1].modify_action = false,
.output_config.modify_generation_selection = false,
.generate_event_on_channel[CONF_PWM_CHANNEL] = true,
.on_event_perform_channel_action[CONF_TCC_CAPTURE_CHANNEL] = true
};
config_event_for_capture();
config_dma_for_capture();
config_dma_for_wave();
}
Add to user application initialization (typically the start of main()
):