pca9532.c 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  1. /*****************************************************************************
  2. *
  3. * Copyright(C) 2011, Embedded Artists AB
  4. * All rights reserved.
  5. *
  6. ******************************************************************************
  7. * Software that is described herein is for illustrative purposes only
  8. * which provides customers with programming information regarding the
  9. * products. This software is supplied "AS IS" without any warranties.
  10. * Embedded Artists AB assumes no responsibility or liability for the
  11. * use of the software, conveys no license or title under any patent,
  12. * copyright, or mask work right to the product. Embedded Artists AB
  13. * reserves the right to make changes in the software without
  14. * notification. Embedded Artists AB also make no representation or
  15. * warranty that such application will be suitable for the specified
  16. * use without further testing or modification.
  17. *****************************************************************************/
  18. /*
  19. * NOTE: I2C must have been initialized before calling any functions in this
  20. * file.
  21. */
  22. /******************************************************************************
  23. * Includes
  24. *****************************************************************************/
  25. //#include "board.h"
  26. #include "chip.h"
  27. #include "pca9532.h"
  28. /******************************************************************************
  29. * Defines and typedefs
  30. *****************************************************************************/
  31. #define I2C_PORT (LPC_I2C0)
  32. #define LS_MODE_ON 0x01
  33. #define LS_MODE_BLINK0 0x02
  34. #define LS_MODE_BLINK1 0x03
  35. /******************************************************************************
  36. * External global variables
  37. *****************************************************************************/
  38. /******************************************************************************
  39. * Local variables
  40. *****************************************************************************/
  41. static uint16_t blink0Shadow = 0;
  42. static uint16_t blink1Shadow = 0;
  43. static uint16_t ledStateShadow = 0;
  44. /******************************************************************************
  45. * Local Functions
  46. *****************************************************************************/
  47. static Status I2CWrite(uint32_t addr, uint8_t* buf, uint32_t len)
  48. {
  49. I2CM_XFER_T i2cData;
  50. i2cData.slaveAddr = addr;
  51. i2cData.options = 0;
  52. i2cData.status = 0;
  53. i2cData.txBuff = buf;
  54. i2cData.txSz = len;
  55. i2cData.rxBuff = NULL;
  56. i2cData.rxSz = 0;
  57. if (Chip_I2CM_XferBlocking(LPC_I2C0, &i2cData) == 0) {
  58. return ERROR;
  59. }
  60. return SUCCESS;
  61. }
  62. static Status I2CRead(uint32_t addr, uint8_t* buf, uint32_t len)
  63. {
  64. I2CM_XFER_T i2cData;
  65. i2cData.slaveAddr = addr;
  66. i2cData.options = 0;
  67. i2cData.status = 0;
  68. i2cData.txBuff = NULL;
  69. i2cData.txSz = 0;
  70. i2cData.rxBuff = buf;
  71. i2cData.rxSz = len;
  72. if (Chip_I2CM_XferBlocking(LPC_I2C0, &i2cData) == 0) {
  73. return ERROR;
  74. }
  75. return SUCCESS;
  76. }
  77. static void setLsStates(uint16_t states, uint8_t* ls, uint8_t mode)
  78. {
  79. #define IS_LED_SET(bit, x) ( ( ((x) & (bit)) != 0 ) ? 1 : 0 )
  80. int i = 0;
  81. for (i = 0; i < 4; i++) {
  82. ls[i] |= ( (IS_LED_SET(0x0001, states)*mode << 0)
  83. | (IS_LED_SET(0x0002, states)*mode << 2)
  84. | (IS_LED_SET(0x0004, states)*mode << 4)
  85. | (IS_LED_SET(0x0008, states)*mode << 6) );
  86. states >>= 4;
  87. }
  88. }
  89. static void setLeds(void)
  90. {
  91. uint8_t buf[5];
  92. uint8_t ls[4] = {0,0,0,0};
  93. uint16_t states = ledStateShadow;
  94. /* LEDs in On/Off state */
  95. setLsStates(states, ls, LS_MODE_ON);
  96. /* set the LEDs that should blink */
  97. setLsStates(blink0Shadow, ls, LS_MODE_BLINK0);
  98. setLsStates(blink1Shadow, ls, LS_MODE_BLINK1);
  99. buf[0] = PCA9532_LS0 | PCA9532_AUTO_INC;
  100. buf[1] = ls[0];
  101. buf[2] = ls[1];
  102. buf[3] = ls[2];
  103. buf[4] = ls[3];
  104. I2CWrite(PCA9532_I2C_ADDR, buf, 5);
  105. }
  106. /******************************************************************************
  107. * Public Functions
  108. *****************************************************************************/
  109. /******************************************************************************
  110. *
  111. * Description:
  112. * Initialize the PCA9532 Device
  113. *
  114. *****************************************************************************/
  115. void pca9532_init (void)
  116. {
  117. /* nothing to initialize */
  118. }
  119. /******************************************************************************
  120. *
  121. * Description:
  122. * Get the LED states
  123. *
  124. * Params:
  125. * [in] shadow - TRUE if the states should be retrieved from the shadow
  126. * variables. The shadow variable are updated when any
  127. * of setLeds, setBlink0Leds and/or setBlink1Leds are
  128. * called.
  129. *
  130. * FALSE if the state should be retrieved from the PCA9532
  131. * device. A blinkin LED may be reported as on or off
  132. * depending on the state when calling the function.
  133. *
  134. * Returns:
  135. * A mask where a 1 indicates that a LED is on (or blinking).
  136. *
  137. *****************************************************************************/
  138. uint16_t pca9532_getLedState (uint32_t shadow)
  139. {
  140. uint8_t buf[2];
  141. uint16_t ret = 0;
  142. if (shadow) {
  143. /* a blink LED is reported as on*/
  144. ret = (ledStateShadow | blink0Shadow | blink1Shadow);
  145. }
  146. else {
  147. /*
  148. * A blinking LED may be reported as on or off depending on
  149. * its state when reading the Input register.
  150. */
  151. buf[0] = PCA9532_INPUT0;
  152. I2CWrite(PCA9532_I2C_ADDR, buf, 1);
  153. I2CRead(PCA9532_I2C_ADDR, buf, 1);
  154. ret = buf[0];
  155. buf[0] = PCA9532_INPUT1;
  156. I2CWrite(PCA9532_I2C_ADDR, buf, 1);
  157. I2CRead(PCA9532_I2C_ADDR, buf, 1);
  158. ret |= (buf[0] << 8);
  159. /* invert since LEDs are active low */
  160. ret = ((~ret) & 0xFFFF);
  161. }
  162. return (ret & ~PCA9532_NOT_USED);
  163. }
  164. /******************************************************************************
  165. *
  166. * Description:
  167. * Set LED states (on or off).
  168. *
  169. * Params:
  170. * [in] ledOnMask - The LEDs that should be turned on. This mask has
  171. * priority over ledOffMask
  172. * [in] ledOffMask - The LEDs that should be turned off.
  173. *
  174. *****************************************************************************/
  175. void pca9532_setLeds (uint16_t ledOnMask, uint16_t ledOffMask)
  176. {
  177. /* turn off leds */
  178. ledStateShadow &= (~(ledOffMask) & 0xffff);
  179. /* ledOnMask has priority over ledOffMask */
  180. ledStateShadow |= ledOnMask;
  181. /* turn off blinking */
  182. blink0Shadow &= (~(ledOffMask) & 0xffff);
  183. blink1Shadow &= (~(ledOffMask) & 0xffff);
  184. setLeds();
  185. }
  186. /******************************************************************************
  187. *
  188. * Description:
  189. * Set the blink period for PWM0. Valid values are 0 - 255 where 0
  190. * means 152 Hz and 255 means 0.59 Hz. A value of 151 means 1 Hz.
  191. *
  192. * Params:
  193. * [in] period - the period for pwm0
  194. *
  195. *****************************************************************************/
  196. void pca9532_setBlink0Period(uint8_t period)
  197. {
  198. uint8_t buf[2];
  199. buf[0] = PCA9532_PSC0;
  200. buf[1] = period;
  201. I2CWrite(PCA9532_I2C_ADDR, buf, 2);
  202. }
  203. /******************************************************************************
  204. *
  205. * Description:
  206. * Set the duty cycle for PWM0. Valid values are 0 - 100. 25 means the LED
  207. * is on 25% of the period.
  208. *
  209. * Params:
  210. * [in] duty - duty cycle
  211. *
  212. *****************************************************************************/
  213. void pca9532_setBlink0Duty(uint8_t duty)
  214. {
  215. uint8_t buf[2];
  216. uint32_t tmp = duty;
  217. if (tmp > 100) {
  218. tmp = 100;
  219. }
  220. tmp = (256 * tmp)/100;
  221. buf[0] = PCA9532_PWM0;
  222. buf[1] = tmp;
  223. I2CWrite(PCA9532_I2C_ADDR, buf, 2);
  224. }
  225. /******************************************************************************
  226. *
  227. * Description:
  228. * Set the LEDs that should blink with rate and duty cycle from PWM0.
  229. * Blinking is turned off with pca9532_setLeds.
  230. *
  231. * Params:
  232. * [in] ledMask - LEDs that should blink.
  233. *
  234. *****************************************************************************/
  235. void pca9532_setBlink0Leds(uint16_t ledMask)
  236. {
  237. blink0Shadow |= ledMask;
  238. setLeds();
  239. }
  240. /******************************************************************************
  241. *
  242. * Description:
  243. * Set the blink period for PWM1. Valid values are 0 - 255 where 0
  244. * means 152 Hz and 255 means 0.59 Hz. A value of 151 means 1 Hz.
  245. *
  246. * Params:
  247. * [in] period - The period for PWM1
  248. *
  249. *****************************************************************************/
  250. void pca9532_setBlink1Period(uint8_t period)
  251. {
  252. uint8_t buf[2];
  253. buf[0] = PCA9532_PSC1;
  254. buf[1] = period;
  255. I2CWrite(PCA9532_I2C_ADDR, buf, 2);
  256. }
  257. /******************************************************************************
  258. *
  259. * Description:
  260. * Set the duty cycle for PWM1. Valid values are 0 - 100. 25 means the LED
  261. * is on 25% of the period.
  262. *
  263. * Params:
  264. * [in] duty - duty cycle.
  265. *
  266. *****************************************************************************/
  267. void pca9532_setBlink1Duty(uint8_t duty)
  268. {
  269. uint8_t buf[2];
  270. uint32_t tmp = duty;
  271. if (tmp > 100) {
  272. tmp = 100;
  273. }
  274. tmp = (256 * tmp)/100;
  275. buf[0] = PCA9532_PWM1;
  276. buf[1] = tmp;
  277. I2CWrite(PCA9532_I2C_ADDR, buf, 2);
  278. }
  279. /******************************************************************************
  280. *
  281. * Description:
  282. * Set the LEDs that should blink with rate and duty cycle from PWM1.
  283. * Blinking is turned off with pca9532_setLeds.
  284. *
  285. * Params:
  286. * [in] ledMask - LEDs that should blink.
  287. *
  288. *****************************************************************************/
  289. void pca9532_setBlink1Leds(uint16_t ledMask)
  290. {
  291. blink1Shadow |= ledMask;
  292. setLeds();
  293. }