OSDN Git Service

Update lejos_osek to nxtOSEK_v205b0.zip
[nxt-jsp/etrobo-atk.git] / nxtOSEK / lejos_nxj / src / nxtvm / platform / nxt / systick.c
1
2 /*
3  *  This provides a 1000Hz tick for the system.
4  *
5  *  NB At 1000Hz, a U32 will roll over in approx 50 days.
6  *  Therefore a todo to get rid of this at some stage.
7  *
8  *  We're using TC0
9  */
10
11 #include "aic.h"
12 #include "AT91SAM7.h"
13 #include "interrupts.h"
14 #include "systick.h"
15
16 #include "nxt_motors.h"
17 #include "nxt_avr.h"
18
19 extern volatile unsigned char gMakeRequest;
20
21 #define PIT_FREQ 1000           /* Hz */
22
23 #define LOW_PRIORITY_IRQ 10
24
25 static volatile U32 systick_sec;
26 static volatile U32 systick_sub_sec;
27 static volatile U32 systick_ms;
28
29 extern void systick_isr_entry(void);
30 extern void systick_low_priority_entry(void);
31
32 // Systick low priority
33 void
34 systick_low_priority_C(void)
35 {
36   *AT91C_AIC_ICCR = (1 << LOW_PRIORITY_IRQ);
37 //  gMakeRequest = 1;           // trigger Java tick request
38   nxt_avr_1kHz_update();
39   nxt_motor_1kHz_process();
40 }
41
42 // Called at 1000Hz
43 void
44 systick_isr_C(void)
45 {
46   U32 status;
47
48   /* Read status to confirm interrupt */
49   status = *AT91C_PITC_PIVR;
50
51 //  systick_low_priority_C();
52
53   systick_ms++;
54
55   systick_sub_sec++;
56
57   if (systick_sub_sec >= PIT_FREQ) {
58     systick_sub_sec = 0;
59     systick_sec++;
60   }
61   // Trigger low priority task
62   *AT91C_AIC_ISCR = (1 << LOW_PRIORITY_IRQ);
63 }
64
65
66
67 U32
68 systick_get_ms(void)
69 {
70   // We're using a 32-bitter and can assume that we
71   // don't need to do any locking here.
72   return systick_ms;
73 }
74
75
76 void
77 systick_wait_ms(U32 ms)
78 {
79   volatile U32 final = ms + systick_ms;
80
81   while (systick_ms < final) {
82   }
83 }
84
85
86 void
87 systick_wait_ns(U32 ns)
88 {
89   volatile x = (ns >> 7) + 1;
90
91   while (x) {
92     x--;
93   }
94 }
95
96 void
97 systick_init(void)
98 {
99   int i_state = interrupts_get_and_disable();
100
101   aic_mask_off(LOW_PRIORITY_IRQ);
102   aic_set_vector(LOW_PRIORITY_IRQ, (1 << 5) /* positive internal edge */ |
103                  AIC_INT_LEVEL_LOW, (U32) systick_low_priority_entry);
104   aic_mask_on(LOW_PRIORITY_IRQ);
105
106   aic_mask_off(AT91C_PERIPHERAL_ID_SYSIRQ);
107   aic_set_vector(AT91C_PERIPHERAL_ID_SYSIRQ, (1 << 5) /* positive internal edge */ |
108                  AIC_INT_LEVEL_NORMAL, (U32) systick_isr_entry);
109
110   aic_mask_on(AT91C_PERIPHERAL_ID_SYSIRQ);
111   *AT91C_PITC_PIMR = ((CLOCK_FREQUENCY / 16 / PIT_FREQ) - 1) | 0x03000000;      /* Enable, enable interrupts */
112
113   if (i_state)
114     interrupts_enable();
115 }
116
117 void
118 systick_get_time(U32 *sec, U32 *usec)
119 {
120   int istate = interrupts_get_and_disable();
121
122   if (sec)
123     *sec = systick_sec;
124   if (usec)
125     *usec = systick_sub_sec * (1000000 / PIT_FREQ);
126
127   if (istate)
128     interrupts_enable();
129 }
130
131
132 static U32 test_counter;
133 void
134 systick_test(void)
135 {
136   while (1) {
137     test_counter++;
138     systick_wait_ms(2000);
139   }
140 }
141
142 void systick_suspend()
143 {
144   aic_mask_off(LOW_PRIORITY_IRQ);
145 }
146
147 void systick_resume()
148 {
149   aic_mask_on(LOW_PRIORITY_IRQ);
150 }
151