-
Notifications
You must be signed in to change notification settings - Fork 0
/
irmp-main-chibios.c
179 lines (149 loc) · 5.13 KB
/
irmp-main-chibios.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
+/*---------------------------------------------------------------------------------------------------------------------------------------------------
* irmp-main-chibios.c - demo main module to test IRMP decoder on ChibiOS
*
* This demo module needs to be compiled with the Makefiles and board config
* as provided and generated by ChibiOS
*
* Add IRMP to your ChibiOS-Makefile like this:
*
* IRMP_PATH = ../irmp
* ALLCSRC += $(IRMP_PATH)/irmp.c
* UDEFS += -DIRMP_CHIBIOS_HAL
* UINCDIR += $(IRMP_PATH)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*---------------------------------------------------------------------------------------------------------------------------------------------------
*/
#include "hal.h"
#include "ch.h"
#include "chprintf.h"
#include "irmp.h"
/*
* Timer definition for IRMP, using the GPT driver from ChibiOS HAL
*/
// the callback function
static void irmp_timer_callback(GPTDriver *gptp)
{
(void)gptp;
(void)irmp_ISR();
}
// GPT timer configuration.
static const GPTConfig irmp_gpt_cfg =
{
F_INTERRUPTS*10, /* timer tick frequency, a bit faster than the IRMP interrupts to improve accuracy .*/
irmp_timer_callback, /* Timer callback function.*/
0,
0
};
#if IRMP_USE_IDLE_CALL == 1
/*
* Idle and sleepmode handling
*
* irmp_idle is called from irmp_ISR when irmp is idle.
* Switch off the timer and use a pinchange interrupt.
*
* When a pinchange is detected, re-enable the timer.
*
* To actually send the controller into a sleep mode, you have to provide code in
* CH_CFG_IDLE_ENTER_HOOK() or enable CORTEX_ENABLE_WFI_IDLE. Then ChibiOS activates
* the sleepmode when all threads are idle
*
* Both functions are called from irq context, so only use ...I syscalls
*/
static void irmp_reenable(void *arg)
{
(void)arg;
palDisableLineEventI(LINE_IR_IN);
gptStartContinuousI(&GPTD14, 10);
// call irmp_ISR once, the next call is then done by the timer again
// this gives a slight timing imperfection but it seems to be within the allowed tolerance
(void) irmp_ISR();
}
void irmp_idle(void)
{
gptStopTimerI(&GPTD14);
palSetLineCallbackI(LINE_IR_IN, irmp_reenable, NULL);
palEnableLineEventI(LINE_IR_IN, PAL_EVENT_MODE_FALLING_EDGE);
}
#endif // IRMP_USE_IDLE_CALL
/*
* IR receive thread, sends decoded IR data to a serial data stream
*/
thread_t *ir_receive_thread_p = NULL;
static THD_WORKING_AREA(waIRThread, 256);
static THD_FUNCTION(IRThread, arg)
{
(void)arg;
ir_receive_thread_p = chThdGetSelfX();
// initialize the serial stream according to halconf.h
sdStart(&SD1, NULL);
// Welcome message
chprintf((BaseSequentialStream *)&SD1,"IRMP Receiver\r\nReady\r\n");
while (true)
{
IRMP_DATA irmp_data;
#if IRMP_USE_EVENT == 1
// the more elegant way: wait till event from irmp arrives
// wait for event sent from irmp_ISR
chEvtWaitAnyTimeout(ALL_EVENTS,TIME_INFINITE);
#else
// the dumb way
chThdSleepMilliseconds(100);
#endif
if (irmp_get_data (&irmp_data))
{
chprintf((BaseSequentialStream *)&SD1,">>IR: 0x%02x 0x%04x 0x%04x 0x%02x\r\n",
irmp_data.protocol, irmp_data.address, irmp_data.command, irmp_data.flags);
}
}
}
#if defined(_CHIBIOS_NIL_)
/*
* for ChibiOS/NIL:
* Threads static table, one entry per thread. The number of entries must
* match NIL_CFG_NUM_THREADS.
*/
THD_TABLE_BEGIN
THD_TABLE_ENTRY(waIRThread, "IRThread", IRThread, NULL)
THD_TABLE_END
#endif
/*
* Application entry point.
*/
int main(void)
{
/*
* System initializations.
* - HAL initialization, this also initializes the configured device drivers
* and performs the board-specific initializations.
* - Kernel initialization, the main() function becomes a thread and the
* RTOS is active.
*/
halInit();
irmp_init();
chSysInit();
#if defined(_CHIBIOS_RT_)
/*
* for ChibiOS/RT:
* Create & start the IR receive thread
*/
chThdCreateStatic(waIRThread, sizeof(waIRThread), NORMALPRIO, IRThread, NULL);
#endif
// now the system is ready: init and start the timer for IRMP
// Here we use timer 14, but you could use any other.
// The actual timer used must be available on the chosen hardware
// and activated in mcuconf.h (e.g. use #define STM32_GPT_USE_TIM14 TRUE)
gptStart(&GPTD14, &irmp_gpt_cfg);
gptStartContinuous(&GPTD14, 10);
/* This is now the idle thread loop, you may perform here a low priority
task but you must never try to sleep or wait in this loop. Note that
this tasks runs at the lowest priority level so any instruction added
here will be executed after all other tasks have been started.*/
while (true)
{
;
}
}