@@ -299,24 +299,6 @@ void us_ticker_clear_interrupt(void)
299
299
300
300
#define MAX_RTC_COUNTER_VAL ((1uL << RTC_COUNTER_BITS) - 1)
301
301
302
- /**
303
- * The value previously set in the capture compare register of channel 1
304
- */
305
- static uint32_t previous_tick_cc_value = 0 ;
306
-
307
- /* The Period of RTC oscillator, unit [1/RTC1_CONFIG_FREQUENCY] */
308
- static uint32_t os_rtc_period ;
309
-
310
- /* Variable for frozen RTC1 counter value. It is used when system timer is disabled. */
311
- static uint32_t frozen_sub_tick = 0 ;
312
-
313
-
314
- #ifdef MBED_CONF_RTOS_PRESENT
315
- #include "rtx_os.h" //import osRtxInfo, SysTick_Handler()
316
-
317
- static inline void clear_tick_interrupt ();
318
- #endif
319
-
320
302
#ifndef RTC1_CONFIG_FREQUENCY
321
303
#define RTC1_CONFIG_FREQUENCY 32678 // [Hz]
322
304
#endif
@@ -325,210 +307,15 @@ static uint32_t frozen_sub_tick = 0;
325
307
326
308
void COMMON_RTC_IRQ_HANDLER (void )
327
309
{
328
- if (nrf_rtc_event_pending (COMMON_RTC_INSTANCE , OS_TICK_EVENT )) {
329
- #ifdef MBED_CONF_RTOS_PRESENT
330
- clear_tick_interrupt ();
331
- // Trigger the SysTick_Handler just after exit form RTC Handler.
332
- NVIC_SetPendingIRQ (SWI3_IRQn );
333
-
334
- nrf_gpio_pin_set (11 );
335
- #endif
336
- } else {
310
+ if (!nrf_rtc_event_pending (COMMON_RTC_INSTANCE , OS_TICK_EVENT )) {
337
311
common_rtc_irq_handler ();
338
312
}
339
313
}
340
314
341
-
342
- #ifdef MBED_CONF_RTOS_PRESENT
343
- /**
344
- * Return the next number of clock cycle needed for the next tick.
345
- * @note This function has been carefully optimized for a systick occurring every 1000us.
346
- */
347
- static uint32_t get_next_tick_cc_delta ()
348
- {
349
- uint32_t delta = 0 ;
350
-
351
- if (osRtxConfig .tick_freq != 1000 ) {
352
- // In RTX, by default SYSTICK is is used.
353
- // A tick event is generated every os_trv + 1 clock cycles of the system timer.
354
- delta = os_rtc_period ;
355
- } else {
356
- // If the clockrate is set to 1000us then 1000 tick should happen every second.
357
- // Unfortunatelly, when clockrate is set to 1000, os_trv is equal to 31.
358
- // If (os_trv + 1) is used as the delta value between two ticks, 1000 ticks will be
359
- // generated in 32000 clock cycle instead of 32768 clock cycles.
360
- // As a result, if a user schedule an OS timer to start in 100s, the timer will start
361
- // instead after 97.656s
362
- // The code below fix this issue, a clock rate of 1000s will generate 1000 ticks in 32768
363
- // clock cycles.
364
- // The strategy is simple, for 1000 ticks:
365
- // * 768 ticks will occur 33 clock cycles after the previous tick
366
- // * 232 ticks will occur 32 clock cycles after the previous tick
367
- // By default every delta is equal to 33.
368
- // Every five ticks (20%, 200 delta in one second), the delta is equal to 32
369
- // The remaining (32) deltas equal to 32 are distributed using primes numbers.
370
- static uint32_t counter = 0 ;
371
- if ((counter % 5 ) == 0 || (counter % 31 ) == 0 || (counter % 139 ) == 0 || (counter == 503 )) {
372
- delta = 32 ;
373
- } else {
374
- delta = 33 ;
375
- }
376
- ++ counter ;
377
- if (counter == 1000 ) {
378
- counter = 0 ;
379
- }
380
- }
381
- return delta ;
382
- }
383
-
384
- static inline void clear_tick_interrupt ()
385
- {
386
- nrf_rtc_event_clear (COMMON_RTC_INSTANCE , OS_TICK_EVENT );
387
- nrf_rtc_event_disable (COMMON_RTC_INSTANCE , OS_TICK_INT_MASK );
388
- }
389
-
390
- /**
391
- * Indicate if a value is included in a range which can be wrapped.
392
- * @param begin start of the range
393
- * @param end end of the range
394
- * @param val value to check
395
- * @return true if the value is included in the range and false otherwise.
396
- */
397
- static inline bool is_in_wrapped_range (uint32_t begin , uint32_t end , uint32_t val )
398
- {
399
- // regular case, begin < end
400
- // return true if begin <= val < end
401
- if (begin < end ) {
402
- if (begin <= val && val < end ) {
403
- return true;
404
- } else {
405
- return false;
406
- }
407
- } else {
408
- // In this case end < begin because it has wrap around the limits
409
- // return false if end < val < begin
410
- if (end < val && val < begin ) {
411
- return false;
412
- } else {
413
- return true;
414
- }
415
- }
416
-
417
- }
418
-
419
- /**
420
- * Register the next tick.
421
- */
422
- static void register_next_tick ()
423
- {
424
- previous_tick_cc_value = nrf_rtc_cc_get (COMMON_RTC_INSTANCE , OS_TICK_CC_CHANNEL );
425
- uint32_t delta = get_next_tick_cc_delta ();
426
- uint32_t new_compare_value = (previous_tick_cc_value + delta ) & MAX_RTC_COUNTER_VAL ;
427
-
428
- // Disable irq directly for few cycles,
429
- // Validation of the new CC value against the COUNTER,
430
- // Setting the new CC value and enabling CC IRQ should be an atomic operation
431
- // Otherwise, there is a possibility to set an invalid CC value because
432
- // the RTC1 keeps running.
433
- // This code is very short 20-38 cycles in the worst case, it shouldn't
434
- // disturb softdevice.
435
- __disable_irq ();
436
- uint32_t current_counter = nrf_rtc_counter_get (COMMON_RTC_INSTANCE );
437
-
438
- // If an overflow occur, set the next tick in COUNTER + delta clock cycles
439
- if (is_in_wrapped_range (previous_tick_cc_value , new_compare_value , current_counter + 1 ) == false) {
440
- new_compare_value = current_counter + delta ;
441
- }
442
- nrf_rtc_cc_set (COMMON_RTC_INSTANCE , OS_TICK_CC_CHANNEL , new_compare_value );
443
- // Enable generation of the compare event for the value set above (this
444
- // event will trigger the interrupt).
445
- nrf_rtc_event_enable (COMMON_RTC_INSTANCE , OS_TICK_INT_MASK );
446
- __enable_irq ();
447
- }
448
-
449
-
450
- /**
451
- * Initialize alternative hardware timer as RTX kernel timer
452
- * This function is directly called by RTX.
453
- * @note this function shouldn't be called directly.
454
- * @return IRQ number of the alternative hardware timer
455
- */
456
- int32_t osRtxSysTimerSetup (void )
457
- {
458
- common_rtc_init ();
459
-
460
- os_rtc_period = (RTC1_CONFIG_FREQUENCY ) / osRtxConfig .tick_freq ;
461
-
462
- return nrf_drv_get_IRQn (COMMON_RTC_INSTANCE );
463
- }
464
-
465
- // Start SysTickt timer emulation
466
- void osRtxSysTimerEnable (void )
467
- {
468
- nrf_rtc_int_enable (COMMON_RTC_INSTANCE , OS_TICK_INT_MASK );
469
-
470
- uint32_t current_cnt = nrf_rtc_counter_get (COMMON_RTC_INSTANCE );
471
- nrf_rtc_cc_set (COMMON_RTC_INSTANCE , OS_TICK_CC_CHANNEL , current_cnt );
472
- register_next_tick ();
473
-
474
- NVIC_SetVector (SWI3_IRQn , (uint32_t )SysTick_Handler );
475
- NVIC_SetPriority (SWI3_IRQn , (1UL << __NVIC_PRIO_BITS ) - 1UL ); /* set Priority for Emulated Systick Interrupt */
476
- NVIC_EnableIRQ (SWI3_IRQn );
477
- }
478
-
479
- // Stop SysTickt timer emulation
480
- void osRtxSysTimerDisable (void )
315
+ IRQn_Type mbed_get_m0_tick_irqn ()
481
316
{
482
- nrf_rtc_int_disable (COMMON_RTC_INSTANCE , OS_TICK_INT_MASK );
483
-
484
- // RTC1 is free runing. osRtxSysTimerGetCount will return proper frozen value
485
- // thanks to geting frozen value instead of RTC1 counter value
486
- frozen_sub_tick = nrf_rtc_counter_get (COMMON_RTC_INSTANCE );
487
- }
488
-
489
-
490
-
491
- /**
492
- * Acknowledge the tick interrupt.
493
- * This function is called by the function OS_Tick_Handler of RTX.
494
- * @note this function shouldn't be called directly.
495
- */
496
- void osRtxSysTimerAckIRQ (void )
497
- {
498
- register_next_tick ();
499
- }
500
-
501
- // provide a free running incremental value over the entire 32-bit range
502
- uint32_t osRtxSysTimerGetCount (void )
503
- {
504
- uint32_t current_cnt ;
505
- uint32_t sub_tick ;
506
-
507
- if (nrf_rtc_int_is_enabled (COMMON_RTC_INSTANCE , OS_TICK_INT_MASK )) {
508
- // system timer is enabled
509
- current_cnt = nrf_rtc_counter_get (COMMON_RTC_INSTANCE );
510
-
511
- if (current_cnt >= previous_tick_cc_value ) {
512
- //0 prev current MAX
513
- //|------|---------|------------|---->
514
- sub_tick = current_cnt - previous_tick_cc_value ;
515
- } else {
516
- //0 current prev MAX
517
- //|------|---------|------------|---->
518
- sub_tick = MAX_RTC_COUNTER_VAL - previous_tick_cc_value + current_cnt ;
519
- }
520
- } else { // system timer is disabled
521
- sub_tick = frozen_sub_tick ;
522
- }
523
-
524
- return (os_rtc_period * osRtxInfo .kernel .tick ) + sub_tick ;
525
- }
526
-
527
- // Timer Tick frequency
528
- uint32_t osRtxSysTimerGetFreq (void ) {
529
- return RTC1_CONFIG_FREQUENCY ;
317
+ return SWI3_IRQn ;
530
318
}
531
319
532
- #endif // #ifdef MBED_CONF_RTOS_PRESENT
533
320
534
321
#endif // defined(TARGET_MCU_NRF51822)
0 commit comments