RCInput_RPI.h 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. #pragma once
  2. #include "AP_HAL_Linux.h"
  3. #include "RCInput.h"
  4. #include <signal.h>
  5. #include <pthread.h>
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <unistd.h>
  9. #include <string.h>
  10. #include <errno.h>
  11. #include <stdarg.h>
  12. #include <stdint.h>
  13. #include <signal.h>
  14. #include <time.h>
  15. #include <sys/time.h>
  16. #include <sys/types.h>
  17. #include <sys/stat.h>
  18. #include <fcntl.h>
  19. #include <sys/mman.h>
  20. #include <assert.h>
  21. #include <queue>
  22. #if CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_BH
  23. #define RCIN_RPI_CHN_NUM 8
  24. #else
  25. #define RCIN_RPI_CHN_NUM 1
  26. #endif
  27. namespace Linux {
  28. enum state_t{
  29. RCIN_RPI_INITIAL_STATE = -1,
  30. RCIN_RPI_ZERO_STATE = 0,
  31. RCIN_RPI_ONE_STATE = 1
  32. };
  33. //Memory table structure
  34. typedef struct {
  35. void **virt_pages;
  36. void **phys_pages;
  37. uint32_t page_count;
  38. } memory_table_t;
  39. //DMA control block structure
  40. typedef struct {
  41. uint32_t info, src, dst, length,
  42. stride, next, pad[2];
  43. } dma_cb_t;
  44. class Memory_table {
  45. // Allow RCInput_RPI access to private members of Memory_table
  46. friend class RCInput_RPI;
  47. private:
  48. void** _virt_pages;
  49. void** _phys_pages;
  50. uint32_t _page_count;
  51. public:
  52. Memory_table();
  53. Memory_table(uint32_t, int);
  54. ~Memory_table();
  55. //Get virtual address from the corresponding physical address from memory_table.
  56. void* get_virt_addr(const uint32_t phys_addr) const;
  57. // This function returns physical address with help of pointer, which is offset from the beginning of the buffer.
  58. void* get_page(void **pages, const uint32_t addr) const;
  59. // This function returns offset from the beginning of the buffer using (virtual) address in 'pages' and memory_table.
  60. uint32_t get_offset(void **pages, const uint32_t addr) const;
  61. //How many bytes are available for reading in circle buffer?
  62. uint32_t bytes_available(const uint32_t read_addr, const uint32_t write_addr) const;
  63. uint32_t get_page_count() const;
  64. };
  65. class RCInput_RPI : public RCInput
  66. {
  67. public:
  68. void init() override;
  69. void _timer_tick(void) override;
  70. RCInput_RPI();
  71. ~RCInput_RPI();
  72. private:
  73. //Physical adresses of peripherals. Are different on different Raspberries.
  74. uint32_t dma_base;
  75. uint32_t clk_base;
  76. uint32_t pcm_base;
  77. //registers
  78. static volatile uint32_t *pcm_reg;
  79. static volatile uint32_t *clk_reg;
  80. static volatile uint32_t *dma_reg;
  81. Memory_table *circle_buffer;
  82. Memory_table *con_blocks;
  83. uint64_t curr_tick;
  84. uint32_t curr_tick_inc;
  85. uint32_t curr_pointer;
  86. uint32_t curr_channel;
  87. struct RcChannel {
  88. RcChannel() :
  89. prev_tick(0), delta_time(0),
  90. width_s0(0), width_s1(0),
  91. curr_signal(0), last_signal(0),
  92. enable_pin(0), state(RCIN_RPI_INITIAL_STATE)
  93. {}
  94. uint64_t prev_tick;
  95. uint64_t delta_time;
  96. uint16_t width_s0;
  97. uint16_t width_s1;
  98. uint8_t curr_signal;
  99. uint8_t last_signal;
  100. state_t state;
  101. AP_HAL::DigitalSource *enable_pin;
  102. } rc_channels[RCIN_RPI_CHN_NUM];
  103. bool _initialized = false;
  104. void init_dma_cb(dma_cb_t** cbp, uint32_t mode, uint32_t source, uint32_t dest, uint32_t length, uint32_t stride, uint32_t next_cb);
  105. void* map_peripheral(uint32_t base, uint32_t len);
  106. void init_registers();
  107. void init_ctrl_data();
  108. void init_PCM();
  109. void init_DMA();
  110. void init_buffer();
  111. static void stop_dma();
  112. static void termination_handler(int signum);
  113. void set_sigaction();
  114. void set_physical_addresses(int version);
  115. void teardown() override;
  116. };
  117. }