* (c) 2020 Martin Mareš <mj@ucw.cz>
*/
+#define BSB_USB_VENDOR 0x4242
+#define BSB_USB_PRODUCT 0x0003
+#define BSB_USB_VERSION 0x0100
+
+/*
+ * Endpoints:
+ *
+ * 0x00 = control endpoint
+ * Vendor-defined request 0x00 sends struct bsb_stats in little endian.
+ *
+ * 0x01 = bulk endpoint
+ * Used for sending frames to BSB. Accepts BSB frames. CRC will be calculated
+ * automatically.
+ *
+ * 0x82 = interrupt endpoint
+ * Used for receiving frames from BSB and status reports on sent frames.
+ * The first byte is a status byte (TX_RESULT_xxx), the rest is a frame.
+ * If status == TX_RESULT_NONE, the frame is a received frame.
+ * If status == TX_RESULT_OK, the frame is a received reply to the sent frame.
+ * Otherwise, the status indicates transmit error and the frame is empty.
+ */
+
+// Status sent on the interrupt endpoint
+#define BSB_TX_RESULTS \
+ P(NONE) \
+ P(OK) \
+ P(OVERRUN) \
+ P(MALFORMED) \
+ P(FORBIDDEN) \
+ P(TIMEOUT) \
+ P(TOO_MANY_RETRIES)
+
enum bsb_tx_result {
- TX_RESULT_NONE,
- TX_RESULT_OK,
- TX_RESULT_OVERRUN,
- TX_RESULT_MALFORMED,
- TX_RESULT_FORBIDDEN,
- TX_RESULT_TIMEOUT,
- TX_RESULT_TOO_MANY_RETRIES,
+#define P(x) TX_RESULT_##x,
+ BSB_TX_RESULTS
+#undef P
};
-// Sent via USB in little-endian format
+// Statistics sent on the control endpoint
+#define BSB_STATS \
+ P(rx_noise) \
+ P(rx_errors) \
+ P(rx_invalid) \
+ P(rx_overruns) \
+ P(rx_timeouts) \
+ P(rx_bad_crc) \
+ P(rx_ok) \
+ P(tx_overruns) \
+ P(tx_rejects) \
+ P(tx_timeouts) \
+ P(tx_collisions) \
+ P(tx_reply_timeouts) \
+ P(tx_ok_no_reply) \
+ P(tx_ok_replied)
+
struct bsb_stats {
- u32 rx_noise;
- u32 rx_errors;
- u32 rx_invalid;
- u32 rx_overruns;
- u32 rx_timeouts;
- u32 rx_bad_crc;
- u32 rx_ok;
- u32 tx_overruns;
- u32 tx_rejects;
- u32 tx_timeouts;
- u32 tx_collisions;
- u32 tx_ok;
+#define P(x) u32 x;
+ BSB_STATS
+#undef P
};
+/*
+ * Structure of BSB frames
+ *
+ * start of frame (0xdc)
+ * source address XOR 0x80
+ * destination address
+ * length
+ * operation
+ * <parameters depending on operation>
+ * 16-bit CRC
+ */
+
+// Positions of fields in a frame
+enum bsb_frame {
+ BF_SOF,
+ BF_SRC,
+ BF_DEST,
+ BF_LEN,
+ BF_OP,
+};
+
+enum bsb_address {
+ BSB_ADDR_BOILER = 0,
+ BSB_ADDR_EXT_BOARD = 3,
+ BSB_ADDR_ROOM1 = 6,
+ BSB_ADDR_ROOM2 = 7,
+ BSB_ADDR_GATEWAY = 0x42, // That's us
+ BSB_ADDR_BROADCAST = 0x7f,
+};
+
+enum bsb_op {
+ BSB_OP_REQUEST_INFO = 1,
+ BSB_OP_INFO = 2,
+ BSB_OP_SET = 3,
+ BSB_OP_ACK = 4,
+ BSB_OP_NACK = 5,
+ BSB_OP_QUERY = 6,
+ BSB_OP_ANSWER = 7,
+ BSB_OP_ERROR = 8,
+ BSB_OP_QUERY_DEFAULT = 0x0f,
+ BSB_OP_ANSWER_DEFAULT = 0x10,
+};