comm.h 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. #ifndef COMM_H_
  2. #define COMM_H_
  3. #include "util.h"
  4. #include <stdint.h>
  5. #include <avr/pgmspace.h>
  6. #ifndef COMM_PAYLOAD_LEN
  7. # define COMM_PAYLOAD_LEN 8
  8. #endif
  9. #ifndef COMM_LOCAL_ADDRESS
  10. # define COMM_LOCAL_ADDRESS 0
  11. #endif
  12. #ifndef COMM_BAUDRATE
  13. # define COMM_BAUDRATE 9600
  14. #endif
  15. #ifndef COMM_TX_QUEUE_SIZE
  16. # define COMM_TX_QUEUE_SIZE 4 /* Must be power of two */
  17. #endif
  18. #define COMM_TX_QUEUE_MASK (COMM_TX_QUEUE_SIZE - 1)
  19. #ifndef COMM_RX_QUEUE_SIZE
  20. # define COMM_RX_QUEUE_SIZE 4 /* Must be power of two */
  21. #endif
  22. #define COMM_RX_QUEUE_MASK (COMM_RX_QUEUE_SIZE - 1)
  23. enum comm_frame_control {
  24. COMM_FC_RESET = 0x01,
  25. COMM_FC_REQ_ACK = 0x02,
  26. COMM_FC_ACK = 0x04,
  27. COMM_FC_ERRCODE = 0xC0,
  28. COMM_FC_ERRCODE_SHIFT = 6,
  29. };
  30. enum comm_errcode {
  31. COMM_ERR_OK, /* Ok. */
  32. COMM_ERR_FAIL, /* Failure. */
  33. COMM_ERR_FCS, /* Checksum error. */
  34. COMM_ERR_Q, /* Queue overflow. */
  35. };
  36. typedef uint16_t comm_crc_t; /* little endian checksum*/
  37. #define COMM_HDR_LEN 4
  38. #define COMM_FCS_LEN sizeof(comm_crc_t)
  39. struct comm_message {
  40. uint8_t fc; /* Frame control. */
  41. uint8_t seq; /* Sequence number. */
  42. uint8_t addr; /* Source and destination address. */
  43. uint8_t reserved;
  44. uint8_t payload[COMM_PAYLOAD_LEN]; /* Payload. */
  45. comm_crc_t fcs; /* Frame check sequence. */
  46. } _packed;
  47. #define COMM_MSG_INIT() { \
  48. .fc = 0, \
  49. .seq = 0, \
  50. .addr = COMM_LOCAL_ADDRESS & 0x0F, \
  51. }
  52. #define COMM_MSG(_name) \
  53. struct comm_message _name = COMM_MSG_INIT()
  54. static inline uint8_t comm_msg_err(const struct comm_message *msg)
  55. {
  56. return (msg->fc & COMM_FC_ERRCODE) >> COMM_FC_ERRCODE_SHIFT;
  57. }
  58. static inline void comm_msg_set_err(struct comm_message *msg, uint8_t err)
  59. {
  60. msg->fc = (msg->fc & ~COMM_FC_ERRCODE) | (err << COMM_FC_ERRCODE_SHIFT);
  61. }
  62. static inline uint8_t comm_msg_sa(const struct comm_message *msg)
  63. {
  64. return msg->addr & 0x0F;
  65. }
  66. static inline void comm_msg_set_sa(struct comm_message *msg, uint8_t sa)
  67. {
  68. msg->addr = (msg->addr & 0xF0) | (sa & 0x0F);
  69. }
  70. static inline uint8_t comm_msg_da(const struct comm_message *msg)
  71. {
  72. return msg->addr >> 4;
  73. }
  74. static inline void comm_msg_set_da(struct comm_message *msg, uint8_t da)
  75. {
  76. msg->addr = (msg->addr & 0x0F) | (da << 4);
  77. }
  78. #define comm_payload(payload_ptr_type, msg) ((payload_ptr_type)((msg)->payload))
  79. void comm_init(void);
  80. void comm_work(void);
  81. void comm_centisecond_tick(void);
  82. void comm_message_send(struct comm_message *msg, uint8_t dest_addr);
  83. void comm_drain_tx_queue(void);
  84. extern bool comm_handle_rx_message(const struct comm_message *msg,
  85. void *reply_payload);
  86. #endif /* COMM_H_ */