/** * \brief Set up a USART in SPI master mode device. * * The returned device descriptor structure must be passed to the driver * whenever that device should be used as current slave device. * * \param p_usart Base address of the USART instance. * \param device Pointer to usart device struct that should be initialized. * \param flags USART configuration flags. Common flags for all * implementations are the usart modes, which should be SPI_MODE_0, * SPI_MODE_1, SPI_MODE_2, SPI_MODE_3. * \param baud_rate Baud rate for communication with slave device in Hz. * \param sel_id Board specific select id. */ void usart_spi_setup_device(Usart *p_usart, struct usart_spi_device *device, spi_flags_t flags, unsigned long baud_rate, board_spi_select_id_t sel_id) { usart_spi_opt_t opt; /* avoid Cppcheck Warning */ UNUSED(device); UNUSED(sel_id); /* Basic usart SPI configuration. */ opt.baudrate = baud_rate; opt.char_length = US_MR_CHRL_8_BIT; opt.spi_mode = flags; opt.channel_mode = US_MR_CHMODE_NORMAL; /* Initialize the USART module as SPI master. */ #if (SAM4L) usart_init_spi_master(p_usart, &opt, sysclk_get_pba_hz()); #else usart_init_spi_master(p_usart, &opt, sysclk_get_peripheral_hz()); #endif usart_enable_rx(p_usart); usart_enable_tx(p_usart); }
/** * \brief Retrieves the current rate in Hz of the Peripheral Bus clock attached * to the specified peripheral. * * \param module Pointer to the module's base address. * * \return Frequency of the bus attached to the specified peripheral, in Hz. */ uint32_t sysclk_get_peripheral_bus_hz(const volatile void *module) { /* Fallthroughs intended for modules sharing the same peripheral bus. */ switch ((uintptr_t)module) { case IISC_ADDR: case SPI_ADDR: case TC0_ADDR: case TC1_ADDR: case TWIM0_ADDR: case TWIS0_ADDR: case TWIM1_ADDR: case TWIS1_ADDR: case USART0_ADDR: case USART1_ADDR: case USART2_ADDR: case USART3_ADDR: case ADCIFE_ADDR: case DACC_ADDR: case ACIFC_ADDR: case GLOC_ADDR: case ABDACB_ADDR: case TRNG_ADDR: case PARC_ADDR: case CATB_ADDR: case TWIM2_ADDR: case TWIM3_ADDR: #if !SAM4LS case LCDCA_ADDR: #endif return sysclk_get_pba_hz(); case HFLASHC_ADDR: case HCACHE_ADDR: case HMATRIX_ADDR: case PDCA_ADDR: case CRCCU_ADDR: case USBC_ADDR: case PEVC_ADDR: return sysclk_get_pbb_hz(); case PM_ADDR: case CHIPID_ADDR: case SCIF_ADDR: case FREQM_ADDR: case GPIO_ADDR: return sysclk_get_pbc_hz(); case BPM_ADDR: case BSCIF_ADDR: case AST_ADDR: case WDT_ADDR: case EIC_ADDR: case PICOUART_ADDR: return sysclk_get_pbd_hz(); default: Assert(false); return 0; } }
/** * \brief Test Synchronous clock * * This test enables source clock for main clock, sets CPU/HSB, * PBA,PBB,PBC(if have), PBD(if have) division factor, and then check * if the chip is set correctly. * * \note It's not easy to measure CPU/HSB,PBA... frequency, even through * some chips have freqm module. Using external module may cause some * reliability issue. Since synchronous clocks share the common root * main clock, they only need set division factor. So we just test * the related registers if set correctly after calling common clock * service. * * \param test Current test case. */ static void run_sync_clock_test(const struct test_case *test) { bool status; /* avoid Cppcheck Warning */ UNUSED(status); sysclk_init(); //PBA clock set, usart can be used usart_ready = 1; #ifdef CONFIG_CPU_HZ status = (CONFIG_CPU_HZ == sysclk_get_cpu_hz()); test_assert_true(test, status, "CPU clock set fail"); #endif #ifdef CONFIG_PBA_HZ status = (CONFIG_PBA_HZ == sysclk_get_pba_hz()); test_assert_true(test, status, "PBA clock set fail"); #endif #ifdef CONFIG_PBB_HZ status = (CONFIG_PBB_HZ == sysclk_get_pbb_hz()); test_assert_true(test, status, "PBB clock set fail"); #endif #ifdef CONFIG_PBC_HZ status = (CONFIG_PBC_HZ == sysclk_get_pbc_hz()); test_assert_true(test, status, "PBC clock set fail"); #endif #ifdef CONFIG_PBD_HZ status = (CONFIG_PBD_HZ == sysclk_get_pbd_hz()); test_assert_true(test, status, "PBD clock set fail"); #endif }
extern void init_spi (void) { sysclk_enable_pba_module(SYSCLK_SPI); static const gpio_map_t SPI_GPIO_MAP = { {SPI_SCK_PIN, SPI_SCK_FUNCTION }, {SPI_MISO_PIN, SPI_MISO_FUNCTION}, {SPI_MOSI_PIN, SPI_MOSI_FUNCTION}, {SPI_NPCS0_PIN, SPI_NPCS0_FUNCTION }, {SPI_NPCS1_PIN, SPI_NPCS1_FUNCTION }, }; // Assign GPIO to SPI. gpio_enable_module(SPI_GPIO_MAP, sizeof(SPI_GPIO_MAP) / sizeof(SPI_GPIO_MAP[0])); spi_options_t spiOptions = { .reg = DAC_SPI, .baudrate = 4000000, .bits = 8, .trans_delay = 0, .spck_delay = 0, .stay_act = 1, .spi_mode = 1, .modfdis = 1 }; // Initialize as master. spi_initMaster(SPI, &spiOptions); // Set SPI selection mode: variable_ps, pcs_decode, delay. spi_selectionMode(SPI, 0, 0, 0); // Enable SPI module. spi_enable(SPI); // spi_setupChipReg( SPI, &spiOptions, FPBA_HZ ); spi_setupChipReg(SPI, &spiOptions, sysclk_get_pba_hz() ); // add ADC chip register spiOptions.reg = ADC_SPI; spiOptions.baudrate = 20000000; spiOptions.bits = 16; spiOptions.spi_mode = 2; spiOptions.spck_delay = 0; spiOptions.trans_delay = 5; spiOptions.stay_act = 0; spiOptions.modfdis = 0; spi_setupChipReg( SPI, &spiOptions, FPBA_HZ ); // spi_enable(SPI); }
/** * Enable direct to serial * @param enable * @param baud */ void da2sEnable(char enable, uint32_t baud) { uint32_t div; if (enable) { if (!da2sEnabled) { disableUsartAndDma(); if (baud == 0) baud = BAUD_DEFAULT; } if (baud) { div = (sysclk_get_pba_hz() + (baud * (16 / 8) / 2)) / (baud * (16 / 8)); USART_DA2S.brgr = ((div >> 3) << AVR32_USART_BRGR_CD) | ((div & 7) << AVR32_USART_BRGR_FP); } if (!da2sEnabled) { da2s.rx.tail = 0; da2s.tx.head = 0; da2s.tx.queuedTail = 0; da2sEnabled = 1; USART_DA2S.mr = (AVR32_USART_MR_OVER_X16 << AVR32_USART_MR_OVER) | (AVR32_USART_MR_MSBF_LSBF << AVR32_USART_MR_MSBF) | (AVR32_USART_MR_CHMODE_NORMAL << AVR32_USART_MR_CHMODE) | (AVR32_USART_MR_NBSTOP_1 << AVR32_USART_MR_NBSTOP) | (AVR32_USART_MR_PAR_NONE << AVR32_USART_MR_PAR) | (AVR32_USART_MR_CHRL_8 << AVR32_USART_MR_CHRL) | (AVR32_USART_MR_USCLKS_MCK << AVR32_USART_MR_USCLKS) | (AVR32_USART_MR_MODE_NORMAL << AVR32_USART_MR_MODE); INTC_register_interrupt(&rxDMA, AVR32_PDCA_IRQ_2, AVR32_INTC_INT3); INTC_register_interrupt(&txDMA, AVR32_PDCA_IRQ_1, AVR32_INTC_INT2); DMA_USART_DA2S_TX.mar = (uint32_t) &da2s.tx.buffer[0]; DMA_USART_DA2S_RX.mar = (uint32_t) &da2s.rx.buffer[0]; DMA_USART_DA2S_TX.psr = AVR32_PDCA_PID_USART1_TX; DMA_USART_DA2S_RX.psr = AVR32_PDCA_PID_USART1_RX; DMA_USART_DA2S_TX.mr = AVR32_PDCA_MR_SIZE_BYTE << AVR32_PDCA_MR_SIZE_OFFSET; DMA_USART_DA2S_RX.mr = AVR32_PDCA_MR_SIZE_BYTE << AVR32_PDCA_MR_SIZE_OFFSET; DMA_USART_DA2S_TX.cr = AVR32_PDCA_CR_TEN_MASK; DMA_USART_DA2S_RX.cr = AVR32_PDCA_CR_TEN_MASK; DMA_USART_DA2S_RX.ier = AVR32_PDCA_IER_RCZ_MASK; USART_DA2S.cr = AVR32_USART_CR_RXEN_MASK | AVR32_USART_CR_TXEN_MASK; } } else if (da2sEnabled) {
/** * Configure TWI * @param config */ void twiConfig(const twiConfigT *config) { uint32_t divisor; uint8_t prescale; if (config->master != twi.modeMaster) twiReset(); if (config->freq) { divisor = (sysclk_get_pba_hz() + 2 * config->freq - 1) / (2 * config->freq); if (divisor > 4) { divisor -= 4; } else { divisor = 0; } prescale = 0; while (divisor > 0xff && prescale <= 7) { divisor = (divisor + 1) >> 1; prescale++; } if (divisor <= 0xff && prescale <= 7) { AVR32_TWI.cwgr = (divisor << AVR32_TWI_CWGR_CLDIV_OFFSET) | (divisor << AVR32_TWI_CWGR_CHDIV_OFFSET) | ((uint32_t) prescale << AVR32_TWI_CWGR_CKDIV_OFFSET); } }
/** * \brief Initialize ADC driver to read the board temperature sensor. * * Initializes the board's ADC driver module and configures the ADC channel * connected to the onboard NTC temperature sensor ready for conversions. */ static void init_adc(void) { // Assign and enable GPIO pin to the ADC function. gpio_enable_module_pin(ADC_TEMPERATURE_PIN, ADC_TEMPERATURE_FUNCTION); const adcifb_opt_t adcifb_opt = { .resolution = AVR32_ADCIFB_ACR_RES_12BIT, .shtim = 15, .ratio_clkadcifb_clkadc = 2, .startup = 3, .sleep_mode_enable = false }; // Enable and configure the ADCIFB module sysclk_enable_peripheral_clock(&AVR32_ADCIFB); adcifb_configure(&AVR32_ADCIFB, &adcifb_opt); // Configure the trigger (No trigger, only software trigger) adcifb_configure_trigger(&AVR32_ADCIFB, AVR32_ADCIFB_TRGMOD_NT, 0); // Enable the ADCIFB channel to NTC temperature sensor adcifb_channels_enable(&AVR32_ADCIFB, ADC_TEMPERATURE_CHANNEL); } /** * \brief Initializes the USART. * * Initializes the board USART ready for serial data to be transmitted and * received. */ static void init_usart(void) { const usart_options_t usart_options = { .baudrate = 57600, .charlength = 8, .paritytype = USART_NO_PARITY, .stopbits = USART_1_STOPBIT, .channelmode = USART_NORMAL_CHMODE }; // Initialize USART in RS232 mode with the requested settings. sysclk_enable_peripheral_clock(USART); usart_init_rs232(USART, &usart_options, sysclk_get_pba_hz()); } /** * \brief Initializes the PWM subsystem ready to generate the RGB LED PWM * waves. * * Initializes the on-chip PWM module and configures the RGB LED PWM outputs so * the the brightness of the three individual channels can be adjusted. */ static void init_pwm(void) { // GPIO pin/function map for the RGB LEDs. gpio_enable_module_pin(LED_RED_PWMA, LED_PWMA_FUNCTION); gpio_enable_module_pin(LED_GREEN_PWMA, LED_PWMA_FUNCTION); gpio_enable_module_pin(LED_BLUE_PWMA, LED_PWMA_FUNCTION); const scif_gclk_opt_t genclk3_opt = { .clock_source = SCIF_GCCTRL_CPUCLOCK, .divider = 8, .diven = true, }; // Start generic clock 3 for the PWM outputs. scif_start_gclk(AVR32_PM_GCLK_GCLK3, &genclk3_opt); // Enable RGB LED PWM. sysclk_enable_peripheral_clock(&AVR32_PWMA); pwma_config_enable(&AVR32_PWMA,EXAMPLE_PWMA_FREQUENCY,EXAMPLE_PWMA_GCLK_FREQUENCY,0); pwma_set_channels_value(&AVR32_PWMA,PWM_CHANNEL_RED | PWM_CHANNEL_BLUE| PWM_CHANNEL_GREEN,255); } /** * \brief Application main loop. */ int main(void) { board_init(); sysclk_init(); sysclk_enable_peripheral_clock(USART); // Initialize touch, ADC, USART and PWM init_adc(); init_usart(); init_pwm(); init_touch(); while (true) { uint32_t adc_data; // Read slider and button and update RGB led touch_handler(); // Wait until the ADC is ready to perform a conversion. do { } while (!adcifb_is_ready(&AVR32_ADCIFB)); // Start an ADCIFB conversion sequence. adcifb_start_conversion_sequence(&AVR32_ADCIFB); // Wait until the converted data is available. do { } while (!adcifb_is_drdy(&AVR32_ADCIFB)); // Get the last converted data. adc_data = (adcifb_get_last_data(&AVR32_ADCIFB) & 0x3FF); // Write temperature data to USART do { } while (!usart_tx_empty(USART)); usart_write_char(USART, (adc_data >> 8)); do { } while (!usart_tx_empty(USART)); usart_write_char(USART, (adc_data & 0xFF)); } }
/** * \brief Initializes the ADCIFB module with trigger * - Initialize the trigger mode & compare interrupts for ADCIFB * * \retval STATUS_OK Configuration OK * \retval ERR_TIMEOUT Timeout on configuring ADCIFB module * \retval ERR_BUSY ADCIFB module unable to configure the trigger */ static status_code_t adc_init() { /* GPIO pin/adc - function map. */ static const gpio_map_t ADCIFB_GPIO_MAP = { {EXAMPLE_ADCIFB_PIN, EXAMPLE_ADCIFB_FUNCTION} }; /* ADCIFB Configuration */ adcifb_opt_t adcifb_opt = { /* Resolution mode */ .resolution = AVR32_ADCIFB_ACR_RES_10BIT, /* Channels Sample & Hold Time in [0,15] */ .shtim = ADC_SAMPLE_HOLD_TIME, /* ADC Clock Prescaler */ .ratio_clkadcifb_clkadc = (sysclk_get_pba_hz()) / ADC_FREQUENCY, .startup = ADC_STARTUP_TIME, /* ADCIFB Sleep Mode enabled */ .sleep_mode_enable = true }; /* Disable pull up on ADCIFB channel input pin */ gpio_disable_pin_pull_up(EXAMPLE_ADCIFB_PIN); /* Enable the ADC pins */ gpio_enable_module(ADCIFB_GPIO_MAP, sizeof(ADCIFB_GPIO_MAP) / sizeof(ADCIFB_GPIO_MAP[0])); /* Enable ADCIFB clock */ sysclk_enable_pba_module(SYSCLK_ADCIFB); /* Configure the ADCIFB peripheral */ if (adcifb_configure(adcifb, &adcifb_opt)) { /* Error configuring the ADCIFB */ return ERR_TIMEOUT; } /* Configure the trigger for ADCIFB peripheral */ if (adcifb_configure_trigger(adcifb, AVR32_ADCIFB_TRGR_TRGMOD_EVT, 0)) { /* Error configuring the trigger for ADCIFB */ return ERR_BUSY; } /* Enable ADCIFB Channel 0 */ adcifb_channels_enable(adcifb, EXAMPLE_ADCIFB_CHANNEL); /* Disable global interrupts */ cpu_irq_disable(); /* * Initialize the interrupt vectors * Note: This function adds nothing for IAR as the interrupts are * handled by the IAR compiler itself. It provides an abstraction * between GCC & IAR compiler to use interrupts. * Refer function implementation in interrupt_avr32.h */ irq_initialize_vectors(); /* * Register the ADCIFB interrupt handler * Note: This function adds nothing for IAR as the interrupts are * handled by the IAR compiler itself. It provides an abstraction * between GCC & IAR compiler to use interrupts. * Refer function implementation in interrupt_avr32.h */ irq_register_handler(&ADCIFB_interrupt_handler, AVR32_ADCIFB_IRQ, ADC_INTERRUPT_PRIORITY); /* * Set the threshold value in CVR.LV register to generate interrupt * when the value detected is above the threshold. * 1.500 V with 10-bit resolution */ adcifb_set_high_compare_value(adcifb, ADC_COMPARE_VALUE); /* Enable the Analog Compare option in ADCIFB */ adcifb_enable_analog_compare_mode(adcifb); /* Enable the data ready interrupt for ADCIFB */ adcifb_enable_compare_gt_interrupt(adcifb); return STATUS_OK; } /* End of adc_init() */ /** * \brief Asynchronous Timer Initialization * - Start the 32KHz Oscillator * - Initializes the AST module with periodic trigger events * * \retval STATUS_OK Configuration OK * \retval ERR_TIMEOUT Error in configuring the AST module */ static status_code_t ast_init() { /* Initial Count value to write in AST */ unsigned long ast_counter = 0; /* Set the prescaler to set a periodic trigger from AST */ avr32_ast_pir0_t pir = { .insel = AST_TRIGGER_PRESCALER }; /* Set the OSC32 parameters */ scif_osc32_opt_t osc32_opt = { .mode = SCIF_OSC_MODE_2PIN_CRYSTAL_HICUR, .startup = OSC32_STARTUP_8192, .pinsel = BOARD_OSC32_PINSEL, .en1k = false, .en32k = true }; /* Enable the 32KHz Oscillator */ scif_start_osc32(&osc32_opt, true); /* Enable the Peripheral Event System Clock */ sysclk_enable_hsb_module(SYSCLK_EVENT); /* Enable PBA clock for AST clock to switch its source */ sysclk_enable_pba_module(SYSCLK_AST); /* Initialize the AST in counter mode */ if (!ast_init_counter(&AVR32_AST, AST_CLOCK_SOURCE, AST_PRESCALER, ast_counter)) { return ERR_TIMEOUT; } /* Initialize the periodic value register with the prescaler */ ast_set_periodic0_value(&AVR32_AST, pir); /* Enable the AST periodic event */ ast_enable_periodic0(&AVR32_AST); /* Clear All AST Interrupt request and clear SR */ ast_clear_all_status_flags(&AVR32_AST); /* Enable the AST */ ast_enable(&AVR32_AST); /* Disable PBA clock for AST after switching its source to OSC32 */ sysclk_disable_pba_module(SYSCLK_AST); return STATUS_OK; } /* End of ast_init() */ /** * \brief Low Power Configuration * Initializes the power saving measures to reduce power consumption * - Enable pullups on GPIO pins * - Disable the clocks to unused modules * - Disable internal voltage regulator when in 1.8V supply mode */ static void power_save_measures_init() { uint8_t i; uint32_t gpio_mask[AVR32_GPIO_PORT_LENGTH] = {0}; /* * Enable internal pull-ups on all unused GPIO pins * Note: Pull-ups on Oscillator or JTAG pins can be enabled only if they * are not used as an oscillator or JTAG pin respectively. */ for (i = 0; i < (sizeof(gpio_used_pins) / sizeof(uint32_t)); i++) { gpio_mask[gpio_used_pins[i] >> 5] |= 1 << (gpio_used_pins[i] & 0x1F); } for (i = 0; i < AVR32_GPIO_PORT_LENGTH; i++) { gpio_configure_group(i, ~(gpio_mask[i]), GPIO_PULL_UP | GPIO_DIR_INPUT); } /* Disable OCD clock which is not disabled by sysclk service */ sysclk_disable_cpu_module(SYSCLK_OCD); #if POWER_SUPPLY_MODE_1_8V /* * When using 1.8V Single supply mode, the Voltage Regulator can be * shut-down using the code below, in-order to save power. * See Voltage Regulator Calibration Register in datasheet for more *info. * CAUTION: When using 3.3V Single supply mode, the Voltage Regulator * cannot be shut-down and the application will hang in this loop. */ uint32_t tmp = (AVR32_SCIF.vregcr); tmp &= (~(1 << 5 | 1 << 18)); AVR32_SCIF.unlock = 0xAA000000 | AVR32_SCIF_VREGCR; AVR32_SCIF.vregcr = tmp; /* Wait until internal voltage regulator is disabled. */ while ((AVR32_SCIF.vregcr & 0x00040020)) { } #endif } /* End of power_save_measures_init() */
/** * \brief Initializes the ACIFB module with trigger * - Start the GCLK for ACIFB * - Initialize the trigger mode & compare interrupts for ACIFB * * \retval STATUS_OK Configuration OK * \retval ERR_TIMEOUT Timeout on configuring ACIFB module * \retval ERR_BUSY ACIFB module unable to configure the trigger */ static status_code_t ac_init() { /* struct genclk_config gcfg; */ uint32_t div = sysclk_get_pba_hz() / AC_GCLK_FREQUENCY; scif_gc_setup(AC_GCLK_ID, AC_GCLK_SRC, AVR32_GC_DIV_CLOCK, div); /* Now enable the generic clock */ scif_gc_enable(AC_GCLK_ID); /* GPIO pin/acifb - function map. */ static const gpio_map_t ACIFB_GPIO_MAP = { {EXAMPLE_ACIFBP_PIN, EXAMPLE_ACIFBP_FUNCTION}, {EXAMPLE_ACIFBN_PIN, EXAMPLE_ACIFBN_FUNCTION}, }; /* ACIFB Configuration */ const acifb_t acifb_opt = { .sut = 6, /* Resolution mode */ .actest = TESTMODE_OFF, .eventen = true }; /* ACIFB Channel Configuration */ const acifb_channel_t acifb_channel_opt = { /* Filter length */ .filter_len = 0, /* Hysteresis value */ .hysteresis_value = 0, /* Output event when ACOUT is zero? */ .event_negative = false, /* Output event when ACOUT is one? */ .event_positive = false, /* Set the positive input */ .positive_input = PI_ACP, /* Set the negative input */ .negative_input = NI_ACN, /* Set the comparator mode */ .mode = MODE_EVENT_TRIGGERED, /* Interrupt settings */ .interrupt_settings = IS_VINP_LT_VINN, /* Analog comparator channel number */ .ac_n = EXAMPLE_ACIFB_CHANNEL }; /* Enable Analog Comparator clock */ sysclk_enable_pba_module(SYSCLK_ACIFB); /* Disable pullup on ACIFB channel input pins */ gpio_disable_pin_pull_up(EXAMPLE_ACIFBP_PIN); gpio_disable_pin_pull_up(EXAMPLE_ACIFBN_PIN); /* Enable the ACIFB pins */ gpio_enable_module(ACIFB_GPIO_MAP, sizeof(ACIFB_GPIO_MAP) / sizeof(ACIFB_GPIO_MAP[0])); /* Configure the ACIFB peripheral */ acifb_setup_and_enable(acifb, &acifb_opt); /* Configure the ACIFB channel with interrupt & trigger */ acifb_channels_setup(acifb, &acifb_channel_opt, AC_NB_CHANNELS); /* Disable global interrupts */ cpu_irq_disable(); /* * Initialize the interrupt vectors * Note: This function adds nothing for IAR as the interrupts are * handled by the IAR compiler itself. It provides an abstraction * between GCC & IAR compiler to use interrupts. * Refer function implementation in interrupt_avr32.h */ irq_initialize_vectors(); /* * Register the ACIFB interrupt handler * Note: This function adds nothing for IAR as the interrupts are * handled by the IAR compiler itself. It provides an abstraction * between GCC & IAR compiler to use interrupts. * Refer function implementation in interrupt_avr32.h */ irq_register_handler(&ACIFB_interrupt_handler, AVR32_ACIFB_IRQ, AC_INTERRUPT_PRIORITY); /* Enable Analog Comparator Channel interrupt */ acifb_enable_comparison_interrupt(acifb, EXAMPLE_ACIFB_CHANNEL); /* Enable global interrupts */ cpu_irq_enable(); return STATUS_OK; } /* End of ac_init() */ /** * \brief Asynchronous Timer Initialization * - Start the 32KHz Oscillator * - Initializes the AST module with periodic trigger events * * \retval STATUS_OK Configuration OK * \retval ERR_BUSY Error in configuring the AST module */ static status_code_t ast_init() { /* Initial Count value to write in AST */ unsigned long ast_counter = 0; /* Set the prescaler to set a periodic trigger from AST */ avr32_ast_pir0_t pir = { .insel = AST_TRIGGER_PRESCALER }; /* Set the OSC32 parameters */ scif_osc32_opt_t osc32_opt = { .mode = SCIF_OSC_MODE_2PIN_CRYSTAL_HICUR, .startup = OSC32_STARTUP_8192, .pinsel = BOARD_OSC32_PINSEL, .en1k = false, .en32k = true }; /* Enable the 32KHz Oscillator */ scif_start_osc32(&osc32_opt, true); /* Enable the Peripheral Event System Clock */ sysclk_enable_hsb_module(SYSCLK_EVENT); /* Enable PBA clock for AST clock to switch its source */ sysclk_enable_pba_module(SYSCLK_AST); /* Initialize the AST in counter mode */ if (!ast_init_counter(&AVR32_AST, AST_CLOCK_SOURCE, AST_PRESCALER, ast_counter)) { return ERR_BUSY; } /* Initialize the periodic value register with the prescaler */ ast_set_periodic0_value(&AVR32_AST, pir); /* Enable the AST periodic event */ ast_enable_periodic0(&AVR32_AST); /* Clear All AST Interrupt request and clear SR */ ast_clear_all_status_flags(&AVR32_AST); /* Enable the AST */ ast_enable(&AVR32_AST); /* Disable PBA clock for AST after switching its source to OSC32 */ sysclk_disable_pba_module(SYSCLK_AST); return STATUS_OK; } /* End of ast_init() */ /** * \brief Low Power Configuration * Initializes the power saving measures to reduce power consumption * - Enable pull-ups on GPIO pins * - Disable the clocks to unwanted modules * - Disable internal voltage regulator when in 1.8V supply mode */ static void power_save_measures_init() { uint8_t i; uint32_t gpio_mask[AVR32_GPIO_PORT_LENGTH] = {0}; /* * Enable internal pull-ups on all unused GPIO pins * Note: Pull-ups on Oscillator or JTAG pins can be enabled only if they * are not used as an oscillator or JTAG pin respectively. */ for (i = 0; i < (sizeof(gpio_used_pins) / sizeof(uint32_t)); i++) { gpio_mask[gpio_used_pins[i] >> 5] |= 1 << (gpio_used_pins[i] & 0x1F); } for (i = 0; i < AVR32_GPIO_PORT_LENGTH; i++) { gpio_configure_group(i, ~(gpio_mask[i]), GPIO_PULL_UP | GPIO_DIR_INPUT); } /* Disable OCD clock which is not disabled by sysclk service */ sysclk_disable_cpu_module(SYSCLK_OCD); #if POWER_SUPPLY_MODE_1_8V /* * When using 1.8V Single supply mode, the Voltage Regulator can be * shut-down using the code below, in-order to save power. * See Voltage Regulator Calibration Register in datasheet for more *info. * CAUTION: When using 3.3V Single supply mode, the Voltage Regulator * cannot be shut-down and the application will hang in this loop. */ uint32_t tmp = (AVR32_SCIF.vregcr); tmp &= (~(1 << 5 | 1 << 18)); AVR32_SCIF.unlock = 0xAA000000 | AVR32_SCIF_VREGCR; AVR32_SCIF.vregcr = tmp; /* Wait until internal voltage regulator is disabled. */ while ((AVR32_SCIF.vregcr & 0x00040020)) { } #endif } /* End of power_save_measures_init() */
/** * \brief Main Application Routine * - Initialize the system clocks * - Initialize the sleep manager * - Initialize the power save measures * - Initialize the ACIFB module * - Initialize the AST to trigger ACIFB at regular intervals * - Go to STATIC sleep mode and wake up on a touch status change */ int main(void) { /* Switch on the STATUS LED */ gpio_clr_gpio_pin(STATUS_LED); /* Switch off the error LED. */ gpio_set_gpio_pin(ERROR_LED); /* * Initialize the system clock. * Note: Clock settings are specified in conf_clock.h */ sysclk_init(); /* * Initialize the sleep manager. * Note: CONFIG_SLEEPMGR_ENABLE should have been defined in conf_sleepmgr.h */ sleepmgr_init(); /* Lock required sleep mode. */ sleepmgr_lock_mode(SLEEPMGR_STATIC); /* Initialize the delay routines */ delay_init(sysclk_get_cpu_hz()); /* Initialize the power saving features */ power_save_measures_init(); /* Switch off the error LED. */ gpio_set_gpio_pin(ERROR_LED); #if DEBUG_MESSAGES /* Enable the clock to USART interface */ sysclk_enable_peripheral_clock(DBG_USART); /* Initialize the USART interface to print trace messages */ init_dbg_rs232(sysclk_get_pba_hz()); print_dbg("\r Sleepwalking with ACIFB Module in UC3L \n"); print_dbg("\r Initializing ACIFB Module..... \n"); #endif /* Initialize the Analog Comparator peripheral */ if (ac_init() != STATUS_OK) { #if DEBUG_MESSAGES /* Error initializing the ACIFB peripheral */ print_dbg("\r Error initializing Analog Comparator module \n"); #endif while (1) { delay_ms(LED_DELAY); gpio_tgl_gpio_pin(ERROR_LED); } } #if DEBUG_MESSAGES print_dbg("\r ACIFB Module initialized. \n"); print_dbg("\r Initializing AST Module..... \n"); #endif /* Initialize the AST peripheral */ if (ast_init() != STATUS_OK) { #if DEBUG_MESSAGES print_dbg("\r Error initializing AST module \n"); #endif /* Error initializing the AST peripheral */ while (1) { delay_ms(LED_DELAY); gpio_tgl_gpio_pin(ERROR_LED); } } #if DEBUG_MESSAGES print_dbg("\r AST Module initialized. \n"); #endif /* Application routine */ while (1) { /* Enable Asynchronous wake-up for ACIFB */ pm_asyn_wake_up_enable(AVR32_PM_AWEN_ACIFBWEN_MASK); #if DEBUG_MESSAGES print_dbg("\r Going to STATIC sleep mode \n"); print_dbg( "\r Wake up only when input is higher than threshold \n"); #endif /* Switch off the status LED */ gpio_set_gpio_pin(STATUS_LED); /* Disable GPIO clock before entering sleep mode */ sysclk_disable_pba_module(SYSCLK_GPIO); AVR32_INTC.ipr[0]; /* Enter STATIC sleep mode */ sleepmgr_enter_sleep(); /* Enable GPIO clock after waking from sleep mode */ sysclk_enable_pba_module(SYSCLK_GPIO); /* Switch on the status LED */ gpio_clr_gpio_pin(STATUS_LED); #if DEBUG_MESSAGES print_dbg("\r Output higher than threshold \n"); print_dbg("\n"); #else /* LED on for few ms */ delay_ms(LED_DELAY); #endif /* Clear the wake up & enable it to enter sleep mode again */ pm_asyn_wake_up_disable(AVR32_PM_AWEN_ACIFBWEN_MASK); /* Clear All AST Interrupt request and clear SR */ ast_clear_all_status_flags(&AVR32_AST); } return 0; } /* End of main() */
/** * \brief TC Initialization * * Initializes and start the TC module with the following: * - Counter in Up mode with automatic reset on RC compare match. * - fPBA/8 is used as clock source for TC * - Enables RC compare match interrupt * \param tc Base address of the TC module */ void tc_init(volatile avr32_tc_t *tc) { // Options for waveform generation. static const tc_waveform_opt_t waveform_opt = { // Channel selection. .channel = EXAMPLE_TC_CHANNEL, // Software trigger effect on TIOB. .bswtrg = TC_EVT_EFFECT_NOOP, // External event effect on TIOB. .beevt = TC_EVT_EFFECT_NOOP, // RC compare effect on TIOB. .bcpc = TC_EVT_EFFECT_NOOP, // RB compare effect on TIOB. .bcpb = TC_EVT_EFFECT_NOOP, // Software trigger effect on TIOA. .aswtrg = TC_EVT_EFFECT_NOOP, // External event effect on TIOA. .aeevt = TC_EVT_EFFECT_NOOP, // RC compare effect on TIOA. .acpc = TC_EVT_EFFECT_NOOP, /* * RA compare effect on TIOA. * (other possibilities are none, set and clear). */ .acpa = TC_EVT_EFFECT_NOOP, /* * Waveform selection: Up mode with automatic trigger(reset) * on RC compare. */ .wavsel = TC_WAVEFORM_SEL_UP_MODE_RC_TRIGGER, // External event trigger enable. .enetrg = false, // External event selection. .eevt = 0, // External event edge selection. .eevtedg = TC_SEL_NO_EDGE, // Counter disable when RC compare. .cpcdis = false, // Counter clock stopped with RC compare. .cpcstop = false, // Burst signal selection. .burst = false, // Clock inversion. .clki = false, // Internal source clock 2, connected to fPBA / 2. .tcclks = TC_CLOCK_SOURCE_TC2 }; // Options for enabling TC interrupts static const tc_interrupt_t tc_interrupt = { .etrgs = 0, .ldrbs = 0, .ldras = 0, .cpcs = 1, // Enable interrupt on RC compare alone .cpbs = 0, .cpas = 0, .lovrs = 0, .covfs = 0 }; INTC_register_interrupt(&tc_irq, EXAMPLE_TC_IRQ, EXAMPLE_TC_IRQ_PRIORITY); // Initialize the timer/counter. tc_init_waveform(tc, &waveform_opt); /* * Set the compare triggers. * We configure it to count every 1 milliseconds. * We want: (1 / (fPBA / 8)) * RC = 1 ms, hence RC = (fPBA / 8) / 1000 * to get an interrupt every 10 ms. */ tc_write_rc(tc, EXAMPLE_TC_CHANNEL, (sysclk_get_pba_hz() / 2 / IN_FORMAT_LSBYTE_SAMPLE_FREQ)); // configure the timer interrupt tc_configure_interrupts(tc, EXAMPLE_TC_CHANNEL, &tc_interrupt); // Start the timer/counter. tc_start(tc, EXAMPLE_TC_CHANNEL); }
int main(void) { sysclk_init(); int i=0; // board_init(); sysclk_enable_pba_module(SYSCLK_SPI); // spi_reset(SPI_EXAMPLE); // spi_set_master_mode(SPI_EXAMPLE); // spi_disable_modfault(SPI_EXAMPLE); // spi_disable_loopback(SPI_EXAMPLE); // spi_set_chipselect(SPI_EXAMPLE,(1 << AVR32_SPI_MR_PCS_SIZE) - 1); // spi_disable_variable_chipselect(SPI_EXAMPLE); // spi_disable_chipselect_decoding(SPI_EXAMPLE); // spi_set_delay(SPI_EXAMPLE,0); // spi_set_chipselect_delay_bct(SPI_EXAMPLE,0,0); // spi_set_chipselect_delay_bs(SPI_EXAMPLE,0,0); // spi_set_bits_per_transfer(SPI_EXAMPLE,0, 8); // spi_set_baudrate_register(SPI_EXAMPLE,0, getBaudDiv(1000000, sysclk_get_peripheral_bus_hz(SPI_EXAMPLE))); // spi_enable_active_mode(SPI_EXAMPLE,0); // spi_set_mode(SPI_EXAMPLE,0,SPI_MODE_0); static const gpio_map_t SPI_GPIO_MAP = { {AT45DBX_SPI_SCK_PIN, AT45DBX_SPI_SCK_FUNCTION }, {AT45DBX_SPI_MISO_PIN, AT45DBX_SPI_MISO_FUNCTION}, {AT45DBX_SPI_MOSI_PIN, AT45DBX_SPI_MOSI_FUNCTION}, {AT45DBX_SPI_NPCS0_PIN, AT45DBX_SPI_NPCS0_FUNCTION }, // {AT45DBX_SPI_NPCS1_PIN, AT45DBX_SPI_NPCS1_FUNCTION }, }; // Assign GPIO to SPI. gpio_enable_module(SPI_GPIO_MAP, sizeof(SPI_GPIO_MAP) / sizeof(SPI_GPIO_MAP[0])); spi_options_t spiOptions = { .reg = 0, .baudrate = 1000000, .bits = 8, .trans_delay = 0, .spck_delay = 0, .stay_act = 1, .spi_mode = 0, .modfdis = 1 }; // Initialize as master. spi_initMaster(SPI_EXAMPLE, &spiOptions); // Set SPI selection mode: variable_ps, pcs_decode, delay. spi_selectionMode(SPI_EXAMPLE, 0, 0, 0); // Enable SPI module. spi_enable(SPI_EXAMPLE); // spi_setupChipReg( SPI, &spiOptions, FPBA_HZ ); spi_setupChipReg(SPI_EXAMPLE, &spiOptions, sysclk_get_pba_hz() ); spi_enable(SPI_EXAMPLE); while (true) { i++; delay_ms(10); // status = spi_at45dbx_mem_check(); spi_selectChip(SPI_EXAMPLE,0); spi_put(SPI_EXAMPLE,i); spi_unselectChip(SPI_EXAMPLE,0); } }
/*! \brief Main function. Execution starts here. * * \retval 42 Fatal error. */ int main(void) { uint32_t iter=0; uint32_t cs2200_out_freq=11289600; static bool b_sweep_up=true; static uint32_t freq_step=0; // USART options. static usart_serial_options_t USART_SERIAL_OPTIONS = { .baudrate = USART_SERIAL_EXAMPLE_BAUDRATE, .charlength = USART_SERIAL_CHAR_LENGTH, .paritytype = USART_SERIAL_PARITY, .stopbits = USART_SERIAL_STOP_BIT }; // Initialize the TWI using the internal RCOSC init_twi(AVR32_PM_RCOSC_FREQUENCY); // Initialize the CS2200 and produce a default frequency. cs2200_setup(11289600, FOSC0); sysclk_init(); // Initialize the board. // The board-specific conf_board.h file contains the configuration of the board // initialization. board_init(); // Initialize the TWI init_twi(sysclk_get_pba_hz()); // Initialize Serial Interface using Stdio Library stdio_serial_init(USART_SERIAL_EXAMPLE,&USART_SERIAL_OPTIONS); // Initialize the HMatrix. init_hmatrix(); print_dbg("\r\nCS2200 Example\r\n"); // Generate a 12.288 MHz frequency out of the CS2200. print_dbg("Output 12.288 MHz\r\n"); cs2200_freq_clk_out(_32_BITS_RATIO(12288000, FOSC0)); cpu_delay_ms( 10000, sysclk_get_cpu_hz()); // Generate a 11.2896 MHz frequency out of the CS2200. print_dbg("Output 11.2896 MHz\r\n"); cs2200_freq_clk_out(_32_BITS_RATIO(cs2200_out_freq, FOSC0)); cpu_delay_ms( 10000, sysclk_get_cpu_hz()); print_dbg("Sweep from 11.2896 MHz steps of 100 PPM\r\n"); freq_step = PPM(cs2200_out_freq, 100); while(1) { uint32_t ratio; if(b_sweep_up) { if( iter<=10 ) { print_dbg("Add 100 PPM\r\n"); iter++; cs2200_out_freq += freq_step; ratio = _32_BITS_RATIO(cs2200_out_freq, FOSC0); cs2200_freq_clk_adjust((uint16_t)ratio); cpu_delay_ms( 1000, sysclk_get_cpu_hz()); while( twi_is_busy() ); } else b_sweep_up=false; } if(!b_sweep_up) { if( iter>0 ) { print_dbg("Sub 100 PPM\r\n"); iter--; cs2200_out_freq -= freq_step; ratio = _32_BITS_RATIO(cs2200_out_freq, FOSC0); cs2200_freq_clk_adjust((uint16_t)ratio); cpu_delay_ms( 1000, sysclk_get_cpu_hz()); while( twi_is_busy() ); } else b_sweep_up=true; } } }
/** * \brief TC Initialization * * Initializes and start the TC module with the following: * - Counter in Up mode with automatic reset on RC compare match. * - fPBA/8 is used as clock source for TC * - Enables RC compare match interrupt * \param tc Base address of the TC module */ static void tc_init(volatile avr32_tc_t *tc) { // Options for waveform generation. static const tc_waveform_opt_t waveform_opt = { // Channel selection. .channel = EXAMPLE_TC_CHANNEL, // Software trigger effect on TIOB. .bswtrg = TC_EVT_EFFECT_NOOP, // External event effect on TIOB. .beevt = TC_EVT_EFFECT_NOOP, // RC compare effect on TIOB. .bcpc = TC_EVT_EFFECT_NOOP, // RB compare effect on TIOB. .bcpb = TC_EVT_EFFECT_NOOP, // Software trigger effect on TIOA. .aswtrg = TC_EVT_EFFECT_NOOP, // External event effect on TIOA. .aeevt = TC_EVT_EFFECT_NOOP, // RC compare effect on TIOA. .acpc = TC_EVT_EFFECT_NOOP, /* RA compare effect on TIOA. * (other possibilities are none, set and clear). */ .acpa = TC_EVT_EFFECT_NOOP, /* Waveform selection: Up mode with automatic trigger(reset) * on RC compare. */ .wavsel = TC_WAVEFORM_SEL_UP_MODE_RC_TRIGGER, // External event trigger enable. .enetrg = false, // External event selection. .eevt = 0, // External event edge selection. .eevtedg = TC_SEL_NO_EDGE, // Counter disable when RC compare. .cpcdis = false, // Counter clock stopped with RC compare. .cpcstop = false, // Burst signal selection. .burst = false, // Clock inversion. .clki = false, // Internal source clock 3, connected to fPBA / 8. .tcclks = TC_CLOCK_SOURCE_TC3 }; // Options for enabling TC interrupts static const tc_interrupt_t tc_interrupt = { .etrgs = 0, .ldrbs = 0, .ldras = 0, .cpcs = 1, // Enable interrupt on RC compare alone .cpbs = 0, .cpas = 0, .lovrs = 0, .covfs = 0 }; // Initialize the timer/counter. tc_init_waveform(tc, &waveform_opt); /* * Set the compare triggers. * We configure it to count every 10 milliseconds. * We want: (1 / (fPBA / 8)) * RC = 10 ms, hence RC = (fPBA / 8) / 100 * to get an interrupt every 10 ms. */ tc_write_rc(tc, EXAMPLE_TC_CHANNEL, (sysclk_get_pba_hz() / 8 / 100)); // configure the timer interrupt tc_configure_interrupts(tc, EXAMPLE_TC_CHANNEL, &tc_interrupt); // Start the timer/counter. tc_start(tc, EXAMPLE_TC_CHANNEL); } /** * \brief Main function * * Main function performs the following: * - Configure the TC Module * - Register the TC interrupt * - Configure, enable the CPCS (RC compare match) interrupt, * - and start a TC channel in waveform mode */ int main(void) { volatile avr32_tc_t *tc = EXAMPLE_TC; uint32_t timer = 0; /** * \note the call to sysclk_init() will disable all non-vital * peripheral clocks, except for the peripheral clocks explicitly * enabled in conf_clock.h. */ sysclk_init(); // Enable the clock to the selected example Timer/counter peripheral module. sysclk_enable_peripheral_clock(EXAMPLE_TC); // Disable the interrupts cpu_irq_disable(); // Initialize interrupt vectors. INTC_init_interrupts(); // Register the RTC interrupt handler to the interrupt controller. INTC_register_interrupt(&tc_irq, EXAMPLE_TC_IRQ, EXAMPLE_TC_IRQ_PRIORITY); // Enable the interrupts cpu_irq_enable(); // Initialize the timer module tc_init(tc); while(1) { // Update the timer every 10 milli second. if ((update_timer)) { timer++; /* * TODO: Place a breakpoint here and watch the update of timer * variable in the Watch Window. */ // Reset the timer update flag to wait till next timer interrupt update_timer = false; } } }
/** * \brief Initializes the touch measurement timer. * * We need a timer that triggers approx. every millisecond. * The touch library seems to need this as time-base. */ static void init_timer(void) { volatile avr32_tc_t *tc = TOUCH_MEASUREMENT_TC; const tc_waveform_opt_t waveform_options = { .channel = TOUCH_MEASUREMENT_TC_CHANNEL, //! Software trigger effect on TIOB. .bswtrg = TC_EVT_EFFECT_NOOP, //! External event effect on TIOB. .beevt = TC_EVT_EFFECT_NOOP, //! RC compare effect on TIOB. .bcpc = TC_EVT_EFFECT_NOOP, //! RB compare effect on TIOB. .bcpb = TC_EVT_EFFECT_NOOP, //! Software trigger effect on TIOA. .aswtrg = TC_EVT_EFFECT_NOOP, //! External event effect on TIOA. .aeevt = TC_EVT_EFFECT_NOOP, //! RC compare effect on TIOA: toggle. .acpc = TC_EVT_EFFECT_NOOP, //! RA compare effect on TIOA: toggle. .acpa = TC_EVT_EFFECT_NOOP, //! Waveform selection .wavsel = TC_WAVEFORM_SEL_UP_MODE_RC_TRIGGER, //! External event trigger enable. .enetrg = 0, //! External event selection. .eevt = 0, //! External event edge selection. .eevtedg = TC_SEL_NO_EDGE, //! Counter disable when RC compare. .cpcdis = 0, //! Counter clock stopped with RC compare. .cpcstop = 0, //! Burst signal selection. .burst = 0, //! Clock inversion selection. .clki = 0, //! Internal source clock 3 (fPBA / 8). .tcclks = TC_CLOCK_SOURCE_TC3 }; const tc_interrupt_t tc_interrupt = { .etrgs = 0, .ldrbs = 0, .ldras = 0, .cpcs = 1, .cpbs = 0, .cpas = 0, .lovrs = 0, .covfs = 0, }; #if (defined __GNUC__) Disable_global_interrupt(); INTC_register_interrupt(&tc_irq, TOUCH_MEASUREMENT_TC_IRQ, AVR32_INTC_INT0); Enable_global_interrupt(); #endif /* initialize the timer/counter. */ sysclk_enable_peripheral_clock(&AVR32_TC1); tc_init_waveform(tc, &waveform_options); /* set the compare triggers. */ tc_write_rc(tc, TOUCH_MEASUREMENT_TC_CHANNEL, (sysclk_get_pba_hz() / 8) / 1000); tc_configure_interrupts(tc, TOUCH_MEASUREMENT_TC_CHANNEL, &tc_interrupt); tc_start(tc, TOUCH_MEASUREMENT_TC_CHANNEL); } /** * \brief Initializes the touch library configuration. * * Sets the correct configuration for the QTouch library. */ static void qt_set_parameters(void) { /* This will be modified by the user to different values. */ qt_config_data.qt_di = DEF_QT_DI; qt_config_data.qt_neg_drift_rate = DEF_QT_NEG_DRIFT_RATE; qt_config_data.qt_pos_drift_rate = DEF_QT_POS_DRIFT_RATE; qt_config_data.qt_max_on_duration = DEF_QT_MAX_ON_DURATION; qt_config_data.qt_drift_hold_time = DEF_QT_DRIFT_HOLD_TIME; qt_config_data.qt_recal_threshold = DEF_QT_RECAL_THRESHOLD; qt_config_data.qt_pos_recal_delay = DEF_QT_POS_RECAL_DELAY; /* * This function is called after the library has made capacitive * measurements, but before it has processed them. The user can use * this hook to apply filter functions to the measured signal * values. (Possibly to fix sensor layout faults). */ qt_filter_callback = NULL; } /** * \brief Initialize touch sensors * * The touch channels are connected on the GPIO controller 4 which is a part of * port X * * Touch Button: * GPIO * 98 SNSK1 CHANNEL1_SNS * 99 SNS1 CHANNEL1_SNSK * * Touch Slider: * 100 SNS0 CHANNEL2_SNS * 101 SNSK0 CHANNEL2_SNSK * 102 SNS1 CHANNEL3_SNS * 103 SNSK1 CHANNEL3_SNSK * 104 SNS2 CHANNEL4_SNS * 105 SNSK2 CHANNEL4_SNSK */ void touch_init(void) { /* * Reset sensing is only needed when doing re-initialization during * run-time */ // qt_reset_sensing(); qt_enable_key(CHANNEL_1, NO_AKS_GROUP, 30u, HYST_12_5); /* * Position hysteresis is not used in QTouch slider so this value will * be ignored */ qt_enable_slider(CHANNEL_2, CHANNEL_4, NO_AKS_GROUP, 20u, HYST_12_5, RES_8_BIT, 0); qt_init_sensing(); qt_set_parameters(); #ifdef _DEBUG_INTERFACE_ sysclk_enable_peripheral_clock(&AVR32_SPI0); /* Initialize debug protocol */ QDebug_Init(); /* Process commands from PC */ QDebug_ProcessCommands(); #endif init_timer(); }
/** * \brief Main Application Routine * -Initialize the system clocks \n * -Configure and Enable the PWMA Generic clock \n * -Configure and Enable the PWMA Module \n * -Load Duty cycle value using Interlinked multi-value mode \n * -Register and Enable the Interrupt \n * -Enter into sleep mode \n */ int main (void) { uint32_t div; bool config_status = FAIL; bool set_value_status = FAIL; /* * Duty cycle value to be loaded. As Two channels are used * in this example, two values has been assigned. Initialize the unused * channel duty cycle value to 0, as it may take some garbage values * and will return FAIL while updating duty cycle as the value might * exceed the limit NOTE : Maximum four values can be loaded at a time, * as the channel limitation for Interlinked multi-value mode is four. */ uint16_t duty_cycle[] = {11,5,0,0}; /* PWMA Pin and Function Map */ static const gpio_map_t PWMA_GPIO_MAP = { {EXAMPLE_PWMA_PIN1, EXAMPLE_PWMA_FUNCTION1}, {EXAMPLE_PWMA_PIN2, EXAMPLE_PWMA_FUNCTION2}, }; /* Enable the PWMA Pins */ gpio_enable_module(PWMA_GPIO_MAP, sizeof(PWMA_GPIO_MAP) / sizeof(PWMA_GPIO_MAP[0])); /* * Calculate the division factor value to be loaded and * Enable the Generic clock */ div = div_ceil((sysclk_get_pba_hz()) , EXAMPLE_PWMA_GCLK_FREQUENCY); genclk_enable_config(EXAMPLE_PWMA_GCLK_ID,EXAMPLE_PWMA_GCLK_SOURCE,div); /* * Initialize the System clock * Note: Clock should be configured in conf_clock.h */ sysclk_init(); /* Initialize the delay routines */ delay_init(sysclk_get_cpu_hz()); /* * Configure and Enable the PWMA Module. The LED will turned if * configuration fails because of invalid argument. */ config_status = pwma_config_enable(pwma, EXAMPLE_PWMA_OUTPUT_FREQUENCY, EXAMPLE_PWMA_GCLK_FREQUENCY, PWMA_SPREAD); /* Error in configuring the PWMA module */ if (config_status == FAIL){ while (1) { delay_ms(10); gpio_tgl_gpio_pin(ERROR_LED); } } /* Load the duty cycle values using Interlinked multi-value mode */ set_value_status = pwma_set_multiple_values(pwma, ((EXAMPLE_PWMA_CHANNEL_ID1<<0) | (EXAMPLE_PWMA_CHANNEL_ID2<<8)), (uint16_t*)&duty_cycle); /* Error in loading the duty cycle value */ if (set_value_status == FAIL){ while (1) { delay_ms(10); gpio_tgl_gpio_pin(ERROR_LED); } } /* Disable global interrupts */ cpu_irq_disable(); /* * Initialize the interrupt vectors * Note: This function adds nothing for IAR as the interrupts are * handled by the IAR compiler itself. It provides an abstraction * between GCC & IAR compiler to use interrupts. * Refer function implementation in interrupt_avr32.h */ irq_initialize_vectors(); /* * Register the ACIFB interrupt handler * Note: This function adds nothing for IAR as the interrupts are * handled by the IAR compiler itself. It provides an abstraction * between GCC & IAR compiler to use interrupts. * Refer function implementation in interrupt_avr32.h */ irq_register_handler(&tofl_irq, AVR32_PWMA_IRQ, PWMA_INTERRUPT_PRIORITY); /* Enable the Timebase overflow interrupt */ pwma->ier = AVR32_PWMA_IER_TOFL_MASK; /* Enable global interrupt */ cpu_irq_enable(); /* Go to sleep mode */ while(1){ /* Enter into sleep mode */ pm_sleep(AVR32_PM_SMODE_FROZEN); } } /* End of main() */
void memories_initialization(void) { //-- Hmatrix bus configuration // This improve speed performance #ifdef AVR32_HMATRIXB union { unsigned long scfg; avr32_hmatrixb_scfg_t SCFG; } u_avr32_hmatrixb_scfg; sysclk_enable_pbb_module(SYSCLK_HMATRIX); // For the internal-flash HMATRIX slave, use last master as default. u_avr32_hmatrixb_scfg.scfg = AVR32_HMATRIXB.scfg[AVR32_HMATRIXB_SLAVE_FLASH]; u_avr32_hmatrixb_scfg.SCFG.defmstr_type = AVR32_HMATRIXB_DEFMSTR_TYPE_LAST_DEFAULT; AVR32_HMATRIXB.scfg[AVR32_HMATRIXB_SLAVE_FLASH] = u_avr32_hmatrixb_scfg.scfg; // For the internal-SRAM HMATRIX slave, use last master as default. u_avr32_hmatrixb_scfg.scfg = AVR32_HMATRIXB.scfg[AVR32_HMATRIXB_SLAVE_SRAM]; u_avr32_hmatrixb_scfg.SCFG.defmstr_type = AVR32_HMATRIXB_DEFMSTR_TYPE_LAST_DEFAULT; AVR32_HMATRIXB.scfg[AVR32_HMATRIXB_SLAVE_SRAM] = u_avr32_hmatrixb_scfg.scfg; # ifdef AVR32_HMATRIXB_SLAVE_EBI // For the EBI HMATRIX slave, use last master as default. u_avr32_hmatrixb_scfg.scfg = AVR32_HMATRIXB.scfg[AVR32_HMATRIXB_SLAVE_EBI]; u_avr32_hmatrixb_scfg.SCFG.defmstr_type = AVR32_HMATRIXB_DEFMSTR_TYPE_LAST_DEFAULT; AVR32_HMATRIXB.scfg[AVR32_HMATRIXB_SLAVE_EBI] = u_avr32_hmatrixb_scfg.scfg; # endif #endif #ifdef AVR32_HMATRIX union { unsigned long scfg; avr32_hmatrix_scfg_t SCFG; } u_avr32_hmatrix_scfg; sysclk_enable_pbb_module(SYSCLK_HMATRIX); // For the internal-flash HMATRIX slave, use last master as default. u_avr32_hmatrix_scfg.scfg = AVR32_HMATRIX.scfg[AVR32_HMATRIX_SLAVE_FLASH]; u_avr32_hmatrix_scfg.SCFG.defmstr_type = AVR32_HMATRIX_DEFMSTR_TYPE_LAST_DEFAULT; AVR32_HMATRIX.scfg[AVR32_HMATRIX_SLAVE_FLASH] = u_avr32_hmatrix_scfg.scfg; // For the internal-SRAM HMATRIX slave, use last master as default. u_avr32_hmatrix_scfg.scfg = AVR32_HMATRIX.scfg[AVR32_HMATRIX_SLAVE_SRAM]; u_avr32_hmatrix_scfg.SCFG.defmstr_type = AVR32_HMATRIX_DEFMSTR_TYPE_LAST_DEFAULT; AVR32_HMATRIX.scfg[AVR32_HMATRIX_SLAVE_SRAM] = u_avr32_hmatrix_scfg.scfg; # ifdef AVR32_HMATRIX_SLAVE_EBI // For the EBI HMATRIX slave, use last master as default. u_avr32_hmatrix_scfg.scfg = AVR32_HMATRIX.scfg[AVR32_HMATRIX_SLAVE_EBI]; u_avr32_hmatrix_scfg.SCFG.defmstr_type = AVR32_HMATRIX_DEFMSTR_TYPE_LAST_DEFAULT; AVR32_HMATRIX.scfg[AVR32_HMATRIX_SLAVE_EBI] = u_avr32_hmatrix_scfg.scfg; # endif #endif #ifdef AVR32_HMATRIX_MASTER_USBB_DMA union { unsigned long mcfg; avr32_hmatrix_mcfg_t MCFG; } u_avr32_hmatrix_mcfg; // For the USBB DMA HMATRIX master, use infinite length burst. u_avr32_hmatrix_mcfg.mcfg = AVR32_HMATRIX.mcfg[AVR32_HMATRIX_MASTER_USBB_DMA]; u_avr32_hmatrix_mcfg.MCFG.ulbt = AVR32_HMATRIX_ULBT_INFINITE; AVR32_HMATRIX.mcfg[AVR32_HMATRIX_MASTER_USBB_DMA] = u_avr32_hmatrix_mcfg.mcfg; // For the USBB DPRAM HMATRIX slave, use the USBB DMA as fixed default master. u_avr32_hmatrix_scfg.scfg = AVR32_HMATRIX.scfg[AVR32_HMATRIX_SLAVE_USBB_DPRAM]; u_avr32_hmatrix_scfg.SCFG.fixed_defmstr = AVR32_HMATRIX_MASTER_USBB_DMA; u_avr32_hmatrix_scfg.SCFG.defmstr_type = AVR32_HMATRIX_DEFMSTR_TYPE_FIXED_DEFAULT; AVR32_HMATRIX.scfg[AVR32_HMATRIX_SLAVE_USBB_DPRAM] = u_avr32_hmatrix_scfg.scfg; #endif #if (defined AT45DBX_MEM) && (AT45DBX_MEM == ENABLE) sysclk_enable_peripheral_clock(AT45DBX_SPI_MODULE); at45dbx_init(); #endif #if ((defined SD_MMC_MCI_0_MEM) && (SD_MMC_MCI_0_MEM == ENABLE)) \ || ((defined SD_MMC_MCI_1_MEM) && (SD_MMC_MCI_1_MEM == ENABLE)) sysclk_enable_pbb_module(SYSCLK_MCI); sysclk_enable_hsb_module(SYSCLK_DMACA); sd_mmc_mci_init(SD_SLOT_8BITS, sysclk_get_pbb_hz(), sysclk_get_cpu_hz()); #endif #if (defined SD_MMC_SPI_MEM) && (SD_MMC_SPI_MEM == ENABLE) // SPI options. spi_options_t spiOptions = { .reg = SD_MMC_SPI_NPCS, .baudrate = SD_MMC_SPI_MASTER_SPEED, // Defined in conf_sd_mmc_spi.h. .bits = SD_MMC_SPI_BITS, // Defined in conf_sd_mmc_spi.h. .spck_delay = 0, .trans_delay = 0, .stay_act = 1, .spi_mode = 0, .modfdis = 1 }; sysclk_enable_peripheral_clock(SD_MMC_SPI); // If the SPI used by the SD/MMC is not enabled. if (!spi_is_enabled(SD_MMC_SPI)) { // Initialize as master. spi_initMaster(SD_MMC_SPI, &spiOptions); // Set selection mode: variable_ps, pcs_decode, delay. spi_selectionMode(SD_MMC_SPI, 0, 0, 0); // Enable SPI. spi_enable(SD_MMC_SPI); } // Initialize SD/MMC with SPI PB clock. sd_mmc_spi_init(spiOptions,sysclk_get_pba_hz()); #endif // SD_MMC_SPI_MEM == ENABLE }
/** \brief Main function - init and loop to display ADC values */ int main(void) { /* GPIO pin/ADC-function map. */ const gpio_map_t ADCIFB_GPIO_MAP = { {EXAMPLE_ADCIFB_PIN, EXAMPLE_ADCIFB_FUNCTION} }; /* ADCIFB Configuration */ adcifb_opt_t adcifb_opt = { /* Resolution mode */ .resolution = AVR32_ADCIFB_ACR_RES_12BIT, /* Channels Sample & Hold Time in [0,15] */ .shtim = 15, .ratio_clkadcifb_clkadc = (sysclk_get_pba_hz() / EXAMPLE_TARGET_CLK_ADC_FREQ_HZ), /* * Startup time in [0,127], where * Tstartup = startup * 8 * Tclk_adc (assuming Tstartup ~ 15us max) */ .startup = 3, /* ADCIFB Sleep Mode disabled */ .sleep_mode_enable = false }; uint32_t adc_data; /* Initialize the system clocks */ sysclk_init(); /* Init debug serial line */ init_dbg_rs232(sysclk_get_pba_hz()); /* Assign and enable GPIO pins to the ADC function. */ gpio_enable_module(ADCIFB_GPIO_MAP, sizeof(ADCIFB_GPIO_MAP) / sizeof(ADCIFB_GPIO_MAP[0])); /* Enable and configure the ADCIFB module */ if (adcifb_configure(&AVR32_ADCIFB, &adcifb_opt) != PASS) { /* Config error. */ while (true) { gpio_tgl_gpio_pin(LED0_GPIO); delay_ms(100); } } /* Configure the trigger mode */ /* "No trigger, only software trigger can start conversions". */ if (adcifb_configure_trigger(&AVR32_ADCIFB, AVR32_ADCIFB_TRGMOD_NT, 0) != PASS) { /* Config error. */ while (true) { gpio_tgl_gpio_pin(LED1_GPIO); delay_ms(100); } } /* Enable the ADCIFB channel the battery is connected to. */ adcifb_channels_enable(&AVR32_ADCIFB, EXAMPLE_ADCIFB_CHANNEL_MASK); while (true) { while (adcifb_is_ready(&AVR32_ADCIFB) != true) { /* Wait until the ADC is ready to perform a conversion. */ } /* Start an ADCIFB conversion sequence. */ adcifb_start_conversion_sequence(&AVR32_ADCIFB); while (adcifb_is_drdy(&AVR32_ADCIFB) != true) { /* Wait until the converted data is available. */ } /* Get the last converted data. */ adc_data = adcifb_get_last_data(&AVR32_ADCIFB); /* Display the current voltage of the battery. */ print_dbg("\x1B[2J\x1B[H\r\nADCIFB Example\r\nHEX Value for " EXAMPLE_ADCIFB_CHANNEL_NAME " : 0x"); print_dbg_hex(adc_data & AVR32_ADCIFB_LCDR_LDATA_MASK); print_dbg("\r\n"); delay_ms(500); /* * Note1: there is a resistor bridge between the battery and the * ADC pad on the AT32UC3L-EK. The data converted is thus half * of * the battery voltage. */ /* * Note2: if the battery is not in place, the conversion is out * of * spec because the ADC input is then higher than ADVREF. */ } }
int32_t i2c_driver_init(uint8_t i2c_device) { int32_t i; volatile avr32_twim_t *twim; switch (i2c_device) { case 0: twim = &AVR32_TWIM0; // Register PDCA IRQ interrupt. INTC_register_interrupt( (__int_handler) &pdca_int_handler_i2c0, TWI0_DMA_IRQ, AVR32_INTC_INT0); gpio_enable_module_pin(AVR32_TWIMS0_TWCK_0_0_PIN, AVR32_TWIMS0_TWCK_0_0_FUNCTION); gpio_enable_module_pin(AVR32_TWIMS0_TWD_0_0_PIN, AVR32_TWIMS0_TWD_0_0_FUNCTION); break; case 1: twim = &AVR32_TWIM1;// Register PDCA IRQ interrupt. INTC_register_interrupt( (__int_handler) &pdca_int_handler_i2c0, TWI1_DMA_IRQ, AVR32_INTC_INT0); gpio_enable_module_pin(AVR32_TWIMS1_TWCK_0_0_PIN, AVR32_TWIMS1_TWCK_0_0_FUNCTION); gpio_enable_module_pin(AVR32_TWIMS1_TWD_0_0_PIN, AVR32_TWIMS1_TWD_0_0_FUNCTION); gpio_enable_pin_pull_up(AVR32_TWIMS1_TWCK_0_0_PIN); gpio_enable_pin_pull_up(AVR32_TWIMS1_TWD_0_0_PIN); break; default: // invalid device ID return -1; } for (i = 0; i < I2C_SCHEDULE_SLOTS; i++) { schedule[i2c_device][i].active = -1; } bool global_interrupt_enabled = cpu_irq_is_enabled (); // Disable TWI interrupts if (global_interrupt_enabled) { cpu_irq_disable (); } twim->idr = ~0UL; // Enable master transfer twim->cr = AVR32_TWIM_CR_MEN_MASK; // Reset TWI twim->cr = AVR32_TWIM_CR_SWRST_MASK; if (global_interrupt_enabled) { cpu_irq_enable (); } // Clear SR twim->scr = ~0UL; // register Register twim_master_interrupt_handler interrupt on level CONF_TWIM_IRQ_LEVEL // irqflags_t flags = cpu_irq_save(); // irq_register_handler(twim_master_interrupt_handler, // CONF_TWIM_IRQ_LINE, CONF_TWIM_IRQ_LEVEL); // cpu_irq_restore(flags); // Select the speed if (twim_set_speed(twim, 100000, sysclk_get_pba_hz()) == ERR_INVALID_ARG) { return ERR_INVALID_ARG; } return STATUS_OK; }
void i2c_driver_init(uint8_t i2c_device) { volatile avr32_twim_t *twim; switch (i2c_device) { case I2C0: twim = &AVR32_TWIM0; ///< Register PDCA IRQ interrupt. INTC_register_interrupt( (__int_handler) &i2c_int_handler_i2c0, AVR32_TWIM0_IRQ, AVR32_INTC_INT1); gpio_enable_module_pin(AVR32_TWIMS0_TWCK_0_0_PIN, AVR32_TWIMS0_TWCK_0_0_FUNCTION); gpio_enable_module_pin(AVR32_TWIMS0_TWD_0_0_PIN, AVR32_TWIMS0_TWD_0_0_FUNCTION); break; case I2C1: twim = &AVR32_TWIM1;///< Register PDCA IRQ interrupt. //INTC_register_interrupt( (__int_handler) &i2c_int_handler_i2c1, AVR32_TWIM1_IRQ, AVR32_INTC_INT1); gpio_enable_module_pin(AVR32_TWIMS1_TWCK_0_0_PIN, AVR32_TWIMS1_TWCK_0_0_FUNCTION); gpio_enable_module_pin(AVR32_TWIMS1_TWD_0_0_PIN, AVR32_TWIMS1_TWD_0_0_FUNCTION); break; default: ///< invalid device ID return; } static twim_options_t twi_opt= { .pba_hz = 64000000, .speed = 400000, .chip = 0xff, .smbus = false }; twi_opt.pba_hz = sysclk_get_pba_hz(); status_code_t ret_twim_init = twim_master_init(twim, &twi_opt); print_util_dbg_print("\r\n"); switch(ret_twim_init) { case ERR_IO_ERROR : print_util_dbg_print("NO Twim probe here \r\n"); case STATUS_OK : print_util_dbg_print("I2C initialised \r\n"); break; default : print_util_dbg_print("Error initialising I2C \r\n"); break; } } int8_t i2c_driver_reset(uint8_t i2c_device) { volatile avr32_twim_t *twim; switch (i2c_device) { case 0: twim = &AVR32_TWIM0; break; case 1: twim = &AVR32_TWIM1; break; default: ///< invalid device ID return -1; } bool global_interrupt_enabled = cpu_irq_is_enabled (); ///< Disable TWI interrupts if (global_interrupt_enabled) { cpu_irq_disable (); } twim->idr = ~0UL; ///< Enable master transfer twim->cr = AVR32_TWIM_CR_MEN_MASK; ///< Reset TWI twim->cr = AVR32_TWIM_CR_SWRST_MASK; if (global_interrupt_enabled) { cpu_irq_enable (); } ///< Clear SR twim->scr = ~0UL; return STATUS_OK; //No error } int8_t i2c_driver_trigger_request(uint8_t i2c_device, i2c_packet_t *transfer) { ///< initiate transfer of given request ///< set up DMA channel volatile avr32_twim_t *twim; bool global_interrupt_enabled = cpu_irq_is_enabled (); if (global_interrupt_enabled) { cpu_irq_disable (); } switch (i2c_device) { case 0: twim = &AVR32_TWIM0; twim->cr = AVR32_TWIM_CR_MEN_MASK; twim->cr = AVR32_TWIM_CR_SWRST_MASK; twim->cr = AVR32_TWIM_CR_MDIS_MASK; twim->scr = ~0UL; // Clear the interrupt flags twim->idr = ~0UL; if (twim_set_speed(twim, transfer->i2c_speed, sysclk_get_pba_hz()) == ERR_INVALID_ARG) { return ERR_INVALID_ARG; } //pdca_load_channel(TWI0_DMA_CH, (void *)schedule[i2c_device][schedule_slot].config.write_data, schedule[i2c_device][schedule_slot].config.write_count); ///< Enable pdca interrupt each time the reload counter reaches zero, i.e. each time ///< the whole block was received //pdca_enable_interrupt_transfer_error(TWI0_DMA_CH); break; case 1: twim = &AVR32_TWIM1; twim->cr = AVR32_TWIM_CR_MEN_MASK; twim->cr = AVR32_TWIM_CR_SWRST_MASK; twim->cr = AVR32_TWIM_CR_MDIS_MASK; twim->scr = ~0UL; ///< Clear the interrupt flags twim->idr = ~0UL; if (twim_set_speed(twim, transfer->i2c_speed, sysclk_get_pba_hz()) == ERR_INVALID_ARG) { return ERR_INVALID_ARG; } break; default: ///< invalid device ID return -1; } ///< set up I2C speed and mode //twim_set_speed(twim, 100000, sysclk_get_pba_hz()); switch (1/*conf->direction*/) { case I2C_READ: twim->cmdr = (transfer->slave_address << AVR32_TWIM_CMDR_SADR_OFFSET) | (transfer->data_size << AVR32_TWIM_CMDR_NBYTES_OFFSET) | (AVR32_TWIM_CMDR_VALID_MASK) | (AVR32_TWIM_CMDR_START_MASK) | (AVR32_TWIM_CMDR_STOP_MASK) | (AVR32_TWIM_CMDR_READ_MASK); twim->ncmdr = 0; twim->ier = AVR32_TWIM_IER_STD_MASK | AVR32_TWIM_IER_RXRDY_MASK; break; case I2C_WRITE1_THEN_READ: ///< set up next command register for the burst read transfer ///< set up command register to initiate the write transfer. The DMA will take care of the reading once this is done. twim->cmdr = (transfer->slave_address << AVR32_TWIM_CMDR_SADR_OFFSET) | ((1)<< AVR32_TWIM_CMDR_NBYTES_OFFSET) | (AVR32_TWIM_CMDR_VALID_MASK) | (AVR32_TWIM_CMDR_START_MASK) //| (AVR32_TWIM_CMDR_STOP_MASK) | (0 << AVR32_TWIM_CMDR_READ_OFFSET); ; twim->ncmdr = (transfer->slave_address << AVR32_TWIM_CMDR_SADR_OFFSET) | ((transfer->data_size) << AVR32_TWIM_CMDR_NBYTES_OFFSET) | (AVR32_TWIM_CMDR_VALID_MASK) | (AVR32_TWIM_CMDR_START_MASK) | (AVR32_TWIM_CMDR_STOP_MASK) | (AVR32_TWIM_CMDR_READ_MASK); twim->ier = AVR32_TWIM_IER_STD_MASK | AVR32_TWIM_IER_RXRDY_MASK | AVR32_TWIM_IER_TXRDY_MASK; ///< set up writing of one byte (usually a slave register index) twim->cr = AVR32_TWIM_CR_MEN_MASK; twim->thr = transfer->write_then_read_preamble; twim->cr = AVR32_TWIM_CR_MEN_MASK; break; case I2C_WRITE: twim->cmdr = (transfer->slave_address << AVR32_TWIM_CMDR_SADR_OFFSET) | ((transfer->data_size) << AVR32_TWIM_CMDR_NBYTES_OFFSET) | (AVR32_TWIM_CMDR_VALID_MASK) | (AVR32_TWIM_CMDR_START_MASK) | (AVR32_TWIM_CMDR_STOP_MASK); twim->ncmdr = 0; ; twim->ier = AVR32_TWIM_IER_NAK_MASK | AVR32_TWIM_IER_TXRDY_MASK; break; } ///< start transfer current_transfer = transfer; current_transfer->transfer_in_progress = 1; current_transfer->data_index = 0; if (global_interrupt_enabled) { cpu_irq_enable (); } twim->cr = AVR32_TWIM_CR_MEN_MASK; return STATUS_OK; }
/** * \brief Function to initialize the Timer/Counter module in Waveform mode. * It fires the ISR at regular intervals to start QTouch Acquisition. */ void init_timer_isr( void ) { // Configure the timer isr to fire regularly volatile avr32_tc_t *tc = &AVR32_TC; // Waveform Mode Options for TC static const tc_waveform_opt_t WAVEFORM_OPT = { // Channel selection : channel 0. .channel = TC_CHANNEL, // Software trigger effect on TIOB : none. .bswtrg = TC_EVT_EFFECT_NOOP, // External event effect on TIOB : none. .beevt = TC_EVT_EFFECT_NOOP, // RC compare effect on TIOB : none. .bcpc = TC_EVT_EFFECT_NOOP, // RB compare effect on TIOB : none. .bcpb = TC_EVT_EFFECT_NOOP, // Software trigger effect on TIOA : none. .aswtrg = TC_EVT_EFFECT_NOOP, // External event effect on TIOA : none. .aeevt = TC_EVT_EFFECT_NOOP, // RC compare effect on TIOA: None .acpc = TC_EVT_EFFECT_NOOP, // RA compare effect on TIOA: none .acpa = TC_EVT_EFFECT_NOOP, // Waveform selection: Up mode with automatic trigger(reset) on RC compare. .wavsel = TC_WAVEFORM_SEL_UP_MODE_RC_TRIGGER, // External event trigger enable : no effect. .enetrg = false, // External event selection : . .eevt = 0u, // External event edge selection : none. .eevtedg = TC_SEL_NO_EDGE, // Counter disable when RC compare. .cpcdis = false, // Counter clock stopped with RC compare. .cpcstop = false, // Burst signal selection. .burst = false, // Clock inversion. .clki = false, // Internal source clock 3 .tcclks = TC_CLOCK }; // Configure the interrupts static const tc_interrupt_t TC_INTERRUPT = { .etrgs = 0u, .ldrbs = 0u, .ldras = 0u, // Interrupt is enabled for RC compare match .cpcs = 1u, .cpbs = 0u, .cpas = 0u, .lovrs = 0u, .covfs = 0u }; // Initialize the timer/counter waveform. tc_init_waveform(tc, &WAVEFORM_OPT); /* * Set the compare triggers. * We configure it to count every 1 milliseconds. * We want: (1 / (fPBA / 8)) * RC = 1 ms, hence RC = (fPBA / 8) / 1000 * to get an interrupt every 10 ms. */ tc_write_rc(tc, TC_CHANNEL, (sysclk_get_pba_hz() / 8 / 1000)); // Configure the interrupts for channel 0 tc_configure_interrupts(tc, TC_CHANNEL, &TC_INTERRUPT); // Initialize interrupt vectors. irq_initialize_vectors(); // Register the timer interrupt handler to the interrupt controller irq_register_handler(&tc_irq, TC_IRQ, AVR32_INTC_INT0); // Start the timer/counter. tc_start(tc, TC_CHANNEL); } // end of init_timer_isr
// initialize application timer extern void init_tc (void) { volatile avr32_tc_t *tc = APP_TC; // waveform options static const tc_waveform_opt_t waveform_opt = { .channel = APP_TC_CHANNEL, // channel .bswtrg = TC_EVT_EFFECT_NOOP, // software trigger action on TIOB .beevt = TC_EVT_EFFECT_NOOP, // external event action .bcpc = TC_EVT_EFFECT_NOOP, // rc compare action .bcpb = TC_EVT_EFFECT_NOOP, // rb compare .aswtrg = TC_EVT_EFFECT_NOOP, // soft trig on TIOA .aeevt = TC_EVT_EFFECT_NOOP, // etc .acpc = TC_EVT_EFFECT_NOOP, .acpa = TC_EVT_EFFECT_NOOP, // Waveform selection: Up mode with automatic trigger(reset) on RC compare. .wavsel = TC_WAVEFORM_SEL_UP_MODE_RC_TRIGGER, .enetrg = false, // external event trig .eevt = 0, // extern event select .eevtedg = TC_SEL_NO_EDGE, // extern event edge .cpcdis = false, // counter disable when rc compare .cpcstop = false, // counter stopped when rc compare .burst = false, .clki = false, // Internal source clock 5, connected to fPBA / 128. .tcclks = TC_CLOCK_SOURCE_TC5 }; // Options for enabling TC interrupts static const tc_interrupt_t tc_interrupt = { .etrgs = 0, .ldrbs = 0, .ldras = 0, .cpcs = 1, // Enable interrupt on RC compare alone .cpbs = 0, .cpas = 0, .lovrs = 0, .covfs = 0 }; // Initialize the timer/counter. tc_init_waveform(tc, &waveform_opt); // set timer compare trigger. // we want it to overflow and generate an interrupt every 1 ms // so (1 / fPBA / 128) * RC = 0.001 // so RC = fPBA / 128 / 1000 // tc_write_rc(tc, APP_TC_CHANNEL, (FPBA_HZ / 128000)); tc_write_rc(tc, APP_TC_CHANNEL, (FPBA_HZ / 128000)); // configure the timer interrupt tc_configure_interrupts(tc, APP_TC_CHANNEL, &tc_interrupt); // Start the timer/counter. tc_start(tc, APP_TC_CHANNEL); } extern void init_spi (void) { sysclk_enable_pba_module(SYSCLK_SPI); static const gpio_map_t SPI_GPIO_MAP = { {SPI_SCK_PIN, SPI_SCK_FUNCTION }, {SPI_MISO_PIN, SPI_MISO_FUNCTION}, {SPI_MOSI_PIN, SPI_MOSI_FUNCTION}, {SPI_NPCS0_PIN, SPI_NPCS0_FUNCTION }, {SPI_NPCS1_PIN, SPI_NPCS1_FUNCTION }, {SPI_NPCS2_PIN, SPI_NPCS2_FUNCTION }, }; // Assign GPIO to SPI. gpio_enable_module(SPI_GPIO_MAP, sizeof(SPI_GPIO_MAP) / sizeof(SPI_GPIO_MAP[0])); spi_options_t spiOptions = { .reg = DAC_SPI, .baudrate = 2000000, .bits = 8, .trans_delay = 0, .spck_delay = 0, .stay_act = 1, .spi_mode = 1, .modfdis = 1 }; // Initialize as master. spi_initMaster(SPI, &spiOptions); // Set SPI selection mode: variable_ps, pcs_decode, delay. spi_selectionMode(SPI, 0, 0, 0); // Enable SPI module. spi_enable(SPI); // spi_setupChipReg( SPI, &spiOptions, FPBA_HZ ); spi_setupChipReg(SPI, &spiOptions, sysclk_get_pba_hz() ); // add ADC chip register spiOptions.reg = ADC_SPI; spiOptions.baudrate = 20000000; spiOptions.bits = 16; spiOptions.spi_mode = 2; spiOptions.spck_delay = 0; spiOptions.trans_delay = 5; spiOptions.stay_act = 0; spiOptions.modfdis = 0; spi_setupChipReg( SPI, &spiOptions, FPBA_HZ ); // add OLED chip register spiOptions.reg = OLED_SPI; spiOptions.baudrate = 40000000; spiOptions.bits = 8; spiOptions.spi_mode = 3; spiOptions.spck_delay = 0; spiOptions.trans_delay = 0; spiOptions.stay_act = 1; spiOptions.modfdis = 1; spi_setupChipReg( SPI, &spiOptions, FPBA_HZ ); } // initialize USB host stack void init_usb_host (void) { uhc_start(); } // initialize i2c void init_i2c_master(void) { twi_options_t opt; int status; static const gpio_map_t TWI_GPIO_MAP = { {AVR32_TWI_SDA_0_0_PIN, AVR32_TWI_SDA_0_0_FUNCTION}, {AVR32_TWI_SCL_0_0_PIN, AVR32_TWI_SCL_0_0_FUNCTION} }; gpio_enable_module(TWI_GPIO_MAP, sizeof(TWI_GPIO_MAP) / sizeof(TWI_GPIO_MAP[0])); // options settings opt.pba_hz = FOSC0; opt.speed = TWI_SPEED; opt.chip = 0x50; // initialize TWI driver with options // status = twi_master_init(&AVR32_TWI, &opt); status = twi_master_init(TWI, &opt); /* // check init result if (status == TWI_SUCCESS) print_dbg("\r\ni2c init"); else print_dbg("\r\ni2c init FAIL"); */ } void init_i2c_slave(void) { twi_options_t opt; twi_slave_fct_t twi_slave_fct; int status; static const gpio_map_t TWI_GPIO_MAP = { {AVR32_TWI_SDA_0_0_PIN, AVR32_TWI_SDA_0_0_FUNCTION}, {AVR32_TWI_SCL_0_0_PIN, AVR32_TWI_SCL_0_0_FUNCTION} }; gpio_enable_module(TWI_GPIO_MAP, sizeof(TWI_GPIO_MAP) / sizeof(TWI_GPIO_MAP[0])); // options settings opt.pba_hz = FOSC0; opt.speed = TWI_SPEED; opt.chip = 0x50; // initialize TWI driver with options twi_slave_fct.rx = &twi_slave_rx; twi_slave_fct.tx = &twi_slave_tx; twi_slave_fct.stop = &twi_slave_stop; status = twi_slave_init(&AVR32_TWI, &opt, &twi_slave_fct ); /* // check init result if (status == TWI_SUCCESS) print_dbg("\r\ni2c init"); else print_dbg("\r\ni2c init FAIL"); */ }
//##################################################### void adc_init(unsigned long chanels_mask, unsigned char mode, unsigned short period) { // Assign and enable GPIO pin to the ADC function. if(chanels_mask & (1 << 0)) { gpio_enable_module_pin(AVR32_ADCIFB_AD_0_PIN, AVR32_ADCIFB_AD_0_FUNCTION); //adcifb_channels_enable(&AVR32_ADCIFB, 1 << 0); } if(chanels_mask & (1 << 1)) { gpio_enable_module_pin(AVR32_ADCIFB_AD_1_PIN, AVR32_ADCIFB_AD_1_FUNCTION); //adcifb_channels_enable(&AVR32_ADCIFB, 1 << 1); } if(chanels_mask & (1 << 2)) { gpio_enable_module_pin(AVR32_ADCIFB_AD_2_PIN, AVR32_ADCIFB_AD_2_FUNCTION); //adcifb_channels_enable(&AVR32_ADCIFB, 1 << 2); } if(chanels_mask & (1 << 3)) { gpio_enable_module_pin(AVR32_ADCIFB_AD_3_PIN, AVR32_ADCIFB_AD_3_FUNCTION); //adcifb_channels_enable(&AVR32_ADCIFB, 1 << 3); } if(chanels_mask & (1 << 4)) { gpio_enable_module_pin(AVR32_ADCIFB_AD_4_PIN, AVR32_ADCIFB_AD_4_FUNCTION); //adcifb_channels_enable(&AVR32_ADCIFB, 1 << 4); } if(chanels_mask & (1 << 5)) { gpio_enable_module_pin(AVR32_ADCIFB_AD_5_PIN, AVR32_ADCIFB_AD_5_FUNCTION); //adcifb_channels_enable(&AVR32_ADCIFB, 1 << 5); } if(chanels_mask & (1 << 6)) { gpio_enable_module_pin(AVR32_ADCIFB_AD_6_PIN, AVR32_ADCIFB_AD_6_FUNCTION); //adcifb_channels_enable(&AVR32_ADCIFB, 1 << 6); } if(chanels_mask & (1 << 7)) { gpio_enable_module_pin(AVR32_ADCIFB_AD_7_PIN, AVR32_ADCIFB_AD_7_FUNCTION); //adcifb_channels_enable(&AVR32_ADCIFB, 1 << 7); } unsigned long pba_clock = sysclk_get_pba_hz(); adcifb_opt_t adcifb_opt = { .resolution = AVR32_ADCIFB_ACR_RES_8BIT, .shtim = 15, .ratio_clkadcifb_clkadc = pba_clock / 6000000, .startup = 3, .sleep_mode_enable = false }; // Enable and configure the ADCIFB module sysclk_enable_peripheral_clock(&AVR32_ADCIFB); adcifb_configure(&AVR32_ADCIFB, &adcifb_opt); // Configure the trigger (No trigger, only software trigger) adcifb_configure_trigger(&AVR32_ADCIFB, mode /*AVR32_ADCIFB_TRGR_TRGMOD_PT*/, period); adcifb_channels_enable(&AVR32_ADCIFB, chanels_mask); } //##################################################### void adc_channels_enable_pio(unsigned long chanels_mask) { // Assign and enable GPIO pin to the ADC function. if(chanels_mask & (1 << 0)) { gpio_enable_module_pin(AVR32_ADCIFB_AD_0_PIN, AVR32_ADCIFB_AD_0_FUNCTION); //adcifb_channels_enable(&AVR32_ADCIFB, 1 << 0); } if(chanels_mask & (1 << 1)) { gpio_enable_module_pin(AVR32_ADCIFB_AD_1_PIN, AVR32_ADCIFB_AD_1_FUNCTION); //adcifb_channels_enable(&AVR32_ADCIFB, 1 << 1); } if(chanels_mask & (1 << 2)) { gpio_enable_module_pin(AVR32_ADCIFB_AD_2_PIN, AVR32_ADCIFB_AD_2_FUNCTION); //adcifb_channels_enable(&AVR32_ADCIFB, 1 << 2); } if(chanels_mask & (1 << 3)) { gpio_enable_module_pin(AVR32_ADCIFB_AD_3_PIN, AVR32_ADCIFB_AD_3_FUNCTION); //adcifb_channels_enable(&AVR32_ADCIFB, 1 << 3); } if(chanels_mask & (1 << 4)) { gpio_enable_module_pin(AVR32_ADCIFB_AD_4_PIN, AVR32_ADCIFB_AD_4_FUNCTION); //adcifb_channels_enable(&AVR32_ADCIFB, 1 << 4); } if(chanels_mask & (1 << 5)) { gpio_enable_module_pin(AVR32_ADCIFB_AD_5_PIN, AVR32_ADCIFB_AD_5_FUNCTION); //adcifb_channels_enable(&AVR32_ADCIFB, 1 << 5); } if(chanels_mask & (1 << 6)) { gpio_enable_module_pin(AVR32_ADCIFB_AD_6_PIN, AVR32_ADCIFB_AD_6_FUNCTION); //adcifb_channels_enable(&AVR32_ADCIFB, 1 << 6); } if(chanels_mask & (1 << 7)) { gpio_enable_module_pin(AVR32_ADCIFB_AD_7_PIN, AVR32_ADCIFB_AD_7_FUNCTION); //adcifb_channels_enable(&AVR32_ADCIFB, 1 << 7); } adcifb_channels_enable(&AVR32_ADCIFB, chanels_mask); } //##################################################### void adc_channels_enable(unsigned long chanels_mask) { adcifb_channels_enable(&AVR32_ADCIFB, chanels_mask); }
/** * \brief TC Initialization * * Initializes and start the TC module with the following: * - Counter in Up mode with automatic reset on RC compare match. * - fPBA/8 is used as clock source for TC * - Enables RC compare match interrupt * \param tc Base address of the TC module */ static void tc_init(volatile avr32_tc_t *tc) { // Options for waveform generation. static const tc_waveform_opt_t waveform_opt = { // Channel selection. .channel = EXAMPLE_TC_CHANNEL, // Software trigger effect on TIOB. .bswtrg = TC_EVT_EFFECT_NOOP, // External event effect on TIOB. .beevt = TC_EVT_EFFECT_NOOP, // RC compare effect on TIOB. .bcpc = TC_EVT_EFFECT_NOOP, // RB compare effect on TIOB. .bcpb = TC_EVT_EFFECT_NOOP, // Software trigger effect on TIOA. .aswtrg = TC_EVT_EFFECT_NOOP, // External event effect on TIOA. .aeevt = TC_EVT_EFFECT_NOOP, // RC compare effect on TIOA. .acpc = TC_EVT_EFFECT_NOOP, /* * RA compare effect on TIOA. * (other possibilities are none, set and clear). */ .acpa = TC_EVT_EFFECT_NOOP, /* * Waveform selection: Up mode with automatic trigger(reset) * on RC compare. */ .wavsel = TC_WAVEFORM_SEL_UP_MODE_RC_TRIGGER, // External event trigger enable. .enetrg = false, // External event selection. .eevt = 0, // External event edge selection. .eevtedg = TC_SEL_NO_EDGE, // Counter disable when RC compare. .cpcdis = false, // Counter clock stopped with RC compare. .cpcstop = false, // Burst signal selection. .burst = false, // Clock inversion. .clki = false, // Internal source clock 3, connected to fPBA / 8. .tcclks = TC_CLOCK_SOURCE_TC3 }; // Options for enabling TC interrupts static const tc_interrupt_t tc_interrupt = { .etrgs = 0, .ldrbs = 0, .ldras = 0, .cpcs = 1, // Enable interrupt on RC compare alone .cpbs = 0, .cpas = 0, .lovrs = 0, .covfs = 0 }; // Initialize the timer/counter. tc_init_waveform(tc, &waveform_opt); /* * Set the compare triggers. * We configure it to count every 1 milliseconds. * We want: (1 / (fPBA / 8)) * RC = 1 ms, hence RC = (fPBA / 8) / 1000 * to get an interrupt every 10 ms. */ tc_write_rc(tc, EXAMPLE_TC_CHANNEL, (sysclk_get_pba_hz() / 8 / 1000)); // configure the timer interrupt tc_configure_interrupts(tc, EXAMPLE_TC_CHANNEL, &tc_interrupt); // Start the timer/counter. tc_start(tc, EXAMPLE_TC_CHANNEL); } /*! \brief Main function: * - Configure the CPU to run at 12MHz * - Configure the USART * - Register the TC interrupt (GCC only) * - Configure, enable the CPCS (RC compare match) interrupt, and start a * TC channel in waveform mode * - In an infinite loop, update the USART message every second. */ int main(void) { volatile avr32_tc_t *tc = EXAMPLE_TC; uint32_t timer = 0; /** * \note the call to sysclk_init() will disable all non-vital * peripheral clocks, except for the peripheral clocks explicitly * enabled in conf_clock.h. */ sysclk_init(); // Enable the clock to the selected example Timer/counter peripheral module. sysclk_enable_peripheral_clock(EXAMPLE_TC); // Initialize the USART module for trace messages init_dbg_rs232(sysclk_get_pba_hz()); // Disable the interrupts cpu_irq_disable(); #if defined (__GNUC__) // Initialize interrupt vectors. INTC_init_interrupts(); // Register the RTC interrupt handler to the interrupt controller. INTC_register_interrupt(&tc_irq, EXAMPLE_TC_IRQ, EXAMPLE_TC_IRQ_PRIORITY); #endif // Enable the interrupts cpu_irq_enable(); // Initialize the timer module tc_init(tc); while (1) { // Update the display on USART every second. if ((update_timer) && (!(tc_tick%1000))) { timer++; // Set cursor to the position (1; 5) print_dbg("\x1B[5;1H"); // Print the timer value print_dbg("ATMEL AVR UC3 - Timer/Counter Example 3\n\rTimer: "); print_dbg_ulong(timer); print_dbg(" s"); // Reset the timer update flag to wait till next timer interrupt update_timer = false; } } }
int main (void) { // Initialize CPU clock to 48 MHz (configured in conf_clock.h) sysclk_init(); // Initialize the EVK1100 and its pin configuration board_init(); // Enable LED1 and LED2 as GPIO output gpio_enable_gpio_pin(LED0_GPIO); gpio_enable_gpio_pin(LED1_GPIO); gpio_configure_pin(LED0_GPIO, GPIO_DIR_OUTPUT); gpio_configure_pin(LED1_GPIO, GPIO_DIR_OUTPUT); // Define USART GPIO pin map static const gpio_map_t USART_GPIO_MAP = { {USART_RXD_PIN, USART_RXD_FUNCTION}, {USART_TXD_PIN, USART_TXD_FUNCTION} }; // Define USART options static usart_options_t usart_options = { .baudrate = 9600, .charlength = 8, .paritytype = USART_NO_PARITY, .stopbits = USART_1_STOPBIT, .channelmode = USART_NORMAL_CHMODE }; // Assign GPIO gpio_enable_module( USART_GPIO_MAP, sizeof(USART_GPIO_MAP) / sizeof(USART_GPIO_MAP[0]) ); // Initialize USART usart_init_rs232(USART, &usart_options, sysclk_get_pba_hz()); // Disable all interrupts Disable_global_interrupt(); // Initialize interrupt module INTC_init_interrupts(); // Define handler and configure interrupt with INT1 priority INTC_register_interrupt(&push_button_interrupt_handler, AVR32_GPIO_IRQ_0 + (GPIO_PUSH_BUTTON_1/8), AVR32_INTC_INT1); // Enable falling edge interrupt on Push Button 1 gpio_enable_pin_interrupt(GPIO_PUSH_BUTTON_1, GPIO_FALLING_EDGE); // Enable global interrupts Enable_global_interrupt(); // Set initial state // STATE_1 = LED0 On, LED1 Off // STATE_2 = LED0 Off, LED1 On gpio_set_pin_low(LED0_GPIO); gpio_set_pin_high(LED1_GPIO); while (1) { // If an interrupt has happened and run_once is true... if (run_once) { switch (state_indicator) { // ... and if current state is STATE_1... case STATE_1: // Activate LED0 and deactivate LED1 gpio_set_pin_low(LED0_GPIO); gpio_set_pin_high(LED1_GPIO); // Send debug message over USART usart_write_line(USART,"--------------\r\n"); usart_write_line(USART,"Interrupt detected on PB1\r\n"); usart_write_line(USART,"STATE_1 engaged!\r\n"); usart_write_line(USART,"LED1 = ON\r\n"); usart_write_line(USART,"LED2 = OFF\r\n"); usart_write_line(USART,"--------------\r\n"); break; // ... and if current state is STATE_2... case STATE_2: // Activate LED1 and deactivate LED0 gpio_set_pin_low(LED1_GPIO); gpio_set_pin_high(LED0_GPIO); // Send debug message over USART usart_write_line(USART,"--------------\r\n"); usart_write_line(USART,"Interrupt detected on PB1\r\n"); usart_write_line(USART,"STATE_2 engaged!\r\n"); usart_write_line(USART,"LED1 = OFF\r\n"); usart_write_line(USART,"LED2 = ON\r\n"); usart_write_line(USART,"--------------\r\n"); break; } // Reset run_once to false run_once = FALSE; } // Otherwise, do nothing! } }