pikeyd165 – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 /* bcm2835.c
2 // C and C++ support for Broadcom BCM 2835 as used in Raspberry Pi
3 // http://elinux.org/RPi_Low-level_peripherals
4 // http://www.raspberrypi.org/wp-content/uploads/2012/02/BCM2835-ARM-Peripherals.pdf
5 //
6 // Author: Mike McCauley
7 // Copyright (C) 2011-2013 Mike McCauley
8 // $Id: bcm2835.c,v 1.28 2020/01/11 05:07:13 mikem Exp mikem $
9 */
10  
11 // Needed to compile with gcc -std=c99, as reported by John Blaiklock.
12 #define _POSIX_C_SOURCE 200809L
13  
14 #include <stdlib.h>
15 #include <stdio.h>
16 #include <errno.h>
17 #include <fcntl.h>
18 #include <sys/mman.h>
19 #include <string.h>
20 #include <time.h>
21 #include <unistd.h>
22 #include <sys/types.h>
23  
24 #define BCK2835_LIBRARY_BUILD
25 #include "bcm2835.h"
26  
27 /* This define enables a little test program (by default a blinking output on pin RPI_GPIO_PIN_11)
28 // You can do some safe, non-destructive testing on any platform with:
29 // gcc bcm2835.c -D BCM2835_TEST
30 // ./a.out
31 */
32 /*#define BCM2835_TEST*/
33  
34 /* Uncommenting this define compiles alternative I2C code for the version 1 RPi
35 // The P1 header I2C pins are connected to SDA0 and SCL0 on V1.
36 // By default I2C code is generated for the V2 RPi which has SDA1 and SCL1 connected.
37 */
38 /* #define I2C_V1*/
39  
40 /* Physical address and size of the peripherals block
41 // May be overridden on RPi2
42 */
43 off_t bcm2835_peripherals_base = BCM2835_PERI_BASE;
44 size_t bcm2835_peripherals_size = BCM2835_PERI_SIZE;
45  
46 /* Virtual memory address of the mapped peripherals block
47 */
48 uint32_t *bcm2835_peripherals = (uint32_t *)MAP_FAILED;
49  
50 /* And the register bases within the peripherals block
51 */
52 volatile uint32_t *bcm2835_gpio = (uint32_t *)MAP_FAILED;
53 volatile uint32_t *bcm2835_pwm = (uint32_t *)MAP_FAILED;
54 volatile uint32_t *bcm2835_clk = (uint32_t *)MAP_FAILED;
55 volatile uint32_t *bcm2835_pads = (uint32_t *)MAP_FAILED;
56 volatile uint32_t *bcm2835_spi0 = (uint32_t *)MAP_FAILED;
57 volatile uint32_t *bcm2835_bsc0 = (uint32_t *)MAP_FAILED;
58 volatile uint32_t *bcm2835_bsc1 = (uint32_t *)MAP_FAILED;
59 volatile uint32_t *bcm2835_st = (uint32_t *)MAP_FAILED;
60 volatile uint32_t *bcm2835_aux = (uint32_t *)MAP_FAILED;
61 volatile uint32_t *bcm2835_spi1 = (uint32_t *)MAP_FAILED;
62 /* BEB*/
63 volatile uint32_t *bcm2835_smi = (uint32_t *)MAP_FAILED;
64  
65  
66  
67 /* This variable allows us to test on hardware other than RPi.
68 // It prevents access to the kernel memory, and does not do any peripheral access
69 // Instead it prints out what it _would_ do if debug were 0
70 */
71 static uint8_t debug = 0;
72  
73 /* RPI 4 has different pullup registers - we need to know if we have that type */
74  
75 static uint8_t pud_type_rpi4 = 0;
76  
77 /* RPI 4 has different pullup operation - make backwards compat */
78  
79 static uint8_t pud_compat_setting = BCM2835_GPIO_PUD_OFF;
80  
81 /* I2C The time needed to transmit one byte. In microseconds.
82 */
83 static int i2c_byte_wait_us = 0;
84  
85 /* SPI bit order. BCM2835 SPI0 only supports MSBFIRST, so we instead
86 * have a software based bit reversal, based on a contribution by Damiano Benedetti
87 */
88 static uint8_t bcm2835_spi_bit_order = BCM2835_SPI_BIT_ORDER_MSBFIRST;
89 static uint8_t bcm2835_byte_reverse_table[] =
90 {
91 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
92 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
93 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
94 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
95 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
96 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
97 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
98 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
99 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
100 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
101 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
102 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
103 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
104 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
105 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
106 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
107 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
108 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
109 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
110 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
111 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
112 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
113 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
114 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
115 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
116 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
117 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
118 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
119 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
120 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
121 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
122 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
123 };
124  
125 static uint8_t bcm2835_correct_order(uint8_t b)
126 {
127 if (bcm2835_spi_bit_order == BCM2835_SPI_BIT_ORDER_LSBFIRST)
128 return bcm2835_byte_reverse_table[b];
129 else
130 return b;
131 }
132  
133 #ifdef BCM2835_HAVE_LIBCAP
134 #include <sys/capability.h>
135 static int bcm2835_has_capability(cap_value_t capability)
136 {
137 int ok = 0;
138 cap_t cap = cap_get_proc();
139 if (cap)
140 {
141 cap_flag_value_t value;
142 if (cap_get_flag(cap,capability,CAP_EFFECTIVE,&value) == 0 && value == CAP_SET)
143 ok = 1;
144 cap_free(cap);
145 }
146 return ok;
147 }
148 #endif
149  
150 /*
151 // Low level register access functions
152 */
153  
154 /* Function to return the pointers to the hardware register bases */
155 uint32_t* bcm2835_regbase(uint8_t regbase)
156 {
157 switch (regbase)
158 {
159 case BCM2835_REGBASE_ST:
160 return (uint32_t *)bcm2835_st;
161 case BCM2835_REGBASE_GPIO:
162 return (uint32_t *)bcm2835_gpio;
163 case BCM2835_REGBASE_PWM:
164 return (uint32_t *)bcm2835_pwm;
165 case BCM2835_REGBASE_CLK:
166 return (uint32_t *)bcm2835_clk;
167 case BCM2835_REGBASE_PADS:
168 return (uint32_t *)bcm2835_pads;
169 case BCM2835_REGBASE_SPI0:
170 return (uint32_t *)bcm2835_spi0;
171 case BCM2835_REGBASE_BSC0:
172 return (uint32_t *)bcm2835_bsc0;
173 case BCM2835_REGBASE_BSC1:
174 return (uint32_t *)bcm2835_st;
175 case BCM2835_REGBASE_AUX:
176 return (uint32_t *)bcm2835_aux;
177 case BCM2835_REGBASE_SPI1:
178 return (uint32_t *)bcm2835_spi1;
179 /* BEB */
180 case BCM2835_REGBASE_SMI:
181 return (uint32_t *)bcm2835_smi;
182  
183  
184 }
185 return (uint32_t *)MAP_FAILED;
186 }
187  
188 void bcm2835_set_debug(uint8_t d)
189 {
190 debug = d;
191 }
192  
193 unsigned int bcm2835_version(void)
194 {
195 return BCM2835_VERSION;
196 }
197  
198 /* Read with memory barriers from peripheral
199 *
200 */
201 uint32_t bcm2835_peri_read(volatile uint32_t* paddr)
202 {
203 uint32_t ret;
204 if (debug)
205 {
206 printf("bcm2835_peri_read paddr %p\n", (void *) paddr);
207 return 0;
208 }
209 else
210 {
211 __sync_synchronize();
212 ret = *paddr;
213 __sync_synchronize();
214 return ret;
215 }
216 }
217  
218 /* read from peripheral without the read barrier
219 * This can only be used if more reads to THE SAME peripheral
220 * will follow. The sequence must terminate with memory barrier
221 * before any read or write to another peripheral can occur.
222 * The MB can be explicit, or one of the barrier read/write calls.
223 */
224 uint32_t bcm2835_peri_read_nb(volatile uint32_t* paddr)
225 {
226 if (debug)
227 {
228 printf("bcm2835_peri_read_nb paddr %p\n", paddr);
229 return 0;
230 }
231 else
232 {
233 return *paddr;
234 }
235 }
236  
237 /* Write with memory barriers to peripheral
238 */
239  
240 void bcm2835_peri_write(volatile uint32_t* paddr, uint32_t value)
241 {
242 if (debug)
243 {
244 printf("bcm2835_peri_write paddr %p, value %08X\n", paddr, value);
245 }
246 else
247 {
248 __sync_synchronize();
249 *paddr = value;
250 __sync_synchronize();
251 }
252 }
253  
254 /* write to peripheral without the write barrier */
255 void bcm2835_peri_write_nb(volatile uint32_t* paddr, uint32_t value)
256 {
257 if (debug)
258 {
259 printf("bcm2835_peri_write_nb paddr %p, value %08X\n",
260 paddr, value);
261 }
262 else
263 {
264 *paddr = value;
265 }
266 }
267  
268 /* Set/clear only the bits in value covered by the mask
269 * This is not atomic - can be interrupted.
270 */
271 void bcm2835_peri_set_bits(volatile uint32_t* paddr, uint32_t value, uint32_t mask)
272 {
273 uint32_t v = bcm2835_peri_read(paddr);
274 v = (v & ~mask) | (value & mask);
275 bcm2835_peri_write(paddr, v);
276 }
277  
278 /*
279 // Low level convenience functions
280 */
281  
282 /* Function select
283 // pin is a BCM2835 GPIO pin number NOT RPi pin number
284 // There are 6 control registers, each control the functions of a block
285 // of 10 pins.
286 // Each control register has 10 sets of 3 bits per GPIO pin:
287 //
288 // 000 = GPIO Pin X is an input
289 // 001 = GPIO Pin X is an output
290 // 100 = GPIO Pin X takes alternate function 0
291 // 101 = GPIO Pin X takes alternate function 1
292 // 110 = GPIO Pin X takes alternate function 2
293 // 111 = GPIO Pin X takes alternate function 3
294 // 011 = GPIO Pin X takes alternate function 4
295 // 010 = GPIO Pin X takes alternate function 5
296 //
297 // So the 3 bits for port X are:
298 // X / 10 + ((X % 10) * 3)
299 */
300 void bcm2835_gpio_fsel(uint8_t pin, uint8_t mode)
301 {
302 /* Function selects are 10 pins per 32 bit word, 3 bits per pin */
303 volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPFSEL0/4 + (pin/10);
304 uint8_t shift = (pin % 10) * 3;
305 uint32_t mask = BCM2835_GPIO_FSEL_MASK << shift;
306 uint32_t value = mode << shift;
307 bcm2835_peri_set_bits(paddr, value, mask);
308 }
309  
310 /* Set output pin */
311 void bcm2835_gpio_set(uint8_t pin)
312 {
313 volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPSET0/4 + pin/32;
314 uint8_t shift = pin % 32;
315 bcm2835_peri_write(paddr, 1 << shift);
316 }
317  
318 /* Clear output pin */
319 void bcm2835_gpio_clr(uint8_t pin)
320 {
321 volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPCLR0/4 + pin/32;
322 uint8_t shift = pin % 32;
323 bcm2835_peri_write(paddr, 1 << shift);
324 }
325  
326 /* Set all output pins in the mask */
327 void bcm2835_gpio_set_multi(uint32_t mask)
328 {
329 volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPSET0/4;
330 bcm2835_peri_write(paddr, mask);
331 }
332  
333 /* Clear all output pins in the mask */
334 void bcm2835_gpio_clr_multi(uint32_t mask)
335 {
336 volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPCLR0/4;
337 bcm2835_peri_write(paddr, mask);
338 }
339  
340 /* Read input pin */
341 uint8_t bcm2835_gpio_lev(uint8_t pin)
342 {
343 volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPLEV0/4 + pin/32;
344 uint8_t shift = pin % 32;
345 uint32_t value = bcm2835_peri_read(paddr);
346 return (value & (1 << shift)) ? HIGH : LOW;
347 }
348  
349 /* See if an event detection bit is set
350 // Sigh cant support interrupts yet
351 */
352 uint8_t bcm2835_gpio_eds(uint8_t pin)
353 {
354 volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPEDS0/4 + pin/32;
355 uint8_t shift = pin % 32;
356 uint32_t value = bcm2835_peri_read(paddr);
357 return (value & (1 << shift)) ? HIGH : LOW;
358 }
359  
360 uint32_t bcm2835_gpio_eds_multi(uint32_t mask)
361 {
362 volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPEDS0/4;
363 uint32_t value = bcm2835_peri_read(paddr);
364 return (value & mask);
365 }
366  
367 /* Write a 1 to clear the bit in EDS */
368 void bcm2835_gpio_set_eds(uint8_t pin)
369 {
370 volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPEDS0/4 + pin/32;
371 uint8_t shift = pin % 32;
372 uint32_t value = 1 << shift;
373 bcm2835_peri_write(paddr, value);
374 }
375  
376 void bcm2835_gpio_set_eds_multi(uint32_t mask)
377 {
378 volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPEDS0/4;
379 bcm2835_peri_write(paddr, mask);
380 }
381  
382 /* Rising edge detect enable */
383 void bcm2835_gpio_ren(uint8_t pin)
384 {
385 volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPREN0/4 + pin/32;
386 uint8_t shift = pin % 32;
387 uint32_t value = 1 << shift;
388 bcm2835_peri_set_bits(paddr, value, value);
389 }
390 void bcm2835_gpio_clr_ren(uint8_t pin)
391 {
392 volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPREN0/4 + pin/32;
393 uint8_t shift = pin % 32;
394 uint32_t value = 1 << shift;
395 bcm2835_peri_set_bits(paddr, 0, value);
396 }
397  
398 /* Falling edge detect enable */
399 void bcm2835_gpio_fen(uint8_t pin)
400 {
401 volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPFEN0/4 + pin/32;
402 uint8_t shift = pin % 32;
403 uint32_t value = 1 << shift;
404 bcm2835_peri_set_bits(paddr, value, value);
405 }
406 void bcm2835_gpio_clr_fen(uint8_t pin)
407 {
408 volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPFEN0/4 + pin/32;
409 uint8_t shift = pin % 32;
410 uint32_t value = 1 << shift;
411 bcm2835_peri_set_bits(paddr, 0, value);
412 }
413  
414 /* High detect enable */
415 void bcm2835_gpio_hen(uint8_t pin)
416 {
417 volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPHEN0/4 + pin/32;
418 uint8_t shift = pin % 32;
419 uint32_t value = 1 << shift;
420 bcm2835_peri_set_bits(paddr, value, value);
421 }
422 void bcm2835_gpio_clr_hen(uint8_t pin)
423 {
424 volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPHEN0/4 + pin/32;
425 uint8_t shift = pin % 32;
426 uint32_t value = 1 << shift;
427 bcm2835_peri_set_bits(paddr, 0, value);
428 }
429  
430 /* Low detect enable */
431 void bcm2835_gpio_len(uint8_t pin)
432 {
433 volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPLEN0/4 + pin/32;
434 uint8_t shift = pin % 32;
435 uint32_t value = 1 << shift;
436 bcm2835_peri_set_bits(paddr, value, value);
437 }
438 void bcm2835_gpio_clr_len(uint8_t pin)
439 {
440 volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPLEN0/4 + pin/32;
441 uint8_t shift = pin % 32;
442 uint32_t value = 1 << shift;
443 bcm2835_peri_set_bits(paddr, 0, value);
444 }
445  
446 /* Async rising edge detect enable */
447 void bcm2835_gpio_aren(uint8_t pin)
448 {
449 volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPAREN0/4 + pin/32;
450 uint8_t shift = pin % 32;
451 uint32_t value = 1 << shift;
452 bcm2835_peri_set_bits(paddr, value, value);
453 }
454 void bcm2835_gpio_clr_aren(uint8_t pin)
455 {
456 volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPAREN0/4 + pin/32;
457 uint8_t shift = pin % 32;
458 uint32_t value = 1 << shift;
459 bcm2835_peri_set_bits(paddr, 0, value);
460 }
461  
462 /* Async falling edge detect enable */
463 void bcm2835_gpio_afen(uint8_t pin)
464 {
465 volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPAFEN0/4 + pin/32;
466 uint8_t shift = pin % 32;
467 uint32_t value = 1 << shift;
468 bcm2835_peri_set_bits(paddr, value, value);
469 }
470 void bcm2835_gpio_clr_afen(uint8_t pin)
471 {
472 volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPAFEN0/4 + pin/32;
473 uint8_t shift = pin % 32;
474 uint32_t value = 1 << shift;
475 bcm2835_peri_set_bits(paddr, 0, value);
476 }
477  
478 /* Set pullup/down */
479 void bcm2835_gpio_pud(uint8_t pud)
480 {
481 if( pud_type_rpi4 )
482 {
483 pud_compat_setting = pud;
484 }
485 else {
486 volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPPUD/4;
487 bcm2835_peri_write(paddr, pud);
488 }
489 }
490  
491 /* Pullup/down clock
492 // Clocks the value of pud into the GPIO pin
493 */
494 void bcm2835_gpio_pudclk(uint8_t pin, uint8_t on)
495 {
496 if( pud_type_rpi4 )
497 {
498 if( on )
499 bcm2835_gpio_set_pud( pin, pud_compat_setting);
500 }
501 else
502 {
503 volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPPUDCLK0/4 + pin/32;
504 uint8_t shift = pin % 32;
505 bcm2835_peri_write(paddr, (on ? 1 : 0) << shift);
506 }
507 }
508  
509 /* Read GPIO pad behaviour for groups of GPIOs */
510 uint32_t bcm2835_gpio_pad(uint8_t group)
511 {
512 if (bcm2835_pads == MAP_FAILED)
513 return 0;
514  
515 volatile uint32_t* paddr = bcm2835_pads + BCM2835_PADS_GPIO_0_27/4 + group;
516 return bcm2835_peri_read(paddr);
517 }
518  
519 /* Set GPIO pad behaviour for groups of GPIOs
520 // powerup value for all pads is
521 // BCM2835_PAD_SLEW_RATE_UNLIMITED | BCM2835_PAD_HYSTERESIS_ENABLED | BCM2835_PAD_DRIVE_8mA
522 */
523 void bcm2835_gpio_set_pad(uint8_t group, uint32_t control)
524 {
525 if (bcm2835_pads == MAP_FAILED)
526 return;
527  
528 volatile uint32_t* paddr = bcm2835_pads + BCM2835_PADS_GPIO_0_27/4 + group;
529 bcm2835_peri_write(paddr, control | BCM2835_PAD_PASSWRD);
530 }
531  
532 /* Some convenient arduino-like functions
533 // milliseconds
534 */
535 void bcm2835_delay(unsigned int millis)
536 {
537 struct timespec sleeper;
538  
539 sleeper.tv_sec = (time_t)(millis / 1000);
540 sleeper.tv_nsec = (long)(millis % 1000) * 1000000;
541 nanosleep(&sleeper, NULL);
542 }
543  
544 /* microseconds */
545 void bcm2835_delayMicroseconds(uint64_t micros)
546 {
547 struct timespec t1;
548 uint64_t start;
549  
550 if (debug)
551 {
552 /* Cant access sytem timers in debug mode */
553 printf("bcm2835_delayMicroseconds %lld\n", (long long int) micros);
554 return;
555 }
556  
557 /* Calling nanosleep() takes at least 100-200 us, so use it for
558 // long waits and use a busy wait on the System Timer for the rest.
559 */
560 start = bcm2835_st_read();
561  
562 /* Not allowed to access timer registers (result is not as precise)*/
563 if (start==0)
564 {
565 t1.tv_sec = 0;
566 t1.tv_nsec = 1000 * (long)(micros);
567 nanosleep(&t1, NULL);
568 return;
569 }
570  
571 if (micros > 450)
572 {
573 t1.tv_sec = 0;
574 t1.tv_nsec = 1000 * (long)(micros - 200);
575 nanosleep(&t1, NULL);
576 }
577  
578 bcm2835_st_delay(start, micros);
579 }
580  
581 /*
582 // Higher level convenience functions
583 */
584  
585 /* Set the state of an output */
586 void bcm2835_gpio_write(uint8_t pin, uint8_t on)
587 {
588 if (on)
589 bcm2835_gpio_set(pin);
590 else
591 bcm2835_gpio_clr(pin);
592 }
593  
594 /* Set the state of a all 32 outputs in the mask to on or off */
595 void bcm2835_gpio_write_multi(uint32_t mask, uint8_t on)
596 {
597 if (on)
598 bcm2835_gpio_set_multi(mask);
599 else
600 bcm2835_gpio_clr_multi(mask);
601 }
602  
603 /* Set the state of a all 32 outputs in the mask to the values in value */
604 void bcm2835_gpio_write_mask(uint32_t value, uint32_t mask)
605 {
606 bcm2835_gpio_set_multi(value & mask);
607 bcm2835_gpio_clr_multi((~value) & mask);
608 }
609  
610 /* Set the pullup/down resistor for a pin
611 //
612 // The GPIO Pull-up/down Clock Registers control the actuation of internal pull-downs on
613 // the respective GPIO pins. These registers must be used in conjunction with the GPPUD
614 // register to effect GPIO Pull-up/down changes. The following sequence of events is
615 // required:
616 // 1. Write to GPPUD to set the required control signal (i.e. Pull-up or Pull-Down or neither
617 // to remove the current Pull-up/down)
618 // 2. Wait 150 cycles ? this provides the required set-up time for the control signal
619 // 3. Write to GPPUDCLK0/1 to clock the control signal into the GPIO pads you wish to
620 // modify ? NOTE only the pads which receive a clock will be modified, all others will
621 // retain their previous state.
622 // 4. Wait 150 cycles ? this provides the required hold time for the control signal
623 // 5. Write to GPPUD to remove the control signal
624 // 6. Write to GPPUDCLK0/1 to remove the clock
625 //
626 // RPi has P1-03 and P1-05 with 1k8 pullup resistor
627 //
628 // RPI 4 uses a different PUD method - no clock
629  
630 */
631 void bcm2835_gpio_set_pud(uint8_t pin, uint8_t pud)
632 {
633 if( pud_type_rpi4 )
634 {
635 int shiftbits = (pin & 0xf) << 1;
636 uint32_t bits;
637 uint32_t pull;
638  
639 switch (pud)
640 {
641 case BCM2835_GPIO_PUD_OFF: pull = 0; break;
642 case BCM2835_GPIO_PUD_UP: pull = 1; break;
643 case BCM2835_GPIO_PUD_DOWN: pull = 2; break;
644 default: return;
645 }
646  
647 volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPPUPPDN0/4 + (pin >> 4);
648  
649 bits = bcm2835_peri_read_nb( paddr );
650 bits &= ~(3 << shiftbits);
651 bits |= (pull << shiftbits);
652  
653 bcm2835_peri_write_nb( paddr, bits );
654  
655 } else
656 {
657 bcm2835_gpio_pud(pud);
658 delayMicroseconds(10);
659 bcm2835_gpio_pudclk(pin, 1);
660 delayMicroseconds(10);
661 bcm2835_gpio_pud(BCM2835_GPIO_PUD_OFF);
662 bcm2835_gpio_pudclk(pin, 0);
663 }
664  
665 }
666  
667  
668 uint8_t bcm2835_gpio_get_pud(uint8_t pin)
669 {
670 uint8_t ret = BCM2835_GPIO_PUD_ERROR;
671  
672 if( pud_type_rpi4 )
673 {
674 uint32_t bits;
675 volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPPUPPDN0/4 + (pin >> 4);
676 bits = (bcm2835_peri_read_nb( paddr ) >> ((pin & 0xf)<<1)) & 0x3;
677  
678 switch (bits)
679 {
680 case 0: ret = BCM2835_GPIO_PUD_OFF; break;
681 case 1: ret = BCM2835_GPIO_PUD_UP; break;
682 case 2: ret = BCM2835_GPIO_PUD_DOWN; break;
683 default: ret = BCM2835_GPIO_PUD_ERROR;
684 }
685 }
686  
687 return ret;
688 }
689  
690 static void bcm2835_aux_spi_reset(void)
691 {
692 volatile uint32_t* cntl0 = bcm2835_spi1 + BCM2835_AUX_SPI_CNTL0/4;
693 volatile uint32_t* cntl1 = bcm2835_spi1 + BCM2835_AUX_SPI_CNTL1/4;
694  
695 bcm2835_peri_write(cntl1, 0);
696 bcm2835_peri_write(cntl0, BCM2835_AUX_SPI_CNTL0_CLEARFIFO);
697 }
698  
699 int bcm2835_spi_begin(void)
700 {
701 volatile uint32_t* paddr;
702  
703 if (bcm2835_spi0 == MAP_FAILED)
704 return 0; /* bcm2835_init() failed, or not root */
705  
706 /* Set the SPI0 pins to the Alt 0 function to enable SPI0 access on them */
707 bcm2835_gpio_fsel(RPI_GPIO_P1_26, BCM2835_GPIO_FSEL_ALT0); /* CE1 */
708 bcm2835_gpio_fsel(RPI_GPIO_P1_24, BCM2835_GPIO_FSEL_ALT0); /* CE0 */
709 bcm2835_gpio_fsel(RPI_GPIO_P1_21, BCM2835_GPIO_FSEL_ALT0); /* MISO */
710 bcm2835_gpio_fsel(RPI_GPIO_P1_19, BCM2835_GPIO_FSEL_ALT0); /* MOSI */
711 bcm2835_gpio_fsel(RPI_GPIO_P1_23, BCM2835_GPIO_FSEL_ALT0); /* CLK */
712  
713 /* Set the SPI CS register to the some sensible defaults */
714 paddr = bcm2835_spi0 + BCM2835_SPI0_CS/4;
715 bcm2835_peri_write(paddr, 0); /* All 0s */
716  
717 /* Clear TX and RX fifos */
718 bcm2835_peri_write_nb(paddr, BCM2835_SPI0_CS_CLEAR);
719  
720 return 1; // OK
721 }
722  
723 void bcm2835_spi_end(void)
724 {
725 /* Set all the SPI0 pins back to input */
726 bcm2835_gpio_fsel(RPI_GPIO_P1_26, BCM2835_GPIO_FSEL_INPT); /* CE1 */
727 bcm2835_gpio_fsel(RPI_GPIO_P1_24, BCM2835_GPIO_FSEL_INPT); /* CE0 */
728 bcm2835_gpio_fsel(RPI_GPIO_P1_21, BCM2835_GPIO_FSEL_INPT); /* MISO */
729 bcm2835_gpio_fsel(RPI_GPIO_P1_19, BCM2835_GPIO_FSEL_INPT); /* MOSI */
730 bcm2835_gpio_fsel(RPI_GPIO_P1_23, BCM2835_GPIO_FSEL_INPT); /* CLK */
731 }
732  
733 void bcm2835_spi_setBitOrder(uint8_t order)
734 {
735 bcm2835_spi_bit_order = order;
736 }
737  
738 /* defaults to 0, which means a divider of 65536.
739 // The divisor must be a power of 2. Odd numbers
740 // rounded down. The maximum SPI clock rate is
741 // of the APB clock
742 */
743 void bcm2835_spi_setClockDivider(uint16_t divider)
744 {
745 volatile uint32_t* paddr = bcm2835_spi0 + BCM2835_SPI0_CLK/4;
746 bcm2835_peri_write(paddr, divider);
747 }
748  
749 void bcm2835_spi_set_speed_hz(uint32_t speed_hz)
750 {
751 uint16_t divider = (uint16_t) ((uint32_t) BCM2835_CORE_CLK_HZ / speed_hz);
752 divider &= 0xFFFE;
753 bcm2835_spi_setClockDivider(divider);
754 }
755  
756 void bcm2835_spi_setDataMode(uint8_t mode)
757 {
758 volatile uint32_t* paddr = bcm2835_spi0 + BCM2835_SPI0_CS/4;
759 /* Mask in the CPO and CPHA bits of CS */
760 bcm2835_peri_set_bits(paddr, mode << 2, BCM2835_SPI0_CS_CPOL | BCM2835_SPI0_CS_CPHA);
761 }
762  
763 /* Writes (and reads) a single byte to SPI */
764 uint8_t bcm2835_spi_transfer(uint8_t value)
765 {
766 volatile uint32_t* paddr = bcm2835_spi0 + BCM2835_SPI0_CS/4;
767 volatile uint32_t* fifo = bcm2835_spi0 + BCM2835_SPI0_FIFO/4;
768 uint32_t ret;
769  
770 /* This is Polled transfer as per section 10.6.1
771 // BUG ALERT: what happens if we get interupted in this section, and someone else
772 // accesses a different peripheral?
773 // Clear TX and RX fifos
774 */
775 bcm2835_peri_set_bits(paddr, BCM2835_SPI0_CS_CLEAR, BCM2835_SPI0_CS_CLEAR);
776  
777 /* Set TA = 1 */
778 bcm2835_peri_set_bits(paddr, BCM2835_SPI0_CS_TA, BCM2835_SPI0_CS_TA);
779  
780 /* Maybe wait for TXD */
781 while (!(bcm2835_peri_read(paddr) & BCM2835_SPI0_CS_TXD))
782 ;
783  
784 /* Write to FIFO, no barrier */
785 bcm2835_peri_write_nb(fifo, bcm2835_correct_order(value));
786  
787 /* Wait for DONE to be set */
788 while (!(bcm2835_peri_read_nb(paddr) & BCM2835_SPI0_CS_DONE))
789 ;
790  
791 /* Read any byte that was sent back by the slave while we sere sending to it */
792 ret = bcm2835_correct_order(bcm2835_peri_read_nb(fifo));
793  
794 /* Set TA = 0, and also set the barrier */
795 bcm2835_peri_set_bits(paddr, 0, BCM2835_SPI0_CS_TA);
796  
797 return ret;
798 }
799  
800 /* Writes (and reads) an number of bytes to SPI */
801 void bcm2835_spi_transfernb(char* tbuf, char* rbuf, uint32_t len)
802 {
803 volatile uint32_t* paddr = bcm2835_spi0 + BCM2835_SPI0_CS/4;
804 volatile uint32_t* fifo = bcm2835_spi0 + BCM2835_SPI0_FIFO/4;
805 uint32_t TXCnt=0;
806 uint32_t RXCnt=0;
807  
808 /* This is Polled transfer as per section 10.6.1
809 // BUG ALERT: what happens if we get interupted in this section, and someone else
810 // accesses a different peripheral?
811 */
812  
813 /* Clear TX and RX fifos */
814 bcm2835_peri_set_bits(paddr, BCM2835_SPI0_CS_CLEAR, BCM2835_SPI0_CS_CLEAR);
815  
816 /* Set TA = 1 */
817 bcm2835_peri_set_bits(paddr, BCM2835_SPI0_CS_TA, BCM2835_SPI0_CS_TA);
818  
819 /* Use the FIFO's to reduce the interbyte times */
820 while((TXCnt < len)||(RXCnt < len))
821 {
822 /* TX fifo not full, so add some more bytes */
823 while(((bcm2835_peri_read(paddr) & BCM2835_SPI0_CS_TXD))&&(TXCnt < len ))
824 {
825 bcm2835_peri_write_nb(fifo, bcm2835_correct_order(tbuf[TXCnt]));
826 TXCnt++;
827 }
828 /* Rx fifo not empty, so get the next received bytes */
829 while(((bcm2835_peri_read(paddr) & BCM2835_SPI0_CS_RXD))&&( RXCnt < len ))
830 {
831 rbuf[RXCnt] = bcm2835_correct_order(bcm2835_peri_read_nb(fifo));
832 RXCnt++;
833 }
834 }
835 /* Wait for DONE to be set */
836 while (!(bcm2835_peri_read_nb(paddr) & BCM2835_SPI0_CS_DONE))
837 ;
838  
839 /* Set TA = 0, and also set the barrier */
840 bcm2835_peri_set_bits(paddr, 0, BCM2835_SPI0_CS_TA);
841 }
842  
843 /* Writes an number of bytes to SPI */
844 void bcm2835_spi_writenb(const char* tbuf, uint32_t len)
845 {
846 volatile uint32_t* paddr = bcm2835_spi0 + BCM2835_SPI0_CS/4;
847 volatile uint32_t* fifo = bcm2835_spi0 + BCM2835_SPI0_FIFO/4;
848 uint32_t i;
849  
850 /* This is Polled transfer as per section 10.6.1
851 // BUG ALERT: what happens if we get interupted in this section, and someone else
852 // accesses a different peripheral?
853 // Answer: an ISR is required to issue the required memory barriers.
854 */
855  
856 /* Clear TX and RX fifos */
857 bcm2835_peri_set_bits(paddr, BCM2835_SPI0_CS_CLEAR, BCM2835_SPI0_CS_CLEAR);
858  
859 /* Set TA = 1 */
860 bcm2835_peri_set_bits(paddr, BCM2835_SPI0_CS_TA, BCM2835_SPI0_CS_TA);
861  
862 for (i = 0; i < len; i++)
863 {
864 /* Maybe wait for TXD */
865 while (!(bcm2835_peri_read(paddr) & BCM2835_SPI0_CS_TXD))
866 ;
867  
868 /* Write to FIFO, no barrier */
869 bcm2835_peri_write_nb(fifo, bcm2835_correct_order(tbuf[i]));
870  
871 /* Read from FIFO to prevent stalling */
872 while (bcm2835_peri_read(paddr) & BCM2835_SPI0_CS_RXD)
873 (void) bcm2835_peri_read_nb(fifo);
874 }
875  
876 /* Wait for DONE to be set */
877 while (!(bcm2835_peri_read_nb(paddr) & BCM2835_SPI0_CS_DONE)) {
878 while (bcm2835_peri_read(paddr) & BCM2835_SPI0_CS_RXD)
879 (void) bcm2835_peri_read_nb(fifo);
880 };
881  
882 /* Set TA = 0, and also set the barrier */
883 bcm2835_peri_set_bits(paddr, 0, BCM2835_SPI0_CS_TA);
884 }
885  
886 /* Writes (and reads) an number of bytes to SPI
887 // Read bytes are copied over onto the transmit buffer
888 */
889 void bcm2835_spi_transfern(char* buf, uint32_t len)
890 {
891 bcm2835_spi_transfernb(buf, buf, len);
892 }
893  
894 void bcm2835_spi_chipSelect(uint8_t cs)
895 {
896 volatile uint32_t* paddr = bcm2835_spi0 + BCM2835_SPI0_CS/4;
897 /* Mask in the CS bits of CS */
898 bcm2835_peri_set_bits(paddr, cs, BCM2835_SPI0_CS_CS);
899 }
900  
901 void bcm2835_spi_setChipSelectPolarity(uint8_t cs, uint8_t active)
902 {
903 volatile uint32_t* paddr = bcm2835_spi0 + BCM2835_SPI0_CS/4;
904 uint8_t shift = 21 + cs;
905 /* Mask in the appropriate CSPOLn bit */
906 bcm2835_peri_set_bits(paddr, active << shift, 1 << shift);
907 }
908  
909 void bcm2835_spi_write(uint16_t data)
910 {
911 #if 0
912 char buf[2];
913  
914 buf[0] = data >> 8;
915 buf[1] = data & 0xFF;
916  
917 bcm2835_spi_transfern(buf, 2);
918 #else
919 volatile uint32_t* paddr = bcm2835_spi0 + BCM2835_SPI0_CS/4;
920 volatile uint32_t* fifo = bcm2835_spi0 + BCM2835_SPI0_FIFO/4;
921  
922 /* Clear TX and RX fifos */
923 bcm2835_peri_set_bits(paddr, BCM2835_SPI0_CS_CLEAR, BCM2835_SPI0_CS_CLEAR);
924  
925 /* Set TA = 1 */
926 bcm2835_peri_set_bits(paddr, BCM2835_SPI0_CS_TA, BCM2835_SPI0_CS_TA);
927  
928 /* Maybe wait for TXD */
929 while (!(bcm2835_peri_read(paddr) & BCM2835_SPI0_CS_TXD))
930 ;
931  
932 /* Write to FIFO */
933 bcm2835_peri_write_nb(fifo, (uint32_t) data >> 8);
934 bcm2835_peri_write_nb(fifo, data & 0xFF);
935  
936  
937 /* Wait for DONE to be set */
938 while (!(bcm2835_peri_read_nb(paddr) & BCM2835_SPI0_CS_DONE))
939 ;
940  
941 /* Set TA = 0, and also set the barrier */
942 bcm2835_peri_set_bits(paddr, 0, BCM2835_SPI0_CS_TA);
943 #endif
944 }
945  
946 int bcm2835_aux_spi_begin(void)
947 {
948 volatile uint32_t* enable = bcm2835_aux + BCM2835_AUX_ENABLE/4;
949 volatile uint32_t* cntl0 = bcm2835_spi1 + BCM2835_AUX_SPI_CNTL0/4;
950 volatile uint32_t* cntl1 = bcm2835_spi1 + BCM2835_AUX_SPI_CNTL1/4;
951  
952 if (bcm2835_spi1 == MAP_FAILED)
953 return 0; /* bcm2835_init() failed, or not root */
954  
955 /* Set the SPI pins to the Alt 4 function to enable SPI1 access on them */
956 bcm2835_gpio_fsel(RPI_V2_GPIO_P1_36, BCM2835_GPIO_FSEL_ALT4); /* SPI1_CE2_N */
957 bcm2835_gpio_fsel(RPI_V2_GPIO_P1_35, BCM2835_GPIO_FSEL_ALT4); /* SPI1_MISO */
958 bcm2835_gpio_fsel(RPI_V2_GPIO_P1_38, BCM2835_GPIO_FSEL_ALT4); /* SPI1_MOSI */
959 bcm2835_gpio_fsel(RPI_V2_GPIO_P1_40, BCM2835_GPIO_FSEL_ALT4); /* SPI1_SCLK */
960  
961 bcm2835_aux_spi_setClockDivider(bcm2835_aux_spi_CalcClockDivider(1000000)); // Default 1MHz SPI
962  
963 bcm2835_peri_write(enable, BCM2835_AUX_ENABLE_SPI0);
964 bcm2835_peri_write(cntl1, 0);
965 bcm2835_peri_write(cntl0, BCM2835_AUX_SPI_CNTL0_CLEARFIFO);
966  
967 return 1; /* OK */
968 }
969  
970 void bcm2835_aux_spi_end(void)
971 {
972 /* Set all the SPI1 pins back to input */
973 bcm2835_gpio_fsel(RPI_V2_GPIO_P1_36, BCM2835_GPIO_FSEL_INPT); /* SPI1_CE2_N */
974 bcm2835_gpio_fsel(RPI_V2_GPIO_P1_35, BCM2835_GPIO_FSEL_INPT); /* SPI1_MISO */
975 bcm2835_gpio_fsel(RPI_V2_GPIO_P1_38, BCM2835_GPIO_FSEL_INPT); /* SPI1_MOSI */
976 bcm2835_gpio_fsel(RPI_V2_GPIO_P1_40, BCM2835_GPIO_FSEL_INPT); /* SPI1_SCLK */
977 }
978  
979 #define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
980  
981 uint16_t bcm2835_aux_spi_CalcClockDivider(uint32_t speed_hz)
982 {
983 uint16_t divider;
984  
985 if (speed_hz < (uint32_t) BCM2835_AUX_SPI_CLOCK_MIN) {
986 speed_hz = (uint32_t) BCM2835_AUX_SPI_CLOCK_MIN;
987 } else if (speed_hz > (uint32_t) BCM2835_AUX_SPI_CLOCK_MAX) {
988 speed_hz = (uint32_t) BCM2835_AUX_SPI_CLOCK_MAX;
989 }
990  
991 divider = (uint16_t) DIV_ROUND_UP(BCM2835_CORE_CLK_HZ, 2 * speed_hz) - 1;
992  
993 if (divider > (uint16_t) BCM2835_AUX_SPI_CNTL0_SPEED_MAX) {
994 return (uint16_t) BCM2835_AUX_SPI_CNTL0_SPEED_MAX;
995 }
996  
997 return divider;
998 }
999  
1000 static uint32_t spi1_speed;
1001  
1002 void bcm2835_aux_spi_setClockDivider(uint16_t divider)
1003 {
1004 spi1_speed = (uint32_t) divider;
1005 }
1006  
1007 void bcm2835_aux_spi_write(uint16_t data)
1008 {
1009 volatile uint32_t* cntl0 = bcm2835_spi1 + BCM2835_AUX_SPI_CNTL0/4;
1010 volatile uint32_t* cntl1 = bcm2835_spi1 + BCM2835_AUX_SPI_CNTL1/4;
1011 volatile uint32_t* stat = bcm2835_spi1 + BCM2835_AUX_SPI_STAT/4;
1012 volatile uint32_t* io = bcm2835_spi1 + BCM2835_AUX_SPI_IO/4;
1013  
1014 uint32_t _cntl0 = (spi1_speed << BCM2835_AUX_SPI_CNTL0_SPEED_SHIFT);
1015 _cntl0 |= BCM2835_AUX_SPI_CNTL0_CS2_N;
1016 _cntl0 |= BCM2835_AUX_SPI_CNTL0_ENABLE;
1017 _cntl0 |= BCM2835_AUX_SPI_CNTL0_MSBF_OUT;
1018 _cntl0 |= 16; // Shift length
1019  
1020 bcm2835_peri_write(cntl0, _cntl0);
1021 bcm2835_peri_write(cntl1, BCM2835_AUX_SPI_CNTL1_MSBF_IN);
1022  
1023 while (bcm2835_peri_read(stat) & BCM2835_AUX_SPI_STAT_TX_FULL)
1024 ;
1025  
1026 bcm2835_peri_write(io, (uint32_t) data << 16);
1027 }
1028  
1029 void bcm2835_aux_spi_writenb(const char *tbuf, uint32_t len) {
1030 volatile uint32_t* cntl0 = bcm2835_spi1 + BCM2835_AUX_SPI_CNTL0/4;
1031 volatile uint32_t* cntl1 = bcm2835_spi1 + BCM2835_AUX_SPI_CNTL1/4;
1032 volatile uint32_t* stat = bcm2835_spi1 + BCM2835_AUX_SPI_STAT/4;
1033 volatile uint32_t* txhold = bcm2835_spi1 + BCM2835_AUX_SPI_TXHOLD/4;
1034 volatile uint32_t* io = bcm2835_spi1 + BCM2835_AUX_SPI_IO/4;
1035  
1036 char *tx = (char *) tbuf;
1037 uint32_t tx_len = len;
1038 uint32_t count;
1039 uint32_t data;
1040 uint32_t i;
1041 uint8_t byte;
1042  
1043 uint32_t _cntl0 = (spi1_speed << BCM2835_AUX_SPI_CNTL0_SPEED_SHIFT);
1044 _cntl0 |= BCM2835_AUX_SPI_CNTL0_CS2_N;
1045 _cntl0 |= BCM2835_AUX_SPI_CNTL0_ENABLE;
1046 _cntl0 |= BCM2835_AUX_SPI_CNTL0_MSBF_OUT;
1047 _cntl0 |= BCM2835_AUX_SPI_CNTL0_VAR_WIDTH;
1048  
1049 bcm2835_peri_write(cntl0, _cntl0);
1050 bcm2835_peri_write(cntl1, BCM2835_AUX_SPI_CNTL1_MSBF_IN);
1051  
1052 while (tx_len > 0) {
1053  
1054 while (bcm2835_peri_read(stat) & BCM2835_AUX_SPI_STAT_TX_FULL)
1055 ;
1056  
1057 count = MIN(tx_len, 3);
1058 data = 0;
1059  
1060 for (i = 0; i < count; i++) {
1061 byte = (tx != NULL) ? (uint8_t) *tx++ : (uint8_t) 0;
1062 data |= byte << (8 * (2 - i));
1063 }
1064  
1065 data |= (count * 8) << 24;
1066 tx_len -= count;
1067  
1068 if (tx_len != 0) {
1069 bcm2835_peri_write(txhold, data);
1070 } else {
1071 bcm2835_peri_write(io, data);
1072 }
1073  
1074 while (bcm2835_peri_read(stat) & BCM2835_AUX_SPI_STAT_BUSY)
1075 ;
1076  
1077 (void) bcm2835_peri_read(io);
1078 }
1079 }
1080  
1081 void bcm2835_aux_spi_transfernb(const char *tbuf, char *rbuf, uint32_t len) {
1082 volatile uint32_t* cntl0 = bcm2835_spi1 + BCM2835_AUX_SPI_CNTL0/4;
1083 volatile uint32_t* cntl1 = bcm2835_spi1 + BCM2835_AUX_SPI_CNTL1/4;
1084 volatile uint32_t* stat = bcm2835_spi1 + BCM2835_AUX_SPI_STAT/4;
1085 volatile uint32_t* txhold = bcm2835_spi1 + BCM2835_AUX_SPI_TXHOLD/4;
1086 volatile uint32_t* io = bcm2835_spi1 + BCM2835_AUX_SPI_IO/4;
1087  
1088 char *tx = (char *)tbuf;
1089 char *rx = (char *)rbuf;
1090 uint32_t tx_len = len;
1091 uint32_t rx_len = len;
1092 uint32_t count;
1093 uint32_t data;
1094 uint32_t i;
1095 uint8_t byte;
1096  
1097 uint32_t _cntl0 = (spi1_speed << BCM2835_AUX_SPI_CNTL0_SPEED_SHIFT);
1098 _cntl0 |= BCM2835_AUX_SPI_CNTL0_CS2_N;
1099 _cntl0 |= BCM2835_AUX_SPI_CNTL0_ENABLE;
1100 _cntl0 |= BCM2835_AUX_SPI_CNTL0_MSBF_OUT;
1101 _cntl0 |= BCM2835_AUX_SPI_CNTL0_VAR_WIDTH;
1102  
1103 bcm2835_peri_write(cntl0, _cntl0);
1104 bcm2835_peri_write(cntl1, BCM2835_AUX_SPI_CNTL1_MSBF_IN);
1105  
1106 while ((tx_len > 0) || (rx_len > 0)) {
1107  
1108 while (!(bcm2835_peri_read(stat) & BCM2835_AUX_SPI_STAT_TX_FULL) && (tx_len > 0)) {
1109 count = MIN(tx_len, 3);
1110 data = 0;
1111  
1112 for (i = 0; i < count; i++) {
1113 byte = (tx != NULL) ? (uint8_t) *tx++ : (uint8_t) 0;
1114 data |= byte << (8 * (2 - i));
1115 }
1116  
1117 data |= (count * 8) << 24;
1118 tx_len -= count;
1119  
1120 if (tx_len != 0) {
1121 bcm2835_peri_write(txhold, data);
1122 } else {
1123 bcm2835_peri_write(io, data);
1124 }
1125  
1126 }
1127  
1128 while (!(bcm2835_peri_read(stat) & BCM2835_AUX_SPI_STAT_RX_EMPTY) && (rx_len > 0)) {
1129 count = MIN(rx_len, 3);
1130 data = bcm2835_peri_read(io);
1131  
1132 if (rbuf != NULL) {
1133 switch (count) {
1134 case 3:
1135 *rx++ = (char)((data >> 16) & 0xFF);
1136 /*@fallthrough@*/
1137 /* no break */
1138 case 2:
1139 *rx++ = (char)((data >> 8) & 0xFF);
1140 /*@fallthrough@*/
1141 /* no break */
1142 case 1:
1143 *rx++ = (char)((data >> 0) & 0xFF);
1144 }
1145 }
1146  
1147 rx_len -= count;
1148 }
1149  
1150 while (!(bcm2835_peri_read(stat) & BCM2835_AUX_SPI_STAT_BUSY) && (rx_len > 0)) {
1151 count = MIN(rx_len, 3);
1152 data = bcm2835_peri_read(io);
1153  
1154 if (rbuf != NULL) {
1155 switch (count) {
1156 case 3:
1157 *rx++ = (char)((data >> 16) & 0xFF);
1158 /*@fallthrough@*/
1159 /* no break */
1160 case 2:
1161 *rx++ = (char)((data >> 8) & 0xFF);
1162 /*@fallthrough@*/
1163 /* no break */
1164 case 1:
1165 *rx++ = (char)((data >> 0) & 0xFF);
1166 }
1167 }
1168  
1169 rx_len -= count;
1170 }
1171 }
1172 }
1173  
1174 void bcm2835_aux_spi_transfern(char *buf, uint32_t len) {
1175 bcm2835_aux_spi_transfernb(buf, buf, len);
1176 }
1177  
1178 /* Writes (and reads) a single byte to AUX SPI */
1179 uint8_t bcm2835_aux_spi_transfer(uint8_t value)
1180 {
1181 volatile uint32_t* cntl0 = bcm2835_spi1 + BCM2835_AUX_SPI_CNTL0/4;
1182 volatile uint32_t* cntl1 = bcm2835_spi1 + BCM2835_AUX_SPI_CNTL1/4;
1183 volatile uint32_t* stat = bcm2835_spi1 + BCM2835_AUX_SPI_STAT/4;
1184 volatile uint32_t* io = bcm2835_spi1 + BCM2835_AUX_SPI_IO/4;
1185  
1186 uint32_t data;
1187  
1188 uint32_t _cntl0 = (spi1_speed << BCM2835_AUX_SPI_CNTL0_SPEED_SHIFT);
1189 _cntl0 |= BCM2835_AUX_SPI_CNTL0_CS2_N;
1190 _cntl0 |= BCM2835_AUX_SPI_CNTL0_ENABLE;
1191 _cntl0 |= BCM2835_AUX_SPI_CNTL0_MSBF_OUT;
1192 _cntl0 |= BCM2835_AUX_SPI_CNTL0_CPHA_IN;
1193 _cntl0 |= 8; // Shift length.
1194  
1195 uint32_t _cntl1 = BCM2835_AUX_SPI_CNTL1_MSBF_IN;
1196  
1197 bcm2835_peri_write(cntl1, _cntl1);
1198 bcm2835_peri_write(cntl0, _cntl0);
1199  
1200 bcm2835_peri_write(io, (uint32_t) bcm2835_correct_order(value) << 24);
1201  
1202 while (bcm2835_peri_read(stat) & BCM2835_AUX_SPI_STAT_BUSY)
1203 ;
1204  
1205 data = bcm2835_correct_order(bcm2835_peri_read(io) & 0xff);
1206  
1207 bcm2835_aux_spi_reset();
1208  
1209 return data;
1210 }
1211  
1212  
1213 int bcm2835_i2c_begin(void)
1214 {
1215 uint16_t cdiv;
1216  
1217 if ( bcm2835_bsc0 == MAP_FAILED
1218 || bcm2835_bsc1 == MAP_FAILED)
1219 return 0; /* bcm2835_init() failed, or not root */
1220  
1221 #ifdef I2C_V1
1222 volatile uint32_t* paddr = bcm2835_bsc0 + BCM2835_BSC_DIV/4;
1223 /* Set the I2C/BSC0 pins to the Alt 0 function to enable I2C access on them */
1224 bcm2835_gpio_fsel(RPI_GPIO_P1_03, BCM2835_GPIO_FSEL_ALT0); /* SDA */
1225 bcm2835_gpio_fsel(RPI_GPIO_P1_05, BCM2835_GPIO_FSEL_ALT0); /* SCL */
1226 #else
1227 volatile uint32_t* paddr = bcm2835_bsc1 + BCM2835_BSC_DIV/4;
1228 /* Set the I2C/BSC1 pins to the Alt 0 function to enable I2C access on them */
1229 bcm2835_gpio_fsel(RPI_V2_GPIO_P1_03, BCM2835_GPIO_FSEL_ALT0); /* SDA */
1230 bcm2835_gpio_fsel(RPI_V2_GPIO_P1_05, BCM2835_GPIO_FSEL_ALT0); /* SCL */
1231 #endif
1232  
1233 /* Read the clock divider register */
1234 cdiv = bcm2835_peri_read(paddr);
1235 /* Calculate time for transmitting one byte
1236 // 1000000 = micros seconds in a second
1237 // 9 = Clocks per byte : 8 bits + ACK
1238 */
1239 i2c_byte_wait_us = ((float)cdiv / BCM2835_CORE_CLK_HZ) * 1000000 * 9;
1240  
1241 return 1;
1242 }
1243  
1244 void bcm2835_i2c_end(void)
1245 {
1246 #ifdef I2C_V1
1247 /* Set all the I2C/BSC0 pins back to input */
1248 bcm2835_gpio_fsel(RPI_GPIO_P1_03, BCM2835_GPIO_FSEL_INPT); /* SDA */
1249 bcm2835_gpio_fsel(RPI_GPIO_P1_05, BCM2835_GPIO_FSEL_INPT); /* SCL */
1250 #else
1251 /* Set all the I2C/BSC1 pins back to input */
1252 bcm2835_gpio_fsel(RPI_V2_GPIO_P1_03, BCM2835_GPIO_FSEL_INPT); /* SDA */
1253 bcm2835_gpio_fsel(RPI_V2_GPIO_P1_05, BCM2835_GPIO_FSEL_INPT); /* SCL */
1254 #endif
1255 }
1256  
1257 void bcm2835_i2c_setSlaveAddress(uint8_t addr)
1258 {
1259 /* Set I2C Device Address */
1260 #ifdef I2C_V1
1261 volatile uint32_t* paddr = bcm2835_bsc0 + BCM2835_BSC_A/4;
1262 #else
1263 volatile uint32_t* paddr = bcm2835_bsc1 + BCM2835_BSC_A/4;
1264 #endif
1265 bcm2835_peri_write(paddr, addr);
1266 }
1267  
1268 /* defaults to 0x5dc, should result in a 166.666 kHz I2C clock frequency.
1269 // The divisor must be a power of 2. Odd numbers
1270 // rounded down.
1271 */
1272 void bcm2835_i2c_setClockDivider(uint16_t divider)
1273 {
1274 #ifdef I2C_V1
1275 volatile uint32_t* paddr = bcm2835_bsc0 + BCM2835_BSC_DIV/4;
1276 #else
1277 volatile uint32_t* paddr = bcm2835_bsc1 + BCM2835_BSC_DIV/4;
1278 #endif
1279 bcm2835_peri_write(paddr, divider);
1280 /* Calculate time for transmitting one byte
1281 // 1000000 = micros seconds in a second
1282 // 9 = Clocks per byte : 8 bits + ACK
1283 */
1284 i2c_byte_wait_us = ((float)divider / BCM2835_CORE_CLK_HZ) * 1000000 * 9;
1285 }
1286  
1287 /* set I2C clock divider by means of a baudrate number */
1288 void bcm2835_i2c_set_baudrate(uint32_t baudrate)
1289 {
1290 uint32_t divider;
1291 /* use 0xFFFE mask to limit a max value and round down any odd number */
1292 divider = (BCM2835_CORE_CLK_HZ / baudrate) & 0xFFFE;
1293 bcm2835_i2c_setClockDivider( (uint16_t)divider );
1294 }
1295  
1296 /* Writes an number of bytes to I2C */
1297 uint8_t bcm2835_i2c_write(const char * buf, uint32_t len)
1298 {
1299 #ifdef I2C_V1
1300 volatile uint32_t* dlen = bcm2835_bsc0 + BCM2835_BSC_DLEN/4;
1301 volatile uint32_t* fifo = bcm2835_bsc0 + BCM2835_BSC_FIFO/4;
1302 volatile uint32_t* status = bcm2835_bsc0 + BCM2835_BSC_S/4;
1303 volatile uint32_t* control = bcm2835_bsc0 + BCM2835_BSC_C/4;
1304 #else
1305 volatile uint32_t* dlen = bcm2835_bsc1 + BCM2835_BSC_DLEN/4;
1306 volatile uint32_t* fifo = bcm2835_bsc1 + BCM2835_BSC_FIFO/4;
1307 volatile uint32_t* status = bcm2835_bsc1 + BCM2835_BSC_S/4;
1308 volatile uint32_t* control = bcm2835_bsc1 + BCM2835_BSC_C/4;
1309 #endif
1310  
1311 uint32_t remaining = len;
1312 uint32_t i = 0;
1313 uint8_t reason = BCM2835_I2C_REASON_OK;
1314  
1315 /* Clear FIFO */
1316 bcm2835_peri_set_bits(control, BCM2835_BSC_C_CLEAR_1 , BCM2835_BSC_C_CLEAR_1 );
1317 /* Clear Status */
1318 bcm2835_peri_write(status, BCM2835_BSC_S_CLKT | BCM2835_BSC_S_ERR | BCM2835_BSC_S_DONE);
1319 /* Set Data Length */
1320 bcm2835_peri_write(dlen, len);
1321 /* pre populate FIFO with max buffer */
1322 while( remaining && ( i < BCM2835_BSC_FIFO_SIZE ) )
1323 {
1324 bcm2835_peri_write_nb(fifo, buf[i]);
1325 i++;
1326 remaining--;
1327 }
1328  
1329 /* Enable device and start transfer */
1330 bcm2835_peri_write(control, BCM2835_BSC_C_I2CEN | BCM2835_BSC_C_ST);
1331  
1332 /* Transfer is over when BCM2835_BSC_S_DONE */
1333 while(!(bcm2835_peri_read(status) & BCM2835_BSC_S_DONE ))
1334 {
1335 while ( remaining && (bcm2835_peri_read(status) & BCM2835_BSC_S_TXD ))
1336 {
1337 /* Write to FIFO */
1338 bcm2835_peri_write(fifo, buf[i]);
1339 i++;
1340 remaining--;
1341 }
1342 }
1343  
1344 /* Received a NACK */
1345 if (bcm2835_peri_read(status) & BCM2835_BSC_S_ERR)
1346 {
1347 reason = BCM2835_I2C_REASON_ERROR_NACK;
1348 }
1349  
1350 /* Received Clock Stretch Timeout */
1351 else if (bcm2835_peri_read(status) & BCM2835_BSC_S_CLKT)
1352 {
1353 reason = BCM2835_I2C_REASON_ERROR_CLKT;
1354 }
1355  
1356 /* Not all data is sent */
1357 else if (remaining)
1358 {
1359 reason = BCM2835_I2C_REASON_ERROR_DATA;
1360 }
1361  
1362 bcm2835_peri_set_bits(control, BCM2835_BSC_S_DONE , BCM2835_BSC_S_DONE);
1363  
1364 return reason;
1365 }
1366  
1367 /* Read an number of bytes from I2C */
1368 uint8_t bcm2835_i2c_read(char* buf, uint32_t len)
1369 {
1370 #ifdef I2C_V1
1371 volatile uint32_t* dlen = bcm2835_bsc0 + BCM2835_BSC_DLEN/4;
1372 volatile uint32_t* fifo = bcm2835_bsc0 + BCM2835_BSC_FIFO/4;
1373 volatile uint32_t* status = bcm2835_bsc0 + BCM2835_BSC_S/4;
1374 volatile uint32_t* control = bcm2835_bsc0 + BCM2835_BSC_C/4;
1375 #else
1376 volatile uint32_t* dlen = bcm2835_bsc1 + BCM2835_BSC_DLEN/4;
1377 volatile uint32_t* fifo = bcm2835_bsc1 + BCM2835_BSC_FIFO/4;
1378 volatile uint32_t* status = bcm2835_bsc1 + BCM2835_BSC_S/4;
1379 volatile uint32_t* control = bcm2835_bsc1 + BCM2835_BSC_C/4;
1380 #endif
1381  
1382 uint32_t remaining = len;
1383 uint32_t i = 0;
1384 uint8_t reason = BCM2835_I2C_REASON_OK;
1385  
1386 /* Clear FIFO */
1387 bcm2835_peri_set_bits(control, BCM2835_BSC_C_CLEAR_1 , BCM2835_BSC_C_CLEAR_1 );
1388 /* Clear Status */
1389 bcm2835_peri_write_nb(status, BCM2835_BSC_S_CLKT | BCM2835_BSC_S_ERR | BCM2835_BSC_S_DONE);
1390 /* Set Data Length */
1391 bcm2835_peri_write_nb(dlen, len);
1392 /* Start read */
1393 bcm2835_peri_write_nb(control, BCM2835_BSC_C_I2CEN | BCM2835_BSC_C_ST | BCM2835_BSC_C_READ);
1394  
1395 /* wait for transfer to complete */
1396 while (!(bcm2835_peri_read_nb(status) & BCM2835_BSC_S_DONE))
1397 {
1398 /* we must empty the FIFO as it is populated and not use any delay */
1399 while (remaining && bcm2835_peri_read_nb(status) & BCM2835_BSC_S_RXD)
1400 {
1401 /* Read from FIFO, no barrier */
1402 buf[i] = bcm2835_peri_read_nb(fifo);
1403 i++;
1404 remaining--;
1405 }
1406 }
1407  
1408 /* transfer has finished - grab any remaining stuff in FIFO */
1409 while (remaining && (bcm2835_peri_read_nb(status) & BCM2835_BSC_S_RXD))
1410 {
1411 /* Read from FIFO, no barrier */
1412 buf[i] = bcm2835_peri_read_nb(fifo);
1413 i++;
1414 remaining--;
1415 }
1416  
1417 /* Received a NACK */
1418 if (bcm2835_peri_read(status) & BCM2835_BSC_S_ERR)
1419 {
1420 reason = BCM2835_I2C_REASON_ERROR_NACK;
1421 }
1422  
1423 /* Received Clock Stretch Timeout */
1424 else if (bcm2835_peri_read(status) & BCM2835_BSC_S_CLKT)
1425 {
1426 reason = BCM2835_I2C_REASON_ERROR_CLKT;
1427 }
1428  
1429 /* Not all data is received */
1430 else if (remaining)
1431 {
1432 reason = BCM2835_I2C_REASON_ERROR_DATA;
1433 }
1434  
1435 bcm2835_peri_set_bits(status, BCM2835_BSC_S_DONE , BCM2835_BSC_S_DONE);
1436  
1437 return reason;
1438 }
1439  
1440 /* Read an number of bytes from I2C sending a repeated start after writing
1441 // the required register. Only works if your device supports this mode
1442 */
1443 uint8_t bcm2835_i2c_read_register_rs(char* regaddr, char* buf, uint32_t len)
1444 {
1445 #ifdef I2C_V1
1446 volatile uint32_t* dlen = bcm2835_bsc0 + BCM2835_BSC_DLEN/4;
1447 volatile uint32_t* fifo = bcm2835_bsc0 + BCM2835_BSC_FIFO/4;
1448 volatile uint32_t* status = bcm2835_bsc0 + BCM2835_BSC_S/4;
1449 volatile uint32_t* control = bcm2835_bsc0 + BCM2835_BSC_C/4;
1450 #else
1451 volatile uint32_t* dlen = bcm2835_bsc1 + BCM2835_BSC_DLEN/4;
1452 volatile uint32_t* fifo = bcm2835_bsc1 + BCM2835_BSC_FIFO/4;
1453 volatile uint32_t* status = bcm2835_bsc1 + BCM2835_BSC_S/4;
1454 volatile uint32_t* control = bcm2835_bsc1 + BCM2835_BSC_C/4;
1455 #endif
1456 uint32_t remaining = len;
1457 uint32_t i = 0;
1458 uint8_t reason = BCM2835_I2C_REASON_OK;
1459  
1460 /* Clear FIFO */
1461 bcm2835_peri_set_bits(control, BCM2835_BSC_C_CLEAR_1 , BCM2835_BSC_C_CLEAR_1 );
1462 /* Clear Status */
1463 bcm2835_peri_write(status, BCM2835_BSC_S_CLKT | BCM2835_BSC_S_ERR | BCM2835_BSC_S_DONE);
1464 /* Set Data Length */
1465 bcm2835_peri_write(dlen, 1);
1466 /* Enable device and start transfer */
1467 bcm2835_peri_write(control, BCM2835_BSC_C_I2CEN);
1468 bcm2835_peri_write(fifo, regaddr[0]);
1469 bcm2835_peri_write(control, BCM2835_BSC_C_I2CEN | BCM2835_BSC_C_ST);
1470  
1471 /* poll for transfer has started */
1472 while ( !( bcm2835_peri_read(status) & BCM2835_BSC_S_TA ) )
1473 {
1474 /* Linux may cause us to miss entire transfer stage */
1475 if(bcm2835_peri_read(status) & BCM2835_BSC_S_DONE)
1476 break;
1477 }
1478  
1479 /* Send a repeated start with read bit set in address */
1480 bcm2835_peri_write(dlen, len);
1481 bcm2835_peri_write(control, BCM2835_BSC_C_I2CEN | BCM2835_BSC_C_ST | BCM2835_BSC_C_READ );
1482  
1483 /* Wait for write to complete and first byte back. */
1484 bcm2835_delayMicroseconds(i2c_byte_wait_us * 3);
1485  
1486 /* wait for transfer to complete */
1487 while (!(bcm2835_peri_read(status) & BCM2835_BSC_S_DONE))
1488 {
1489 /* we must empty the FIFO as it is populated and not use any delay */
1490 while (remaining && bcm2835_peri_read(status) & BCM2835_BSC_S_RXD)
1491 {
1492 /* Read from FIFO */
1493 buf[i] = bcm2835_peri_read(fifo);
1494 i++;
1495 remaining--;
1496 }
1497 }
1498  
1499 /* transfer has finished - grab any remaining stuff in FIFO */
1500 while (remaining && (bcm2835_peri_read(status) & BCM2835_BSC_S_RXD))
1501 {
1502 /* Read from FIFO */
1503 buf[i] = bcm2835_peri_read(fifo);
1504 i++;
1505 remaining--;
1506 }
1507  
1508 /* Received a NACK */
1509 if (bcm2835_peri_read(status) & BCM2835_BSC_S_ERR)
1510 {
1511 reason = BCM2835_I2C_REASON_ERROR_NACK;
1512 }
1513  
1514 /* Received Clock Stretch Timeout */
1515 else if (bcm2835_peri_read(status) & BCM2835_BSC_S_CLKT)
1516 {
1517 reason = BCM2835_I2C_REASON_ERROR_CLKT;
1518 }
1519  
1520 /* Not all data is sent */
1521 else if (remaining)
1522 {
1523 reason = BCM2835_I2C_REASON_ERROR_DATA;
1524 }
1525  
1526 bcm2835_peri_set_bits(control, BCM2835_BSC_S_DONE , BCM2835_BSC_S_DONE);
1527  
1528 return reason;
1529 }
1530  
1531 /* Sending an arbitrary number of bytes before issuing a repeated start
1532 // (with no prior stop) and reading a response. Some devices require this behavior.
1533 */
1534 uint8_t bcm2835_i2c_write_read_rs(char* cmds, uint32_t cmds_len, char* buf, uint32_t buf_len)
1535 {
1536 #ifdef I2C_V1
1537 volatile uint32_t* dlen = bcm2835_bsc0 + BCM2835_BSC_DLEN/4;
1538 volatile uint32_t* fifo = bcm2835_bsc0 + BCM2835_BSC_FIFO/4;
1539 volatile uint32_t* status = bcm2835_bsc0 + BCM2835_BSC_S/4;
1540 volatile uint32_t* control = bcm2835_bsc0 + BCM2835_BSC_C/4;
1541 #else
1542 volatile uint32_t* dlen = bcm2835_bsc1 + BCM2835_BSC_DLEN/4;
1543 volatile uint32_t* fifo = bcm2835_bsc1 + BCM2835_BSC_FIFO/4;
1544 volatile uint32_t* status = bcm2835_bsc1 + BCM2835_BSC_S/4;
1545 volatile uint32_t* control = bcm2835_bsc1 + BCM2835_BSC_C/4;
1546 #endif
1547  
1548 uint32_t remaining = cmds_len;
1549 uint32_t i = 0;
1550 uint8_t reason = BCM2835_I2C_REASON_OK;
1551  
1552 /* Clear FIFO */
1553 bcm2835_peri_set_bits(control, BCM2835_BSC_C_CLEAR_1 , BCM2835_BSC_C_CLEAR_1 );
1554  
1555 /* Clear Status */
1556 bcm2835_peri_write(status, BCM2835_BSC_S_CLKT | BCM2835_BSC_S_ERR | BCM2835_BSC_S_DONE);
1557  
1558 /* Set Data Length */
1559 bcm2835_peri_write(dlen, cmds_len);
1560  
1561 /* pre populate FIFO with max buffer */
1562 while( remaining && ( i < BCM2835_BSC_FIFO_SIZE ) )
1563 {
1564 bcm2835_peri_write_nb(fifo, cmds[i]);
1565 i++;
1566 remaining--;
1567 }
1568  
1569 /* Enable device and start transfer */
1570 bcm2835_peri_write(control, BCM2835_BSC_C_I2CEN | BCM2835_BSC_C_ST);
1571  
1572 /* poll for transfer has started (way to do repeated start, from BCM2835 datasheet) */
1573 while ( !( bcm2835_peri_read(status) & BCM2835_BSC_S_TA ) )
1574 {
1575 /* Linux may cause us to miss entire transfer stage */
1576 if(bcm2835_peri_read_nb(status) & BCM2835_BSC_S_DONE)
1577 break;
1578 }
1579  
1580 remaining = buf_len;
1581 i = 0;
1582  
1583 /* Send a repeated start with read bit set in address */
1584 bcm2835_peri_write(dlen, buf_len);
1585 bcm2835_peri_write(control, BCM2835_BSC_C_I2CEN | BCM2835_BSC_C_ST | BCM2835_BSC_C_READ );
1586  
1587 /* Wait for write to complete and first byte back. */
1588 bcm2835_delayMicroseconds(i2c_byte_wait_us * (cmds_len + 1));
1589  
1590 /* wait for transfer to complete */
1591 while (!(bcm2835_peri_read_nb(status) & BCM2835_BSC_S_DONE))
1592 {
1593 /* we must empty the FIFO as it is populated and not use any delay */
1594 while (remaining && bcm2835_peri_read(status) & BCM2835_BSC_S_RXD)
1595 {
1596 /* Read from FIFO, no barrier */
1597 buf[i] = bcm2835_peri_read_nb(fifo);
1598 i++;
1599 remaining--;
1600 }
1601 }
1602  
1603 /* transfer has finished - grab any remaining stuff in FIFO */
1604 while (remaining && (bcm2835_peri_read(status) & BCM2835_BSC_S_RXD))
1605 {
1606 /* Read from FIFO */
1607 buf[i] = bcm2835_peri_read(fifo);
1608 i++;
1609 remaining--;
1610 }
1611  
1612 /* Received a NACK */
1613 if (bcm2835_peri_read(status) & BCM2835_BSC_S_ERR)
1614 {
1615 reason = BCM2835_I2C_REASON_ERROR_NACK;
1616 }
1617  
1618 /* Received Clock Stretch Timeout */
1619 else if (bcm2835_peri_read(status) & BCM2835_BSC_S_CLKT)
1620 {
1621 reason = BCM2835_I2C_REASON_ERROR_CLKT;
1622 }
1623  
1624 /* Not all data is sent */
1625 else if (remaining)
1626 {
1627 reason = BCM2835_I2C_REASON_ERROR_DATA;
1628 }
1629  
1630 bcm2835_peri_set_bits(control, BCM2835_BSC_S_DONE , BCM2835_BSC_S_DONE);
1631  
1632 return reason;
1633 }
1634  
1635 /* SMI support courtesy Benoit Bouchez */
1636 int bcm2835_smi_begin(void)
1637 {
1638 volatile uint32_t* paddr;
1639 uint32_t defConfig;
1640  
1641 if (bcm2835_smi == MAP_FAILED)
1642 return 0; /* bcm2835_smi_init() failed, or not root */
1643  
1644 /* Set the SMI pins to the Alt 1 function to enable SMI access on them */
1645 bcm2835_gpio_fsel(2, BCM2835_GPIO_FSEL_ALT1); /* SA3 */
1646 bcm2835_gpio_fsel(3, BCM2835_GPIO_FSEL_ALT1); /* SA2 */
1647 bcm2835_gpio_fsel(4, BCM2835_GPIO_FSEL_ALT1); /* SA1 */
1648 bcm2835_gpio_fsel(5, BCM2835_GPIO_FSEL_ALT1); /* SA0 */
1649 bcm2835_gpio_fsel(6, BCM2835_GPIO_FSEL_ALT1); /* SOE_N / SE */
1650 bcm2835_gpio_fsel(7, BCM2835_GPIO_FSEL_ALT1); /* SWE_N / SRW_N */
1651 bcm2835_gpio_fsel(8, BCM2835_GPIO_FSEL_ALT1); /* SD0 */
1652 bcm2835_gpio_fsel(9, BCM2835_GPIO_FSEL_ALT1); /* SD1 */
1653 bcm2835_gpio_fsel(10, BCM2835_GPIO_FSEL_ALT1); /* SD2 */
1654 bcm2835_gpio_fsel(11, BCM2835_GPIO_FSEL_ALT1); /* SD3 */
1655 bcm2835_gpio_fsel(12, BCM2835_GPIO_FSEL_ALT1); /* SD4 */
1656 bcm2835_gpio_fsel(13, BCM2835_GPIO_FSEL_ALT1); /* SD5 */
1657 bcm2835_gpio_fsel(14, BCM2835_GPIO_FSEL_ALT1); /* SD6 */
1658 bcm2835_gpio_fsel(15, BCM2835_GPIO_FSEL_ALT1); /* SD7 */
1659  
1660 /* Set the SMI clock to 125MHz -> one clock period lasts 8 ns */
1661 paddr = bcm2835_clk + SMICLK_CNTL;
1662 bcm2835_peri_write (paddr, 0x5A000000); /* Disable SMI clock */
1663 paddr = bcm2835_clk + SMICLK_DIV;
1664 bcm2835_peri_write (paddr, 0x5A004000); /* Set clock divider to 4 */
1665 paddr = bcm2835_clk + SMICLK_CNTL;
1666 bcm2835_peri_write (paddr, 0x5A000016); /* Enable SMI clock with PLLD */
1667  
1668 /* Set a default useable configuration for the four SMI config slots */
1669 /* 8 bits, Intel mode, always pace, 10 clocks for R/W setup = 80 ns
1670 20 clocks for R/W strobe = 160 ns, 20 clocks for R/W hold = 160 ns,
1671 1 clock for pace control (not used but a value is needed) */
1672 defConfig = BCM2835_SMI_RW_WID8 | BCM2835_SMI_RW_MODE80 |
1673 BCM2835_SMI_RW_PACEALL | (10<<BCM2835_SMI_RW_SETUP_LS) |
1674 (20<<BCM2835_SMI_RW_STROBE_LS) | (20<<BCM2835_SMI_RW_HOLD_LS) |
1675 (1<<BCM2835_SMI_RW_PACE_LS);
1676  
1677 paddr = bcm2835_smi + BCM2835_SMI_READ0;
1678 bcm2835_peri_write (paddr, defConfig);
1679 paddr = bcm2835_smi + BCM2835_SMI_WRITE0;
1680 bcm2835_peri_write (paddr, defConfig);
1681 paddr = bcm2835_smi + BCM2835_SMI_READ1;
1682 bcm2835_peri_write (paddr, defConfig);
1683 paddr = bcm2835_smi + BCM2835_SMI_WRITE1;
1684 bcm2835_peri_write (paddr, defConfig);
1685 paddr = bcm2835_smi + BCM2835_SMI_READ2;
1686 bcm2835_peri_write (paddr, defConfig);
1687 paddr = bcm2835_smi + BCM2835_SMI_WRITE2;
1688 bcm2835_peri_write (paddr, defConfig);
1689 paddr = bcm2835_smi + BCM2835_SMI_READ3;
1690 bcm2835_peri_write (paddr, defConfig);
1691 paddr = bcm2835_smi + BCM2835_SMI_WRITE3;
1692 bcm2835_peri_write (paddr, defConfig);
1693  
1694 return 1; // OK
1695 } /* bcm2835_smi_begin */
1696 /* --------------------------------------------------- */
1697  
1698 void bcm2835_smi_end(void)
1699 {
1700 /* Set all the SMI pins back to input */
1701 bcm2835_gpio_fsel(2, BCM2835_GPIO_FSEL_INPT); /* SA3 */
1702 bcm2835_gpio_fsel(3, BCM2835_GPIO_FSEL_INPT); /* SA2 */
1703 bcm2835_gpio_fsel(4, BCM2835_GPIO_FSEL_INPT); /* SA1 */
1704 bcm2835_gpio_fsel(5, BCM2835_GPIO_FSEL_INPT); /* SA0 */
1705 bcm2835_gpio_fsel(6, BCM2835_GPIO_FSEL_INPT); /* SOE_N / SE */
1706 bcm2835_gpio_fsel(7, BCM2835_GPIO_FSEL_INPT); /* SWE_N / SRW_N */
1707 bcm2835_gpio_fsel(8, BCM2835_GPIO_FSEL_INPT); /* SD0 */
1708 bcm2835_gpio_fsel(9, BCM2835_GPIO_FSEL_INPT); /* SD1 */
1709 bcm2835_gpio_fsel(10, BCM2835_GPIO_FSEL_INPT); /* SD2 */
1710 bcm2835_gpio_fsel(11, BCM2835_GPIO_FSEL_INPT); /* SD3 */
1711 bcm2835_gpio_fsel(12, BCM2835_GPIO_FSEL_INPT); /* SD4 */
1712 bcm2835_gpio_fsel(13, BCM2835_GPIO_FSEL_INPT); /* SD5 */
1713 bcm2835_gpio_fsel(14, BCM2835_GPIO_FSEL_INPT); /* SD6 */
1714 bcm2835_gpio_fsel(15, BCM2835_GPIO_FSEL_INPT); /* SD7 */
1715 } /* bcm2835_smi_end */
1716 /* --------------------------------------------------- */
1717  
1718 void bcm2835_smi_set_timing (uint32_t smichannel, uint32_t readchannel,
1719 uint32_t setupcycles, uint32_t strobecycles,
1720 uint32_t holdcycles, uint32_t pacecycles)
1721 {
1722 int RegOffset;
1723 volatile uint32_t* psmitiming;
1724 uint32_t RegValue;
1725  
1726 if (readchannel!=0)
1727 {
1728 switch (smichannel)
1729 {
1730 case 0 : RegOffset = BCM2835_SMI_READ0; break;
1731 case 1 : RegOffset = BCM2835_SMI_READ1; break;
1732 case 2 : RegOffset = BCM2835_SMI_READ2; break;
1733 case 3 : RegOffset = BCM2835_SMI_READ3; break;
1734 default : return;
1735 }
1736 }
1737 else
1738 {
1739 switch (smichannel)
1740 {
1741 case 0 : RegOffset = BCM2835_SMI_WRITE0; break;
1742 case 1 : RegOffset = BCM2835_SMI_WRITE1; break;
1743 case 2 : RegOffset = BCM2835_SMI_WRITE2; break;
1744 case 3 : RegOffset = BCM2835_SMI_WRITE3; break;
1745 default : return;
1746 }
1747 }
1748  
1749 /* Get current timing configuration of the slot */
1750 psmitiming = bcm2835_smi + RegOffset;
1751 RegValue = bcm2835_peri_read (psmitiming);
1752 /* Clear timing fields in register */
1753 RegValue &= ~(BCM2835_SMI_RW_SETUP_MSK|BCM2835_SMI_RW_HOLD_MSK|BCM2835_SMI_RW_PACE_MSK|BCM2835_SMI_RW_STROBE_MSK);
1754 /* Set timing values and write back to register */
1755 RegValue |= (setupcycles << BCM2835_SMI_RW_SETUP_LS) |
1756 (strobecycles << BCM2835_SMI_RW_STROBE_LS) |
1757 (holdcycles << BCM2835_SMI_RW_HOLD_LS) |
1758 (pacecycles << BCM2835_SMI_RW_PACE_LS);
1759 bcm2835_peri_write (psmitiming, RegValue);
1760 } /* bcm2835_set_smi_timing */
1761 /* --------------------------------------------------- */
1762  
1763 void bcm2835_smi_write(uint32_t smichannel, uint8_t data, uint32_t address)
1764 {
1765 uint32_t status;
1766 volatile uint32_t* psmics = bcm2835_smi + BCM2835_SMI_DIRCS;
1767 volatile uint32_t* psmiaddr = bcm2835_smi + BCM2835_SMI_DIRADDR;
1768 volatile uint32_t* psmidata = bcm2835_smi + BCM2835_SMI_DIRDATA;
1769  
1770 /* Make sure we use a configuration that exists */
1771 if (smichannel>3) return;
1772  
1773 /* clear done bit if set */
1774 if (bcm2835_peri_read(psmics) & BCM2835_SMI_DIRCS_DONE)
1775 {
1776 bcm2835_peri_write (psmics, BCM2835_SMI_DIRCS_DONE);
1777 }
1778  
1779 /* Start write transfer */
1780 bcm2835_peri_write (psmiaddr, (smichannel<<BCM2835_SMI_DIRADRS_DEV_LS) | (address&BCM2835_SMI_DIRADRS_MSK));
1781 bcm2835_peri_write (psmidata, data);
1782 bcm2835_peri_write (psmics, BCM2835_SMI_DIRCS_WRITE|BCM2835_SMI_DIRCS_START|BCM2835_SMI_DIRCS_ENABLE);
1783  
1784 /* Wait until write cycle is finished */
1785 do {
1786 status = bcm2835_peri_read(psmics);
1787 } while ((status & BCM2835_SMI_DIRCS_DONE)==0);
1788  
1789 /* clear done bit */
1790 bcm2835_peri_write (psmics, BCM2835_SMI_DIRCS_DONE);
1791 } /* bcm2835_smi_write */
1792 /* --------------------------------------------------- */
1793  
1794 uint32_t bcm2835_smi_read (uint32_t smichannel, uint32_t address)
1795 {
1796 uint32_t status;
1797 uint32_t data;
1798 volatile uint32_t* psmics = bcm2835_smi + BCM2835_SMI_DIRCS;
1799 volatile uint32_t* psmiaddr = bcm2835_smi + BCM2835_SMI_DIRADDR;
1800 volatile uint32_t* psmidata = bcm2835_smi + BCM2835_SMI_DIRDATA;
1801  
1802 /* Make sure we use a configuration that exists */
1803 if (smichannel>3) return 0;
1804  
1805 /* clear done bit if set */
1806 if (bcm2835_peri_read(psmics) & BCM2835_SMI_DIRCS_DONE)
1807 {
1808 bcm2835_peri_write (psmics, BCM2835_SMI_DIRCS_DONE);
1809 }
1810  
1811 /* Start read transfer */
1812 bcm2835_peri_write (psmiaddr, (smichannel<<BCM2835_SMI_DIRADRS_DEV_LS) | (address&BCM2835_SMI_DIRADRS_MSK));
1813 bcm2835_peri_write (psmics, BCM2835_SMI_DIRCS_START|BCM2835_SMI_DIRCS_ENABLE);
1814  
1815 /* Wait until read cycle is finished */
1816 do {
1817 status = bcm2835_peri_read(psmics);
1818 } while ((status & BCM2835_SMI_DIRCS_DONE)==0);
1819  
1820 /* Read data */
1821 data = bcm2835_peri_read (psmidata);
1822  
1823 /* clear done bit */
1824 bcm2835_peri_write (psmics, BCM2835_SMI_DIRCS_DONE);
1825  
1826 return data;
1827 } /* bcm2835_smi_read */
1828 /* --------------------------------------------------- */
1829  
1830 /* Read the System Timer Counter (64-bits) */
1831 uint64_t bcm2835_st_read(void)
1832 {
1833 volatile uint32_t* paddr;
1834 uint32_t hi, lo;
1835 uint64_t st;
1836  
1837 if (bcm2835_st==MAP_FAILED)
1838 return 0;
1839  
1840 paddr = bcm2835_st + BCM2835_ST_CHI/4;
1841 hi = bcm2835_peri_read(paddr);
1842  
1843 paddr = bcm2835_st + BCM2835_ST_CLO/4;
1844 lo = bcm2835_peri_read(paddr);
1845  
1846 paddr = bcm2835_st + BCM2835_ST_CHI/4;
1847 st = bcm2835_peri_read(paddr);
1848  
1849 /* Test for overflow */
1850 if (st == hi)
1851 {
1852 st <<= 32;
1853 st += lo;
1854 }
1855 else
1856 {
1857 st <<= 32;
1858 paddr = bcm2835_st + BCM2835_ST_CLO/4;
1859 st += bcm2835_peri_read(paddr);
1860 }
1861 return st;
1862 }
1863  
1864 /* Delays for the specified number of microseconds with offset */
1865 void bcm2835_st_delay(uint64_t offset_micros, uint64_t micros)
1866 {
1867 uint64_t compare = offset_micros + micros;
1868  
1869 while(bcm2835_st_read() < compare)
1870 ;
1871 }
1872  
1873 /* PWM */
1874  
1875 void bcm2835_pwm_set_clock(uint32_t divisor)
1876 {
1877 if ( bcm2835_clk == MAP_FAILED
1878 || bcm2835_pwm == MAP_FAILED)
1879 return; /* bcm2835_init() failed or not root */
1880  
1881 /* From Gerts code */
1882 divisor &= 0xfff;
1883 /* Stop PWM clock */
1884 bcm2835_peri_write(bcm2835_clk + BCM2835_PWMCLK_CNTL, BCM2835_PWM_PASSWRD | 0x01);
1885 bcm2835_delay(110); /* Prevents clock going slow */
1886 /* Wait for the clock to be not busy */
1887 while ((bcm2835_peri_read(bcm2835_clk + BCM2835_PWMCLK_CNTL) & 0x80) != 0)
1888 bcm2835_delay(1);
1889 /* set the clock divider and enable PWM clock */
1890 bcm2835_peri_write(bcm2835_clk + BCM2835_PWMCLK_DIV, BCM2835_PWM_PASSWRD | (divisor << 12));
1891 bcm2835_peri_write(bcm2835_clk + BCM2835_PWMCLK_CNTL, BCM2835_PWM_PASSWRD | 0x11); /* Source=osc and enable */
1892 }
1893  
1894 void bcm2835_pwm_set_mode(uint8_t channel, uint8_t markspace, uint8_t enabled)
1895 {
1896 if ( bcm2835_clk == MAP_FAILED
1897 || bcm2835_pwm == MAP_FAILED)
1898 return; /* bcm2835_init() failed or not root */
1899  
1900 uint32_t control = bcm2835_peri_read(bcm2835_pwm + BCM2835_PWM_CONTROL);
1901  
1902 if (channel == 0)
1903 {
1904 if (markspace)
1905 control |= BCM2835_PWM0_MS_MODE;
1906 else
1907 control &= ~BCM2835_PWM0_MS_MODE;
1908 if (enabled)
1909 control |= BCM2835_PWM0_ENABLE;
1910 else
1911 control &= ~BCM2835_PWM0_ENABLE;
1912 }
1913 else if (channel == 1)
1914 {
1915 if (markspace)
1916 control |= BCM2835_PWM1_MS_MODE;
1917 else
1918 control &= ~BCM2835_PWM1_MS_MODE;
1919 if (enabled)
1920 control |= BCM2835_PWM1_ENABLE;
1921 else
1922 control &= ~BCM2835_PWM1_ENABLE;
1923 }
1924  
1925 /* If you use the barrier here, wierd things happen, and the commands dont work */
1926 bcm2835_peri_write_nb(bcm2835_pwm + BCM2835_PWM_CONTROL, control);
1927 /* bcm2835_peri_write_nb(bcm2835_pwm + BCM2835_PWM_CONTROL, BCM2835_PWM0_ENABLE | BCM2835_PWM1_ENABLE | BCM2835_PWM0_MS_MODE | BCM2835_PWM1_MS_MODE); */
1928  
1929 }
1930  
1931 void bcm2835_pwm_set_range(uint8_t channel, uint32_t range)
1932 {
1933 if ( bcm2835_clk == MAP_FAILED
1934 || bcm2835_pwm == MAP_FAILED)
1935 return; /* bcm2835_init() failed or not root */
1936  
1937 if (channel == 0)
1938 bcm2835_peri_write_nb(bcm2835_pwm + BCM2835_PWM0_RANGE, range);
1939 else if (channel == 1)
1940 bcm2835_peri_write_nb(bcm2835_pwm + BCM2835_PWM1_RANGE, range);
1941 }
1942  
1943 void bcm2835_pwm_set_data(uint8_t channel, uint32_t data)
1944 {
1945 if ( bcm2835_clk == MAP_FAILED
1946 || bcm2835_pwm == MAP_FAILED)
1947 return; /* bcm2835_init() failed or not root */
1948  
1949 if (channel == 0)
1950 bcm2835_peri_write_nb(bcm2835_pwm + BCM2835_PWM0_DATA, data);
1951 else if (channel == 1)
1952 bcm2835_peri_write_nb(bcm2835_pwm + BCM2835_PWM1_DATA, data);
1953 }
1954  
1955 /* Allocate page-aligned memory. */
1956 void *malloc_aligned(size_t size)
1957 {
1958 void *mem;
1959 errno = posix_memalign(&mem, BCM2835_PAGE_SIZE, size);
1960 return (errno ? NULL : mem);
1961 }
1962  
1963 /* Map 'size' bytes starting at 'off' in file 'fd' to memory.
1964 // Return mapped address on success, MAP_FAILED otherwise.
1965 // On error print message.
1966 */
1967 static void *mapmem(const char *msg, size_t size, int fd, off_t off)
1968 {
1969 void *map = mmap(NULL, size, (PROT_READ | PROT_WRITE), MAP_SHARED, fd, off);
1970 if (map == MAP_FAILED)
1971 fprintf(stderr, "bcm2835_init: %s mmap failed: %s\n", msg, strerror(errno));
1972 return map;
1973 }
1974  
1975 static void unmapmem(void **pmem, size_t size)
1976 {
1977 if (*pmem == MAP_FAILED) return;
1978 munmap(*pmem, size);
1979 *pmem = MAP_FAILED;
1980 }
1981  
1982 /* Initialise this library. */
1983 int bcm2835_init(void)
1984 {
1985 int memfd;
1986 int ok;
1987 FILE *fp;
1988  
1989 if (debug)
1990 {
1991 bcm2835_peripherals = (uint32_t*)BCM2835_PERI_BASE;
1992  
1993 bcm2835_pads = bcm2835_peripherals + BCM2835_GPIO_PADS/4;
1994 bcm2835_clk = bcm2835_peripherals + BCM2835_CLOCK_BASE/4;
1995 bcm2835_gpio = bcm2835_peripherals + BCM2835_GPIO_BASE/4;
1996 bcm2835_pwm = bcm2835_peripherals + BCM2835_GPIO_PWM/4;
1997 bcm2835_spi0 = bcm2835_peripherals + BCM2835_SPI0_BASE/4;
1998 bcm2835_bsc0 = bcm2835_peripherals + BCM2835_BSC0_BASE/4;
1999 bcm2835_bsc1 = bcm2835_peripherals + BCM2835_BSC1_BASE/4;
2000 bcm2835_st = bcm2835_peripherals + BCM2835_ST_BASE/4;
2001 bcm2835_aux = bcm2835_peripherals + BCM2835_AUX_BASE/4;
2002 bcm2835_spi1 = bcm2835_peripherals + BCM2835_SPI1_BASE/4;
2003 /* BEB */
2004 bcm2835_smi = bcm2835_peripherals + BCM2835_SMI_BASE/4;
2005  
2006  
2007 return 1; /* Success */
2008 }
2009  
2010 /* Figure out the base and size of the peripheral address block
2011 // using the device-tree. Required for RPi2/3/4, optional for RPi 1
2012 */
2013 if ((fp = fopen(BMC2835_RPI2_DT_FILENAME , "rb")))
2014 {
2015 unsigned char buf[16];
2016 uint32_t base_address;
2017 uint32_t peri_size;
2018 if (fread(buf, 1, sizeof(buf), fp) >= 8)
2019 {
2020 base_address = (buf[4] << 24) |
2021 (buf[5] << 16) |
2022 (buf[6] << 8) |
2023 (buf[7] << 0);
2024  
2025 peri_size = (buf[8] << 24) |
2026 (buf[9] << 16) |
2027 (buf[10] << 8) |
2028 (buf[11] << 0);
2029  
2030 if (!base_address)
2031 {
2032 /* looks like RPI 4 */
2033 base_address = (buf[8] << 24) |
2034 (buf[9] << 16) |
2035 (buf[10] << 8) |
2036 (buf[11] << 0);
2037  
2038 peri_size = (buf[12] << 24) |
2039 (buf[13] << 16) |
2040 (buf[14] << 8) |
2041 (buf[15] << 0);
2042 }
2043 /* check for valid known range formats */
2044 if ((buf[0] == 0x7e) &&
2045 (buf[1] == 0x00) &&
2046 (buf[2] == 0x00) &&
2047 (buf[3] == 0x00) &&
2048 ((base_address == BCM2835_PERI_BASE) || (base_address == BCM2835_RPI2_PERI_BASE) || (base_address == BCM2835_RPI4_PERI_BASE)))
2049 {
2050 bcm2835_peripherals_base = (off_t)base_address;
2051 bcm2835_peripherals_size = (size_t)peri_size;
2052 if( base_address == BCM2835_RPI4_PERI_BASE )
2053 {
2054 pud_type_rpi4 = 1;
2055 }
2056 }
2057  
2058 }
2059  
2060 fclose(fp);
2061 }
2062 /* else we are prob on RPi 1 with BCM2835, and use the hardwired defaults */
2063  
2064 /* Now get ready to map the peripherals block
2065 * If we are not root, try for the new /dev/gpiomem interface and accept
2066 * the fact that we can only access GPIO
2067 * else try for the /dev/mem interface and get access to everything
2068 */
2069 memfd = -1;
2070 ok = 0;
2071 if (geteuid() == 0
2072 #ifdef BCM2835_HAVE_LIBCAP
2073 || bcm2835_has_capability(CAP_SYS_RAWIO)
2074 #endif
2075 )
2076 {
2077 /* Open the master /dev/mem device */
2078 if ((memfd = open("/dev/mem", O_RDWR | O_SYNC) ) < 0)
2079 {
2080 fprintf(stderr, "bcm2835_init: Unable to open /dev/mem: %s\n",
2081 strerror(errno)) ;
2082 goto exit;
2083 }
2084  
2085 /* Base of the peripherals block is mapped to VM */
2086 bcm2835_peripherals = mapmem("gpio", bcm2835_peripherals_size, memfd, bcm2835_peripherals_base);
2087 if (bcm2835_peripherals == MAP_FAILED) goto exit;
2088  
2089 /* Now compute the base addresses of various peripherals,
2090 // which are at fixed offsets within the mapped peripherals block
2091 // Caution: bcm2835_peripherals is uint32_t*, so divide offsets by 4
2092 */
2093 bcm2835_gpio = bcm2835_peripherals + BCM2835_GPIO_BASE/4;
2094 bcm2835_pwm = bcm2835_peripherals + BCM2835_GPIO_PWM/4;
2095 bcm2835_clk = bcm2835_peripherals + BCM2835_CLOCK_BASE/4;
2096 bcm2835_pads = bcm2835_peripherals + BCM2835_GPIO_PADS/4;
2097 bcm2835_spi0 = bcm2835_peripherals + BCM2835_SPI0_BASE/4;
2098 bcm2835_bsc0 = bcm2835_peripherals + BCM2835_BSC0_BASE/4; /* I2C */
2099 bcm2835_bsc1 = bcm2835_peripherals + BCM2835_BSC1_BASE/4; /* I2C */
2100 bcm2835_st = bcm2835_peripherals + BCM2835_ST_BASE/4;
2101 bcm2835_aux = bcm2835_peripherals + BCM2835_AUX_BASE/4;
2102 bcm2835_spi1 = bcm2835_peripherals + BCM2835_SPI1_BASE/4;
2103 /* BEB */
2104 bcm2835_smi = bcm2835_peripherals + BCM2835_SMI_BASE/4;
2105  
2106  
2107 ok = 1;
2108 }
2109 else
2110 {
2111 /* Not root, try /dev/gpiomem */
2112 /* Open the master /dev/mem device */
2113 if ((memfd = open("/dev/gpiomem", O_RDWR | O_SYNC) ) < 0)
2114 {
2115 fprintf(stderr, "bcm2835_init: Unable to open /dev/gpiomem: %s\n",
2116 strerror(errno)) ;
2117 goto exit;
2118 }
2119  
2120 /* Base of the peripherals block is mapped to VM */
2121 bcm2835_peripherals_base = 0;
2122 bcm2835_peripherals = mapmem("gpio", bcm2835_peripherals_size, memfd, bcm2835_peripherals_base);
2123 if (bcm2835_peripherals == MAP_FAILED) goto exit;
2124 bcm2835_gpio = bcm2835_peripherals;
2125 ok = 1;
2126 }
2127  
2128 exit:
2129 if (memfd >= 0)
2130 close(memfd);
2131  
2132 if (!ok)
2133 bcm2835_close();
2134  
2135 return ok;
2136 }
2137  
2138 /* Close this library and deallocate everything */
2139 int bcm2835_close(void)
2140 {
2141 if (debug) return 1; /* Success */
2142  
2143 unmapmem((void**) &bcm2835_peripherals, bcm2835_peripherals_size);
2144 bcm2835_peripherals = MAP_FAILED;
2145 bcm2835_gpio = MAP_FAILED;
2146 bcm2835_pwm = MAP_FAILED;
2147 bcm2835_clk = MAP_FAILED;
2148 bcm2835_pads = MAP_FAILED;
2149 bcm2835_spi0 = MAP_FAILED;
2150 bcm2835_bsc0 = MAP_FAILED;
2151 bcm2835_bsc1 = MAP_FAILED;
2152 bcm2835_st = MAP_FAILED;
2153 bcm2835_aux = MAP_FAILED;
2154 bcm2835_spi1 = MAP_FAILED;
2155 /* BEB */
2156 bcm2835_smi = MAP_FAILED;
2157  
2158 return 1; /* Success */
2159 }
2160  
2161 #ifdef BCM2835_TEST
2162 /* this is a simple test program that prints out what it will do rather than
2163 // actually doing it
2164 */
2165 int main(int argc, char **argv)
2166 {
2167 /* Be non-destructive */
2168 bcm2835_set_debug(1);
2169  
2170 if (!bcm2835_init())
2171 return 1;
2172  
2173 /* Configure some GPIO pins fo some testing
2174 // Set RPI pin P1-11 to be an output
2175 */
2176 bcm2835_gpio_fsel(RPI_GPIO_P1_11, BCM2835_GPIO_FSEL_OUTP);
2177 /* Set RPI pin P1-15 to be an input */
2178 bcm2835_gpio_fsel(RPI_GPIO_P1_15, BCM2835_GPIO_FSEL_INPT);
2179 /* with a pullup */
2180 bcm2835_gpio_set_pud(RPI_GPIO_P1_15, BCM2835_GPIO_PUD_UP);
2181 /* And a low detect enable */
2182 bcm2835_gpio_len(RPI_GPIO_P1_15);
2183 /* and input hysteresis disabled on GPIOs 0 to 27 */
2184 bcm2835_gpio_set_pad(BCM2835_PAD_GROUP_GPIO_0_27, BCM2835_PAD_SLEW_RATE_UNLIMITED|BCM2835_PAD_DRIVE_8mA);
2185  
2186 #if 1
2187 /* Blink */
2188 while (1)
2189 {
2190 /* Turn it on */
2191 bcm2835_gpio_write(RPI_GPIO_P1_11, HIGH);
2192  
2193 /* wait a bit */
2194 bcm2835_delay(500);
2195  
2196 /* turn it off */
2197 bcm2835_gpio_write(RPI_GPIO_P1_11, LOW);
2198  
2199 /* wait a bit */
2200 bcm2835_delay(500);
2201 }
2202 #endif
2203  
2204 #if 0
2205 /* Read input */
2206 while (1)
2207 {
2208 /* Read some data */
2209 uint8_t value = bcm2835_gpio_lev(RPI_GPIO_P1_15);
2210 printf("read from pin 15: %d\n", value);
2211  
2212 /* wait a bit */
2213 bcm2835_delay(500);
2214 }
2215 #endif
2216  
2217 #if 0
2218 /* Look for a low event detection
2219 // eds will be set whenever pin 15 goes low
2220 */
2221 while (1)
2222 {
2223 if (bcm2835_gpio_eds(RPI_GPIO_P1_15))
2224 {
2225 /* Now clear the eds flag by setting it to 1 */
2226 bcm2835_gpio_set_eds(RPI_GPIO_P1_15);
2227 printf("low event detect for pin 15\n");
2228 }
2229  
2230 /* wait a bit */
2231 bcm2835_delay(500);
2232 }
2233 #endif
2234  
2235 if (!bcm2835_close())
2236 return 1;
2237  
2238 return 0;
2239 }
2240 #endif
2241  
2242  
2243