bcm2835.c 60 KB

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