PlatformIO package of the Teensy core framework compatible with GCC 10 & C++20
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

141 lines
4.3KB

  1. /* Copyright (c) 2009 Nordic Semiconductor. All Rights Reserved.
  2. *
  3. * The information contained herein is property of Nordic Semiconductor ASA.
  4. * Terms and conditions of usage are described in detail in NORDIC
  5. * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
  6. *
  7. * Licensees are granted free, non-transferable use of the information. NO
  8. * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
  9. * the file.
  10. *
  11. * $LastChangedRevision$
  12. */
  13. /**
  14. * My project template
  15. */
  16. #include <avr/pgmspace.h>
  17. #include <ble_system.h>
  18. #include <lib_aci.h>
  19. #include "aci_setup.h"
  20. // aci_struct that will contain
  21. // total initial credits
  22. // current credit
  23. // current state of the aci (setup/standby/active/sleep)
  24. // open remote pipe pending
  25. // close remote pipe pending
  26. // Current pipe available bitmap
  27. // Current pipe closed bitmap
  28. // Current connection interval, slave latency and link supervision timeout
  29. // Current State of the the GATT client (Service Discovery status)
  30. static hal_aci_evt_t aci_data;
  31. static hal_aci_data_t aci_cmd;
  32. aci_status_code_t aci_setup(aci_state_t *aci_stat, uint8_t num_cmds, uint8_t num_cmd_offset)
  33. {
  34. uint8_t i = 0;
  35. uint8_t evt_count = 0;
  36. aci_evt_t * aci_evt = NULL;
  37. while (i < num_cmds)
  38. {
  39. //Copy the setup ACI message from Flash to RAM
  40. //Add 2 bytes to the length byte for status byte, length for the total number of bytes
  41. memcpy_P(&aci_cmd, &(aci_stat->aci_setup_info.setup_msgs[num_cmd_offset+i]),
  42. pgm_read_byte_near(&(aci_stat->aci_setup_info.setup_msgs[num_cmd_offset+i].buffer[0]))+2);
  43. //Put the Setup ACI message in the command queue
  44. if (!hal_aci_tl_send(&aci_cmd))
  45. {
  46. Serial.println(F("Cmd Queue Full"));
  47. return ACI_STATUS_ERROR_INTERNAL;
  48. }
  49. else
  50. {
  51. //Debug messages:
  52. //Serial.print(F("Setup msg"));
  53. //Serial.println(i, DEC);
  54. #ifdef __arm__
  55. // This entire setup scheme may have an off-by-one error, where it tries to
  56. // put 8 commends into the queue which can only hold 7 due to the way the
  57. // head & tail indexes are managed. On AVR, the processor is simply too
  58. // slow to fill the queue before at least one interrupt, but a fast ARM
  59. // processor can easily do so. This delay is a workaround to avoid having
  60. // to restructure a lot of code...
  61. delayMicroseconds(10);
  62. #endif
  63. }
  64. i++;
  65. }
  66. while (1)
  67. {
  68. //We will sit here if we do not get the same number of command response evts as the commands sent to the ACI
  69. //
  70. //@check The setup wil fail in the while(1) below when the 32KHz source for the nRF8001 is in-correct in the setup generated in the nRFgo studio
  71. if (true == lib_aci_event_get(aci_stat, &aci_data))
  72. {
  73. aci_evt = &aci_data.evt;
  74. evt_count++;
  75. if (ACI_EVT_CMD_RSP != aci_evt->evt_opcode )
  76. {
  77. //Got something other than a command response evt -> Error
  78. return ACI_STATUS_ERROR_INTERNAL;
  79. }
  80. if (!((ACI_STATUS_TRANSACTION_CONTINUE == aci_evt->params.cmd_rsp.cmd_status) ||
  81. (ACI_STATUS_TRANSACTION_COMPLETE == aci_evt->params.cmd_rsp.cmd_status)))
  82. {
  83. return (aci_status_code_t )aci_evt->params.cmd_rsp.cmd_status;
  84. }
  85. else
  86. {
  87. //Serial.print(F("Cmd Response Evt "));
  88. //Serial.println(evt_count);
  89. }
  90. if (num_cmds == evt_count)
  91. {
  92. break;
  93. }
  94. }
  95. }
  96. return ((aci_status_code_t)aci_evt->params.cmd_rsp.cmd_status);
  97. }
  98. aci_status_code_t do_aci_setup(aci_state_t *aci_stat)
  99. {
  100. aci_status_code_t status = ACI_STATUS_ERROR_CRC_MISMATCH;
  101. uint8_t i=0;
  102. if(ACI_QUEUE_SIZE >= aci_stat->aci_setup_info.num_setup_msgs)
  103. {
  104. status = aci_setup(aci_stat, aci_stat->aci_setup_info.num_setup_msgs, 0);
  105. }
  106. else
  107. {
  108. for(i=0; i<(aci_stat->aci_setup_info.num_setup_msgs/ACI_QUEUE_SIZE); i++)
  109. {
  110. //Serial.print(ACI_QUEUE_SIZE, DEC);
  111. //Serial.print(F(" "));
  112. //Serial.println(0+(ACI_QUEUE_SIZE*i), DEC);
  113. status = aci_setup(aci_stat, ACI_QUEUE_SIZE, (ACI_QUEUE_SIZE*i));
  114. }
  115. if ((aci_stat->aci_setup_info.num_setup_msgs % ACI_QUEUE_SIZE) != 0)
  116. {
  117. status = aci_setup(aci_stat, aci_stat->aci_setup_info.num_setup_msgs % ACI_QUEUE_SIZE, (ACI_QUEUE_SIZE*i));
  118. }
  119. }
  120. return status;
  121. }