PageRenderTime 135ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 0ms

/sw/airborne/lisa/test/lisa_test_adxl345_dma.c

https://bitbucket.org/tamasszabo/paparazzi_mavlink
C | 185 lines | 127 code | 30 blank | 28 comment | 8 complexity | 651a88057e4e0d5917f869d591b1b4c8 MD5 | raw file
  1. /*
  2. * Copyright (C) 2009 Antoine Drouin <poinix@gmail.com>
  3. *
  4. * This file is part of paparazzi.
  5. *
  6. * paparazzi is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2, or (at your option)
  9. * any later version.
  10. *
  11. * paparazzi is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with paparazzi; see the file COPYING. If not, write to
  18. * the Free Software Foundation, 59 Temple Place - Suite 330,
  19. * Boston, MA 02111-1307, USA.
  20. */
  21. #include "libopencm3/stm32/f1/gpio.h"
  22. #include "libopencm3/stm32/f1/nvic.h"
  23. #include "libopencm3/stm32/exti.h"
  24. #include BOARD_CONFIG
  25. #include "mcu.h"
  26. #include "mcu_periph/sys_time.h"
  27. #include "mcu_periph/uart.h"
  28. #include "subsystems/datalink/downlink.h"
  29. #include "mcu_periph/spi.h"
  30. #include "peripherals/adxl345_regs.h"
  31. #include "led.h"
  32. #ifndef ADXL345_SLAVE_IDX
  33. #define ADXL345_SLAVE_IDX SPI_SLAVE2
  34. #endif
  35. #ifndef ADXL345_SPI_DEV
  36. #define ADXL345_SPI_DEV spi2
  37. #endif
  38. #define CONFIGURED 6
  39. static uint8_t acc_status=0;
  40. static volatile uint8_t acc_data_available = FALSE;
  41. static volatile uint8_t foo = FALSE;
  42. struct spi_transaction adxl345_spi_trans;
  43. static uint8_t dma_tx_buf[7];
  44. static uint8_t dma_rx_buf[7];
  45. static void write_to_reg(uint8_t addr, uint8_t val);
  46. static void adxl345_trans_cb(struct spi_transaction *trans);
  47. static inline void init_adxl345_spi_trans( void );
  48. static void read_data(void);
  49. static inline void main_init( void );
  50. static inline void main_periodic_task( void );
  51. static inline void main_event_task( void );
  52. void hw_init(void);
  53. int main(void) {
  54. main_init();
  55. while(1) {
  56. if (sys_time_check_and_ack_timer(0))
  57. main_periodic_task();
  58. main_event_task();
  59. }
  60. return 0;
  61. }
  62. static inline void main_init( void ) {
  63. mcu_init();
  64. hw_init();
  65. init_adxl345_spi_trans();
  66. sys_time_register_timer((1./PERIODIC_FREQUENCY), NULL);
  67. }
  68. static inline void main_periodic_task( void ) {
  69. RunOnceEvery(10,
  70. {
  71. DOWNLINK_SEND_ALIVE(DefaultChannel, DefaultDevice, 16, MD5SUM);
  72. LED_PERIODIC();
  73. });
  74. if (acc_status != CONFIGURED) {
  75. /* set data rate to 800Hz */
  76. write_to_reg(ADXL345_REG_BW_RATE, 0x0D);
  77. /* enable data ready interrupt */
  78. write_to_reg(ADXL345_REG_INT_ENABLE, 1<<7);
  79. /* Enable full res and interrupt active low */
  80. write_to_reg(ADXL345_REG_DATA_FORMAT, 1<<3|1<<5);
  81. /* reads data once to bring interrupt line up */
  82. /* switch to measurememnt mode */
  83. write_to_reg(ADXL345_REG_POWER_CTL, 1<<3);
  84. read_data();
  85. acc_status = CONFIGURED;
  86. }
  87. else {
  88. read_data();
  89. }
  90. }
  91. #define Int16FromBuf(_buf,_idx) ((int16_t)((_buf[_idx+1]<<8) | _buf[_idx]))
  92. static inline void main_event_task( void ) {
  93. if (foo) {
  94. foo = FALSE;
  95. RunOnceEvery(100, {LED_TOGGLE(3);});
  96. }
  97. if (acc_status >= CONFIGURED && acc_data_available) {
  98. acc_data_available = FALSE;
  99. int16_t ax = Int16FromBuf(dma_rx_buf, 1);
  100. int16_t ay = Int16FromBuf(dma_rx_buf, 3);
  101. int16_t az = Int16FromBuf(dma_rx_buf, 5);
  102. int32_t iax = ax;
  103. int32_t iay = ay;
  104. int32_t iaz = az;
  105. RunOnceEvery(10, {DOWNLINK_SEND_IMU_ACCEL_RAW(DefaultChannel, DefaultDevice, &iax, &iay, &iaz);});
  106. }
  107. }
  108. static void write_to_reg(uint8_t addr, uint8_t val) {
  109. adxl345_spi_trans.output_length = 2;
  110. adxl345_spi_trans.input_length = 0;
  111. dma_tx_buf[0] = addr;
  112. dma_tx_buf[1] = val;
  113. spi_submit(&(ADXL345_SPI_DEV), &adxl345_spi_trans);
  114. // FIXME: no busy waiting! if really needed add a timeout!!!!
  115. while(adxl345_spi_trans.status != SPITransSuccess);
  116. }
  117. static void read_data(void) {
  118. adxl345_spi_trans.output_length = 1;
  119. adxl345_spi_trans.input_length = 7;
  120. dma_tx_buf[0] = (1<<7|1<<6|ADXL345_REG_DATA_X0);
  121. spi_submit(&(ADXL345_SPI_DEV), &adxl345_spi_trans);
  122. }
  123. static void adxl345_trans_cb( struct spi_transaction *trans ) {
  124. acc_data_available = TRUE;
  125. }
  126. static inline void init_adxl345_spi_trans( void ) {
  127. adxl345_spi_trans.select = SPISelectUnselect;
  128. adxl345_spi_trans.cpol = SPICpolIdleHigh;
  129. adxl345_spi_trans.cpha = SPICphaEdge2;
  130. adxl345_spi_trans.dss = SPIDss8bit;
  131. adxl345_spi_trans.bitorder = SPIMSBFirst;
  132. adxl345_spi_trans.cdiv = SPIDiv64;
  133. adxl345_spi_trans.slave_idx = ADXL345_SLAVE_IDX;
  134. adxl345_spi_trans.output_length = 7;
  135. adxl345_spi_trans.input_length = 7;
  136. adxl345_spi_trans.after_cb = adxl345_trans_cb;
  137. adxl345_spi_trans.input_buf = &dma_rx_buf[0];
  138. adxl345_spi_trans.output_buf = &dma_tx_buf[0];
  139. }
  140. void hw_init(void) {
  141. /* configure external interrupt exti2 on PB2( accel int ) */
  142. rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPBEN | RCC_APB2ENR_AFIOEN);
  143. gpio_set_mode(GPIOB, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, GPIO2);
  144. exti_select_source(EXTI2, GPIOB);
  145. exti_set_trigger(EXTI2, EXTI_TRIGGER_FALLING);
  146. exti_enable_request(EXTI2);
  147. nvic_set_priority(NVIC_EXTI2_IRQ, 0xF);
  148. nvic_enable_irq(NVIC_EXTI2_IRQ);
  149. }
  150. void exti2_isr(void) {
  151. /* clear EXTI */
  152. exti_reset_request(EXTI2);
  153. LED_TOGGLE(2);
  154. foo = TRUE;
  155. }