//Initialize the clock void clock_init(void) { GlobalInterruptDisable(); INTC_RegisterGroupHandler(INTC_IRQ_GROUP(AVR32_TC_IRQ0), AVR32_INTC_INT0, tc_irq); GlobalInterruptEnable(); // Initialize the timer/counter. tc_init_waveform(tc, &WAVEFORM_OPT); // Initialize the timer/counter waveform. // Set the compare triggers. // Remember TC counter is 16-bits, so counting second is not possible with fPBA = 12 MHz. // We configure it to count ms. // We want: (1/(fPBA/8)) * RC = 0.001 s, hence RC = (fPBA/8) / 1000 = 1500 to get an interrupt every 1 ms. tc_write_rc(tc, TC_CHANNEL, (F_PBA_SPEED / 8) / 1000); // Set RC value. //tc_write_ra(tc, TC_CHANNEL, 0); // Set RA value. //tc_write_rb(tc, TC_CHANNEL, 1900); // Set RB value. //gpio_enable_module_pin(AVR32_TC_A0_0_1_PIN, AVR32_TC_A0_0_1_FUNCTION); //gpio_enable_module_pin(AVR32_TC_B0_0_1_PIN, AVR32_TC_B0_0_1_FUNCTION); tc_configure_interrupts(tc, TC_CHANNEL, &TC_INTERRUPT); // Start the timer/counter. tc_start(tc, TC_CHANNEL); // And start the timer/counter. }
void tc_init(void) { // The timer/counter instance and channel number are used in several functions. // It's defined as local variable for ease-of-use causes and readability. volatile avr32_tc_t *tc = WIFI_TC; // Options for waveform genration. tc_waveform_opt_t waveform_opt = { .channel = WIFI_TC_CHANNEL_ID, // Channel selection. .bswtrg = TC_EVT_EFFECT_NOOP, // Software trigger effect on TIOB. .beevt = TC_EVT_EFFECT_NOOP, // External event effect on TIOB. .bcpc = TC_EVT_EFFECT_NOOP, // RC compare effect on TIOB. .bcpb = TC_EVT_EFFECT_NOOP, // RB compare effect on TIOB. .aswtrg = TC_EVT_EFFECT_NOOP, // Software trigger effect on TIOA. .aeevt = TC_EVT_EFFECT_NOOP, // External event effect on TIOA. .acpc = TC_EVT_EFFECT_TOGGLE, // RC compare effect on TIOA: toggle. .acpa = TC_EVT_EFFECT_TOGGLE, // RA compare effect on TIOA: toggle (other possibilities are none, set and clear). .wavsel = TC_WAVEFORM_SEL_UP_MODE_RC_TRIGGER,// Waveform selection: Up mode with automatic trigger(reset) on RC compare. .enetrg = FALSE, // External event trigger enable. .eevt = TC_EXT_EVENT_SEL_TIOB_INPUT, // External event selection. .eevtedg = TC_SEL_NO_EDGE, // External event edge selection. .cpcdis = FALSE, // Counter disable when RC compare. .cpcstop = FALSE, // Counter clock stopped with RC compare. .burst = TC_BURST_NOT_GATED, // Burst signal selection. .clki = TC_CLOCK_RISING_EDGE, // Clock inversion. .tcclks = TC_CLOCK_SOURCE_TC2 // Internal source clock 3, connected to fPBA / 2. }; // Assign I/O to timer/counter channel pin & function. gpio_enable_module_pin(WIFI_TC_CHANNEL_PIN, WIFI_TC_CHANNEL_FUNCTION); // Initialize the timer/counter. tc_init_waveform(tc, &waveform_opt); // Initialize the timer/counter waveform. // Set the compare triggers. tc_write_ra(tc, WIFI_TC_CHANNEL_ID, 0x01A4); // Set RA value. tc_write_rc(tc, WIFI_TC_CHANNEL_ID, 0x0348); // Set RC value. // Start the timer/counter. tc_start(tc, WIFI_TC_CHANNEL_ID); }
/** * \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; } } }
/*! \brief Configure timer ISR to fire regularly. */ void init_timer (void) { volatile avr32_tc_t *tc = EXAMPLE_TC; /* options for waveform generation. */ static const tc_waveform_opt_t WAVEFORM_OPT = { .channel = EXAMPLE_TC_CHANNEL, /* Channel selection. */ .bswtrg = TC_EVT_EFFECT_NOOP, /* Software trigger effect on TIOB. */ .beevt = TC_EVT_EFFECT_NOOP, /* External event effect on TIOB. */ .bcpc = TC_EVT_EFFECT_NOOP, /* RC compare effect on TIOB. */ .bcpb = TC_EVT_EFFECT_NOOP, /* RB compare effect on TIOB. */ .aswtrg = TC_EVT_EFFECT_NOOP, /* Software trigger effect on TIOA. */ .aeevt = TC_EVT_EFFECT_NOOP, /* External event effect on TIOA. */ .acpc = TC_EVT_EFFECT_NOOP, /* RC compare effect on TIOA: toggle. */ .acpa = TC_EVT_EFFECT_NOOP, /* RA compare effect on TIOA: toggle (other possibilities are none, set and clear). */ .wavsel = TC_WAVEFORM_SEL_UP_MODE_RC_TRIGGER, /* Waveform selection: Up mode with automatic trigger(reset) on RC compare. */ .enetrg = 0u, /* External event trigger enable. */ .eevt = 0u, /* External event selection. */ .eevtedg = TC_SEL_NO_EDGE, /* External event edge selection. */ .cpcdis = 0u, /* Counter disable when RC compare. */ .cpcstop = 0u, /* Counter clock stopped with RC compare. */ .burst = 0u, /* Burst signal selection. */ .clki = 0u, /* Clock inversion. */ .tcclks = TC_CLOCK_SOURCE_TC3 /* Internal source clock 3, connected to fPBA / 8. */ }; static const tc_interrupt_t TC_INTERRUPT = { .etrgs = 0u, .ldrbs = 0u, .ldras = 0u, .cpcs = 1u, .cpbs = 0u, .cpas = 0u, .lovrs = 0u, .covfs = 0u }; /* initialize the timer/counter. */ tc_init_waveform (tc, &WAVEFORM_OPT); /* set the compare triggers. */ tc_write_rc (tc, EXAMPLE_TC_CHANNEL, EXAMPLE_RC_VALUE); /* configure Timer interrupt. */ tc_configure_interrupts (tc, EXAMPLE_TC_CHANNEL, &TC_INTERRUPT); /* start the timer/counter. */ tc_start (tc, EXAMPLE_TC_CHANNEL); } /*! \brief Timer compare ISR. */ #if (defined __GNUC__) __attribute__ ((__interrupt__)) #elif (defined __ICCAVR32__) __interrupt #endif static void tc_irq (void) { /* update the current time */ current_time_ms_touch++; /* every 25th ms */ if ((current_time_ms_touch % measurement_period_ms) == 0u) { /* set flag: it's time to measure touch */ time_to_measure_touch = 1u; } /* clear the interrupt flag. This is a side effect of reading the TC SR. */ tc_read_sr (EXAMPLE_TC, EXAMPLE_TC_CHANNEL); }
/** * \brief Initializes the TC subsystem ready to generate a LED PWM wave. * * Initializes the on-chip TC module in PWM generation mode, and configures the * board LED as an output so that the LED brightness can be adjusted. */ static void pwm_timer_init(void) { // Assign output pin to timer/counter 0 channel B gpio_enable_module_pin(AVR32_TC0_B0_0_0_PIN, AVR32_TC0_B0_0_0_FUNCTION); // Timer waveform options const tc_waveform_opt_t waveform_options = { //! Channel selection. .channel = 0, //! 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_CLEAR, //! RB compare effect on TIOB. .bcpb = TC_EVT_EFFECT_SET, //! 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. .acpa = TC_EVT_EFFECT_NOOP, //! Waveform selection .wavsel = TC_WAVEFORM_SEL_UP_MODE_RC_TRIGGER, //! External event trigger enable. .enetrg = false, //! External event selection (non-zero for Channel B to work) .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 selection. .clki = false, //! Internal source clock 5, fPBA/128. .tcclks = TC_CLOCK_SOURCE_TC5, }; // Setup timer/counter waveform mode sysclk_enable_peripheral_clock(&AVR32_TC0); tc_init_waveform(&AVR32_TC0, &waveform_options); // Write the TOP (RC) and COMPARE (RB) values tc_write_rb(&AVR32_TC0, 0, 1); // Set RB value. tc_write_rc(&AVR32_TC0, 0, 255); // Set RC value. // Start the timer PWM channel tc_start(&AVR32_TC0, 0); } /** * \brief Application main routine */ int main(void) { board_init(); sysclk_init(); irq_initialize_vectors(); cpu_irq_enable(); pwm_timer_init(); touch_init(); while (true) { touch_handler(); } }
/** * \name PWM functions * @{ */ void ui_pwm_led_init(uint8_t lednum) { /* Timer waveform options */ static tc_waveform_opt_t waveform_options = { /* Channel selection. */ .channel = 1, .bswtrg = TC_EVT_EFFECT_NOOP, .beevt = TC_EVT_EFFECT_NOOP, .bcpc = TC_EVT_EFFECT_NOOP, .bcpb = TC_EVT_EFFECT_NOOP, .aswtrg = TC_EVT_EFFECT_NOOP, .aeevt = TC_EVT_EFFECT_NOOP, .acpc = TC_EVT_EFFECT_NOOP, .acpa = TC_EVT_EFFECT_NOOP, /* Waveform selection */ .wavsel = TC_WAVEFORM_SEL_UP_MODE_RC_TRIGGER, /* External event trigger enable. */ .enetrg = false, /* External event selection (non-zero for Channel B to work) */ .eevt = !0, /* External event edge selection. */ .eevtedg = TC_SEL_NO_EDGE, .cpcdis = false, .cpcstop = false, .burst = false, .clki = false, /* Internal source clock 5, fPBA/128. */ .tcclks = TC_CLOCK_SOURCE_TC5, }; switch (lednum) { case LED0: /* Assign output pin to timer/counter 0 channel A */ /* Channel selection. */ waveform_options.channel = 1; waveform_options.bcpc = TC_EVT_EFFECT_NOOP; waveform_options.bcpb = TC_EVT_EFFECT_NOOP; /* RC compare effect on TIOA. */ waveform_options.acpc = TC_EVT_EFFECT_CLEAR; /* RA compare effect on TIOA. */ waveform_options.acpa = TC_EVT_EFFECT_SET; /* Setup timer/counter waveform mode */ sysclk_enable_peripheral_clock(&AVR32_TC0); tc_init_waveform(&AVR32_TC0, &waveform_options); /* Write the TOP (RC) and COMPARE (RA) values */ tc_write_ra(&AVR32_TC0, 1, 1); /* Set RA value. */ tc_write_rc(&AVR32_TC0, 1, 255); /* Set RC value. */ /* Start the timer PWM channel */ tc_start(&AVR32_TC0, 1); break; case LED1: /* Assign output pin to timer/counter 1 channel B */ /* Channel selection. */ waveform_options.channel = 2; waveform_options.acpc = TC_EVT_EFFECT_NOOP; waveform_options.acpa = TC_EVT_EFFECT_NOOP; /* RC compare effect on TIOB. */ waveform_options.bcpc = TC_EVT_EFFECT_CLEAR; /* RB compare effect on TIOB. */ waveform_options.bcpb = TC_EVT_EFFECT_SET; /* Setup timer/counter waveform mode */ sysclk_enable_peripheral_clock(&AVR32_TC1); tc_init_waveform(&AVR32_TC1, &waveform_options); /* Write the TOP (RC) and COMPARE (RB) values */ tc_write_rb(&AVR32_TC1, 2, 1); /* Set RB value. */ tc_write_rc(&AVR32_TC1, 2, 255); /* Set RC value. */ /* Start the timer PWM channel */ tc_start(&AVR32_TC1, 2); break; default: break; } } void ui_pwm_update(uint8_t channum, uint8_t brightness) { switch (channum) { case LED0: if (brightness != 0) { gpio_enable_module_pin(AVR32_TC0_A1_0_1_PIN, AVR32_TC0_A1_0_1_FUNCTION); tc_start(&AVR32_TC0, 1); tc_write_ra(&AVR32_TC0, 1, brightness); } else { tc_stop(&AVR32_TC0, 1); LED_Off(LED0); } break; case LED1: if (brightness != 0) { gpio_enable_module_pin(AVR32_TC1_B2_0_PIN, AVR32_TC1_B2_0_FUNCTION); tc_start(&AVR32_TC1, 2); tc_write_rb(&AVR32_TC1, 2, brightness); } else { tc_stop(&AVR32_TC1, 2); LED_Off(LED0); } break; default: break; } } /* End of PWM */ /** @} */ /** * \name Display functions * @{ */ static void ui_display_enable(void) { delay_init(sysclk_get_cpu_hz()); et024006_Init( sysclk_get_cpu_hz(), sysclk_get_hsb_hz()); /* Clear the display i.e. make it black */ et024006_DrawFilledRect(0, 0, ET024006_WIDTH, ET024006_HEIGHT, BLACK ); /* Set the backlight. */ gpio_set_gpio_pin(ET024006DHU_BL_PIN); ui_display_init_rtc(); ui_display_welcome_msg(); }
/** * \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; } } }
// initialize application timer extern void init_tc (volatile avr32_tc_t *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 / 128 / 1000)); // configure the timer interrupt tc_configure_interrupts(tc, APP_TC_CHANNEL, &tc_interrupt); // Start the timer/counter. tc_start(tc, APP_TC_CHANNEL); } // initialize usb USARTy void init_ftdi_usart (void) { // GPIO map for USART. static const gpio_map_t FTDI_USART_GPIO_MAP = { { FTDI_USART_RX_PIN, FTDI_USART_RX_FUNCTION }, { FTDI_USART_TX_PIN, FTDI_USART_TX_FUNCTION } }; // Options for USART. static const usart_options_t FTDI_USART_OPTIONS = { .baudrate = FTDI_USART_BAUDRATE, .charlength = 8, .paritytype = USART_NO_PARITY, .stopbits = USART_1_STOPBIT, .channelmode = USART_NORMAL_CHMODE }; // Set up GPIO for FTDI_USART gpio_enable_module(FTDI_USART_GPIO_MAP, sizeof(FTDI_USART_GPIO_MAP) / sizeof(FTDI_USART_GPIO_MAP[0])); // Initialize in RS232 mode. usart_init_rs232(FTDI_USART, &FTDI_USART_OPTIONS, FPBA_HZ); } // initialize spi1: OLED, ADC, SD/MMC extern void init_spi1 (void) { static const gpio_map_t OLED_SPI_GPIO_MAP = { {OLED_SPI_SCK_PIN, OLED_SPI_SCK_FUNCTION }, {OLED_SPI_MISO_PIN, OLED_SPI_MISO_FUNCTION}, {OLED_SPI_MOSI_PIN, OLED_SPI_MOSI_FUNCTION}, {OLED_SPI_NPCS0_PIN, OLED_SPI_NPCS0_FUNCTION }, {OLED_SPI_NPCS1_PIN, OLED_SPI_NPCS1_FUNCTION }, {OLED_SPI_NPCS2_PIN, OLED_SPI_NPCS2_FUNCTION }, }; // SPI options for OLED spi_options_t spiOptions = { .reg = OLED_SPI_NPCS, .baudrate = 40000000, .bits = 8, .trans_delay = 0, .spck_delay = 0, .stay_act = 1, .spi_mode = 3, .modfdis = 1 }; // Assign GPIO to SPI. gpio_enable_module(OLED_SPI_GPIO_MAP, sizeof(OLED_SPI_GPIO_MAP) / sizeof(OLED_SPI_GPIO_MAP[0])); // Initialize as master. spi_initMaster(OLED_SPI, &spiOptions); // Set SPI selection mode: variable_ps, pcs_decode, delay. spi_selectionMode(OLED_SPI, 0, 0, 0); // Enable SPI module. spi_enable(OLED_SPI); // setup chip register for OLED spi_setupChipReg( OLED_SPI, &spiOptions, FPBA_HZ ); // add ADC chip register spiOptions.reg = ADC_SPI_NPCS; 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( ADC_SPI, &spiOptions, FPBA_HZ ); // add SD/MMC chip register spiOptions.reg = SD_MMC_SPI_NPCS; spiOptions.baudrate = SD_MMC_SPI_MASTER_SPEED; // Defined in conf_sd_mmc_spi.h; spiOptions.bits = SD_MMC_SPI_BITS; // Defined in conf_sd_mmc_spi.h; spiOptions.spck_delay = 0; spiOptions.trans_delay = 0; spiOptions.stay_act = 1; spiOptions.spi_mode = 0; spiOptions.modfdis = 1; // Initialize SD/MMC driver with SPI clock (PBA). sd_mmc_spi_init(spiOptions, FPBA_HZ); } // init PDCA (Peripheral DMA Controller A) resources for the SPI transfer and start a dummy transfer void init_local_pdca(void) { // PDCA channel for SPI RX pdca_channel_options_t pdca_options_SPI_RX ={ // pdca channel options .addr = (void *)&pdcaRxBuf, .size = FS_BUF_SIZE, // transfer size .r_addr = NULL, // next memory address after 1st transfer complete .r_size = 0, // next transfer counter not used here .pid = AVR32_PDCA_CHANNEL_USED_RX, // select peripheral ID - SPI1 RX .transfer_size = PDCA_TRANSFER_SIZE_BYTE // select size of the transfer: 8,16,32 bits }; // PDCA channel for SPI TX pdca_channel_options_t pdca_options_SPI_TX ={ // pdca channel options .addr = (void *)&pdcaTxBuf, // memory address. .size = FS_BUF_SIZE, // transfer size .r_addr = NULL, // next memory address after 1st transfer complete .r_size = 0, // next transfer counter not used here .pid = AVR32_PDCA_CHANNEL_USED_TX, // select peripheral ID - SPI1 TX .transfer_size = PDCA_TRANSFER_SIZE_BYTE // select size of the transfer: 8,16,32 bits }; // Init PDCA transmission channel pdca_init_channel(AVR32_PDCA_CHANNEL_SPI_TX, &pdca_options_SPI_TX); // Init PDCA Reception channel pdca_init_channel(AVR32_PDCA_CHANNEL_SPI_RX, &pdca_options_SPI_RX); } // intialize resources for bf533 communication: SPI, GPIO void init_bfin_resources(void) { static const gpio_map_t BFIN_SPI_GPIO_MAP = { { BFIN_SPI_SCK_PIN, BFIN_SPI_SCK_FUNCTION }, { BFIN_SPI_MISO_PIN, BFIN_SPI_MISO_FUNCTION }, { BFIN_SPI_MOSI_PIN, BFIN_SPI_MOSI_FUNCTION }, { BFIN_SPI_NPCS0_PIN, BFIN_SPI_NPCS0_FUNCTION }, }; spi_options_t spiOptions = { .reg = BFIN_SPI_NPCS, //// FIXME: //// would prefer fast baudrate / lower trans delay during boot, //// but need multiple registers for boot (fast) and run (slow) //// investigate if this is possible... // .baudrate = 20000000, // .baudrate = 10000000, // .baudrate = 5000000, .baudrate = 20000000, .bits = 8, .spck_delay = 0, // .trans_delay = 0, .trans_delay = 20, .stay_act = 1, .spi_mode = 1, .modfdis = 1 }; // assign pins to SPI. gpio_enable_module(BFIN_SPI_GPIO_MAP, sizeof(BFIN_SPI_GPIO_MAP) / sizeof(BFIN_SPI_GPIO_MAP[0])); // intialize as master spi_initMaster(BFIN_SPI, &spiOptions); // set selection mode: variable_ps, pcs_decode, delay. spi_selectionMode(BFIN_SPI, 0, 0, 0); // enable SPI. spi_enable(BFIN_SPI); // intialize the chip register spi_setupChipReg(BFIN_SPI, &spiOptions, FPBA_HZ); // enable pulldown on bfin HWAIT line //// shit! not implemented... // gpio_enable_pin_pull_down(BFIN_HWAIT_PIN); // enable pullup on bfin RESET line gpio_enable_pin_pull_up(BFIN_RESET_PIN); } // intialize two-wire interface void init_twi(void) { // TWI/I2C GPIO map static const gpio_map_t TWI_GPIO_MAP = { { TWI_DATA_PIN, TWI_DATA_FUNCTION }, { TWI_CLOCK_PIN, TWI_CLOCK_FUNCTION } }; gpio_enable_module(TWI_GPIO_MAP, sizeof(TWI_GPIO_MAP) / sizeof(TWI_GPIO_MAP[0])); } // initialize USB host stack void init_usb_host (void) { // pm_configure_usb_clock(); uhc_start(); }
static void tc_init_fast(volatile avr32_tc_t *tc) { // Options for waveform generation. static const tc_waveform_opt_t waveform_opt_1 = { .channel = FAST_TC_CHANNEL, // Channel selection. .bswtrg = TC_EVT_EFFECT_NOOP, // Software trigger effect on TIOB. .beevt = TC_EVT_EFFECT_NOOP, // External event effect on TIOB. .bcpc = TC_EVT_EFFECT_NOOP, // RC compare effect on TIOB. .bcpb = TC_EVT_EFFECT_NOOP, // RB compare effect on TIOB. .aswtrg = TC_EVT_EFFECT_NOOP, // Software trigger effect on TIOA. .aeevt = TC_EVT_EFFECT_NOOP, // External event effect on TIOA. .acpc = TC_EVT_EFFECT_NOOP, // RC compare effect on TIOA. .acpa = TC_EVT_EFFECT_NOOP, //RA compare effect on TIOA. .wavsel = TC_WAVEFORM_SEL_UP_MODE_RC_TRIGGER, //Waveform selection: Up mode with automatic trigger(reset) .enetrg = false, //// External event trigger enable. .eevt = 0, //// External event selection. .eevtedg = TC_SEL_NO_EDGE, //// External event edge selection. .cpcdis = false, // Counter disable when RC compare. .cpcstop = false, // Counter clock stopped with RC compare. .burst = false, // Burst signal selection .clki = false, // Clock inversion. .tcclks = TC_CLOCK_SOURCE_TC3 // Internal source clock 3, connected to fPBA / 8. }; // 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_1); tc_write_rc(tc, FAST_TC_CHANNEL, 10); // configure the timer interrupt tc_configure_interrupts(tc, FAST_TC_CHANNEL, &tc_interrupt); } static void tc_init_slow(volatile avr32_tc_t *tc) { // Options for waveform generation. static const tc_waveform_opt_t waveform_opt_2 = { .channel = SLOW_TC_fast_CHANNEL, // Channel selection. .bswtrg = TC_EVT_EFFECT_NOOP, // Software trigger effect on TIOB. .beevt = TC_EVT_EFFECT_NOOP, // External event effect on TIOB. .bcpc = TC_EVT_EFFECT_NOOP, // RC compare effect on TIOB. .bcpb = TC_EVT_EFFECT_NOOP, // RB compare effect on TIOB. .aswtrg = TC_EVT_EFFECT_NOOP, // Software trigger effect on TIOA. .aeevt = TC_EVT_EFFECT_NOOP, // External event effect on TIOA. .acpc = TC_EVT_EFFECT_CLEAR, // RC compare effect on TIOA. .acpa = TC_EVT_EFFECT_SET, // RA compare effect on TIOA. .wavsel = TC_WAVEFORM_SEL_UP_MODE_RC_TRIGGER, //Waveform selection: Up mode with automatic trigger(reset) .enetrg = false, // External event trigger enable. .eevt = 0, // External event selection. .eevtedg = TC_SEL_NO_EDGE, // External event edge selection. .cpcdis = false, // Counter disable when RC compare. .cpcstop = false, // Counter clock stopped with RC compare. .burst = false, // Burst signal selection. .clki = false, // Clock inversion. .tcclks = TC_CLOCK_SOURCE_TC3 // Internal source clock 3, connected to fPBA / 8. }; // Initialize the timer/counter. tc_init_waveform(tc, &waveform_opt_2); tc_write_rc(tc, SLOW_TC_fast_CHANNEL, 7500); //counter will count milliseconds tc_write_ra(tc, SLOW_TC_fast_CHANNEL, 3500); //configure ra so that TIOA0 is toggled static const tc_waveform_opt_t waveform_opt_3 = { .channel = SLOW_TC_slow_CHANNEL, // Channel selection. .bswtrg = TC_EVT_EFFECT_NOOP, // Software trigger effect on TIOB. .beevt = TC_EVT_EFFECT_NOOP, // External event effect on TIOB. .bcpc = TC_EVT_EFFECT_NOOP, // RC compare effect on TIOB. .bcpb = TC_EVT_EFFECT_NOOP, // RB compare effect on TIOB. .aswtrg = TC_EVT_EFFECT_NOOP, // Software trigger effect on TIOA. .aeevt = TC_EVT_EFFECT_NOOP, // External event effect on TIOA. .acpc = TC_EVT_EFFECT_NOOP, // RC compare effect on TIOA. .acpa = TC_EVT_EFFECT_NOOP, //RA compare effect on TIOA. .wavsel = TC_WAVEFORM_SEL_UP_MODE_RC_TRIGGER, //Waveform selection: Up mode with automatic trigger(reset) .enetrg = false, //// External event trigger enable. .eevt = 0, //// External event selection. .eevtedg = TC_SEL_NO_EDGE, //// External event edge selection. .cpcdis = false, // Counter disable when RC compare. .cpcstop = false, // Counter clock stopped with RC compare. .burst = false, // Burst signal selection. .clki = false, // Clock inversion. .tcclks = TC_CLOCK_SOURCE_XC0 // Use XC1 as clock source. Must configure TIOA0 to be XC1 }; tc_init_waveform(tc, &waveform_opt_3); tc_write_rc(tc, SLOW_TC_slow_CHANNEL, 100); // tc_select_external_clock(tc,SLOW_TC_slow_CHANNEL,AVR32_TC_BMR_TC0XC0S_TIOA1); //use TIOA1 as XC0 } static void configure_hmatrix(uint32_t mode) { // Configure all Slave in Last Default Master #if (defined AVR32_HMATRIX) for(uint32_t i = 0; i < AVR32_HMATRIX_SLAVE_NUM; i++) { AVR32_HMATRIX.SCFG[i].defmstr_type = mode; } #endif #if (defined AVR32_HMATRIXB) for(uint32_t i = 0;i < AVR32_HMATRIXB_SLAVE_NUM; i++) { AVR32_HMATRIXB.SCFG[i].defmstr_type = mode; } #endif } void board_init(void) { /* This function is meant to contain board-specific initialization code * for, e.g., the I/O pins. The initialization can rely on application- * specific board configuration, found in conf_board.h. */ gpio_local_init(); static pcl_freq_param_t pcl_freq_param = { .cpu_f = CPU_SPEED, .pba_f = PBA_SPEED, .osc0_f = FOSC0, .osc0_startup = OSC0_STARTUP }; if (pcl_configure_clocks(&pcl_freq_param) != PASS) while (true); configure_hmatrix(AVR32_HMATRIXB_DEFMSTR_TYPE_NO_DEFAULT); AVR32_LowLevelInit(); //configure all GPIO gpio_local_enable_pin_output_driver(ADC_CONV_pin); gpio_local_clr_gpio_pin(ADC_CONV_pin); gpio_local_enable_pin_output_driver(DDS_IOUD_pin); gpio_local_clr_gpio_pin(DDS_IOUD_pin); gpio_local_enable_pin_output_driver(DDS_RESET_pin); gpio_local_clr_gpio_pin(DDS_RESET_pin); gpio_local_enable_pin_output_driver(DDS_PDN_pin); gpio_local_set_gpio_pin(DDS_PDN_pin); gpio_local_enable_pin_output_driver(DDS_P0_pin); gpio_local_clr_gpio_pin(DDS_P0_pin); gpio_local_enable_pin_output_driver(DDS_P1_pin); gpio_local_clr_gpio_pin(DDS_P1_pin); gpio_local_enable_pin_output_driver(DDS_P2_pin); gpio_local_clr_gpio_pin(DDS_P2_pin); gpio_local_enable_pin_output_driver(DDS_P3_pin); gpio_local_clr_gpio_pin(DDS_P3_pin); gpio_local_enable_pin_output_driver(RXSW_pin); gpio_local_clr_gpio_pin(RXSW_pin); gpio_local_enable_pin_output_driver(TXSW_pin); gpio_local_clr_gpio_pin(TXSW_pin); gpio_local_enable_pin_output_driver(TPAbias_pin); gpio_local_clr_gpio_pin(TPAbias_pin); gpio_local_enable_pin_output_driver(GEN1_pin); gpio_local_clr_gpio_pin(GEN1_pin); gpio_local_enable_pin_output_driver(GEN2_pin); gpio_local_clr_gpio_pin(GEN2_pin); gpio_local_enable_pin_output_driver(PWM0_pin); gpio_local_clr_gpio_pin(PWM0_pin); gpio_local_disable_pin_output_driver(SD_detect_pin); //configure all peripheral IO static const gpio_map_t GCLK_GPIO_MAP = { {AVR32_SCIF_GCLK_0_1_PIN, AVR32_SCIF_GCLK_0_1_FUNCTION} }; gpio_enable_module(GCLK_GPIO_MAP, sizeof(GCLK_GPIO_MAP) / sizeof(GCLK_GPIO_MAP[0])); genclk_enable_config(9, GENCLK_SRC_CLK_CPU, 2); static const gpio_map_t SPI_GPIO_MAP = { {SPI1_SCK_PIN, SPI1_SCK_FUNCTION}, {SPI1_MOSI_PIN, SPI1_MOSI_FUNCTION}, {SPI1_MISO_PIN, SPI1_MISO_FUNCTION}, {SPI1_NPCS2_PIN, SPI1_NPCS2_FUNCTION} }; gpio_enable_module(SPI_GPIO_MAP, sizeof(SPI_GPIO_MAP) / sizeof(SPI_GPIO_MAP[0])); spi_options_t SPI1_OPTIONS_0 = { .reg = 0, //! The SPI channel to set up. .baudrate = 30000000, //! Preferred baudrate for the SPI. .bits =16, //! Number of bits in each character (8 to 16). .spck_delay =0, //! Delay before first clock pulse after selecting slave (in PBA clock periods). .trans_delay =0, //! Delay between each transfer/character (in PBA clock periods). .stay_act =0, //! Sets this chip to stay active after last transfer to it. .spi_mode =1, //! Which SPI mode to use when transmitting. .modfdis =1 //! Disables the mode fault detection. }; spi_options_t SPI1_OPTIONS_3 = { .reg = 3, //! The SPI channel to set up. .baudrate = 30000000, //! Preferred baudrate for the SPI. .bits =8, //! Number of bits in each character (8 to 16). .spck_delay =0, //! Delay before first clock pulse after selecting slave (in PBA clock periods). .trans_delay =0, //! Delay between each transfer/character (in PBA clock periods). .stay_act =1, //! Sets this chip to stay active after last transfer to it. .spi_mode =0, //! Which SPI mode to use when transmitting. .modfdis =1 //! Disables the mode fault detection. }; spi_initMaster(SPI1, &SPI1_OPTIONS_0); spi_selectionMode(SPI1,1,0,0); spi_enable(SPI1); spi_setupChipReg(SPI1,&SPI1_OPTIONS_0,PBA_SPEED); spi_setupChipReg(SPI1,&SPI1_OPTIONS_3,PBA_SPEED); spi_selectChip(SPI1, 3); static const gpio_map_t USB_USART_GPIO_MAP = { {USB_USART_RX_PIN, USB_USART_RX_FUNCTION}, {USB_USART_TX_PIN, USB_USART_TX_FUNCTION}, {USB_USART_RTS_PIN, USB_USART_RTS_FUNCTION}, {USB_USART_CTS_PIN, USB_USART_CTS_FUNCTION} }; gpio_enable_module(USB_USART_GPIO_MAP, sizeof(USB_USART_GPIO_MAP) / sizeof(USB_USART_GPIO_MAP[0])); static const usart_options_t USB_USART_OPTIONS = { .baudrate = 3000000, .charlength = 8, .paritytype = USART_NO_PARITY, .stopbits = USART_1_STOPBIT, .channelmode = USART_NORMAL_CHMODE }; usart_init_hw_handshaking(USB_USART, &USB_USART_OPTIONS, PBA_SPEED); static const gpio_map_t LCD_USART_GPIO_MAP = { {LCD_USART_RX_PIN, LCD_USART_RX_FUNCTION}, {LCD_USART_TX_PIN, LCD_USART_TX_FUNCTION} }; gpio_enable_module(LCD_USART_GPIO_MAP, sizeof(LCD_USART_GPIO_MAP) / sizeof(LCD_USART_GPIO_MAP[0])); static const usart_options_t LCD_USART_OPTIONS = { .baudrate = 115200, .charlength = 8, .paritytype = USART_NO_PARITY, .stopbits = USART_1_STOPBIT, .channelmode = USART_NORMAL_CHMODE }; usart_init_rs232(LCD_USART, &LCD_USART_OPTIONS, PBA_SPEED); LCD_USART->cr|=AVR32_USART_CR_STTTO_MASK; //set timeout to stop until new character is received LCD_USART->rtor=230; //set to timeout in 2ms my_pdca_init_channel(LCD_USART_RX_PDCA_CHANNEL, (uint32_t)(&LCD_USART_buffer),(uint32_t)(sizeof(LCD_USART_buffer)),LCD_USART_RX_PDCA_PID,0,0, PDCA_TRANSFER_SIZE_BYTE); pdca_disable(LCD_USART_RX_PDCA_CHANNEL); my_pdca_init_channel(USB_USART_RX_PDCA_CHANNEL, (uint32_t)(&host_USART_buffer),(uint32_t)(sizeof(host_USART_buffer)),USB_USART_RX_PDCA_PID,0,0, PDCA_TRANSFER_SIZE_BYTE); pdca_disable(USB_USART_RX_PDCA_CHANNEL); USB_USART->cr|=AVR32_USART_CR_STTTO_MASK; //set timeout to stop until new character is received USB_USART->rtor=15000; //set to timeout in 1ms // GPIO pins used for SD/MMC interface static const gpio_map_t SD_MMC_SPI_GPIO_MAP = { {SPI0_SCK_PIN, SPI0_SCK_FUNCTION }, // SPI Clock. {SPI0_MISO_PIN, SPI0_MISO_FUNCTION}, // MISO. {SPI0_MOSI_PIN, SPI0_MOSI_FUNCTION}, // MOSI. {SPI0_NPCS0_PIN, SPI0_NPCS0_FUNCTION} // Chip Select NPCS. }; //SPI options. spi_options_t SD_spiOptions = { .reg = SD_MMC_SPI_NPCS, .baudrate = SD_SPI_SPEED, // Defined in conf_sd_mmc_spi.h. .bits = 8, // Defined in conf_sd_mmc_spi.h. .spck_delay = 0, .trans_delay = 0, .stay_act = 1, .spi_mode = 0, .modfdis = 1 }; // Assign I/Os to SPI. gpio_enable_module(SD_MMC_SPI_GPIO_MAP,sizeof(SD_MMC_SPI_GPIO_MAP) / sizeof(SD_MMC_SPI_GPIO_MAP[0])); // Initialize as master. spi_initMaster(SPI0, &SD_spiOptions); // Set SPI selection mode: variable_ps, pcs_decode, delay. spi_selectionMode(SPI0, 0, 0, 0); // Enable SPI module. spi_enable(SPI0); // Initialize SD/MMC driver with SPI clock (PBA). sd_mmc_spi_init(SD_spiOptions, PBA_SPEED); tc_init_fast(FAST_TC); tc_init_slow(SLOW_TC); static const gpio_map_t DACIFB_GPIO_MAP = { {AVR32_DACREF_PIN,AVR32_DACREF_FUNCTION}, {AVR32_ADCREFP_PIN,AVR32_ADCREFP_FUNCTION}, {AVR32_ADCREFN_PIN,AVR32_ADCREFN_FUNCTION}, {DAC0A_pin, DAC0A_FUNCTION}, {DAC1A_pin, DAC1A_FUNCTION} }; gpio_enable_module(DACIFB_GPIO_MAP, sizeof(DACIFB_GPIO_MAP) / sizeof(DACIFB_GPIO_MAP[0])); dacifb_opt_t dacifb_opt = { .reference = DACIFB_REFERENCE_EXT , // VDDANA Reference .channel_selection = DACIFB_CHANNEL_SELECTION_A, // Selection Channels A&B .low_power = false, // Low Power Mode .dual = false, // Dual Mode .prescaler_clock_hz = DAC_PRESCALER_CLK // Prescaler Clock (Should be 500Khz) }; // DAC Channel Configuration dacifb_channel_opt_t dacifb_channel_opt = { .auto_refresh_mode = true, // Auto Refresh Mode .trigger_mode = DACIFB_TRIGGER_MODE_MANUAL, // Trigger selection .left_adjustment = false, // Right Adjustment .data_shift = 0, // Number of Data Shift .data_round_enable = false // Data Rouding Mode }; }; volatile avr32_dacifb_t *dacifb0 = &AVR32_DACIFB0; // DACIFB IP registers address volatile avr32_dacifb_t *dacifb1 = &AVR32_DACIFB1; // DACIFB IP registers address //The factory calibration for DADIFB is broken, so use manual calibration //dacifb_get_calibration_data(DAC0,&dacifb_opt,0); dacifb_opt.gain_calibration_value=0x0090; dacifb_opt.offset_calibration_value=0x0153; // configure DACIFB0 dacifb_configure(DAC0,&dacifb_opt,PBA_SPEED); dacifb_configure_channel(DAC0,DACIFB_CHANNEL_SELECTION_A,&dacifb_channel_opt,DAC_PRESCALER_CLK); dacifb_start_channel(DAC0,DACIFB_CHANNEL_SELECTION_A,PBA_SPEED); //The factory calibration for DADIFB is broken, so use manual calibration dacifb_set_value(DAC0,DACIFB_CHANNEL_SELECTION_A,false,1024); //dacifb_get_calibration_data(DAC1, &dacifb_opt,1); dacifb_opt.gain_calibration_value=0x0084; dacifb_opt.offset_calibration_value=0x0102; // configure DACIFB1 dacifb_configure(DAC1,&dacifb_opt,PBA_SPEED); dacifb_configure_channel(DAC1,DACIFB_CHANNEL_SELECTION_A,&dacifb_channel_opt,DAC_PRESCALER_CLK); dacifb_start_channel(DAC1,DACIFB_CHANNEL_SELECTION_A,PBA_SPEED); dacifb_set_value(DAC1,DACIFB_CHANNEL_SELECTION_A,false,1024); DAC0->dr0=2048; DAC1->dr0=4095; }
void setup_timer_controller(__int_handler handler) { // 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 }; sysclk_enable_peripheral_clock((&AVR32_TC)); cpu_irq_disable(); INTC_init_interrupts(); INTC_register_interrupt(handler, EXAMPLE_TC_IRQ, EXAMPLE_TC_IRQ_PRIORITY); cpu_irq_enable(); // Initialize the timer/counter. tc_init_waveform((&AVR32_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((&AVR32_TC), EXAMPLE_TC_CHANNEL, (sysclk_get_pba_hz() / 8 / 1000)); // tc_write_rc((&AVR32_TC), EXAMPLE_TC_CHANNEL, (sysclk_get_pba_hz() / 8 / 2000)); tc_write_rc((&AVR32_TC), EXAMPLE_TC_CHANNEL, (12 * MHz / 8 / 325)); // configure the timer interrupt tc_configure_interrupts((&AVR32_TC), EXAMPLE_TC_CHANNEL, &tc_interrupt); // Start the timer/counter. tc_start((&AVR32_TC), EXAMPLE_TC_CHANNEL); }
/** * \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"); */ }
/** * \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(); }
void PWM_timer_init(void) { //MUST CHANGE BACK!!!!! collective = 100; yaw = 0; pitch = 0; roll = 0; t_a = 0; t_b = 0; t_c = 0; t_r = 0; //Set up the GPIO pins for output of the timers gpio_enable_module_pin(AVR32_TC1_A2_0_PIN, AVR32_TC1_A2_0_FUNCTION); gpio_enable_module_pin(AVR32_TC1_B0_0_PIN, AVR32_TC1_B0_0_FUNCTION); gpio_enable_module_pin(AVR32_TC1_B1_0_PIN, AVR32_TC1_B1_0_FUNCTION); gpio_enable_module_pin(AVR32_TC0_B2_0_PIN, AVR32_TC0_B2_0_FUNCTION); gpio_enable_module_pin(AVR32_TC0_B0_0_0_PIN, AVR32_TC0_B0_0_0_FUNCTION); // Timer waveform options const tc_waveform_opt_t waveform_options_b0_1 = { //! Channel selection. .channel = 0, //! 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_CLEAR, //! RB compare effect on TIOB. .bcpb = TC_EVT_EFFECT_SET, //! 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. .acpa = TC_EVT_EFFECT_NOOP, //! Waveform selection .wavsel = TC_WAVEFORM_SEL_UP_MODE_RC_TRIGGER, //! External event trigger enable. .enetrg = false, //! External event selection (non-zero for Channel B to work) .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 selection. .clki = false, //! Internal source clock 5, fPBA/128. .tcclks = TC_CLOCK_SOURCE_TC4, }; const tc_waveform_opt_t waveform_options_b0_0 = { //! Channel selection. .channel = 0, //! 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_CLEAR, //! RB compare effect on TIOB. .bcpb = TC_EVT_EFFECT_SET, //! 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. .acpa = TC_EVT_EFFECT_NOOP, //! Waveform selection .wavsel = TC_WAVEFORM_SEL_UP_MODE_RC_TRIGGER, //! External event trigger enable. .enetrg = false, //! External event selection (non-zero for Channel B to work) .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 selection. .clki = false, //! Internal source clock 5, fPBA/128. .tcclks = TC_CLOCK_SOURCE_TC4, }; const tc_waveform_opt_t waveform_options_b1 = { //! Channel selection. .channel = 1, //! 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_CLEAR, //! RB compare effect on TIOB. .bcpb = TC_EVT_EFFECT_SET, //! 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. .acpa = TC_EVT_EFFECT_NOOP, //! Waveform selection .wavsel = TC_WAVEFORM_SEL_UP_MODE_RC_TRIGGER, //! External event trigger enable. .enetrg = false, //! External event selection (non-zero for Channel B to work) .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 selection. .clki = false, //! Internal source clock 5, fPBA/128. .tcclks = TC_CLOCK_SOURCE_TC4, }; const tc_waveform_opt_t waveform_options_b2 = { //! Channel selection. .channel = 2, //! 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_CLEAR, //! RB compare effect on TIOB. .bcpb = TC_EVT_EFFECT_SET, //! 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_CLEAR, //! RA compare effect on TIOA. .acpa = TC_EVT_EFFECT_SET, //! Waveform selection .wavsel = TC_WAVEFORM_SEL_UP_MODE_RC_TRIGGER, //! External event trigger enable. .enetrg = false, //! External event selection (non-zero for Channel B to work) .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 selection. .clki = false, //! Internal source clock 5, fPBA/128. .tcclks = TC_CLOCK_SOURCE_TC4, }; const tc_waveform_opt_t waveform_options_a2 = { //! Channel selection. .channel = 2, //! 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_CLEAR, //! RA compare effect on TIOA. .acpa = TC_EVT_EFFECT_SET, //! Waveform selection .wavsel = TC_WAVEFORM_SEL_UP_MODE_RC_TRIGGER, //! External event trigger enable. .enetrg = false, //! External event selection (non-zero for Channel B to work) .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 selection. .clki = false, //! Internal source clock 5, fPBA/128. .tcclks = TC_CLOCK_SOURCE_TC4, }; // Setup timer/counter waveform mode sysclk_enable_peripheral_clock(&AVR32_TC0); sysclk_enable_peripheral_clock(&AVR32_TC1); tc_init_waveform(&AVR32_TC1, &waveform_options_b1); tc_init_waveform(&AVR32_TC1, &waveform_options_b0_1); tc_init_waveform(&AVR32_TC1, &waveform_options_a2); tc_init_waveform(&AVR32_TC0, &waveform_options_b0_0); tc_init_waveform(&AVR32_TC0, &waveform_options_b2); tc_write_rb(&AVR32_TC1, 0, B_BASE); tc_write_rc(&AVR32_TC1, 0, RC_VAL); tc_write_rb(&AVR32_TC1, 1, R_BASE); tc_write_rc(&AVR32_TC1, 1, RC_VAL); tc_write_ra(&AVR32_TC1, 2, A_BASE); tc_write_rc(&AVR32_TC1, 2, RC_VAL); tc_write_rb(&AVR32_TC0, 0, M_BASE); tc_write_rc(&AVR32_TC0, 0, RC_VAL); tc_write_rb(&AVR32_TC0, 2, C_BASE); tc_write_rc(&AVR32_TC0, 2, RC_VAL); // Start the timer PWM channels tc_start(&AVR32_TC1, 2); tc_start(&AVR32_TC1, 0); tc_start(&AVR32_TC1, 1); tc_start(&AVR32_TC0, 0); tc_start(&AVR32_TC0, 2); } void PWM_tester(char servo, int delay){ int initial_delay = 2000; if(servo=='a'){ for(int i=0;i<=O_MAX;i++){ tc_write_ra(&AVR32_TC1, 2, A_BASE-i); if(i==0) delay_ms(initial_delay); else delay_ms(delay); } } else if(servo=='b'){ for(int i=0;i<=O_MAX;i++){ tc_write_rb(&AVR32_TC1, 0, B_BASE+i); if(i==0) delay_ms(initial_delay); else delay_ms(delay); } } else if(servo=='c'){ for(int i=0;i<=O_MAX;i++){ tc_write_rb(&AVR32_TC0, 2, C_BASE-i); if(i==0) delay_ms(initial_delay); else delay_ms(delay); } } else if(servo=='r'){ for(int i=0;i<=R_MAX;i++){ tc_write_rb(&AVR32_TC1, 1, R_BASE+i); if(i==0) delay_ms(initial_delay); else delay_ms(delay); } } else if(servo=='e'){ for(int i=0;i<O_MAX;i++){ tc_write_ra(&AVR32_TC1, 2, A_BASE-i); tc_write_rb(&AVR32_TC1, 0, B_BASE+i); tc_write_rb(&AVR32_TC0, 2, C_BASE-i); if(i<R_MAX) tc_write_rb(&AVR32_TC1, 1, R_BASE+i); //tc_write_rb(&AVR32_TC0, 0, 255); if(i==0) delay_ms(3000); else delay_ms(delay); } } } void PWM_update(void){ //gpio_toggle_pin(LED1_GPIO); t_a = collective-pitch+roll; t_b = collective-pitch-roll; t_c = collective+pitch+pitch; t_r = yaw+100; //if(collective!=0 || yaw !=0 || pitch!=0 || roll !=0) gpio_toggle_pin(LED0_GPIO); check_max_values(); tc_write_ra(&AVR32_TC1, 2, A_BASE-t_a); tc_write_rb(&AVR32_TC1, 0, B_BASE+t_b); tc_write_rb(&AVR32_TC0, 2, C_BASE-t_c); tc_write_rb(&AVR32_TC1, 1, R_BASE+t_r); } void set_motor(char setting){ int level = (int) setting; if(level>100) level = 100; level = (int)(level * 3.75f); tc_write_rb(&AVR32_TC0, 0, M_BASE - level); motor = level; } int get_servo_dat(char servo){ switch(servo){ case 'a': return t_a; break; case 'b': return t_b; break; case 'c': return t_c; break; case 'r': return t_r; break; case 'o': return collective; break; case 'y': return yaw; break; case 'p': return pitch; break; case 'l': return roll; break; case 'm': return motor; break; default: return 0; break; } } void check_max_values(void){ if(t_a>=O_MAX) t_a = O_MAX; else if(t_a<0) t_a = 0; if(t_b>=O_MAX) t_b = O_MAX; else if(t_b<0) t_b = 0; if(t_c>=O_MAX) t_c = O_MAX; else if(t_c<0) t_c = 0; if(t_r>=R_MAX) t_r = R_MAX; else if(t_r<0) t_r = 0; } void set_PWM_dat(int16_t* PWM_dat, char where){ /* [0] = packet type [1] = collective [2] = yaw [3] = pitch [4] = roll */ //gpio_toggle_pin(LED2_GPIO); switch (where){ case 'm': collective = (int8_t)PWM_dat[1]; yaw = (int8_t)PWM_dat[2]; pitch = (int8_t)PWM_dat[3]; roll = (int8_t)PWM_dat[4]; break; default: collective = PWM_dat[0]; yaw = PWM_dat[1]; pitch = PWM_dat[2]; roll = PWM_dat[3]; break; } check_orientation_values(); } void check_orientation_values(void){ if(pitch>MAX_PITCH) pitch = MAX_PITCH; else if(pitch<-MAX_PITCH) pitch = -MAX_PITCH; if(roll>MAX_ROLL) roll = MAX_ROLL; else if(roll<-MAX_ROLL) roll = -MAX_ROLL; if(yaw>MAX_YAW) yaw = MAX_YAW; else if(yaw<-MAX_YAW) yaw = -MAX_YAW; }
/* Setup the timer to generate the tick interrupts. */ static void prvSetupTimerInterrupt(void) { #if( configTICK_USE_TC==1 ) volatile avr32_tc_t *tc = &AVR32_TC; // Options for waveform genration. tc_waveform_opt_t waveform_opt = { .channel = configTICK_TC_CHANNEL, /* Channel selection. */ .bswtrg = TC_EVT_EFFECT_NOOP, /* Software trigger effect on TIOB. */ .beevt = TC_EVT_EFFECT_NOOP, /* External event effect on TIOB. */ .bcpc = TC_EVT_EFFECT_NOOP, /* RC compare effect on TIOB. */ .bcpb = TC_EVT_EFFECT_NOOP, /* RB compare effect on TIOB. */ .aswtrg = TC_EVT_EFFECT_NOOP, /* Software trigger effect on TIOA. */ .aeevt = TC_EVT_EFFECT_NOOP, /* External event effect on TIOA. */ .acpc = TC_EVT_EFFECT_NOOP, /* RC compare effect on TIOA: toggle. */ .acpa = TC_EVT_EFFECT_NOOP, /* RA compare effect on TIOA: toggle (other possibilities are none, set and clear). */ .wavsel = TC_WAVEFORM_SEL_UP_MODE_RC_TRIGGER,/* Waveform selection: Up mode without automatic trigger on RC compare. */ .enetrg = FALSE, /* External event trigger enable. */ .eevt = 0, /* External event selection. */ .eevtedg = TC_SEL_NO_EDGE, /* External event edge selection. */ .cpcdis = FALSE, /* Counter disable when RC compare. */ .cpcstop = FALSE, /* Counter clock stopped with RC compare. */ .burst = FALSE, /* Burst signal selection. */ .clki = FALSE, /* Clock inversion. */ .tcclks = TC_CLOCK_SOURCE_TC2 /* Internal source clock 2. */ }; tc_interrupt_t tc_interrupt = { .etrgs=0, .ldrbs=0, .ldras=0, .cpcs =1, .cpbs =0, .cpas =0, .lovrs=0, .covfs=0, }; #endif /* Disable all interrupt/exception. */ portDISABLE_INTERRUPTS(); /* Register the compare interrupt handler to the interrupt controller and enable the compare interrupt. */ #if( configTICK_USE_TC==1 ) { INTC_register_interrupt(&vTick, configTICK_TC_IRQ, INT0); /* Initialize the timer/counter. */ tc_init_waveform(tc, &waveform_opt); /* Set the compare triggers. Remember TC counter is 16-bits, so counting second is not possible! That's why we configure it to count ms. */ tc_write_rc( tc, configTICK_TC_CHANNEL, ( configPBA_CLOCK_HZ / 4) / configTICK_RATE_HZ ); tc_configure_interrupts( tc, configTICK_TC_CHANNEL, &tc_interrupt ); /* Start the timer/counter. */ tc_start(tc, configTICK_TC_CHANNEL); } #else { INTC_register_interrupt(&vTick, AVR32_CORE_COMPARE_IRQ, INT0); prvScheduleFirstTick(); } #endif }
/*! \brief to initialiaze hw timer */ uint8_t tmr_init(void) { uint8_t timer_multiplier; /* Options for waveform generation. */ tc_waveform_opt_t waveform_opt = { .channel = TIMER_CHANNEL_ID, /* Channel selection. */ .bswtrg = TC_EVT_EFFECT_NOOP, /* Software trigger effect * on TIOB. */ .beevt = TC_EVT_EFFECT_NOOP, /* External event effect * on TIOB. */ .bcpc = TC_EVT_EFFECT_NOOP, /* RC compare effect on * TIOB. */ .bcpb = TC_EVT_EFFECT_NOOP, /* RB compare effect on * TIOB. */ .aswtrg = TC_EVT_EFFECT_NOOP, /* Software trigger effect * on TIOA. */ .aeevt = TC_EVT_EFFECT_NOOP, /* External event effect * on TIOA. */ .acpc = TC_EVT_EFFECT_NOOP, /* RC compare effect on * TIOA */ .acpa = TC_EVT_EFFECT_NOOP, /* RA compare effect on * TIOA */ .wavsel = TC_WAVEFORM_SEL_UP_MODE, /* Waveform selection: Up * mode without automatic * trigger on RC compare. **/ .enetrg = false, /* External event trigger * enable. */ .eevt = TC_EXT_EVENT_SEL_TIOB_INPUT, /* External event * selection. */ .eevtedg = TC_SEL_NO_EDGE, /* External event edge * selection. */ .cpcdis = false, /* Counter disable when RC * compare. */ .cpcstop = false, /* Counter clock stopped * with RC compare. */ .burst = TC_BURST_NOT_GATED, /* Burst signal selection. **/ .clki = TC_CLOCK_RISING_EDGE, /* Clock inversion. */ .tcclks = TC_CLOCK_SOURCE_TC2 /* Internal source clock * 3, connected to fPBA / * 8. */ }; sysclk_enable_peripheral_clock(TIMER); /* Initialize the timer/counter. */ tc_init_waveform(TIMER, &waveform_opt); /* calculate how faster the timer with current clk freq compared to * timer with 1Mhz */ timer_multiplier = sysclk_get_peripheral_bus_hz(TIMER) / DEF_1MHZ; /* */ timer_multiplier = timer_multiplier >> 1; configure_irq_handler(); tmr_enable_ovf_interrupt(); tmr_disable_cc_interrupt(); tc_start(TIMER, TIMER_CHANNEL_ID); return timer_multiplier; } /*! \brief to disable compare interrupt */ void tmr_disable_cc_interrupt(void) { tc_interrupt.cpcs = 0; tc_configure_interrupts(TIMER, TIMER_CHANNEL_ID, &tc_interrupt); }
int main(void) { //-------------------------USART INTERRUPT REGISTRATION.------------// // Set Clock: Oscillator needs to initialized once: First pcl_switch_to_osc(PCL_OSC0, FOSC0, OSC0_STARTUP); // -------------- USART INIT ----------------------------------------------- static const gpio_map_t USART_GPIO_MAP = { {AVR32_USART0_RXD_0_0_PIN, AVR32_USART0_RXD_0_0_FUNCTION}, {AVR32_USART0_TXD_0_0_PIN, AVR32_USART0_TXD_0_0_FUNCTION} }; // USART options. static const usart_options_t USART_OPTIONS = { .baudrate = USART_BAUDRATE, .charlength = 8, .paritytype = USART_NO_PARITY, .stopbits = USART_1_STOPBIT, .channelmode = USART_NORMAL_CHMODE }; // Assign GPIO to USART gpio_enable_module(USART_GPIO_MAP, sizeof(USART_GPIO_MAP) / sizeof(USART_GPIO_MAP[0])); // Init USART usart_init_rs232(USART_0, &USART_OPTIONS, FOSC0); Disable_global_interrupt(); INTC_init_interrupts(); // Init Interrupt Table: Once at first // Register USART Interrupt (hinzufügen) INTC_register_interrupt(&usart_int_handler, AVR32_USART0_IRQ, AVR32_INTC_INT0); USART_0->ier = AVR32_USART_IER_RXRDY_MASK; // Activate ISR on RX Line Enable_global_interrupt(); // ----------------------------------------------------------------------------------- // -------------------------- Display INIT ---------------------------------- // Map SPI Pins static const gpio_map_t DIP204_SPI_GPIO_MAP = { {DIP204_SPI_SCK_PIN, DIP204_SPI_SCK_FUNCTION }, // SPI Clock. {DIP204_SPI_MISO_PIN, DIP204_SPI_MISO_FUNCTION}, // MISO. {DIP204_SPI_MOSI_PIN, DIP204_SPI_MOSI_FUNCTION}, // MOSI. {DIP204_SPI_NPCS_PIN, DIP204_SPI_NPCS_FUNCTION} // Chip Select NPCS. }; // add the spi options driver structure for the LCD DIP204 spi_options_t spiOptions = { .reg = DIP204_SPI_NPCS, .baudrate = 1000000, .bits = 8, .spck_delay = 0, .trans_delay = 0, .stay_act = 1, .spi_mode = 0, .modfdis = 1 }; // SPI Inits: Assign I/Os to SPI gpio_enable_module(DIP204_SPI_GPIO_MAP, sizeof(DIP204_SPI_GPIO_MAP) / sizeof(DIP204_SPI_GPIO_MAP[0])); // Initialize as master spi_initMaster(DIP204_SPI, &spiOptions); // Set selection mode: variable_ps, pcs_decode, delay spi_selectionMode(DIP204_SPI, 0, 0, 0); // Enable SPI spi_enable(DIP204_SPI); // setup chip registers spi_setupChipReg(DIP204_SPI, &spiOptions, FOSC0); // initialize delay driver: Muss vor dip204_init() ausgeführt werden delay_init( FOSC0 ); // initialize LCD dip204_init(backlight_PWM, TRUE); // --------------------------------------------------------------------------------------- // ----------------- Timer Counter Init --------------------------------- // Timer Configs: Options for waveform generation. static const tc_waveform_opt_t WAVEFORM_OPT = { .channel = TC_CHANNEL, // Channel selection. .bswtrg = TC_EVT_EFFECT_NOOP, // Software trigger effect on TIOB. .beevt = TC_EVT_EFFECT_NOOP, // External event effect on TIOB. .bcpc = TC_EVT_EFFECT_NOOP, // RC compare effect on TIOB. .bcpb = TC_EVT_EFFECT_NOOP, // RB compare effect on TIOB. .aswtrg = TC_EVT_EFFECT_NOOP, // Software trigger effect on TIOA. .aeevt = TC_EVT_EFFECT_NOOP, // External event effect on TIOA. .acpc = TC_EVT_EFFECT_NOOP, // RC compare effect on TIOA: toggle. .acpa = TC_EVT_EFFECT_NOOP, // RA compare effect on TIOA: toggle .wavsel = TC_WAVEFORM_SEL_UP_MODE_RC_TRIGGER,// Count till RC and reset (S. 649): Waveform selection .enetrg = FALSE, // External event trigger enable. .eevt = 0, // External event selection. .eevtedg = TC_SEL_NO_EDGE, // External event edge selection. .cpcdis = FALSE, // Counter disable when RC compare. .cpcstop = FALSE, // Counter clock stopped with RC compare. .burst = FALSE, // Burst signal selection. .clki = FALSE, // Clock inversion. .tcclks = TC_CLOCK_SOURCE_TC3 // Internal source clock 3, connected to fPBA / 8. }; // TC Interrupt Enable Register static const tc_interrupt_t TC_INTERRUPT = { .etrgs = 0, .ldrbs = 0, .ldras = 0, .cpcs = 1, .cpbs = 0, .cpas = 0, .lovrs = 0, .covfs = 0 }; // 0 = No Effect | 1 = Enable ( CPCS = 1 enables the RC Compare Interrupt ) // ***************** Timer Setup *********************************************** // Initialize the timer/counter. tc_init_waveform(tc, &WAVEFORM_OPT); // Initialize the timer/counter waveform. // Set the compare triggers. tc_write_rc(tc, TC_CHANNEL, RC); // Set RC value. tc_configure_interrupts(tc, TC_CHANNEL, &TC_INTERRUPT); // Start the timer/counter. tc_start(tc, TC_CHANNEL); // And start the timer/counter. // ******************************************************************************* Disable_global_interrupt(); // Register TC Interrupt INTC_register_interrupt(&tc_irq, AVR32_TC_IRQ0, AVR32_INTC_INT3); Enable_global_interrupt(); // --------------------------------------------------------------------------------------- imu_init(); //-------------------------------TWI R/W --------------------------------------------------- sensorDaten imu_data = {0}; char disp1[30], disp2[30], disp3[30], disp4[30]; short GX,GY,GZ, AX, AY, AZ; //shifted comlete Data RPY currMoveRPY; Quaternion currQuat; currQuat.q0 = 1.0; currQuat.q1 = 0; currQuat.q2 = 0; currQuat.q3 = 0; Quaternion deltaQuat; RotMatrix rot = {0}; RPY reconverted; calibrate_all(&imu_data); while(1){ if(exe){ exe = false; read_sensor(&imu_data); AX = imu_data.acc_x + imu_data.acc_x_bias; AY = imu_data.acc_y + imu_data.acc_y_bias; AZ = imu_data.acc_z + imu_data.acc_z_bias; GX = imu_data.gyro_x + imu_data.gyro_x_bias; GY = imu_data.gyro_y + imu_data.gyro_y_bias; GZ = imu_data.gyro_z + imu_data.gyro_z_bias; //convert to 1G float ax = (float)AX * (-4.0); float ay = (float)AY * (-4.0); //wegen 2^11= 2048, /2 = 1024 entspricht 4G -> 1G = (1024/4) float az = (float)AZ * (-4.0); //convert to 1°/s gx = ((float)GX/ 14.375); // in °/s gy = ((float)GY/ 14.375); gz = ((float)GZ/ 14.375); //Integration over time dGx = (gx*0.03); dGy = (gy*0.03); dGz = (gz*0.03); currMoveRPY.pitch = -dGx; currMoveRPY.roll = dGy; currMoveRPY.yaw = dGz; //aufaddieren auf den aktuellen Winkel IN GRAD gxDeg += dGx; gyDeg += dGy; gzDeg += dGz; //RPY in Quaternion umwandeln RPYtoQuat(&deltaQuat, &currMoveRPY); //normieren normQuat(&deltaQuat); //aufmultiplizeiren quatMultiplication(&deltaQuat, &currQuat, &currQuat); //nochmal normieren normQuat(&currQuat); //rücktransformation nicht nötig!! char send[80]; sprintf(send,"$,%f,%f,%f,%f,#", currQuat.q0, currQuat.q1, currQuat.q2, currQuat.q3); usart_write_line(USART_0,send); sprintf(disp1,"q0:%.3f, GX:%3.0f",currQuat.q0,gxDeg); sprintf(disp2,"q1:%.3f, GY:%3.0f",currQuat.q1, gyDeg); sprintf(disp3,"q2:%.3f, GZ:%3.0f",currQuat.q2, gzDeg); sprintf(disp4,"q3:%.3f",currQuat.q3); dip204_clear_display(); dip204_set_cursor_position(1,1); dip204_write_string(disp1); dip204_set_cursor_position(1,2); dip204_write_string(disp2); dip204_set_cursor_position(1,3); dip204_write_string(disp3); dip204_set_cursor_position(1,4); dip204_write_string(disp4); //sprintf(data,"TEST:%s",high); //print_dbg(data); } } }
int main(void) { U32 i; volatile avr32_tc_t *tc = EXAMPLE_TC; // Configuration du peripherique TC static const tc_waveform_opt_t WAVEFORM_OPT = { .channel = TC_CHANNEL, // Channel selection. .bswtrg = TC_EVT_EFFECT_NOOP, // Software trigger effect on TIOB. .beevt = TC_EVT_EFFECT_NOOP, // External event effect on TIOB. .bcpc = TC_EVT_EFFECT_NOOP, // RC compare effect on TIOB. .bcpb = TC_EVT_EFFECT_NOOP, // RB compare effect on TIOB. .aswtrg = TC_EVT_EFFECT_NOOP, // Software trigger effect on TIOA. .aeevt = TC_EVT_EFFECT_NOOP, // External event effect on TIOA. .acpc = TC_EVT_EFFECT_NOOP, // RC compare effect on TIOA: toggle. .acpa = TC_EVT_EFFECT_NOOP, // RA compare effect on TIOA: toggle .wavsel = TC_WAVEFORM_SEL_UP_MODE_RC_TRIGGER,// Waveform selection: Up mode with automatic trigger(reset) on RC compare. .enetrg = FALSE, // External event trigger enable. .eevt = 0, // External event selection. .eevtedg = TC_SEL_NO_EDGE, // External event edge selection. .cpcdis = FALSE, // Counter disable when RC compare. .cpcstop = FALSE, // Counter clock stopped with RC compare. .burst = FALSE, // Burst signal selection. .clki = FALSE, // Clock inversion. .tcclks = TC_CLOCK_SOURCE_TC4 // Internal source clock 3, connected to fPBA / 8. }; static const tc_interrupt_t TC_INTERRUPT = { .etrgs = 0, .ldrbs = 0, .ldras = 0, .cpcs = 1, .cpbs = 0, .cpas = 0, .lovrs = 0, .covfs = 0 }; /*! \brief Main function: * - Configure the CPU to run at 12MHz * - 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, do nothing */ /* Au reset, le microcontroleur opere sur un crystal interne a 115200Hz. */ /* Nous allons le configurer pour utiliser un crystal externe, FOSC0, a 12Mhz. */ pcl_switch_to_osc(PCL_OSC0, FOSC0, OSC0_STARTUP); Disable_global_interrupt(); // Desactive les interrupts le temps de la config INTC_init_interrupts(); // Initialise les vecteurs d'interrupt // Enregistrement de la nouvelle IRQ du TIMER au Interrupt Controller . INTC_register_interrupt(&tc_irq, EXAMPLE_TC_IRQ, AVR32_INTC_INT0); Enable_global_interrupt(); // Active les interrupts tc_init_waveform(tc, &WAVEFORM_OPT); // Initialize the timer/counter waveform. // Placons le niveau RC a atteindre pour declencher de l'IRQ. // Attention, RC est un 16-bits, valeur max 65535 // We want: (1/(fPBA/32)) * RC = 0.100 s, donc RC = (fPBA/32) / 10 to get an interrupt every 100 ms. tc_write_rc(tc, TC_CHANNEL, (FPBA / 32) / 10); // Set RC value. tc_configure_interrupts(tc, TC_CHANNEL, &TC_INTERRUPT); // Start the timer/counter. tc_start(tc, TC_CHANNEL); // And start the timer/counter. while(1) // Boucle inifinie a vide ! { i++; } }