Example of COUNT & COMPARE registers usage, using the USART software driver (for printing ASCII msgs), the GPIO software driver (to map the USART on I/O pins), the INTC software driver (for interrupt management).
Definition in file cycle_counter_example.c.
#include "intc.h"
#include "compiler.h"
#include "print_funcs.h"
#include "board.h"
#include "cycle_counter.h"
#include "power_clocks_lib.h"
Go to the source code of this file.
Defines | |
#define | _ASSERT_ENABLE_ |
#define | EXAMPLE_TARGET_DFLL_FREQ_HZ 96000000 |
#define | EXAMPLE_TARGET_MCUCLK_FREQ_HZ 12000000 |
#define | EXAMPLE_TARGET_PBACLK_FREQ_HZ 12000000 |
#define | NB_CLOCK_CYCLE_DELAY_LONG 20000000 |
#define | NB_CLOCK_CYCLE_DELAY_SHORT 1000000 |
Functions | |
static void | compare_irq_handler (void) |
int | main (void) |
Variables | |
static volatile unsigned int | u32NbCompareIrqTrigger = 0 |
static volatile unsigned char | u8DisplayMsg = 0 |
Parameters to pcl_configure_clocks(). | |
static scif_gclk_opt_t | gc_dfllif_ref_opt = { SCIF_GCCTRL_SLOWCLOCK, 0, OFF} |
static pcl_freq_param_t | pcl_dfll_freq_param |
#define _ASSERT_ENABLE_ |
Definition at line 112 of file cycle_counter_example.c.
#define EXAMPLE_TARGET_DFLL_FREQ_HZ 96000000 |
Definition at line 121 of file cycle_counter_example.c.
#define EXAMPLE_TARGET_MCUCLK_FREQ_HZ 12000000 |
Definition at line 122 of file cycle_counter_example.c.
#define EXAMPLE_TARGET_PBACLK_FREQ_HZ 12000000 |
#define NB_CLOCK_CYCLE_DELAY_LONG 20000000 |
#define NB_CLOCK_CYCLE_DELAY_SHORT 1000000 |
static void compare_irq_handler | ( | void | ) | [static] |
Definition at line 161 of file cycle_counter_example.c.
References NB_CLOCK_CYCLE_DELAY_LONG, Set_sys_compare, u32NbCompareIrqTrigger, and u8DisplayMsg.
Referenced by main().
00162 { 00163 // Count the number of times this IRQ handler is called. 00164 u32NbCompareIrqTrigger++; 00165 u8DisplayMsg = 1; // Inform the main program that it may display a msg saying 00166 // that the COUNT&COMPARE interrupt occurred. 00167 // Clear the pending interrupt(writing a value to the COMPARE register clears 00168 // any pending compare interrupt requests). Schedule the COUNT&COMPARE match 00169 // interrupt to happen every NB_CLOCK_CYCLE_DELAY_LONG cycles. 00170 Set_sys_compare(NB_CLOCK_CYCLE_DELAY_LONG); 00171 }
int main | ( | void | ) |
Definition at line 193 of file cycle_counter_example.c.
References compare_irq_handler(), EXAMPLE_TARGET_PBACLK_FREQ_HZ, Get_sys_compare, Get_sys_count, NB_CLOCK_CYCLE_DELAY_SHORT, Set_sys_compare, u32NbCompareIrqTrigger, and u8DisplayMsg.
00194 { 00195 U32 u32CompareVal; 00196 U32 u32CompareValVerif; 00197 U32 u32CountVal; 00198 U32 u32CountNextVal; 00199 U8 u8LedMap = 0x01; 00200 00201 00202 #if BOARD == UC3L_EK 00203 // Note: on the AT32UC3L-EK board, there is no crystal/external clock connected 00204 // to the OSC0 pinout XIN0/XOUT0. We shall then program the DFLL and switch the 00205 // main clock source to the DFLL. 00206 pcl_configure_clocks(&pcl_dfll_freq_param); 00207 // Note: since it is dynamically computing the appropriate field values of the 00208 // configuration registers from the parameters structure, this function is not 00209 // optimal in terms of code size. For a code size optimal solution, it is better 00210 // to create a new function from pcl_configure_clocks_dfll0() and modify it 00211 // to use preprocessor computation from pre-defined target frequencies. 00212 00213 // Init DEBUG module 00214 init_dbg_rs232(EXAMPLE_TARGET_PBACLK_FREQ_HZ); 00215 #else 00216 // Configure Osc0 in crystal mode (i.e. use of an external crystal source, with 00217 // frequency FOSC0) with an appropriate startup time then switch the main clock 00218 // source to Osc0. 00219 pcl_switch_to_osc(PCL_OSC0, FOSC0, OSC0_STARTUP); 00220 // Init DEBUG module 00221 init_dbg_rs232(FOSC0); 00222 #endif 00223 00224 print_dbg("---------------------------------------------\n"); 00225 00226 // Read COMPARE register. 00227 // NOTE: it should be equal to 0 (default value upon reset) => The compare 00228 // and exception generation feature is thus currently disabled. 00229 u32CompareVal = Get_sys_compare(); 00230 Assert(!u32CompareVal); 00231 00232 // Read COUNT register. 00233 // NOTE: the COUNT register increments since reset => it should be != 0. 00234 u32CountVal = Get_sys_count(); 00235 Assert(u32CountVal); 00236 00237 #if defined (__GNUC__) 00238 // Disable all interrupts. 00239 Disable_global_interrupt(); 00240 00241 INTC_init_interrupts(); 00242 00243 // Register the compare interrupt handler to the interrupt controller. 00244 // compare_irq_handler is the interrupt handler to register. 00245 // AVR32_CORE_COMPARE_IRQ is the IRQ of the interrupt handler to register. 00246 // AVR32_INTC_INT0 is the interrupt priority level to assign to the group of this IRQ. 00247 // void INTC_register_interrupt(__int_handler handler, unsigned int irq, unsigned int int_level); 00248 INTC_register_interrupt(&compare_irq_handler, AVR32_CORE_COMPARE_IRQ, AVR32_INTC_INT0); 00249 #endif 00250 // Enable all interrupts. 00251 Enable_global_interrupt(); 00252 00253 // Schedule the COUNT&COMPARE match interrupt in NB_CLOCK_CYCLE_DELAY_SHORT 00254 // clock cycles from now. 00255 u32CountVal = Get_sys_count(); 00256 00257 u32CompareVal = u32CountVal + NB_CLOCK_CYCLE_DELAY_SHORT; // WARNING: MUST FIT IN 32bits. 00258 // If u32CompareVal ends up to be 0, make it 1 so that the COMPARE and exception 00259 // generation feature does not get disabled. 00260 if(0 == u32CompareVal) 00261 { 00262 u32CompareVal++; 00263 } 00264 00265 Set_sys_compare(u32CompareVal); // GO 00266 00267 // Check if the previous write in the COMPARE register succeeded. 00268 u32CompareValVerif = Get_sys_compare(); 00269 Assert( u32CompareVal==u32CompareValVerif ); 00270 00271 // The previous COMPARE write succeeded. 00272 // Loop until the COUNT&COMPARE match triggers. 00273 while (!u32NbCompareIrqTrigger) 00274 { 00275 u32CountNextVal = Get_sys_count(); 00276 00277 if (u32CountNextVal < u32CompareVal) 00278 print_dbg("COUNT HAS NOT REACHED COMPARE YET (INFO)\n"); 00279 else if (u32CountNextVal > u32CompareVal) 00280 // This should never happen if COMPARE is not zero. 00281 print_dbg("COUNT IS GREATER THAN COMPARE (INFO)\n"); 00282 else 00283 print_dbg("COUNT IS EQUAL TO COMPARE (INFO)\n"); 00284 // NOTE: since the COUNT register is reset to zero upon COUNT/COMPARE match, 00285 // the printed messages here are not "accurate". 00286 } 00287 00288 while (TRUE) 00289 { 00290 if (u8DisplayMsg) 00291 { 00292 u8DisplayMsg = 0; // Reset 00293 00294 // Turn the current LED on only and move to next LED. 00295 LED_Display_Field(LED0 | 00296 LED1 | 00297 LED2 | 00298 LED3, 00299 u8LedMap); 00300 u8LedMap = max((U8)(u8LedMap << 1) & 0x0F, 0x01); 00301 00302 // Print some info on the debug port. 00303 print_dbg("\nCOMPARE INTERRUPT TRIGGERED (OK): #"); 00304 print_dbg_ulong(u32NbCompareIrqTrigger); 00305 } 00306 } 00307 }
scif_gclk_opt_t gc_dfllif_ref_opt = { SCIF_GCCTRL_SLOWCLOCK, 0, OFF} [static] |
Definition at line 178 of file cycle_counter_example.c.
pcl_freq_param_t pcl_dfll_freq_param [static] |
Initial value:
{ .main_clk_src = PCL_MC_DFLL0, .cpu_f = EXAMPLE_TARGET_MCUCLK_FREQ_HZ, .pba_f = EXAMPLE_TARGET_PBACLK_FREQ_HZ, .pbb_f = EXAMPLE_TARGET_PBACLK_FREQ_HZ, .dfll_f = EXAMPLE_TARGET_DFLL_FREQ_HZ, .pextra_params = &gc_dfllif_ref_opt }
Definition at line 179 of file cycle_counter_example.c.
volatile unsigned int u32NbCompareIrqTrigger = 0 [static] |
Definition at line 132 of file cycle_counter_example.c.
Referenced by compare_irq_handler(), and main().
volatile unsigned char u8DisplayMsg = 0 [static] |
Definition at line 135 of file cycle_counter_example.c.
Referenced by compare_irq_handler(), and main().