rtthread_driver_spi.c 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364
  1. #ifndef APPLICATIONS_HCI_INTERFACE_C_
  2. #define APPLICATIONS_HCI_INTERFACE_C_
  3. #include <rtthread.h>
  4. #include <rtdevice.h>
  5. #include "drv_gpio.h"
  6. #include "rtthread_driver_spi.h"
  7. #include "drivers/hci_driver.h"
  8. #include "drivers/hci_h4.h"
  9. #include "logging/bt_log_impl.h"
  10. #include "common/bt_buf.h"
  11. struct hci_trans_spi_config {
  12. const char *device_name; /* spi device name, i.e. "spi1" */
  13. const char *bus_name; /* spi BUS name, i.e. "spi10" */
  14. int cs_pin_num; /* RT-Thread drv_gpio number of SPI CS PIN */
  15. int irq_pin_num; /* RT-Thread drv_gpio number of SPI IRQ PIN */
  16. uint32_t rate;
  17. int data_width; /* Data width: 8bits, 16bits, 32bits */
  18. int LSB_MSB; /* Data transmission order: LSB:0 MSB:1 */
  19. int Master_Slave; /* Set the master-slave mode of SPI: Master:0 Slave:1 */
  20. int CPOL; /* Set clock polarity(CPOL): 0 1 */
  21. int CPHA; /* Set clock phase(CPHA): 0 1 */
  22. };
  23. static struct hci_trans_spi_config hci_config;
  24. struct rt_spi_device *ble_spi = RT_NULL;
  25. int32_t IsDataAvailable(void);
  26. int32_t HCI_TL_SPI_Init(void* pConf)
  27. {
  28. /******PIN******/
  29. rt_pin_mode(hci_config.irq_pin_num, PIN_MODE_INPUT); // IRQ input
  30. rt_pin_mode(hci_config.cs_pin_num, PIN_MODE_OUTPUT); // CS output
  31. /*******SPI******/
  32. RT_ASSERT(hci_config.device_name);
  33. RT_ASSERT(hci_config.bus_name);
  34. ble_spi = (struct rt_spi_device *)rt_malloc(sizeof(struct rt_spi_device));
  35. if(RT_NULL == ble_spi)
  36. {
  37. printk("Failed to malloc the spi device.\n");
  38. return -RT_ENOMEM;
  39. }
  40. if (RT_EOK != rt_spi_bus_attach_device(ble_spi, hci_config.device_name, hci_config.bus_name, RT_NULL))
  41. {
  42. printk("Failed to attach the spi device.\n");
  43. return -RT_ERROR;
  44. }
  45. /*******SPI Device Config*******/
  46. struct rt_spi_configuration cfg;
  47. cfg.data_width = hci_config.data_width;
  48. cfg.mode = (hci_config.Master_Slave << 3) |
  49. ((hci_config.CPOL << 1) | (hci_config.CPHA << 0)) |
  50. (hci_config.LSB_MSB << 2);
  51. cfg.max_hz = hci_config.rate; /* 1M */
  52. if (RT_EOK != rt_spi_configure(ble_spi, &cfg)) {
  53. printk("Failed to config the spi device.\n");
  54. return -RT_ERROR;
  55. }
  56. return RT_EOK;
  57. }
  58. /**
  59. * @brief Reads from BlueNRG SPI buffer and store data into local buffer.
  60. *
  61. * @param buffer : Buffer where data from SPI are stored
  62. * @param size : Buffer size
  63. * @retval int32_t: Number of read bytes
  64. */
  65. int32_t HCI_TL_SPI_Receive(uint8_t* buffer, uint16_t size)
  66. {
  67. uint16_t byte_count;
  68. uint8_t len = 0;
  69. uint8_t char_00 = 0x00;
  70. volatile uint8_t read_char;
  71. uint8_t header_master[HEADER_SIZE] = {0x0b, 0x00, 0x00, 0x00, 0x00};
  72. uint8_t header_slave[HEADER_SIZE];
  73. /* CS reset */
  74. rt_pin_write(HCI_TL_SPI_CS_PIN, PIN_LOW);
  75. /* Read the header */
  76. rt_spi_transfer(ble_spi, &header_master, &header_slave, HEADER_SIZE); //RTAPI
  77. /* device is ready */
  78. byte_count = (header_slave[4] << 8)| header_slave[3];
  79. if(byte_count > 0)
  80. {
  81. /* avoid to read more data than the size of the buffer */
  82. if (byte_count > size)
  83. {
  84. byte_count = size;
  85. }
  86. for(len = 0; len < byte_count; len++)
  87. {
  88. rt_spi_transfer(ble_spi, &char_00, (uint8_t*)&read_char, 1);
  89. buffer[len] = read_char;
  90. }
  91. }
  92. /**
  93. * To be aligned to the SPI protocol.
  94. * Can bring to a delay inside the frame, due to the BlueNRG-2 that needs
  95. * to check if the header is received or not.
  96. */
  97. uint32_t tickstart = rt_tick_get();
  98. while ((rt_tick_get() - tickstart) < TIMEOUT_IRQ_HIGH) {
  99. if (rt_pin_read(HCI_TL_SPI_IRQ_PIN) == PIN_LOW) {
  100. break;
  101. }
  102. }
  103. /* Release CS line */
  104. rt_pin_write(HCI_TL_SPI_CS_PIN, PIN_HIGH);
  105. return len;
  106. }
  107. /**
  108. * @brief Writes data from local buffer to SPI.
  109. *
  110. * @param buffer : data buffer to be written
  111. * @param size : size of first data buffer to be written
  112. * @retval int32_t: Number of read bytes
  113. */
  114. int32_t HCI_TL_SPI_Send(uint8_t* buffer, uint16_t size)
  115. {
  116. int32_t result;
  117. uint16_t rx_bytes;
  118. uint8_t header_master[HEADER_SIZE] = {0x0a, 0x00, 0x00, 0x00, 0x00};
  119. uint8_t header_slave[HEADER_SIZE];
  120. static uint8_t read_char_buf[MAX_BUFFER_SIZE];
  121. uint32_t tickstart = rt_tick_get();
  122. do
  123. {
  124. uint32_t tickstart_data_available = rt_tick_get();
  125. result = 0;
  126. /* CS reset */
  127. rt_pin_write(HCI_TL_SPI_CS_PIN, PIN_LOW);
  128. /*
  129. * Wait until BlueNRG-2 is ready.
  130. * When ready it will raise the IRQ pin.
  131. */
  132. while(!IsDataAvailable())
  133. {
  134. if((rt_tick_get() - tickstart_data_available) > TIMEOUT_DURATION)
  135. {
  136. printk("%d timeout\r\n", rt_tick_get() - tickstart_data_available);
  137. result = -3;
  138. break;
  139. }
  140. }
  141. if(result == -3)
  142. {
  143. /* The break causes the exiting from the "while", so the CS line must be released */
  144. rt_pin_write(HCI_TL_SPI_CS_PIN, PIN_HIGH);
  145. break;
  146. }
  147. /* Read header */
  148. rt_spi_transfer(ble_spi, &header_master, &header_slave, HEADER_SIZE);
  149. printk("Send header size: %d buffer: %02x", HEADER_SIZE, header_slave[0]);
  150. for (int i = 1; i < HEADER_SIZE; ++i) {
  151. printk("%02x", header_slave[i]);
  152. }
  153. printk("\r\n");
  154. rx_bytes = (((uint16_t)header_slave[2])<<8) | ((uint16_t)header_slave[1]);
  155. if(rx_bytes >= size)
  156. {
  157. /* Buffer is big enough */
  158. rt_spi_transfer(ble_spi, buffer, &read_char_buf, size);
  159. }
  160. else
  161. {
  162. /* Buffer is too small */
  163. result = -2;
  164. }
  165. /* Release CS line */
  166. rt_pin_write(HCI_TL_SPI_CS_PIN, PIN_HIGH);
  167. if((rt_tick_get() - tickstart) > TIMEOUT_DURATION)
  168. {
  169. result = -3;
  170. break;
  171. }
  172. } while(result < 0);
  173. /**
  174. * To be aligned to the SPI protocol.
  175. * Can bring to a delay inside the frame, due to the BlueNRG-2 that needs
  176. * to check if the header is received or not.
  177. */
  178. tickstart = rt_tick_get();
  179. while ((rt_tick_get() - tickstart) < TIMEOUT_IRQ_HIGH) {
  180. if (rt_pin_read(HCI_TL_SPI_IRQ_PIN) == PIN_LOW) {
  181. break;
  182. }
  183. }
  184. return result;
  185. }
  186. /**
  187. * @brief Reports if the BlueNRG has data for the host micro.
  188. *
  189. * @param None
  190. * @retval int32_t: 1 if data are present, 0 otherwise
  191. */
  192. int32_t IsDataAvailable(void)
  193. {
  194. return (rt_pin_read(HCI_TL_SPI_IRQ_PIN) == PIN_HIGH);
  195. }
  196. static int hci_driver_open(void)
  197. {
  198. HCI_TL_SPI_Init(NULL); // RT SPI init
  199. printk("hci_driver_open, SPI_config_finish\n");
  200. return 0;
  201. }
  202. int switch_net_buf_type(uint8_t type)
  203. {
  204. switch (type)
  205. {
  206. case BT_BUF_ACL_OUT:
  207. return HCI_ACLDATA_PKT;
  208. case BT_BUF_CMD:
  209. return HCI_COMMAND_PKT;
  210. default:
  211. printk("Unknown buffer type");
  212. }
  213. return 0;
  214. }
  215. static int hci_driver_send(struct net_buf *buf)
  216. {
  217. uint8_t type = bt_buf_get_type(buf);
  218. // net_buf_push_u8(buf, type);
  219. // uint8_t* data = buf->data;
  220. uint8_t len = buf->len;
  221. if(len >= MAX_BUFFER_SIZE)
  222. {
  223. return -1;
  224. }
  225. uint8_t data[MAX_BUFFER_SIZE];
  226. data[0] = switch_net_buf_type(type);
  227. memcpy(data + 1, buf->data, len); //data[0] is the type copy to data[1]
  228. printk("hci_driver_send, type: %d, len: %d, data: %02x:%02x:%02x:%02x:%02x:%02x\n", type, len, data[0], data[1], data[2], data[3], data[4], data[5]);
  229. if (HCI_TL_SPI_Send(data, len + 1) < 0) { // type +1
  230. return -1;
  231. }
  232. net_buf_unref(buf);
  233. return 0;
  234. }
  235. static int hci_driver_recv(uint8_t *buf, uint16_t len)
  236. {
  237. return HCI_TL_SPI_Receive(buf, len);
  238. }
  239. void hci_driver_init_loop(void)
  240. {
  241. uint8_t data[MAX_BUFFER_SIZE];
  242. uint8_t len = MAX_BUFFER_SIZE;
  243. int ret = HCI_TL_SPI_Receive(data, len); //ret: bytes num Recv
  244. if(ret > 0 && (data[0] != 0)) // type cant be 0
  245. {
  246. printk("hci_driver_init_loop, ret: %d, data: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", ret, data[0], data[1], data[2], data[3], data[4], data[5],data[6],data[7]);
  247. struct net_buf *buf;
  248. switch(data[0])
  249. {
  250. case HCI_EVENT_PKT:
  251. buf = bt_buf_get_controller_tx_evt();
  252. break;
  253. case HCI_ACLDATA_PKT:
  254. buf = bt_buf_get_controller_tx_acl();
  255. break;
  256. default:
  257. return;
  258. }
  259. if (buf)
  260. {
  261. net_buf_add_mem(buf, data + 1, ret - 1);
  262. bt_recv(buf);
  263. }
  264. }
  265. }
  266. static const struct bt_hci_driver drv = {
  267. .open = hci_driver_open,
  268. .send = hci_driver_send,
  269. };
  270. static char device_name[NAME_SIZE];
  271. static char bus_name[NAME_SIZE];
  272. int hci_driver_init(bt_BlueNRG_SPI_interface_t *hci_cfg, int device_idx, int spi_index)
  273. {
  274. rt_sprintf(bus_name, "spi%d", spi_index);
  275. hci_config.bus_name = bus_name;
  276. rt_sprintf(device_name, "spi%d%d", spi_index, device_idx);
  277. hci_config.device_name = device_name;
  278. hci_config.rate = hci_cfg->rate;
  279. hci_config.data_width = hci_cfg->data_width;
  280. hci_config.LSB_MSB = hci_cfg->LSB_MSB;
  281. hci_config.Master_Slave = hci_cfg->Master_Slave;
  282. hci_config.CPOL = hci_cfg->CPOL;
  283. hci_config.CPHA = hci_cfg->CPHA;
  284. hci_config.cs_pin_num = hci_cfg->cs_pin_num;
  285. hci_config.irq_pin_num = hci_cfg->irq_pin_num;
  286. printk("SPI_init_process device_name: %s, spi_name: %s, rate: %d, databits: %d, LSB_MSB: %d, Master_Slave: %d, CPOL: %d, CPHA: %d\n",
  287. hci_config.device_name, hci_config.bus_name, hci_config.rate, hci_config.data_width,
  288. hci_config.LSB_MSB, hci_config.Master_Slave, hci_config.CPOL, hci_config.CPHA);
  289. printk("SPI_init_process cs_pin_num: %d, irq_pin_num: %d\n",
  290. hci_config.cs_pin_num, hci_config.irq_pin_num);
  291. if (bt_hci_driver_register(&drv) != 0)
  292. {
  293. return -1;
  294. }
  295. return 0;
  296. }
  297. #endif /* APPLICATIONS_HCI_INTERFACE_C_ */