ARM7 based quadrocopter
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

at91_pitc.c 3.4KB

12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. /***************************************************************************
  2. * sam7fc - Periodic Timer Handling *
  3. * *
  4. * Copyright (C) 01/2008 by Olaf Rempel *
  5. * razzor@kopf-tisch.de *
  6. * *
  7. * This program is free software; you can redistribute it and/or modify *
  8. * it under the terms of the GNU General Public License as published by *
  9. * the Free Software Foundation; version 2 of the License *
  10. * *
  11. * This program is distributed in the hope that it will be useful, *
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  14. * GNU General Public License for more details. *
  15. * *
  16. * You should have received a copy of the GNU General Public License *
  17. * along with this program; if not, write to the *
  18. * Free Software Foundation, Inc., *
  19. * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
  20. ***************************************************************************/
  21. #include "AT91SAM7S256.h"
  22. #include "at91_pitc.h"
  23. #include "at91_sysc.h"
  24. #include "board.h"
  25. #define PITC_HZ 1000
  26. /* PIV is 20bit -> min. 3Hz @48MHz MCK */
  27. #define HZ_TO_PIV(HZ) (MCK / (16 * HZ))
  28. static LIST_HEAD(timer_list);
  29. volatile static uint32_t pitc_ticks;
  30. static void _pitc_schedule_timer(struct pitc_timer *timer)
  31. {
  32. timer->nextrun = timer->interval + pitc_ticks;
  33. struct pitc_timer *search;
  34. list_for_each_entry(search, &timer_list, list)
  35. if (search->nextrun > timer->nextrun)
  36. break;
  37. list_add_tail(&timer->list, &search->list);
  38. }
  39. void pitc_schedule_timer(struct pitc_timer *timer)
  40. {
  41. /* disable PITC interrupt */
  42. *AT91C_PITC_PIMR &= ~AT91C_PITC_PITIEN;
  43. /* check it timer is already running */
  44. if (timer->nextrun == 0 && timer->interval > 0)
  45. _pitc_schedule_timer(timer);
  46. // TODO: if timer is running, interval changes are delayed
  47. /* enable PITC interrupt */
  48. *AT91C_PITC_PIMR |= AT91C_PITC_PITIEN;
  49. }
  50. void pitc_remove_timer(struct pitc_timer *timer)
  51. {
  52. timer->interval = 0;
  53. }
  54. static void pitc_isr(uint32_t status)
  55. {
  56. /* get Ticks and clear interrupt */
  57. pitc_ticks += (*AT91C_PITC_PIVR & AT91C_PITC_PICNT) >> 20;
  58. struct pitc_timer *search, *tmp;
  59. list_for_each_entry_safe(search, tmp, &timer_list, list) {
  60. /* if this entry not scheduled yet, abort search */
  61. if (pitc_ticks < search->nextrun)
  62. break;
  63. /* remove from list */
  64. list_del(&search->list);
  65. /* exec handler */
  66. if ((search->interval == 0) || search->func(search) == PITC_REMOVE_TIMER) {
  67. /* one-shot timer, mark as completed */
  68. search->nextrun = 0;
  69. continue;
  70. }
  71. /* interval timer, reschedule it */
  72. _pitc_schedule_timer(search);
  73. }
  74. }
  75. uint32_t pitc_get_ticks(void)
  76. {
  77. return pitc_ticks;
  78. }
  79. void at91_pitc_init(void)
  80. {
  81. sysc_register_isr(AT91_SYSIRQ_PIT, &pitc_isr);
  82. *AT91C_PITC_PIMR = (AT91C_PITC_PIV & HZ_TO_PIV(PITC_HZ)) |
  83. AT91C_PITC_PITEN |
  84. AT91C_PITC_PITIEN;
  85. }