123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117 |
- #ifndef COMM_H_
- #define COMM_H_
- #include "util.h"
- #include <stdint.h>
- #include <avr/pgmspace.h>
- #ifndef COMM_PAYLOAD_LEN
- # define COMM_PAYLOAD_LEN 8
- #endif
- #ifndef COMM_LOCAL_ADDRESS
- # define COMM_LOCAL_ADDRESS 0
- #endif
- #ifndef COMM_BAUDRATE
- # define COMM_BAUDRATE 9600
- #endif
- #ifndef COMM_TX_QUEUE_SIZE
- # define COMM_TX_QUEUE_SIZE 4 /* Must be power of two */
- #endif
- #define COMM_TX_QUEUE_MASK (COMM_TX_QUEUE_SIZE - 1)
- #ifndef COMM_RX_QUEUE_SIZE
- # define COMM_RX_QUEUE_SIZE 4 /* Must be power of two */
- #endif
- #define COMM_RX_QUEUE_MASK (COMM_RX_QUEUE_SIZE - 1)
- enum comm_frame_control {
- COMM_FC_RESET = 0x01,
- COMM_FC_REQ_ACK = 0x02,
- COMM_FC_ACK = 0x04,
- COMM_FC_ERRCODE = 0xC0,
- COMM_FC_ERRCODE_SHIFT = 6,
- };
- enum comm_errcode {
- COMM_ERR_OK, /* Ok. */
- COMM_ERR_FAIL, /* Failure. */
- COMM_ERR_FCS, /* Checksum error. */
- COMM_ERR_Q, /* Queue overflow. */
- };
- typedef uint16_t comm_crc_t; /* little endian checksum*/
- #define COMM_HDR_LEN 4
- #define COMM_FCS_LEN sizeof(comm_crc_t)
- struct comm_message {
- uint8_t fc; /* Frame control. */
- uint8_t seq; /* Sequence number. */
- uint8_t addr; /* Source and destination address. */
- uint8_t reserved;
- uint8_t payload[COMM_PAYLOAD_LEN]; /* Payload. */
- comm_crc_t fcs; /* Frame check sequence. */
- } _packed;
- #define COMM_MSG_INIT() { \
- .fc = 0, \
- .seq = 0, \
- .addr = COMM_LOCAL_ADDRESS & 0x0F, \
- }
- #define COMM_MSG(_name) \
- struct comm_message _name = COMM_MSG_INIT()
- static inline uint8_t comm_msg_err(const struct comm_message *msg)
- {
- return (msg->fc & COMM_FC_ERRCODE) >> COMM_FC_ERRCODE_SHIFT;
- }
- static inline void comm_msg_set_err(struct comm_message *msg, uint8_t err)
- {
- msg->fc = (msg->fc & ~COMM_FC_ERRCODE) | (err << COMM_FC_ERRCODE_SHIFT);
- }
- static inline uint8_t comm_msg_sa(const struct comm_message *msg)
- {
- return msg->addr & 0x0F;
- }
- static inline void comm_msg_set_sa(struct comm_message *msg, uint8_t sa)
- {
- msg->addr = (msg->addr & 0xF0) | (sa & 0x0F);
- }
- static inline uint8_t comm_msg_da(const struct comm_message *msg)
- {
- return msg->addr >> 4;
- }
- static inline void comm_msg_set_da(struct comm_message *msg, uint8_t da)
- {
- msg->addr = (msg->addr & 0x0F) | (da << 4);
- }
- #define comm_payload(payload_ptr_type, msg) ((payload_ptr_type)((msg)->payload))
- void comm_init(void);
- void comm_work(void);
- void comm_centisecond_tick(void);
- void comm_message_send(struct comm_message *msg, uint8_t dest_addr);
- void comm_drain_tx_queue(void);
- extern bool comm_handle_rx_message(const struct comm_message *msg,
- void *reply_payload);
- #endif /* COMM_H_ */
|