OSDN Git Service

IR signal -> LED.
[kozos-expbrd/kozos_expbrd.git] / firm / sample / sample1 / os / task_input.c
1
2 #include "kozos.h"
3 #include "re.h"
4 #include "sw.h"
5 #include "intr.h"
6 #include "task_menu.h"
7
8 #define H8_3069F_ISCR       ((volatile uint8 *)0xFEE014)
9 #define H8_3069F_IER        ((volatile uint8 *)0xFEE015)
10 #define H8_3069F_ISR        ((volatile uint8 *)0xFEE016)
11
12 #define H8_3069F_TSTR       ((volatile uint8 *)0xFFFF60)
13 #define H8_3069F_TISRC      ((volatile uint8 *)0xFFFF66)
14
15 #define H8_3069F_16TCR0     ((volatile uint8 *)0xFFFF68)
16 #define H8_3069F_TIOR0      ((volatile uint8 *)0xFFFF69)
17 #define H8_3069F_16TCNT0H   ((volatile uint8 *)0xFFFF6A)
18 #define H8_3069F_16TCNT0L   ((volatile uint8 *)0xFFFF6B)
19
20 #define H8_3069F_16TCR1     ((volatile uint8 *)0xFFFF70)
21 #define H8_3069F_TIOR1      ((volatile uint8 *)0xFFFF71)
22 #define H8_3069F_16TCNT1H   ((volatile uint8 *)0xFFFF72)
23 #define H8_3069F_16TCNT1L   ((volatile uint8 *)0xFFFF73)
24
25 #define MAX_BIT_COUNT (64)
26
27 #define IRQ4_ENABLE() \
28   do { \
29     (*H8_3069F_ISCR |= (1 << 4)); \
30     (*H8_3069F_IER  |= (1 << 4)); \
31   } while (0)
32
33 #define TCNT0_START()   (*H8_3069F_TSTR |=  (1 << 0))
34 #define TCNT0_STOP()    (*H8_3069F_TSTR &= ~(1 << 0))
35 #define TCNT0_VALUE()   (((*H8_3069F_16TCNT0H) << 8) | ((*H8_3069F_16TCNT0L) << 0))
36 #define TCNT0_RESET()  \
37   do { \
38     *H8_3069F_16TCNT0H = 0; \
39     *H8_3069F_16TCNT0L = 0; \
40   } while (0)
41
42 #define TCNT1_START()   (*H8_3069F_TSTR |=  (1 << 1))
43 #define TCNT1_STOP()    (*H8_3069F_TSTR &= ~(1 << 1))
44 #define TCNT1_VALUE()   (((*H8_3069F_16TCNT1H) << 8) | ((*H8_3069F_16TCNT1L) << 0))
45 #define TCNT1_RESET()  \
46   do { \
47     *H8_3069F_16TCNT1H = 0; \
48     *H8_3069F_16TCNT1L = 0; \
49   } while (0)
50
51 #define TCR0_SETUP()        (*H8_3069F_16TCR0 = 0x03)
52 #define TCR0_INTR_ENABLE()  (*H8_3069F_TISRC |=  (1 << 4))
53 #define TCR0_FLAG_CLEAR()   (*H8_3069F_TISRC &= ~(1 << 0))
54
55 #define TCR1_SETUP()        (*H8_3069F_16TCR1 = 0x03)
56 #define TCR1_INTR_ENABLE()  (*H8_3069F_TISRC |=  (1 << 5))
57 #define TCR1_FLAG_CLEAR()   (*H8_3069F_TISRC &= ~(1 << 1))
58
59 #define VS1011E_CHK_DREQ()  (((*PORTCONF_P4DR) & PORTCONF_P4BIT_VSDREQ) ? 0 : 1)
60
61 typedef enum {
62   WaitLeader,
63   FoundLeader,
64   Receiving,
65   Received
66 } ir_state_t;
67
68 static ir_state_t irs = WaitLeader;
69 static uint8 data[MAX_BIT_COUNT / 8];
70 static uint16 bitcnt = 0;
71 static uint16 prev = 0, curr = 0;
72
73 static void remocon_intr_edge(void)
74 {
75   switch (irs) {
76     case WaitLeader:
77       TCNT0_START();
78       bitcnt = 0;
79       irs = FoundLeader;
80       break;
81     case FoundLeader:
82       irs = Receiving;
83       break;
84     case Receiving:
85       if (bitcnt < MAX_BIT_COUNT) {
86         if ((bitcnt % 8) == 0) {
87           data[bitcnt / 8] = 0;
88         }
89         uint16 tmrval = TCNT0_VALUE();
90         if (tmrval > 0x1077) {
91           data[bitcnt / 8] |= (1 << (bitcnt % 8));
92         }
93         bitcnt++;
94       }
95       if (32 <= bitcnt) {
96         irs = Received;
97         menu_remote_from_isr(&data[0], 4);
98       }
99       break;
100     case Received:
101       break;
102     default:
103       break;
104   }
105   TCNT0_RESET();
106 }
107
108 static void remocon_intr_tovf(void)
109 {
110   TCR0_FLAG_CLEAR();
111   irs = WaitLeader;
112   TCNT0_STOP();
113 }
114
115 static void encoder_intr_tovf(void)
116 {
117   TCR1_FLAG_CLEAR();
118
119   /*
120    * \e$B%m!<%?%j!<%(%s%3!<%@F~NO=hM}\e(B
121    */
122   curr = re_read();
123   if (curr != prev) {
124       int dir = (int)(curr & 0xff) - (int)(prev & 0xff);
125       if (dir < 0) {
126           if (-32 < dir) {
127               menu_rotary_from_isr(1, 0);
128           }
129       } else {
130           if (dir < 32) {
131               menu_rotary_from_isr(0, 1);
132           }
133       }
134       prev = curr;
135   }
136
137   /*
138    * \e$B%9%$%C%AF~NO=hM}\e(B
139    */
140   static int sw1_prev = 0, sw1_curr = 0;
141   static int sw2_prev = 0, sw2_curr = 0;
142   static int swr_prev = 0, swr_curr = 0;
143   sw1_curr = sw_read(Sw1);
144   sw2_curr = sw_read(Sw2);
145   swr_curr = sw_read(SwRe);
146   int s1 = 0, s2 = 0, sr = 0;
147   if ((sw1_prev != sw1_curr) && (sw1_curr)) {
148       s1 = 1;
149   }
150   if ((sw2_prev != sw2_curr) && (sw2_curr)) {
151       s2 = 1;
152   }
153   if ((swr_prev != swr_curr) && (swr_curr)) {
154       sr = 1;
155   }
156   if (s1 || s2 || sr) {
157       menu_switch_from_isr(s1, s2, sr);
158   }
159   sw1_prev = sw1_curr;
160   sw2_prev = sw2_curr;
161   swr_prev = swr_curr;
162 }
163
164 int task_input(int argc, char *argv[])
165 {
166   /*
167    * Setup.
168    */
169   kz_setintr(SOFTVEC_TYPE_IR_EDGE, remocon_intr_edge);
170   kz_setintr(SOFTVEC_TYPE_IR_TOVF, remocon_intr_tovf);
171   kz_setintr(SOFTVEC_TYPE_RE_TOVF, encoder_intr_tovf);
172
173   TCR0_SETUP();
174   TCR0_INTR_ENABLE();
175
176   TCR1_SETUP();
177   TCR1_INTR_ENABLE();
178   TCNT1_START();
179
180   IRQ4_ENABLE();
181
182   while (1) {
183     kz_sleep();
184   }
185
186   return 0;
187 }
188