12 | #define BUF_SIZE 64
13 | #define leddir "/sys/class/leds/beaglebone:green:usr%d/"
14 | #define DELAY 300000
15 |
16 | typedef struct {
17 | char* org_trigger;
18 | int org_brightness;
19 | int lednr;
20 | } led_info;
21 |
22 | led_info *led0, *led1, *led2, *led3;
23 | int onBoardLedsExample();
24 | #endif /* EXAMPLES_LEDS_ONBOARDLEDS_H_ */
25 |
--------------------------------------------------------------------------------
/examples/pwm/README.md:
--------------------------------------------------------------------------------
1 | The BeagleBone has eight on-board pwm ports.
2 |
3 | On the BeagleBone Black, we must enable pwm before we can use it.
4 |
5 | To enable the pwm port on the P9 header, gpio 22, we first should disable the on board hdmi port:
6 | Rev A/B: Open the file /media/BEAGLEBONE/uEnv.txt in an editor (vim/nano)
7 | Rev C: Open the file /boot/uEnv.txt in an editor (vim/nano)
8 | Add the key "capemgr.disable_partno="
9 | Add the ports you want to enable, comma separated (BB-UART1, BB-UART2. BB-UART4, BB-UART5)
10 | Reboot
11 | An example line looks like this:
12 |
13 | root@beaglebone:/dev# cat /media/BEAGLEBONE/uEnv.txt
14 | cape_disable=capemgr.disable_partno=BB-BONELT-HDMI,BB-BONELT-HDMIN
15 |
16 |
17 | After reboot, the device tree is no longer loading the HDMI and the pwm port(s) can be loaded. To list the device tree do:
18 | cat /sys/devices/bone_capemgr.9/slots
19 |
20 |
21 | root@arm:/boot# cat /sys/devices/bone_capemgr.9/slots
22 | 0: 54:PF---
23 | 1: 55:PF---
24 | 2: 56:PF---
25 | 3: 57:PF---
26 | 4: ff:P-O-L Bone-LT-eMMC-2G,00A0,Texas Instrument,BB-BONE-EMMC-2G
27 | 5: ff:P-O-- Bone-Black-HDMI,00A0,Texas Instrument,BB-BONELT-HDMI
28 | 6: ff:P-O-- Bone-Black-HDMIN,00A0,Texas Instrument,BB-BONELT-HDMIN
29 |
30 | 
--------------------------------------------------------------------------------
/examples/pwm/pwm_example.c:
--------------------------------------------------------------------------------
1 | /*
2 | * spi.c
3 | *
4 | * Created on: May 31, 2015
5 | * Author: gijs
6 | */
7 |
8 | #include "pwm_example.h"
9 | #include "../../src/log.h"
10 |
11 | int pwmExample() {
12 |
13 | pwm_properties *pwm = malloc(sizeof(pwm_properties));
14 | pwm->name = "pwm_test_P9_22.12";
15 |
16 | int isOpen = pwm_open(pwm);
17 |
18 | if (isOpen == 1) {
19 | if (pwm_set_run(pwm, 0) < 0) {
20 | printf("Could not stop pwm port.\n");
21 | return -1;
22 | }
23 | if (pwm_set_period(pwm, 10000) < 0) {
24 | printf("Could not set period.\n");
25 | return -1;
26 | }
27 | if (pwm_set_duty(pwm, 1000) < 0) {
28 | printf("Could not set duty.\n");
29 | return -1;
30 | }
31 | if (pwm_set_run(pwm, 1) < 0) {
32 | printf("Could not start pwm port.\n");
33 | return -1;
34 | }
35 |
36 | int i=0,j=0;
37 | while(j++ < 10) {
38 | while(i-- > 0) {
39 | if (pwm_set_duty(pwm, i*100) < 0) {
40 | printf("Could not set duty.\n");
41 | return -1;
42 | }
43 | debug("Wrote %d to pwm (%s)", i, pwm->name);
44 | usleep(100000);
45 | }
46 | i = 10;
47 | }
48 |
49 | pwm_set_run(pwm, 0);
50 | }
51 | debug("Finished pwm example.");
52 | return 0;
53 | }
54 |
--------------------------------------------------------------------------------
/examples/pwm/pwm_example.h:
--------------------------------------------------------------------------------
1 | /*
2 | * spi.c
3 | *
4 | * Created on: May 31, 2015
5 | * Author: gijs
6 | */
7 |
8 | #include
9 | #include "../../src/pwm.h"
10 |
11 |
12 | int pwmExample();
13 |
--------------------------------------------------------------------------------
/examples/pwm/pwm_led.fzz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sijpesteijn/BBCLib/7b4ab6acd6969eac9c3109da8e84a4948dfcb498/examples/pwm/pwm_led.fzz
--------------------------------------------------------------------------------
/examples/pwm/pwm_led.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sijpesteijn/BBCLib/7b4ab6acd6969eac9c3109da8e84a4948dfcb498/examples/pwm/pwm_led.png
--------------------------------------------------------------------------------
/examples/spi/README.MD:
--------------------------------------------------------------------------------
1 | The beaglebone black has 2 spi buses.
2 |
3 | The 4 examples are:
4 | * ADXL345
5 | 
6 | Youtube
7 | * MCP23S08
8 | 
9 | Youtube
10 | * MCP4902
11 | 
12 | Youtube
13 | * MCP23S08 -> MCP4902 -> TL082
14 | 
15 | MCP23S08 driving a MCP4902. The outputs from the MCP4902 are amplified by a TL082
16 | Youtube
--------------------------------------------------------------------------------
/examples/spi/adxl345.fzz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sijpesteijn/BBCLib/7b4ab6acd6969eac9c3109da8e84a4948dfcb498/examples/spi/adxl345.fzz
--------------------------------------------------------------------------------
/examples/spi/adxl345.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sijpesteijn/BBCLib/7b4ab6acd6969eac9c3109da8e84a4948dfcb498/examples/spi/adxl345.png
--------------------------------------------------------------------------------
/examples/spi/mcp23s08.fzz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sijpesteijn/BBCLib/7b4ab6acd6969eac9c3109da8e84a4948dfcb498/examples/spi/mcp23s08.fzz
--------------------------------------------------------------------------------
/examples/spi/mcp23s08.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sijpesteijn/BBCLib/7b4ab6acd6969eac9c3109da8e84a4948dfcb498/examples/spi/mcp23s08.png
--------------------------------------------------------------------------------
/examples/spi/mcp23s08_mcp4902.fzz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sijpesteijn/BBCLib/7b4ab6acd6969eac9c3109da8e84a4948dfcb498/examples/spi/mcp23s08_mcp4902.fzz
--------------------------------------------------------------------------------
/examples/spi/mcp23s08_mcp4902.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sijpesteijn/BBCLib/7b4ab6acd6969eac9c3109da8e84a4948dfcb498/examples/spi/mcp23s08_mcp4902.png
--------------------------------------------------------------------------------
/examples/spi/mcp4902.fzz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sijpesteijn/BBCLib/7b4ab6acd6969eac9c3109da8e84a4948dfcb498/examples/spi/mcp4902.fzz
--------------------------------------------------------------------------------
/examples/spi/mcp4902.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sijpesteijn/BBCLib/7b4ab6acd6969eac9c3109da8e84a4948dfcb498/examples/spi/mcp4902.png
--------------------------------------------------------------------------------
/examples/spi/spi_example.c:
--------------------------------------------------------------------------------
1 | /*
2 | * spi.c
3 | *
4 | * Created on: May 31, 2015
5 | * Author: gijs
6 | */
7 |
8 | #include "spi_example.h"
9 | #include "../../src/log.h"
10 |
11 | /*
12 | * MCP23S08 is a 8-Bit I/O Expander with Serial Interface.
13 | * This example lights the 8 leds in sequence for 10 times.
14 | */
15 | int spiMCP23S08Example() {
16 | unsigned char mcp23s08_setup[] = { 0x40, 0x00, 0x00, };
17 | unsigned char mcp23s08_gpios[] = { 0x40, 0x09, 0x01, };
18 |
19 | spi_properties *spi = malloc(sizeof(spi_properties));
20 | spi->spi_id = spi0;
21 | spi->bits_per_word = 8;
22 | spi->mode = 0;
23 | spi->speed = 10000000;
24 | spi->flags = O_RDWR;
25 |
26 | uint8_t isOpen = spi_open(spi);
27 |
28 | if (isOpen == 0) {
29 | spi_send(spi, mcp23s08_setup, sizeof(mcp23s08_setup));
30 | // Loop from 0 to 255 and light the LED bar as a binary counter
31 | int i = 0, j = 0;
32 | while(j++ < 10) {
33 | for (i = 0; i < 8; i++) {
34 | // This function can send and receive data, just sending here
35 | if (spi_send(spi, mcp23s08_gpios, sizeof(mcp23s08_gpios)) == -1) {
36 | perror("Failed to update the display");
37 | return -1;
38 | }
39 | usleep(100000); //sleep for 100ms each loop
40 | mcp23s08_gpios[2] = mcp23s08_gpios[2] << 1;
41 | }
42 | mcp23s08_gpios[2] = 0x01;
43 | }
44 | mcp23s08_gpios[2] = 0x00;
45 | if (spi_send(spi, mcp23s08_gpios, sizeof(mcp23s08_gpios)) == -1) {
46 | perror("Failed to update the display");
47 | return -1;
48 | }
49 | spi_close(spi);
50 | }
51 | debug("Finished spi example.");
52 | return 0;
53 | }
54 |
55 | /*
56 | * ADXL345 is a Digital Accelerometer. It can measure movement on 3 axes.
57 | * This example will probe the axis 20 times every second.
58 | */
59 | int spiADXL345Example() {
60 |
61 | printf("WORK IN PROGRESS\n");
62 | unsigned char adxl345_setup[] = {};
63 | unsigned char receive[6];
64 | signed short data[3];
65 |
66 | spi_properties *spi = malloc(sizeof(spi_properties));
67 | spi->spi_id = spi0;
68 | spi->bits_per_word = 8;
69 | spi->mode = 3;
70 | spi->speed = 2000000;
71 | spi->flags = O_RDWR;
72 |
73 | uint8_t isOpen = spi_open(spi);
74 |
75 | if (isOpen == 0) {
76 | adxl345_setup[0] = 0x31;
77 | adxl345_setup[1] = 0x08;
78 | spi_send(spi, adxl345_setup, 2);
79 | adxl345_setup[0] = 0x2D;
80 | adxl345_setup[1] = 0x08;
81 | spi_send(spi, adxl345_setup, 2);
82 | while(1) {
83 | adxl345_setup[0] = 0x80|0x40|0x32;
84 | adxl345_setup[1] = 0x00;
85 | spi_transfer(spi, adxl345_setup, receive, 6);
86 | data[0] = receive[1]<<8 | receive[0]; // combine MSB and LSB
87 | data[1] = receive[3]<<8 | receive[2];
88 | data[2] = receive[5]<<8 | receive[4];
89 | printf("x = %i \ty = %i\t z = %i\n", data[0], data[1], data[2]);
90 | data[0] = 0;
91 | data[1] = 0;
92 | data[2] = 0;
93 | usleep(1000000);
94 | }
95 | }
96 | return 0;
97 | }
98 |
99 | void write8Bits(spi_properties *spi, unsigned char reg, unsigned char value) {
100 | unsigned char data[2] = {};
101 | data[0] = reg | ((value & 0xf0) >> 4);
102 | data[1] = (value & 0x0f) << 4;
103 | if (spi_send(spi, data, sizeof(data)) == -1) {
104 | perror("Failed to update output.");
105 | }
106 | }
107 |
108 | /*
109 | * MCP4902 is a 8-Bit Dual Voltage Output Digital-to-Analog Converter with SPI Interface.
110 | * This example will increase the output for A untill the maximum and then decrease to the minimum 10 times.
111 | * Output B will reflect the inverse of output A.
112 | * 255
113 | */
114 | int spiMCP4902Example() {
115 |
116 | spi_properties *spi = malloc(sizeof(spi_properties));
117 | spi->spi_id = spi0;
118 | spi->bits_per_word = 8;
119 | spi->mode = 3;
120 | spi->speed = 2400000;
121 | spi->flags = O_RDWR;
122 |
123 | int delay = 1000;
124 |
125 | uint8_t isSpiOpen = spi_open(spi);
126 | if (isSpiOpen == 0) {
127 |
128 | int i = 0;
129 | unsigned char value = 0x00;
130 | while(i++ < 10) {
131 | while(value < 0xff) {
132 | write8Bits(spi, 0x70, value);
133 | write8Bits(spi, 0xf0, ~value);
134 | usleep(delay);
135 | value = value + 1;
136 | }
137 | while(value > 0x00) {
138 | value = value - 1;
139 | write8Bits(spi, 0x70, value);
140 | write8Bits(spi, 0xf0, ~value);
141 | usleep(delay);
142 | }
143 | }
144 | write8Bits(spi, 0x70, 0);
145 | write8Bits(spi, 0xf0, 0);
146 | }
147 | free(spi);
148 | debug("Finished spi example.");
149 | return 0;
150 | }
151 |
152 | void write10Bits(spi_properties *spi, unsigned char reg, unsigned short value) {
153 | unsigned char data[2] = {};
154 | data[0] = reg | ((value & 0xff00) >> 6);
155 | data[1] = (value & 0x00ff);
156 | if (spi_send(spi, data, sizeof(data)) == -1) {
157 | perror("Failed to update output.");
158 | }
159 | }
160 |
161 | /*
162 | * MCP4912 is a 10-Bit Dual Voltage Output Digital-to-Analog Converter with SPI Interface.
163 | * This example will increase the output for A untill the maximum and then decrease to the minimum 10 times.
164 | * Output B will reflect the inverse of output A.
165 | * 1024
166 | */
167 | int spiMCP4912Example() {
168 |
169 | spi_properties *spi = malloc(sizeof(spi_properties));
170 | spi->spi_id = spi0;
171 | spi->bits_per_word = 8;
172 | spi->mode = 3;
173 | spi->speed = 2400000;
174 | spi->flags = O_RDWR;
175 |
176 | int delay = 1000;
177 |
178 | uint8_t isSpiOpen = spi_open(spi);
179 | if (isSpiOpen == 0) {
180 |
181 | int i = 0;
182 | while(i++ < 10) {
183 | unsigned short value = 0x0000;
184 | while(value < 0x03ff) {
185 | write10Bits(spi, 0x70, value);
186 | write10Bits(spi, 0xf0, ~value);
187 | usleep(delay);
188 | value = value + 1;
189 | }
190 | while(value > 0x00) {
191 | value = value - 1;
192 | write10Bits(spi, 0x70, value);
193 | write10Bits(spi, 0xf0, ~value);
194 | usleep(delay);
195 | }
196 | }
197 | write10Bits(spi, 0x70, 0);
198 | write10Bits(spi, 0xf0, 0);
199 | }
200 | free(spi);
201 | debug("Finished spi example.");
202 | return 0;
203 | }
204 |
205 | void write12Bits(spi_properties *spi, unsigned char reg, unsigned short value) {
206 | unsigned char data[2] = {};
207 | data[0] = reg | ((value & 0xff00) >> 8);
208 | data[1] = (value & 0x00ff);
209 | if (spi_send(spi, data, sizeof(data)) == -1) {
210 | perror("Failed to update output.");
211 | }
212 | }
213 |
214 | /*
215 | * MCP4922 is a 12-Bit Dual Voltage Output Digital-to-Analog Converter with SPI Interface.
216 | * This example will increase the output for A untill the maximum and then decrease to the minimum 10 times.
217 | * Output B will reflect the inverse of output A.
218 | * 4096
219 | */
220 | int spiMCP4922Example() {
221 |
222 | spi_properties *spi = malloc(sizeof(spi_properties));
223 | spi->spi_id = spi0;
224 | spi->bits_per_word = 8;
225 | spi->mode = 3;
226 | spi->speed = 2400000;
227 | spi->flags = O_RDWR;
228 |
229 | int delay = 1000;
230 |
231 | uint8_t isSpiOpen = spi_open(spi);
232 | if (isSpiOpen == 0) {
233 |
234 | int i = 0;
235 | unsigned short value = 0;
236 | while(i++ < 10) {
237 | while(value < 4096) {
238 | write12Bits(spi, 0x70, value);
239 | write12Bits(spi, 0xf0, ~value);
240 | usleep(delay);
241 | value = value + 1;
242 | }
243 | while(value > 0) {
244 | value = value - 1;
245 | write12Bits(spi, 0x70, value);
246 | write12Bits(spi, 0xf0, ~value);
247 | usleep(delay);
248 | }
249 | }
250 | write12Bits(spi, 0x70, 0);
251 | write12Bits(spi, 0xf0, 0);
252 | }
253 | free(spi);
254 | debug("Finished spi example.");
255 | return 0;
256 | }
257 |
258 | void dprint(unsigned char value) {
259 | debug("0x%02x", value);
260 | }
261 |
262 | int set_MCP23S08_GPIO_values(spi_properties *spi, unsigned char value) {
263 | unsigned char mcp23s08_gpios[] = { 0x40, 0x09, 0x00, };
264 | mcp23s08_gpios[2] = value;
265 | // dprint(value);
266 | spi_send(spi, mcp23s08_gpios, sizeof(mcp23s08_gpios));
267 | return 1;
268 | }
269 |
270 | int send_MCP49x2_values(spi_properties *spi, unsigned char value) {
271 | int bit_position = 8;
272 | while(bit_position > 0) {
273 | unsigned char bit_to_send = (value & 0x80) >> 2;
274 | // dprint(bit_to_send);
275 | unsigned char clkdata = bit_to_send;
276 | set_MCP23S08_GPIO_values(spi, clkdata);
277 | clkdata = (MCP23S08_SCK | bit_to_send);
278 | set_MCP23S08_GPIO_values(spi, clkdata);
279 | bit_position--;
280 | value = value << 1;
281 | }
282 | return 1;
283 | }
284 |
285 | void set_MCP49x2(unsigned char data[2], unsigned char chip, spi_properties* spi) {
286 | set_MCP23S08_GPIO_values(spi, chip | MCP23S08_SCK | MCP23S08_SDI);
287 | set_MCP23S08_GPIO_values(spi, MCP23S08_SCK | MCP23S08_SDI);
288 | set_MCP23S08_GPIO_values(spi, MCP23S08_SDI);
289 | set_MCP23S08_GPIO_values(spi, MCP23S08_ALL_DOWN);
290 | send_MCP49x2_values(spi, data[0]);
291 | send_MCP49x2_values(spi, data[1]);
292 | set_MCP23S08_GPIO_values(spi, MCP23S08_SCK | MCP23S08_SDI);
293 | set_MCP23S08_GPIO_values(spi, chip | MCP23S08_SCK | MCP23S08_SDI);
294 | }
295 |
296 | void setData(unsigned char *data, unsigned char reg, unsigned short value) {
297 | data[0] = reg | ((value & 0xf0) >> 4);
298 | data[1] = (value & 0x0f) << 4;
299 | }
300 |
301 | int spiMC23S08_MCP4902Example() {
302 | unsigned char mcp23s08_setup[] = { 0x40, 0x00, 0x00, };
303 |
304 | spi_properties *spi = malloc(sizeof(spi_properties));
305 | spi->spi_id = spi0;
306 | spi->bits_per_word = 8;
307 | spi->mode = 0;
308 | spi->speed = 10000000;
309 | spi->flags = O_RDWR;
310 |
311 | uint8_t isOpen = spi_open(spi);
312 |
313 | if (isOpen == 0) {
314 | spi_send(spi, mcp23s08_setup, sizeof(mcp23s08_setup));
315 |
316 | unsigned char data[2] = {};
317 | int delay = 1000;
318 | int i = 0;
319 | while(i++ < 10) {
320 | unsigned short value = 0x0000;
321 | while(value < 0xff) {
322 | setData(data, 0x70, value);
323 | set_MCP49x2(data, MCP4902_1_CS, spi);
324 | setData(data, 0xf0, ~value);
325 | set_MCP49x2(data, MCP4902_1_CS, spi);
326 | usleep(delay);
327 | value = value + 1;
328 | }
329 | while(value > 0x00) {
330 | value = value - 1;
331 | setData(data, 0x70, value);
332 | set_MCP49x2(data, MCP4902_1_CS, spi);
333 | setData(data, 0xf0, ~value);
334 | set_MCP49x2(data, MCP4902_1_CS, spi);
335 | usleep(delay);
336 | }
337 | }
338 | data[0] = 0x70;
339 | data[1] = 0x00;
340 | set_MCP49x2(data, MCP4902_1_CS, spi);
341 | data[0] = 0xf0;
342 | data[1] = 0x00;
343 | set_MCP49x2(data, MCP4902_1_CS, spi);
344 | }
345 |
346 | free(spi);
347 | debug("Finished spi example.");
348 | return 0;
349 | }
350 |
--------------------------------------------------------------------------------
/examples/spi/spi_example.h:
--------------------------------------------------------------------------------
1 | /*
2 | * spi.c
3 | *
4 | * Created on: May 31, 2015
5 | * Author: gijs
6 | */
7 |
8 | #include
9 | #include "../../src/spi.h"
10 | #include "../../src/gpio.h"
11 | #include "../gpio/gpio_example.h"
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 | #include
18 | #include
19 | #include
20 | #include
21 |
22 | #define MCP23S08_ALL_DOWN 0x00
23 | #define MCP4902_1_CS 0x01 //GPIO_0 0000 0001
24 | #define MCP4902_2_CS 0x02 //GPIO_1 0000 0010
25 | #define MCP4922_CS 0x04 //GPIO_2 0000 0100
26 | #define MCP23S08_LDAC 0x08 //GPIO_3 0000 1000
27 | #define MCP23S08_SCK 0x10 //GPIO_4 0001 0000
28 | #define MCP23S08_SDI 0x20 //GPIO_5 0010 0000
29 | #define MCP23S08_SHUTTER 0x40 //GPIO_6 0100 0000
30 | #define MCP23S08_SHUTTER_RETURN 0x80 //GPIO_7 1000 0000
31 |
32 | int spiMCP23S08Example();
33 | int spiADXL345Example();
34 | int spiMCP4902Example();
35 | int spiMCP4912Example();
36 | int spiMCP4922Example();
37 | int spiMC23S08_MCP4902Example();
38 |
--------------------------------------------------------------------------------
/examples/uart/README.md:
--------------------------------------------------------------------------------
1 | The BeagleBone has six on-board serial ports.
2 |
3 | On the BeagleBone Black, it's only the /dev/ttyO0 that is enabled by default, and it is coupled to the serial console. The other serial ports must be enabled before they can be used.
4 |
5 | To enable the uarts 1,2,4 and/or 5 on the BeagleBone Black, rev A, B and C:
6 | Rev A/B: Open the file /media/BEAGLEBONE/uEnv.txt in an editor (vim/nano)
7 | Rev C: Open the file /boot/uEnv.txt in an editor (vim/nano)
8 | Add the key "cape_enable="
9 | Add the ports you want to enable, comma separated (BB-UART1, BB-UART2. BB-UART4, BB-UART5)
10 | Add the key "cape_disable"
11 | And add the BB-BONELT-HDMI and BB-BONELT-HDMIN
12 | Reboot
13 | An example line looks like this:
14 |
15 | root@beaglebone:/dev# cat /boot/uEnv.txt
16 | cape_enable=capemgr.enable_partno=BB-UART1
17 | cape_disable=capemgr.disable_partno=BB-BONELT-HDMI,BB-BONELT-HDMIN
18 |
19 |
20 |
21 | After reboot, the device is present in the device list:
22 |
23 | root@beaglebone:/dev# ls -l /dev/ttyO*
24 | crw-rw---- 1 root tty 249, 0 Jan 1 01:18 /dev/ttyO0
25 | crw-rw---- 1 root dialout 249, 4 Jan 1 01:18 /dev/ttyO4
26 |
27 |
28 | The UARTs map to pins and devices like this:
29 |
30 |
31 | RX TX CTS RTS Device Remark
32 | UART0 J1_4 J1_5 /dev/ttyO0 BeagleBone Black only
33 | UART1 P9_26 P9_24 P9_20 P9_19 /dev/ttyO1
34 | UART2 P9_22 P9_21 P8_37 P8_38 /dev/ttyO2
35 | UART3 P9_42 P8_36 P8_34 /dev/ttyO3 TX only
36 | UART4 P9_11 P9_13 P8_35 P8_33 /dev/ttyO4
37 | UART5 P8_38 P8_37 P8_31 P8_32 /dev/ttyO5
38 |
39 |
40 | 
--------------------------------------------------------------------------------
/examples/uart/uart.fzz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sijpesteijn/BBCLib/7b4ab6acd6969eac9c3109da8e84a4948dfcb498/examples/uart/uart.fzz
--------------------------------------------------------------------------------
/examples/uart/uart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sijpesteijn/BBCLib/7b4ab6acd6969eac9c3109da8e84a4948dfcb498/examples/uart/uart.png
--------------------------------------------------------------------------------
/examples/uart/uart_example.c:
--------------------------------------------------------------------------------
1 | /*
2 | * spi.c
3 | *
4 | * Created on: May 31, 2015
5 | * Author: gijs
6 | */
7 |
8 | #include "uart_example.h"
9 | #include "../../src/log.h"
10 | #include
11 | #include
12 | #include
13 | #include
14 |
15 | /*
16 | * UART.
17 | * This example will send the text 'foo n' (where is an index) a 10 times to the /dev/ttyO1 uart port.
18 | * The received text is printed on the screen.
19 | */
20 | int uartExample() {
21 |
22 | printf("!!! Make sure you have enabled UART1 (/dev/ttyO1) see the README.md how to do this. !!!\n");
23 |
24 | uart_properties *uart = malloc(sizeof(uart_properties));
25 | uart->uart_id = uart1;
26 | uart->baudrate = B4800;
27 |
28 | uint8_t isOpen = uart_open(uart);
29 | int i = 0;
30 |
31 | if (isOpen == 0) {
32 | unsigned char receive[100];
33 | while(i++ < 10)
34 | {
35 | char buf[30];
36 | sprintf(buf, "foo %d", i);
37 |
38 | // Send data to uart1
39 | if (uart_send(uart, buf, strlen(buf) + 1) < 0) {
40 | printf("Could not send data to uart port");
41 | return -1;
42 | }
43 |
44 | usleep(100000);
45 |
46 | // Read data from uart1
47 | if (uart_read(uart, receive, 100) < 0) {
48 | printf("Could not read data from uart port");
49 | return -1;
50 | }
51 |
52 | printf("Read: %s\n",receive);
53 | usleep(50000);
54 | }
55 | uart_close(uart);
56 | }
57 |
58 | debug("Finished pwm example.");
59 | return 0;
60 | }
61 |
--------------------------------------------------------------------------------
/examples/uart/uart_example.h:
--------------------------------------------------------------------------------
1 | /*
2 | * spi.c
3 | *
4 | * Created on: May 31, 2015
5 | * Author: gijs
6 | */
7 |
8 | #include "../../src/uart.h"
9 |
10 | int uartExample();
11 |
--------------------------------------------------------------------------------
/pbr.sh:
--------------------------------------------------------------------------------
1 | #/bin/bash
2 |
3 | git pull
4 | make
5 | ./BBCLib
--------------------------------------------------------------------------------
/src/bbclib.c:
--------------------------------------------------------------------------------
1 | /*
2 | * bbclib.c
3 | *
4 | * Created on: May 31, 2015
5 | * Author: gijs
6 | */
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/src/gpio.c:
--------------------------------------------------------------------------------
1 | /*
2 | * gpio.c
3 | *
4 | * Created on: Jun 7, 2015
5 | * Author: gijs
6 | */
7 |
8 | #include
9 | #include
10 | #include "gpio.h"
11 | #include "log.h"
12 |
13 | int gpio_open(gpio_properties *gpio) {
14 | // info("gpio_open: export gpio: %d", gpio->nr);
15 | FILE *export;
16 | export = fopen(SYSFS_GPIO_DIR "/export", "w");
17 | if (export < 0) {
18 | perror("gpio/export");
19 | return 1;
20 | }
21 | char str[15];
22 | sprintf(str, "%d", gpio->nr);
23 | fputs(str, export);
24 | fclose(export);
25 | printf("%d\n", (int)gpio->direction);
26 | FILE *fd;
27 | char buf[MAX_BUF];
28 |
29 | snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/direction", gpio->nr);
30 | fd = fopen(buf, "w");
31 | if (fd < 0) {
32 | error("Could not set gpio direction: %s", gpio->direction);
33 | return 1;
34 | }
35 | if (gpio->direction == OUTPUT_PIN)
36 | fputs("out", fd);
37 | else
38 | fputs("in", fd);
39 | fclose(fd);
40 | return 0;
41 | }
42 |
43 | int gpio_close(gpio_properties *gpio) {
44 | info("gpio_close: unexport gpio: %d", gpio->nr);
45 | FILE *fd;
46 | fd = fopen(SYSFS_GPIO_DIR "/unexport", "w");
47 | if (fd < 0) {
48 | perror("gpio/unexport");
49 | return 1;
50 | }
51 | char str[15];
52 | sprintf(str, "%d", gpio->nr);
53 | fputs(str, fd);
54 | fclose(fd);
55 |
56 | return 0;
57 | }
58 |
59 | int gpio_set_value(gpio_properties *gpio, int value) {
60 | debug("gpio set value: %d, %d", gpio->nr, value);
61 | FILE *fd;
62 | char buf[MAX_BUF];
63 |
64 | snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/value", gpio->nr);
65 |
66 | fd = fopen(buf, "w");
67 | if (fd < 0) {
68 | perror("gpio/set-value");
69 | return 1;
70 | }
71 |
72 | char str[2];
73 | sprintf(str, "%d", value);
74 | fputs(str, fd);
75 |
76 | fclose(fd);
77 | return 0;
78 | }
79 |
80 | int gpio_get_value(gpio_properties *gpio) {
81 | debug("gpio get value: %d", gpio->nr);
82 | int value;
83 | FILE *fd;
84 | char buf[MAX_BUF];
85 |
86 | snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/value", gpio->nr);
87 | fd = fopen(buf, "r");
88 | if (fd < 0) {
89 | perror("gpio/get-value");
90 | return 1;
91 | }
92 |
93 | char str[2];
94 | fgets(str, 2, fd);
95 |
96 | if (strcmp(str, "1") == 0) {
97 | value = 1;
98 | } else {
99 | value = 0;
100 | }
101 |
102 | fclose(fd);
103 | return value;
104 | }
105 |
106 | int gpio_set_edge(gpio_properties *gpio, char *edge) {
107 | debug("gpio set edge: %d, %s", gpio->nr, edge);
108 | FILE *fd;
109 | char buf[MAX_BUF];
110 |
111 | snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/edge", gpio->nr);
112 |
113 | fd = fopen(buf, "w");
114 | if (fd < 0) {
115 | perror("gpio/set-edge");
116 | return 1;
117 | }
118 |
119 | fputs(edge, fd);
120 | fclose(fd);
121 | return 0;
122 | }
123 |
--------------------------------------------------------------------------------
/src/gpio.h:
--------------------------------------------------------------------------------
1 | /*
2 | * gpio.h
3 | *
4 | * Created on: Jun 7, 2015
5 | * Author: gijs
6 | */
7 |
8 | #ifndef GPIO_H_
9 | #define GPIO_H_
10 |
11 | #define SYSFS_GPIO_DIR "/sys/class/gpio"
12 | #define MAX_BUF 64
13 |
14 | typedef enum {
15 | INPUT_PIN=0,
16 | OUTPUT_PIN
17 | } PIN_DIRECTION;
18 |
19 | typedef struct {
20 | int nr;
21 | PIN_DIRECTION direction;
22 | } gpio_properties;
23 |
24 | extern int gpio_open(gpio_properties *gpio);
25 | extern int gpio_close(gpio_properties *gpio);
26 | extern int gpio_set_value(gpio_properties *gpio, int value);
27 | extern int gpio_get_value(gpio_properties *gpio);
28 | extern int gpio_set_edge(gpio_properties *gpio, char *edge);
29 | #endif /* GPIO_H_ */
30 |
--------------------------------------------------------------------------------
/src/i2c-dev.h:
--------------------------------------------------------------------------------
1 | /*
2 | i2c-dev.h - i2c-bus driver, char device interface
3 |
4 | Copyright (C) 1995-97 Simon G. Vogl
5 | Copyright (C) 1998-99 Frodo Looijaard
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; either version 2 of the License, or
10 | (at your option) any later version.
11 |
12 | This program is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | GNU General Public License for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with this program; if not, write to the Free Software
19 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
20 | MA 02110-1301 USA.
21 | */
22 |
23 | /* $Id: i2c-dev.h 5894 2010-12-12 13:22:29Z khali $ */
24 |
25 | #ifndef LIB_I2CDEV_H
26 | #define LIB_I2CDEV_H
27 |
28 | #include
29 | #include
30 |
31 |
32 | /* -- i2c.h -- */
33 |
34 |
35 | /*
36 | * I2C Message - used for pure i2c transaction, also from /dev interface
37 | */
38 | struct i2c_msg {
39 | __u16 addr; /* slave address */
40 | unsigned short flags;
41 | #define I2C_M_TEN 0x10 /* we have a ten bit chip address */
42 | #define I2C_M_RD 0x01
43 | #define I2C_M_NOSTART 0x4000
44 | #define I2C_M_REV_DIR_ADDR 0x2000
45 | #define I2C_M_IGNORE_NAK 0x1000
46 | #define I2C_M_NO_RD_ACK 0x0800
47 | short len; /* msg length */
48 | char *buf; /* pointer to msg data */
49 | };
50 |
51 | /* To determine what functionality is present */
52 |
53 | #define I2C_FUNC_I2C 0x00000001
54 | #define I2C_FUNC_10BIT_ADDR 0x00000002
55 | #define I2C_FUNC_PROTOCOL_MANGLING 0x00000004 /* I2C_M_{REV_DIR_ADDR,NOSTART,..} */
56 | #define I2C_FUNC_SMBUS_PEC 0x00000008
57 | #define I2C_FUNC_SMBUS_BLOCK_PROC_CALL 0x00008000 /* SMBus 2.0 */
58 | #define I2C_FUNC_SMBUS_QUICK 0x00010000
59 | #define I2C_FUNC_SMBUS_READ_BYTE 0x00020000
60 | #define I2C_FUNC_SMBUS_WRITE_BYTE 0x00040000
61 | #define I2C_FUNC_SMBUS_READ_BYTE_DATA 0x00080000
62 | #define I2C_FUNC_SMBUS_WRITE_BYTE_DATA 0x00100000
63 | #define I2C_FUNC_SMBUS_READ_WORD_DATA 0x00200000
64 | #define I2C_FUNC_SMBUS_WRITE_WORD_DATA 0x00400000
65 | #define I2C_FUNC_SMBUS_PROC_CALL 0x00800000
66 | #define I2C_FUNC_SMBUS_READ_BLOCK_DATA 0x01000000
67 | #define I2C_FUNC_SMBUS_WRITE_BLOCK_DATA 0x02000000
68 | #define I2C_FUNC_SMBUS_READ_I2C_BLOCK 0x04000000 /* I2C-like block xfer */
69 | #define I2C_FUNC_SMBUS_WRITE_I2C_BLOCK 0x08000000 /* w/ 1-byte reg. addr. */
70 |
71 | #define I2C_FUNC_SMBUS_BYTE (I2C_FUNC_SMBUS_READ_BYTE | \
72 | I2C_FUNC_SMBUS_WRITE_BYTE)
73 | #define I2C_FUNC_SMBUS_BYTE_DATA (I2C_FUNC_SMBUS_READ_BYTE_DATA | \
74 | I2C_FUNC_SMBUS_WRITE_BYTE_DATA)
75 | #define I2C_FUNC_SMBUS_WORD_DATA (I2C_FUNC_SMBUS_READ_WORD_DATA | \
76 | I2C_FUNC_SMBUS_WRITE_WORD_DATA)
77 | #define I2C_FUNC_SMBUS_BLOCK_DATA (I2C_FUNC_SMBUS_READ_BLOCK_DATA | \
78 | I2C_FUNC_SMBUS_WRITE_BLOCK_DATA)
79 | #define I2C_FUNC_SMBUS_I2C_BLOCK (I2C_FUNC_SMBUS_READ_I2C_BLOCK | \
80 | I2C_FUNC_SMBUS_WRITE_I2C_BLOCK)
81 |
82 | /* Old name, for compatibility */
83 | #define I2C_FUNC_SMBUS_HWPEC_CALC I2C_FUNC_SMBUS_PEC
84 |
85 | /*
86 | * Data for SMBus Messages
87 | */
88 | #define I2C_SMBUS_BLOCK_MAX 32 /* As specified in SMBus standard */
89 | #define I2C_SMBUS_I2C_BLOCK_MAX 32 /* Not specified but we use same structure */
90 | union i2c_smbus_data {
91 | __u8 byte;
92 | __u16 word;
93 | __u8 block[I2C_SMBUS_BLOCK_MAX + 2]; /* block[0] is used for length */
94 | /* and one more for PEC */
95 | };
96 |
97 | /* smbus_access read or write markers */
98 | #define I2C_SMBUS_READ 1
99 | #define I2C_SMBUS_WRITE 0
100 |
101 | /* SMBus transaction types (size parameter in the above functions)
102 | Note: these no longer correspond to the (arbitrary) PIIX4 internal codes! */
103 | #define I2C_SMBUS_QUICK 0
104 | #define I2C_SMBUS_BYTE 1
105 | #define I2C_SMBUS_BYTE_DATA 2
106 | #define I2C_SMBUS_WORD_DATA 3
107 | #define I2C_SMBUS_PROC_CALL 4
108 | #define I2C_SMBUS_BLOCK_DATA 5
109 | #define I2C_SMBUS_I2C_BLOCK_BROKEN 6
110 | #define I2C_SMBUS_BLOCK_PROC_CALL 7 /* SMBus 2.0 */
111 | #define I2C_SMBUS_I2C_BLOCK_DATA 8
112 |
113 |
114 | /* ----- commands for the ioctl like i2c_command call:
115 | * note that additional calls are defined in the algorithm and hw
116 | * dependent layers - these can be listed here, or see the
117 | * corresponding header files.
118 | */
119 | /* -> bit-adapter specific ioctls */
120 | #define I2C_RETRIES 0x0701 /* number of times a device address */
121 | /* should be polled when not */
122 | /* acknowledging */
123 | #define I2C_TIMEOUT 0x0702 /* set timeout - call with int */
124 |
125 |
126 | /* this is for i2c-dev.c */
127 | #define I2C_SLAVE 0x0703 /* Change slave address */
128 | /* Attn.: Slave address is 7 or 10 bits */
129 | #define I2C_SLAVE_FORCE 0x0706 /* Change slave address */
130 | /* Attn.: Slave address is 7 or 10 bits */
131 | /* This changes the address, even if it */
132 | /* is already taken! */
133 | #define I2C_TENBIT 0x0704 /* 0 for 7 bit addrs, != 0 for 10 bit */
134 |
135 | #define I2C_FUNCS 0x0705 /* Get the adapter functionality */
136 | #define I2C_RDWR 0x0707 /* Combined R/W transfer (one stop only)*/
137 | #define I2C_PEC 0x0708 /* != 0 for SMBus PEC */
138 |
139 | #define I2C_SMBUS 0x0720 /* SMBus-level access */
140 |
141 | /* -- i2c.h -- */
142 |
143 |
144 | /* Note: 10-bit addresses are NOT supported! */
145 |
146 | /* This is the structure as used in the I2C_SMBUS ioctl call */
147 | struct i2c_smbus_ioctl_data {
148 | char read_write;
149 | __u8 command;
150 | int size;
151 | union i2c_smbus_data *data;
152 | };
153 |
154 | /* This is the structure as used in the I2C_RDWR ioctl call */
155 | struct i2c_rdwr_ioctl_data {
156 | struct i2c_msg *msgs; /* pointers to i2c_msgs */
157 | int nmsgs; /* number of i2c_msgs */
158 | };
159 |
160 |
161 | static inline __s32 i2c_smbus_access(int file, char read_write, __u8 command,
162 | int size, union i2c_smbus_data *data)
163 | {
164 | struct i2c_smbus_ioctl_data args;
165 |
166 | args.read_write = read_write;
167 | args.command = command;
168 | args.size = size;
169 | args.data = data;
170 | return ioctl(file,I2C_SMBUS,&args);
171 | }
172 |
173 |
174 | static inline __s32 i2c_smbus_write_quick(int file, __u8 value)
175 | {
176 | return i2c_smbus_access(file,value,0,I2C_SMBUS_QUICK,NULL);
177 | }
178 |
179 | static inline __s32 i2c_smbus_read_byte(int file)
180 | {
181 | union i2c_smbus_data data;
182 | if (i2c_smbus_access(file,I2C_SMBUS_READ,0,I2C_SMBUS_BYTE,&data))
183 | return -1;
184 | else
185 | return 0x0FF & data.byte;
186 |
187 | }
188 |
189 | static inline __s32 i2c_smbus_write_byte(int file, __u8 value)
190 | {
191 | return i2c_smbus_access(file,I2C_SMBUS_WRITE,value,
192 | I2C_SMBUS_BYTE,NULL);
193 | }
194 |
195 | static inline __s32 i2c_smbus_read_byte_data(int file, __u8 command)
196 | {
197 | union i2c_smbus_data data;
198 | if (i2c_smbus_access(file,I2C_SMBUS_READ,command,
199 | I2C_SMBUS_BYTE_DATA,&data))
200 | return -1;
201 | else
202 | return 0x0FF & data.byte;
203 | }
204 |
205 | static inline __s32 i2c_smbus_write_byte_data(int file, __u8 command,
206 | __u8 value)
207 | {
208 | union i2c_smbus_data data;
209 | data.byte = value;
210 | return i2c_smbus_access(file,I2C_SMBUS_WRITE,command,
211 | I2C_SMBUS_BYTE_DATA, &data);
212 | }
213 |
214 | static inline __s32 i2c_smbus_read_word_data(int file, __u8 command)
215 | {
216 | union i2c_smbus_data data;
217 | if (i2c_smbus_access(file,I2C_SMBUS_READ,command,
218 | I2C_SMBUS_WORD_DATA,&data))
219 | return -1;
220 | else
221 | return 0x0FFFF & data.word;
222 | }
223 |
224 | static inline __s32 i2c_smbus_write_word_data(int file, __u8 command,
225 | __u16 value)
226 | {
227 | union i2c_smbus_data data;
228 | data.word = value;
229 | return i2c_smbus_access(file,I2C_SMBUS_WRITE,command,
230 | I2C_SMBUS_WORD_DATA, &data);
231 | }
232 |
233 | static inline __s32 i2c_smbus_process_call(int file, __u8 command, __u16 value)
234 | {
235 | union i2c_smbus_data data;
236 | data.word = value;
237 | if (i2c_smbus_access(file,I2C_SMBUS_WRITE,command,
238 | I2C_SMBUS_PROC_CALL,&data))
239 | return -1;
240 | else
241 | return 0x0FFFF & data.word;
242 | }
243 |
244 |
245 | /* Returns the number of read bytes */
246 | static inline __s32 i2c_smbus_read_block_data(int file, __u8 command,
247 | __u8 *values)
248 | {
249 | union i2c_smbus_data data;
250 | int i;
251 | if (i2c_smbus_access(file,I2C_SMBUS_READ,command,
252 | I2C_SMBUS_BLOCK_DATA,&data))
253 | return -1;
254 | else {
255 | for (i = 1; i <= data.block[0]; i++)
256 | values[i-1] = data.block[i];
257 | return data.block[0];
258 | }
259 | }
260 |
261 | static inline __s32 i2c_smbus_write_block_data(int file, __u8 command,
262 | __u8 length, const __u8 *values)
263 | {
264 | union i2c_smbus_data data;
265 | int i;
266 | if (length > 32)
267 | length = 32;
268 | for (i = 1; i <= length; i++)
269 | data.block[i] = values[i-1];
270 | data.block[0] = length;
271 | return i2c_smbus_access(file,I2C_SMBUS_WRITE,command,
272 | I2C_SMBUS_BLOCK_DATA, &data);
273 | }
274 |
275 | /* Returns the number of read bytes */
276 | /* Until kernel 2.6.22, the length is hardcoded to 32 bytes. If you
277 | ask for less than 32 bytes, your code will only work with kernels
278 | 2.6.23 and later. */
279 | static inline __s32 i2c_smbus_read_i2c_block_data(int file, __u8 command,
280 | __u8 length, __u8 *values)
281 | {
282 | union i2c_smbus_data data;
283 | int i;
284 |
285 | if (length > 32)
286 | length = 32;
287 | data.block[0] = length;
288 | if (i2c_smbus_access(file,I2C_SMBUS_READ,command,
289 | length == 32 ? I2C_SMBUS_I2C_BLOCK_BROKEN :
290 | I2C_SMBUS_I2C_BLOCK_DATA,&data))
291 | return -1;
292 | else {
293 | for (i = 1; i <= data.block[0]; i++)
294 | values[i-1] = data.block[i];
295 | return data.block[0];
296 | }
297 | }
298 |
299 | static inline __s32 i2c_smbus_write_i2c_block_data(int file, __u8 command,
300 | __u8 length,
301 | const __u8 *values)
302 | {
303 | union i2c_smbus_data data;
304 | int i;
305 | if (length > 32)
306 | length = 32;
307 | for (i = 1; i <= length; i++)
308 | data.block[i] = values[i-1];
309 | data.block[0] = length;
310 | return i2c_smbus_access(file,I2C_SMBUS_WRITE,command,
311 | I2C_SMBUS_I2C_BLOCK_BROKEN, &data);
312 | }
313 |
314 | /* Returns the number of read bytes */
315 | static inline __s32 i2c_smbus_block_process_call(int file, __u8 command,
316 | __u8 length, __u8 *values)
317 | {
318 | union i2c_smbus_data data;
319 | int i;
320 | if (length > 32)
321 | length = 32;
322 | for (i = 1; i <= length; i++)
323 | data.block[i] = values[i-1];
324 | data.block[0] = length;
325 | if (i2c_smbus_access(file,I2C_SMBUS_WRITE,command,
326 | I2C_SMBUS_BLOCK_PROC_CALL,&data))
327 | return -1;
328 | else {
329 | for (i = 1; i <= data.block[0]; i++)
330 | values[i-1] = data.block[i];
331 | return data.block[0];
332 | }
333 | }
334 |
335 |
336 | #endif /* LIB_I2CDEV_H */
337 |
338 |
339 |
340 |
341 |
342 |
343 |
--------------------------------------------------------------------------------
/src/i2c.c:
--------------------------------------------------------------------------------
1 | /*
2 | * i2c.c
3 | *
4 | * Created on: Jun 7, 2015
5 | * Author: gijs
6 | */
7 |
8 | #include "i2c.h"
9 |
10 | int res, daddress;
11 |
12 | int open_i2c(i2c_properties *i2c) {
13 | info("i2c open - i2c:%d device address: 0x%x mode:%i", i2c->i2cnr,
14 | i2c->deviceAddress, i2c->openMode);
15 | char filename[20];
16 |
17 | sprintf(filename, "/dev/i2c-%d", i2c->i2cnr);
18 | i2c->fd = open(filename, i2c->openMode);
19 | if (i2c->fd < 0) {
20 | if (errno == ENOENT) {
21 | error("Error: Could not open file /dev/i2c-%d: %s\n", i2c->i2cnr, strerror(ENOENT));
22 | } else {
23 | error("Error: Could not open file `%s': %s\n", filename, strerror(errno));
24 | if (errno == EACCES)
25 | error("Run as root?\n");
26 | }
27 | return -1;
28 | }
29 |
30 | if (ioctl(i2c->fd, I2C_SLAVE, i2c->deviceAddress) < 0) {
31 | error("Error: Could not set address to 0x%02x: %s\n",
32 | i2c->deviceAddress, strerror(errno));
33 | return -errno;
34 | }
35 | return 0;
36 | }
37 |
38 | int write_byte_i2c(i2c_properties *i2c, unsigned char reg) {
39 | res = i2c_smbus_write_byte(i2c->fd, reg);
40 | if (res < 0) {
41 | error("Warning - write failed, filename=%i, register=%i\n",
42 | i2c->fd, reg);
43 | return 1;
44 | }
45 | return 0;
46 | }
47 |
48 | int write_data_i2c(i2c_properties *i2c, unsigned char reg, char value) {
49 | unsigned char buf[2];
50 | buf[0] = reg;
51 | buf[1] = value;
52 | if (write(i2c->fd, buf, 2) != 2) {
53 | error("Warning - write data failed, filename=%i, register=%i\n", i2c->fd,
54 | reg);
55 | return 1;
56 | }
57 | return 0;
58 | }
59 |
60 | int read_i2c(i2c_properties *i2c, unsigned char *readBuffer, int bufferSize) {
61 | if (read(i2c->fd, readBuffer, bufferSize) != bufferSize) {
62 | error("Failed to read in the buffer\n");
63 | return 1;
64 | }
65 | if(readBuffer[0x00]!=0xE5){
66 | info("Problem detected! Device ID is wrong");
67 | }
68 | return 0;
69 | }
70 |
71 |
--------------------------------------------------------------------------------
/src/i2c.h:
--------------------------------------------------------------------------------
1 | /*
2 | * i2c.h
3 | *
4 | * Created on: Jun 7, 2015
5 | * Author: gijs
6 | */
7 |
8 | #ifndef I2C_H_
9 | #define I2C_H_
10 |
11 | #include
12 | #include
13 | #include
14 | #include "i2c-dev.h"
15 | #include
16 | //#include
17 | //#include
18 |
19 | typedef enum {
20 | i2c0 = 0, i2c1 = 1
21 | } i2c;
22 |
23 | typedef struct {
24 | int fd;
25 | i2c i2cnr;
26 | int deviceAddress;
27 | int openMode;
28 | } i2c_properties;
29 |
30 | extern int open_i2c(i2c_properties *i2c);
31 | extern int write_byte_i2c(i2c_properties *i2c, unsigned char reg);
32 | extern int write_data_i2c(i2c_properties *i2c, unsigned char reg, char value);
33 | extern int read_i2c(i2c_properties *i2c, unsigned char *readBuffer, int bufferSize);
34 |
35 | #endif /* I2C_H_ */
36 |
--------------------------------------------------------------------------------
/src/log.c:
--------------------------------------------------------------------------------
1 | //
2 | // Created by Gijs Sijpesteijn on 20/12/2017.
3 | // Until I figure out how to use syslog on apple, I use this.
4 | //
5 |
6 | #include
7 | #include "log.h"
8 | #include
9 | #include
10 |
11 |
12 | void info(const char *message, ...) {
13 | #ifdef __APPLE__
14 | printf(*message, ...);
15 | #else
16 | syslog (LOG_INFO, message);
17 | #endif
18 | }
19 |
20 | void debug(const char *message, ...) {
21 | #ifdef __APPLE__
22 | printf(*message, ...);
23 | #else
24 | syslog (LOG_DEBUG, message);
25 | #endif
26 | }
27 |
28 | void error(const char *message, ...) {
29 | #ifdef __APPLE__
30 | printf(*message, ...);
31 | #else
32 | syslog (LOG_ERR, message);
33 | #endif
34 | }
--------------------------------------------------------------------------------
/src/log.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by Gijs Sijpesteijn on 20/12/2017.
3 | //
4 |
5 | #ifndef BBLASER_LOG_H
6 | #define BBLASER_LOG_H
7 |
8 | extern void info(const char *message, ...);
9 | extern void debug(const char *message, ...);
10 | extern void error(const char *message, ...);
11 |
12 |
13 | #endif //BBLASER_LOG_H
14 |
--------------------------------------------------------------------------------
/src/pwm.c:
--------------------------------------------------------------------------------
1 | /*
2 | * pwm.c
3 | *
4 | * Created on: Jun 7, 2015
5 | * Author: gijs
6 | */
7 |
8 | #include
9 | #include
10 | #include
11 | #include "pwm.h"
12 | #include "log.h"
13 |
14 | int pwm_open(pwm_properties *pwm) {
15 | char filename[60] = PWM_PATH;
16 | strcat(filename, pwm->name);
17 |
18 | if (access(filename, F_OK) == -1) {
19 | error("Could not open file: ", filename);
20 | return 0;
21 | }
22 | return 1;
23 | }
24 |
25 | int pwm_set_run(pwm_properties *pwm, int run) {
26 | char filename[60] = PWM_PATH;
27 | strcat(filename, pwm->name);
28 | strcat(filename, "/");
29 |
30 | strcat(filename, "run");
31 |
32 | int file = open(filename, O_RDWR);
33 | char buf[2];
34 | sprintf(buf, "%d", run);
35 | if (write(file, buf, 2) < 0) {
36 | char* str;
37 | sprintf(str, "Could not execute run. %d", run);
38 | error(str);
39 | return -1;
40 | }
41 | close(file);
42 | return 0;
43 | }
44 |
45 | int pwm_set_period(pwm_properties *pwm, int period) {
46 | char filename[60] = PWM_PATH;
47 | strcat(filename, pwm->name);
48 | strcat(filename, "/");
49 |
50 | strcat(filename, "period");
51 |
52 | int file = open(filename, O_RDWR);
53 | char buf[4];
54 | sprintf(buf, "%d", period);
55 | if (write(file, buf, 4) < 0) {
56 | error("Could not set period. %d", period);
57 | return -1;
58 | }
59 | close(file);
60 | return 0;
61 | }
62 | int pwm_set_duty(pwm_properties *pwm, int duty) {
63 | char filename[60] = PWM_PATH;
64 | strcat(filename, pwm->name);
65 | strcat(filename, "/");
66 |
67 | strcat(filename, "duty");
68 |
69 | int file = open(filename, O_RDWR);
70 | char buf[4];
71 | sprintf(buf, "%d", duty);
72 | if (write(file, buf, 4) < 0) {
73 | error("Could not set duty. %d", duty);
74 | return -1;
75 | }
76 | close(file);
77 | return 0;
78 | }
79 |
--------------------------------------------------------------------------------
/src/pwm.h:
--------------------------------------------------------------------------------
1 | /*
2 | * pwm.h
3 | *
4 | * Created on: Jun 7, 2015
5 | * Author: gijs
6 | */
7 |
8 | #ifndef PWM_H_
9 | #define PWM_H_
10 |
11 | #define PWM_PATH "/sys/devices/ocp.3/"
12 | typedef struct {
13 | char *name;
14 | } pwm_properties;
15 |
16 |
17 | extern int pwm_open(pwm_properties *pwm);
18 | extern int pwm_set_run(pwm_properties *pwm, int run);
19 | extern int pwm_set_period(pwm_properties *pwm, int period);
20 | extern int pwm_set_duty(pwm_properties *pwm, int duty);
21 |
22 | #endif /* PWM_H_ */
23 |
--------------------------------------------------------------------------------
/src/spi.c:
--------------------------------------------------------------------------------
1 | /*
2 | * spi.c
3 | *
4 | * Created on: May 31, 2015
5 | * Author: gijs
6 | */
7 |
8 | #include "spi.h"
9 | #include "log.h"
10 | #include
11 |
12 | uint8_t spi_open(spi_properties *spi) {
13 | // syslog (LOG_INFO, "spi open - spi:%d bits_per_word:%d speed:%d mode:%f", spi, bits_per_word, speed, mode);
14 | char filename[20];
15 | sprintf(filename, "/dev/spidev1.%d", spi->spi_id);
16 | spi->fd = open(filename, spi->flags);
17 | if (spi->fd < 0) {
18 | perror("could not open spi.");
19 | return -1;
20 | }
21 | info("FD: %i", spi->fd);
22 | if (ioctl(spi->fd, SPI_IOC_WR_MODE, &spi->mode)==-1){
23 | perror("SPI: Can't set SPI mode.");
24 | return -1;
25 | }
26 | if (ioctl(spi->fd, SPI_IOC_WR_BITS_PER_WORD, &spi->bits_per_word)==-1){
27 | perror("SPI: Can't set bits per word.");
28 | return -1;
29 | }
30 | if (ioctl(spi->fd, SPI_IOC_WR_MAX_SPEED_HZ, &spi->speed)==-1){
31 | perror("SPI: Can't set max speed HZ");
32 | return -1;
33 | }
34 |
35 | // Check that the properties have been set
36 | info("SPI fd is: %d\n", spi->fd);
37 | info("SPI Mode is: %d\n", spi->mode);
38 | info("SPI Bits is: %d\n", spi->bits_per_word);
39 | info("SPI Speed is: %d\n", spi->speed);
40 | return 0;
41 | }
42 |
43 | uint8_t spi_close(spi_properties *spi) {
44 | info("spi close - spi:%d", spi->fd);
45 | close(spi->fd);
46 | return 0;
47 | }
48 |
49 | uint8_t spi_send(spi_properties *spi, unsigned char tx[], int length) {
50 | unsigned char rx[length];
51 | return spi_transfer(spi, tx, rx, length);
52 | }
53 |
54 | uint8_t spi_transfer(spi_properties *spi, unsigned char tx[], unsigned char rx[], int length) {
55 | struct spi_ioc_transfer transfer = {
56 | .tx_buf = (unsigned long)tx,
57 | .rx_buf = (unsigned long)rx,
58 | .len = length,
59 | .delay_usecs = 0,
60 | .speed_hz = spi->speed,
61 | .bits_per_word = spi->bits_per_word,
62 | };
63 | // send the SPI message (all of the above fields, inc. buffers)
64 | int status = ioctl(spi->fd, SPI_IOC_MESSAGE(1), &transfer);
65 | if (status < 0) {
66 | perror("SPI: SPI_IOC_MESSAGE Failed");
67 | return -1;
68 | }
69 | return 0; //status;
70 | }
71 |
--------------------------------------------------------------------------------
/src/spi.h:
--------------------------------------------------------------------------------
1 | /*
2 | * spi.h
3 | *
4 | * Created on: May 31, 2015
5 | * Author: gijs
6 | */
7 |
8 | #ifndef SPI_H_
9 | #define SPI_H_
10 |
11 | #include
12 | #include
13 | #include
14 |
15 | typedef enum {
16 | spi0 = 0, spi1 = 1
17 | } spi;
18 |
19 | typedef struct {
20 | int fd;
21 | spi spi_id;
22 | uint8_t bits_per_word; /*!< @brief is used to hold the bits per word size of SPI */
23 | uint8_t mode; /*!< @brief is used to hold the mode of SPI */
24 | uint32_t speed; /*!< @brief is used to hold the speed of SPI */
25 | uint8_t flags;
26 | } spi_properties;
27 |
28 | extern uint8_t spi_open(spi_properties* spi);
29 | extern uint8_t spi_send(spi_properties *spi, unsigned char tx[], int length);
30 | extern uint8_t spi_transfer(spi_properties *spi, unsigned char tx[], unsigned char rx[], int length);
31 | extern uint8_t spi_close(spi_properties *spi);
32 |
33 | #endif /* SPI_H_ */
34 |
--------------------------------------------------------------------------------
/src/uart.c:
--------------------------------------------------------------------------------
1 | /*
2 | * uart.c
3 | *
4 | * Created on: Jun 7, 2015
5 | * Author: gijs
6 | */
7 |
8 | #include "uart.h"
9 | #include "log.h"
10 | #include
11 | #include
12 |
13 | int uart_open(uart_properties *uart) {
14 | FILE *slots;
15 | char buf[30] = "/dev/ttyO";
16 | char port_nr[2];
17 | sprintf(port_nr, "%d", uart->uart_id);
18 | strcat(buf,port_nr);
19 | struct termios uart_port;
20 |
21 | // slots = fopen(SLOTS, "w");
22 | // if(slots == NULL) printf("slots didn't open\n");
23 | // fseek(slots,0,SEEK_SET);
24 | //
25 | // fprintf(slots, "BB-UART%i", uart->uart_id+1);
26 | // fflush(slots);
27 | // fclose(slots);
28 |
29 | uart->fd = open(buf, O_RDWR | O_NOCTTY);
30 | if(uart->fd < 0) printf("port failed to open\n");
31 |
32 | bzero(&uart_port,sizeof(uart_port));
33 |
34 | uart_port.c_cflag = uart->baudrate | CS8 | CLOCAL | CREAD;
35 | uart_port.c_iflag = IGNPAR | ICRNL;
36 | uart_port.c_oflag = 0;
37 | uart_port.c_lflag = 0;
38 |
39 | uart_port.c_cc[VTIME] = 0;
40 | uart_port.c_cc[VMIN] = 1;
41 |
42 | //clean the line and set the attributes
43 | tcflush(uart->fd,TCIFLUSH);
44 | tcsetattr(uart->fd,TCSANOW,&uart_port);
45 | return 0;
46 | }
47 |
48 | int uart_send(uart_properties *uart, char *tx, int length) {
49 | if (write(uart->fd, tx, length) == -1) {
50 | error("Could not write %s to uart %i", tx, uart->uart_id);
51 | return -1;
52 | }
53 | info("Wrote %s to uart %i", tx, uart->uart_id);
54 | return 0;
55 | }
56 |
57 | int uart_read(uart_properties *uart,unsigned char *rx, int length) {
58 | int count;
59 | if( (count = read(uart->fd,(void*)rx,length)) > 0) {
60 | error("Could not read from uart %i", uart->uart_id);
61 | return count;
62 | }
63 | info("Read %s from uart %i", rx, uart->uart_id);
64 | return 0;
65 | }
66 |
67 | int uart_close(uart_properties *uart) {
68 | close(uart->fd);
69 | return 0;
70 | }
71 |
--------------------------------------------------------------------------------
/src/uart.h:
--------------------------------------------------------------------------------
1 | /*
2 | * uart.h
3 | *
4 | * Created on: Jun 7, 2015
5 | * Author: gijs
6 | */
7 |
8 | #ifndef UART_H_
9 | #define UART_H_
10 |
11 | #include
12 | #include
13 |
14 | typedef enum {
15 | uart0 = 0, uart1 = 1, uart2 = 2, uart3 = 3, uart4 = 4, uart5 = 5
16 | } uart;
17 |
18 |
19 | typedef struct {
20 | int fd;
21 | uart uart_id;
22 | int baudrate;
23 | } uart_properties;
24 |
25 | extern int uart_open(uart_properties *uart);
26 | extern int uart_send(uart_properties *uart, char *tx, int length);
27 | extern int uart_read(uart_properties *uart,unsigned char *rx, int length);
28 | extern int uart_close(uart_properties *uart);
29 |
30 | #endif /* UART_H_ */
31 |
--------------------------------------------------------------------------------