adxl345.c 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. /*
  2. * Driver for Analog Devices ADXL345 accelerometer.
  3. *
  4. * Code based on BMP085 driver.
  5. */
  6. #include "module.h"
  7. #include "lauxlib.h"
  8. #include "platform.h"
  9. #include <stdlib.h>
  10. #include <string.h>
  11. static const uint32_t adxl345_i2c_id = 0;
  12. static const uint8_t adxl345_i2c_addr = 0x53;
  13. static uint8_t r8u(uint32_t id, uint8_t reg) {
  14. uint8_t ret;
  15. platform_i2c_send_start(id);
  16. platform_i2c_send_address(id, adxl345_i2c_addr, PLATFORM_I2C_DIRECTION_TRANSMITTER);
  17. platform_i2c_send_byte(id, reg);
  18. platform_i2c_send_stop(id);
  19. platform_i2c_send_start(id);
  20. platform_i2c_send_address(id, adxl345_i2c_addr, PLATFORM_I2C_DIRECTION_RECEIVER);
  21. ret = platform_i2c_recv_byte(id, 0);
  22. platform_i2c_send_stop(id);
  23. return ret;
  24. }
  25. static int adxl345_setup(lua_State* L) {
  26. uint8_t devid;
  27. devid = r8u(adxl345_i2c_id, 0x00);
  28. if (devid != 229) {
  29. return luaL_error(L, "device not found");
  30. }
  31. // Enable sensor
  32. platform_i2c_send_start(adxl345_i2c_id);
  33. platform_i2c_send_address(adxl345_i2c_id, adxl345_i2c_addr, PLATFORM_I2C_DIRECTION_TRANSMITTER);
  34. platform_i2c_send_byte(adxl345_i2c_id, 0x2D);
  35. platform_i2c_send_byte(adxl345_i2c_id, 0x08);
  36. platform_i2c_send_stop(adxl345_i2c_id);
  37. return 0;
  38. }
  39. static int adxl345_read(lua_State* L) {
  40. uint8_t data[6];
  41. int x,y,z;
  42. int i;
  43. platform_i2c_send_start(adxl345_i2c_id);
  44. platform_i2c_send_address(adxl345_i2c_id, adxl345_i2c_addr, PLATFORM_I2C_DIRECTION_TRANSMITTER);
  45. platform_i2c_send_byte(adxl345_i2c_id, 0x32);
  46. platform_i2c_send_start(adxl345_i2c_id);
  47. platform_i2c_send_address(adxl345_i2c_id, adxl345_i2c_addr, PLATFORM_I2C_DIRECTION_RECEIVER);
  48. for (i=0; i<5; i++) {
  49. data[i] = platform_i2c_recv_byte(adxl345_i2c_id, 1);
  50. }
  51. data[5] = platform_i2c_recv_byte(adxl345_i2c_id, 0);
  52. platform_i2c_send_stop(adxl345_i2c_id);
  53. x = (int16_t) ((data[1] << 8) | data[0]);
  54. y = (int16_t) ((data[3] << 8) | data[2]);
  55. z = (int16_t) ((data[5] << 8) | data[4]);
  56. lua_pushinteger(L, x);
  57. lua_pushinteger(L, y);
  58. lua_pushinteger(L, z);
  59. return 3;
  60. }
  61. LROT_BEGIN(adxl345)
  62. LROT_FUNCENTRY( read, adxl345_read )
  63. LROT_FUNCENTRY( setup, adxl345_setup )
  64. LROT_END( adxl345, NULL, 0 )
  65. NODEMCU_MODULE(ADXL345, "adxl345", adxl345, NULL);