-
Notifications
You must be signed in to change notification settings - Fork 1
/
infrared_communication.c
139 lines (108 loc) · 4.37 KB
/
infrared_communication.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
//#include "app_pwm.h"
#include "app_timer.h"
#include "ble_lbs.h"
#include "infrared_communication.h"
#include "ir_lib.h"
#include "nrf_delay.h"
#include "nrf_drv_gpiote.h"
#include "nrf_drv_timer.h"
#include "nrf_gpio.h"
#include <stdint.h>
#include "read_set_bit.h"
#include "SEGGER_RTT.h"
#include "nrf_ppi.h"
#include "nrf_soc.h"
#include "nrf_nvic.h"
#include "nrf_drv_ppi.h"
static uint8_t unique_car_IR_ID = 0; /* Unique ID for every car defined by the software. */
void write_car_id(uint8_t car_id){
unique_car_IR_ID = car_id;
}
void ir_shooting(uint8_t * ir_data)
{
// Send infrared signal by implementing the NEC protocol
// Carrier on time is always 560us, and the length of the break determines the bit value
uint8_t p_data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
static uint16_t ir_message[16];
uint32_t ir_buffer_index = 0;
for(int bit = 0; bit < 8; bit++)
{
if((p_data[unique_car_IR_ID] >> bit) & 0x01)
{
// 560us on, 2.25ms time until next symbol
ir_message[ir_buffer_index++] = 560;
ir_message[ir_buffer_index++] = 2250 - 560;
}
else
{
// 560us on, 1.12ms time until next symbol
ir_message[ir_buffer_index++] = 560;
ir_message[ir_buffer_index++] = 1120 - 560;
}
}
SEGGER_RTT_printf(0, "\n\nIR-signal in bits, where an OFF-signal of 1690 is logical 1 and 560 is logical 0\nValue to be sent as ir signal: %d\nON\tOFF (in microseconds)\n", p_data[unique_car_IR_ID]);
for (uint8_t i=0; i<(sizeof(ir_message)/2); i++)
{
SEGGER_RTT_printf(0, "%d", ir_message[i]);
ir_message[i] = ir_message[i++];
SEGGER_RTT_printf(0, "\t%d\n", ir_message[i]);
}
// Send the data in the ir_message buffer
// NOTE! The ir_message buffer must be static or global! The IR lib depends on the data in this buffer until the IR operation is complete.
ir_lib_send(ir_message, ir_buffer_index);
// Sets RGB blue and back to green or red
// TODO: Avoid delays?
nrf_delay_ms(10);
set_rgb_color(2);
nrf_delay_ms(50);
nrf_delay_ms(50);
set_rgb_color(250);
}
#if 0
/** @brief Function for initializing PPI used in infrared signal decoding
* The PPI is needed to convert the timer event into a task.
*/
uint32_t ir_ppi_init(void)
{
uint32_t gpiote_event_addr;
uint32_t timer_task_addr;
nrf_ppi_channel_t ppi_channel;
ret_code_t err_code;
nrf_drv_gpiote_in_config_t config;
config.sense = NRF_GPIOTE_POLARITY_HITOLO;
config.pull = NRF_GPIO_PIN_PULLUP;
config.hi_accuracy = false;
config.is_watcher = false;
nrf_drv_timer_config_t timer_config;
timer_config.frequency = NRF_TIMER_FREQ_1MHz;
timer_config.mode = NRF_TIMER_MODE_TIMER;
timer_config.bit_width = NRF_TIMER_BIT_WIDTH_32;
timer_config.interrupt_priority = 3;
err_code = nrf_drv_timer_init(&ir_timer, &timer_config, timer_dummy_handler);
APP_ERROR_CHECK(err_code);
// Set up GPIOTE
err_code = nrf_drv_gpiote_in_init(IR_RECEIVER_PIN_1, &config, ir_in_pin_handler);
APP_ERROR_CHECK(err_code);
err_code = nrf_drv_gpiote_in_init(IR_RECEIVER_PIN_2, &config, ir_in_pin_handler);
APP_ERROR_CHECK(err_code);
err_code = nrf_drv_gpiote_in_init(IR_RECEIVER_PIN_3, &config, ir_in_pin_handler);
APP_ERROR_CHECK(err_code);
// Set up timer for capturing
nrf_drv_timer_capture_get(&ir_timer, NRF_TIMER_CC_CHANNEL0);
// Set up PPI channel
err_code = nrf_drv_ppi_channel_alloc(&ppi_channel);
APP_ERROR_CHECK(err_code);
timer_task_addr = nrf_drv_timer_capture_task_address_get(&ir_timer, NRF_TIMER_CC_CHANNEL0);
gpiote_event_addr = nrf_drv_gpiote_in_event_addr_get(IR_RECEIVER_PIN_1);
//err_code = nrf_drv_ppi_channel_assign(ppi_channel, gpiote_event_addr, timer_task_addr);
//APP_ERROR_CHECK(err_code);
//err_code = nrf_drv_ppi_channel_enable(ppi_channel);
//APP_ERROR_CHECK(err_code);
nrf_drv_gpiote_in_event_enable(IR_RECEIVER_PIN_1, true);
nrf_drv_gpiote_in_event_enable(IR_RECEIVER_PIN_2, true);
nrf_drv_gpiote_in_event_enable(IR_RECEIVER_PIN_3, true);
// Enable timer
nrf_drv_timer_enable(&ir_timer);
return 0;
}
#endif