u8g_com_io.c 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452
  1. /*
  2. u8g_com_io.c
  3. abstraction layer for low level i/o
  4. Universal 8bit Graphics Library
  5. Copyright (c) 2012, olikraus@gmail.com
  6. All rights reserved.
  7. Redistribution and use in source and binary forms, with or without modification,
  8. are permitted provided that the following conditions are met:
  9. * Redistributions of source code must retain the above copyright notice, this list
  10. of conditions and the following disclaimer.
  11. * Redistributions in binary form must reproduce the above copyright notice, this
  12. list of conditions and the following disclaimer in the documentation and/or other
  13. materials provided with the distribution.
  14. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
  15. CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
  16. INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  17. MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  18. DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
  19. CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  20. SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  21. NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  22. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  23. CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  24. STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  25. ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  26. ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27. Update for ATOMIC operation done (01 Jun 2013)
  28. U8G_ATOMIC_OR(ptr, val)
  29. U8G_ATOMIC_AND(ptr, val)
  30. U8G_ATOMIC_START();
  31. U8G_ATOMIC_END();
  32. uint8_t u8g_Pin(uint8_t port, uint8_t bitpos) Convert to internal number: AVR: port*8+bitpos, ARM: port*16+bitpos
  33. void u8g_SetPinOutput(uint8_t internal_pin_number)
  34. void u8g_SetPinInput(uint8_t internal_pin_number)
  35. void u8g_SetPinLevel(uint8_t internal_pin_number, uint8_t level)
  36. uint8_t u8g_GetPinLevel(uint8_t internal_pin_number)
  37. */
  38. #include "u8g.h"
  39. #if defined(__AVR__)
  40. #include <avr/interrupt.h>
  41. #include <avr/io.h>
  42. typedef volatile uint8_t * IO_PTR;
  43. /* create internal pin number */
  44. uint8_t u8g_Pin(uint8_t port, uint8_t bitpos)
  45. {
  46. port <<= 3;
  47. port += bitpos;
  48. return port;
  49. }
  50. #if defined(__AVR_XMEGA__)
  51. const IO_PTR u8g_avr_ddr_P[] PROGMEM = {
  52. #ifdef PORTA
  53. &PORTA.DIR,
  54. #else
  55. 0,
  56. #endif
  57. &PORTB.DIR,
  58. #ifdef PORTC
  59. &PORTC.DIR,
  60. #ifdef PORTD
  61. &PORTD.DIR,
  62. #ifdef PORTE
  63. &PORTE.DIR,
  64. #ifdef PORTF
  65. &PORTF.DIR,
  66. #ifdef PORTR
  67. &PORTR.DIR,
  68. #endif
  69. #endif
  70. #endif
  71. #endif
  72. #endif
  73. };
  74. const IO_PTR u8g_avr_port_P[] PROGMEM = {
  75. #ifdef PORTA
  76. &PORTA.OUT,
  77. #else
  78. 0,
  79. #endif
  80. &PORTB.OUT,
  81. #ifdef PORTC
  82. &PORTC.OUT,
  83. #ifdef PORTD
  84. &PORTD.OUT,
  85. #ifdef PORTE
  86. &PORTE.OUT,
  87. #ifdef PORTF
  88. &PORTF.OUT,
  89. #ifdef PORTR
  90. &PORTR.OUT,
  91. #endif
  92. #endif
  93. #endif
  94. #endif
  95. #endif
  96. };
  97. const IO_PTR u8g_avr_pin_P[] PROGMEM = {
  98. #ifdef PORTA
  99. &PORTA.IN,
  100. #else
  101. 0,
  102. #endif
  103. &PORTB.IN,
  104. #ifdef PORTC
  105. &PORTC.IN,
  106. #ifdef PORTD
  107. &PORTD.IN,
  108. #ifdef PORTE
  109. &PORTE.IN,
  110. #ifdef PORTF
  111. &PORTF.IN,
  112. #ifdef PORTR
  113. &PORTR.IN,
  114. #endif
  115. #endif
  116. #endif
  117. #endif
  118. #endif
  119. };
  120. #else
  121. const IO_PTR u8g_avr_ddr_P[] PROGMEM = {
  122. #ifdef DDRA
  123. &DDRA,
  124. #else
  125. 0,
  126. #endif
  127. &DDRB,
  128. #ifdef DDRC
  129. &DDRC,
  130. #ifdef DDRD
  131. &DDRD,
  132. #ifdef DDRE
  133. &DDRE,
  134. #ifdef DDRF
  135. &DDRF,
  136. #ifdef DDRG
  137. &DDRG,
  138. #ifdef DDRH
  139. &DDRH,
  140. #endif
  141. #endif
  142. #endif
  143. #endif
  144. #endif
  145. #endif
  146. };
  147. const IO_PTR u8g_avr_port_P[] PROGMEM = {
  148. #ifdef PORTA
  149. &PORTA,
  150. #else
  151. 0,
  152. #endif
  153. &PORTB,
  154. #ifdef PORTC
  155. &PORTC,
  156. #ifdef PORTD
  157. &PORTD,
  158. #ifdef PORTE
  159. &PORTE,
  160. #ifdef PORTF
  161. &PORTF,
  162. #ifdef PORTG
  163. &PORTG,
  164. #ifdef PORTH
  165. &PORTH,
  166. #endif
  167. #endif
  168. #endif
  169. #endif
  170. #endif
  171. #endif
  172. };
  173. const IO_PTR u8g_avr_pin_P[] PROGMEM = {
  174. #ifdef PINA
  175. &PINA,
  176. #else
  177. 0,
  178. #endif
  179. &PINB,
  180. #ifdef PINC
  181. &PINC,
  182. #ifdef PIND
  183. &PIND,
  184. #ifdef PINE
  185. &PINE,
  186. #ifdef PINF
  187. &PINF,
  188. #ifdef PING
  189. &PING,
  190. #ifdef PINH
  191. &PINH,
  192. #endif
  193. #endif
  194. #endif
  195. #endif
  196. #endif
  197. #endif
  198. };
  199. #endif
  200. static volatile uint8_t *u8g_get_avr_io_ptr(const IO_PTR *base, uint8_t offset)
  201. {
  202. volatile uint8_t * tmp;
  203. base += offset;
  204. memcpy_P(&tmp, base, sizeof(volatile uint8_t * PROGMEM));
  205. return tmp;
  206. }
  207. /* set direction to output of the specified pin (internal pin number) */
  208. void u8g_SetPinOutput(uint8_t internal_pin_number)
  209. {
  210. *u8g_get_avr_io_ptr(u8g_avr_ddr_P, internal_pin_number>>3) |= _BV(internal_pin_number&7);
  211. }
  212. void u8g_SetPinInput(uint8_t internal_pin_number)
  213. {
  214. *u8g_get_avr_io_ptr(u8g_avr_ddr_P, internal_pin_number>>3) &= ~_BV(internal_pin_number&7);
  215. }
  216. void u8g_SetPinLevel(uint8_t internal_pin_number, uint8_t level)
  217. {
  218. volatile uint8_t * tmp = u8g_get_avr_io_ptr(u8g_avr_port_P, internal_pin_number>>3);
  219. if ( level == 0 )
  220. {
  221. U8G_ATOMIC_AND(tmp, ~_BV(internal_pin_number&7));
  222. // *tmp &= ~_BV(internal_pin_number&7);
  223. }
  224. else
  225. {
  226. U8G_ATOMIC_OR(tmp, _BV(internal_pin_number&7));
  227. //*tmp |= _BV(internal_pin_number&7);
  228. }
  229. }
  230. uint8_t u8g_GetPinLevel(uint8_t internal_pin_number)
  231. {
  232. volatile uint8_t * tmp = u8g_get_avr_io_ptr(u8g_avr_pin_P, internal_pin_number>>3);
  233. if ( ((*tmp) & _BV(internal_pin_number&7)) != 0 )
  234. return 1;
  235. return 0;
  236. }
  237. #elif defined (__MSP430__)
  238. #include <msp430.h>
  239. typedef volatile uint8_t * IO_PTR;
  240. // MSP430 F5XXX / F6XXX series.
  241. const IO_PTR u8g_msp_ddr_P[] PROGMEM = {
  242. &P1DIR
  243. ,&P2DIR
  244. ,&P3DIR
  245. ,&P4DIR
  246. ,&P5DIR
  247. ,&P6DIR
  248. ,&P7DIR
  249. ,&P8DIR
  250. #if defined (__MSP430_HAS_PORT9_R__)
  251. ,&P9DIR
  252. #if defined (__MSP430_HAS_PORT10_R__)
  253. ,&P10DIR
  254. #endif
  255. #endif
  256. };
  257. const IO_PTR u8g_msp_port_P[] PROGMEM = {
  258. &P1OUT
  259. ,&P2OUT
  260. ,&P3OUT
  261. ,&P4OUT
  262. ,&P5OUT
  263. ,&P6OUT
  264. ,&P7OUT
  265. ,&P8OUT
  266. #if defined (__MSP430_HAS_PORT9_R__)
  267. ,&P9OUT
  268. #if defined (__MSP430_HAS_PORT10_R__)
  269. ,&P10OUT
  270. #endif
  271. #endif
  272. };
  273. const IO_PTR u8g_msp_pin_P[] PROGMEM = {
  274. &P1IN
  275. ,&P2IN
  276. ,&P3IN
  277. ,&P4IN
  278. ,&P5IN
  279. ,&P6IN
  280. ,&P7IN
  281. ,&P8IN
  282. #if defined (__MSP430_HAS_PORT9_R__)
  283. ,&P9IN
  284. #if defined (__MSP430_HAS_PORT10_R__)
  285. ,&P10IN
  286. #endif
  287. #endif
  288. };
  289. uint8_t u8g_Pin(uint8_t port, uint8_t bitpos)
  290. {
  291. port <<= 3;
  292. port += bitpos;
  293. return port;
  294. }
  295. void u8g_SetPinOutput(uint8_t internal_pin_number)
  296. {
  297. uint8_t port = (internal_pin_number >> 3)-1;
  298. uint8_t output = 1 << (internal_pin_number & 0x07);
  299. *u8g_msp_ddr_P[port] |= output;
  300. }
  301. void u8g_SetPinInput(uint8_t internal_pin_number)
  302. {
  303. uint8_t port = (internal_pin_number >> 3)-1;
  304. *u8g_msp_ddr_P[port] &= ~(1 << (internal_pin_number & 0x07));
  305. }
  306. void u8g_SetPinLevel(uint8_t internal_pin_number, uint8_t level)
  307. {
  308. uint8_t port = (internal_pin_number >> 3)-1;
  309. if (level == 0)
  310. {
  311. *u8g_msp_port_P[port] &= ~(1 << (internal_pin_number & 0x07));
  312. }
  313. else
  314. {
  315. *u8g_msp_port_P[port]|= (1 << (internal_pin_number & 0x07));
  316. }
  317. }
  318. uint8_t u8g_GetPinLevel(uint8_t internal_pin_number)
  319. {
  320. uint8_t port = (internal_pin_number >> 3)-1;
  321. uint8_t tmp = *u8g_msp_pin_P[port];
  322. if (tmp & (1 << (internal_pin_number & 0x07)))
  323. {
  324. return 1;
  325. }
  326. return 0;
  327. }
  328. #elif defined(U8G_RASPBERRY_PI)
  329. #include <wiringPi.h>
  330. //#include "/usr/local/include/wiringPi.h"
  331. void u8g_SetPinOutput(uint8_t internal_pin_number) {
  332. pinMode(internal_pin_number, OUTPUT);
  333. }
  334. void u8g_SetPinInput(uint8_t internal_pin_number) {
  335. pinMode(internal_pin_number, INPUT);
  336. }
  337. void u8g_SetPinLevel(uint8_t internal_pin_number, uint8_t level) {
  338. digitalWrite(internal_pin_number, level);
  339. }
  340. uint8_t u8g_GetPinLevel(uint8_t internal_pin_number) {
  341. return digitalRead(internal_pin_number);
  342. }
  343. #else
  344. /* convert "port" and "bitpos" to internal pin number */
  345. uint8_t u8g_Pin(uint8_t port, uint8_t bitpos)
  346. {
  347. port <<= 3;
  348. port += bitpos;
  349. return port;
  350. }
  351. void u8g_SetPinOutput(uint8_t internal_pin_number)
  352. {
  353. }
  354. void u8g_SetPinInput(uint8_t internal_pin_number)
  355. {
  356. }
  357. void u8g_SetPinLevel(uint8_t internal_pin_number, uint8_t level)
  358. {
  359. }
  360. uint8_t u8g_GetPinLevel(uint8_t internal_pin_number)
  361. {
  362. return 0;
  363. }
  364. #endif
  365. #if defined(U8G_WITH_PINLIST)
  366. void u8g_SetPIOutput(u8g_t *u8g, uint8_t pi)
  367. {
  368. uint8_t pin;
  369. pin = u8g->pin_list[pi];
  370. if ( pin != U8G_PIN_NONE )
  371. u8g_SetPinOutput(pin);
  372. }
  373. void u8g_SetPILevel(u8g_t *u8g, uint8_t pi, uint8_t level)
  374. {
  375. uint8_t pin;
  376. pin = u8g->pin_list[pi];
  377. if ( pin != U8G_PIN_NONE )
  378. u8g_SetPinLevel(pin, level);
  379. }
  380. #else /* defined(U8G_WITH_PINLIST) */
  381. void u8g_SetPIOutput(u8g_t *u8g, uint8_t pi)
  382. {
  383. }
  384. void u8g_SetPILevel(u8g_t *u8g, uint8_t pi, uint8_t level)
  385. {
  386. }
  387. #endif /* defined(U8G_WITH_PINLIST) */