2020-08-20 17:47:32 +02:00
|
|
|
#ifndef OBUS_CAN_H
|
|
|
|
#define OBUS_CAN_H
|
|
|
|
|
2020-08-26 21:13:16 +02:00
|
|
|
#include "Arduino.h"
|
2020-08-20 21:13:19 +02:00
|
|
|
#include <assert.h>
|
|
|
|
|
2020-08-20 17:47:32 +02:00
|
|
|
#define CAN_DOMINANT 0
|
|
|
|
#define CAN_RECESSIVE 1
|
|
|
|
|
|
|
|
#define OBUS_CONTROLLER_ID 0x000
|
|
|
|
|
|
|
|
#define OBUS_MSG_LENGTH 8 // Max 8 to fit in a CAN message
|
|
|
|
|
|
|
|
#define OBUS_TYPE_CONTROLLER 0
|
2020-08-26 21:13:16 +02:00
|
|
|
#define OBUS_TYPE_INFO 0
|
2020-08-20 17:47:32 +02:00
|
|
|
#define OBUS_TYPE_PUZZLE 1
|
|
|
|
#define OBUS_TYPE_NEEDY 2
|
|
|
|
|
|
|
|
#define OBUS_MSGTYPE_C_ACK 0
|
|
|
|
#define OBUS_MSGTYPE_C_HELLO 1
|
|
|
|
#define OBUS_MSGTYPE_C_GAMESTART 2
|
|
|
|
#define OBUS_MSGTYPE_C_STATE 3
|
|
|
|
#define OBUS_MSGTYPE_C_SOLVED 4
|
|
|
|
#define OBUS_MSGTYPE_C_TIMEOUT 5
|
|
|
|
#define OBUS_MSGTYPE_C_STRIKEOUT 6
|
|
|
|
|
|
|
|
#define OBUS_MSGTYPE_M_HELLO 0
|
|
|
|
#define OBUS_MSGTYPE_M_STRIKE 1
|
|
|
|
#define OBUS_MSGTYPE_M_SOLVED 2
|
|
|
|
|
2020-08-25 21:47:58 +02:00
|
|
|
#define OBUS_PAYLDTYPE_EMPTY 0
|
|
|
|
#define OBUS_PAYLDTYPE_GAMESTATUS 1
|
|
|
|
#define OBUS_PAYLDTYPE_COUNT 2
|
2020-08-20 17:47:32 +02:00
|
|
|
|
2020-08-26 21:13:16 +02:00
|
|
|
namespace obus_can {
|
|
|
|
|
2020-08-20 17:47:32 +02:00
|
|
|
struct module {
|
|
|
|
uint8_t type;
|
|
|
|
uint8_t id;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct payld_empty {};
|
|
|
|
struct payld_gamestatus {
|
|
|
|
uint32_t time_left;
|
|
|
|
uint8_t strikes;
|
|
|
|
uint8_t max_strikes;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2020-08-26 21:13:16 +02:00
|
|
|
struct message {
|
2020-08-20 17:47:32 +02:00
|
|
|
struct module from;
|
|
|
|
bool priority;
|
|
|
|
uint8_t msg_type;
|
|
|
|
union {
|
|
|
|
struct payld_empty empty;
|
|
|
|
struct payld_gamestatus gamestatus;
|
2020-08-25 21:47:58 +02:00
|
|
|
uint8_t count;
|
2020-08-20 17:47:32 +02:00
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2020-08-20 21:13:19 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Determine payload type for message
|
|
|
|
*
|
|
|
|
* @param module_type One of OBUS_TYPE_*
|
|
|
|
* @param module_type One of OBUS_MSGTYPE_*
|
|
|
|
*
|
|
|
|
* @return One of OBUS_PAYLDTYPE_*
|
|
|
|
*/
|
2020-08-26 21:13:16 +02:00
|
|
|
uint8_t payload_type(uint8_t module_type, uint8_t message_type);
|
2020-08-20 21:13:19 +02:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Initialize the CAN controller for OBUS messaging
|
|
|
|
*/
|
2020-08-26 21:13:16 +02:00
|
|
|
void init();
|
2020-08-20 21:13:19 +02:00
|
|
|
/**
|
|
|
|
* Receive a message
|
|
|
|
*
|
2020-08-27 03:29:16 +02:00
|
|
|
* @param msg Pointer to memory where the received message will be written
|
2020-08-20 21:13:19 +02:00
|
|
|
* @return true if a message was received, false otherwise
|
|
|
|
*/
|
2020-08-26 21:13:16 +02:00
|
|
|
bool receive(struct message *msg);
|
2020-08-20 17:47:32 +02:00
|
|
|
|
2020-08-20 21:13:19 +02:00
|
|
|
/**
|
|
|
|
* Lowlevel interface to send a message, you may want to use one of the helpers, like
|
2020-08-26 21:13:16 +02:00
|
|
|
* send_m_strike
|
2020-08-20 21:13:19 +02:00
|
|
|
*
|
|
|
|
* @param msg Pointer to a message to send
|
|
|
|
*/
|
2020-08-26 21:13:16 +02:00
|
|
|
void send(struct message *msg);
|
2020-08-20 21:13:19 +02:00
|
|
|
|
2020-08-27 03:29:16 +02:00
|
|
|
bool is_error_condition();
|
|
|
|
|
2020-08-20 21:13:19 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* For internal use only
|
|
|
|
*
|
|
|
|
* Send an OBUS message
|
|
|
|
*/
|
2020-08-26 21:13:16 +02:00
|
|
|
inline struct message _msg(struct module from, bool priority, uint8_t msg_type) {
|
2020-08-20 21:13:19 +02:00
|
|
|
|
2020-08-26 21:13:16 +02:00
|
|
|
struct message msg;
|
2020-08-20 21:13:19 +02:00
|
|
|
msg.from = from;
|
|
|
|
msg.priority = priority;
|
|
|
|
msg.msg_type = msg_type;
|
|
|
|
return msg;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* For internal use only
|
|
|
|
*
|
|
|
|
* Send a controller OBUS message with a gamestatus payload
|
|
|
|
*/
|
2020-08-26 21:13:16 +02:00
|
|
|
inline void _send_payld_gamestatus(
|
2020-08-20 17:47:32 +02:00
|
|
|
struct module from, bool priority, uint8_t msg_type,
|
2020-08-20 21:13:19 +02:00
|
|
|
uint32_t time_left, uint8_t strikes, uint8_t max_strikes) {
|
|
|
|
|
2020-08-26 21:13:16 +02:00
|
|
|
struct message msg = _msg(from, priority, msg_type);
|
2020-08-20 21:13:19 +02:00
|
|
|
msg.gamestatus.time_left = time_left;
|
|
|
|
msg.gamestatus.strikes = strikes;
|
|
|
|
msg.gamestatus.max_strikes = max_strikes;
|
2020-08-26 21:13:16 +02:00
|
|
|
send(&msg);
|
2020-08-20 21:13:19 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Send a controller "ACK" OBUS message
|
|
|
|
*/
|
2020-08-26 21:13:16 +02:00
|
|
|
inline void send_c_ack(struct module from) {
|
2020-08-20 21:13:19 +02:00
|
|
|
assert(from.type == OBUS_TYPE_CONTROLLER);
|
2020-08-26 21:13:16 +02:00
|
|
|
struct message msg = _msg(from, false, OBUS_MSGTYPE_C_ACK);
|
|
|
|
send(&msg);
|
2020-08-20 21:13:19 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Send a controller "hello" OBUS message
|
|
|
|
*/
|
2020-08-26 21:13:16 +02:00
|
|
|
inline void send_c_hello(struct module from) {
|
2020-08-20 21:13:19 +02:00
|
|
|
assert(from.type == OBUS_TYPE_CONTROLLER);
|
2020-08-26 21:13:16 +02:00
|
|
|
struct message msg = _msg(from, false, OBUS_MSGTYPE_C_HELLO);
|
|
|
|
send(&msg);
|
2020-08-20 21:13:19 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Send a controller "game start" OBUS message
|
|
|
|
*/
|
2020-08-26 21:13:16 +02:00
|
|
|
inline void send_c_gamestart(
|
2020-08-20 21:13:19 +02:00
|
|
|
struct module from, uint32_t time_left, uint8_t strikes, uint8_t max_strikes) {
|
|
|
|
|
|
|
|
assert(from.type == OBUS_TYPE_CONTROLLER);
|
2020-08-26 21:13:16 +02:00
|
|
|
_send_payld_gamestatus(
|
2020-08-20 21:13:19 +02:00
|
|
|
from, false, OBUS_MSGTYPE_C_GAMESTART, time_left, strikes, max_strikes);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Send a controller "state" OBUS message
|
|
|
|
*/
|
2020-08-26 21:13:16 +02:00
|
|
|
inline void send_c_state(
|
2020-08-20 21:13:19 +02:00
|
|
|
struct module from, uint32_t time_left, uint8_t strikes, uint8_t max_strikes) {
|
|
|
|
|
|
|
|
assert(from.type == OBUS_TYPE_CONTROLLER);
|
2020-08-26 21:13:16 +02:00
|
|
|
_send_payld_gamestatus(
|
2020-08-20 21:13:19 +02:00
|
|
|
from, false, OBUS_MSGTYPE_C_STATE, time_left, strikes, max_strikes);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Send a controller "solved" OBUS message
|
|
|
|
*/
|
2020-08-26 21:13:16 +02:00
|
|
|
inline void send_c_solved(
|
2020-08-20 21:13:19 +02:00
|
|
|
struct module from, uint32_t time_left, uint8_t strikes, uint8_t max_strikes) {
|
|
|
|
|
|
|
|
assert(from.type == OBUS_TYPE_CONTROLLER);
|
2020-08-26 21:13:16 +02:00
|
|
|
_send_payld_gamestatus(
|
2020-08-20 21:13:19 +02:00
|
|
|
from, false, OBUS_MSGTYPE_C_SOLVED, time_left, strikes, max_strikes);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Send a controller "timeout" OBUS message
|
|
|
|
*/
|
2020-08-26 21:13:16 +02:00
|
|
|
inline void send_c_timeout(
|
2020-08-20 21:13:19 +02:00
|
|
|
struct module from, uint32_t time_left, uint8_t strikes, uint8_t max_strikes) {
|
|
|
|
|
|
|
|
assert(from.type == OBUS_TYPE_CONTROLLER);
|
2020-08-26 21:13:16 +02:00
|
|
|
_send_payld_gamestatus(
|
2020-08-20 21:13:19 +02:00
|
|
|
from, false, OBUS_MSGTYPE_C_TIMEOUT, time_left, strikes, max_strikes);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Send a controller "strikeout" OBUS message
|
|
|
|
*/
|
2020-08-26 21:13:16 +02:00
|
|
|
inline void send_c_strikeout(
|
2020-08-20 21:13:19 +02:00
|
|
|
struct module from, uint32_t time_left, uint8_t strikes, uint8_t max_strikes) {
|
|
|
|
|
|
|
|
assert(from.type == OBUS_TYPE_CONTROLLER);
|
2020-08-26 21:13:16 +02:00
|
|
|
_send_payld_gamestatus(
|
2020-08-20 21:13:19 +02:00
|
|
|
from, false, OBUS_MSGTYPE_C_STRIKEOUT, time_left, strikes, max_strikes);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Send a module "hello" OBUS message
|
|
|
|
*/
|
2020-08-26 21:13:16 +02:00
|
|
|
inline void send_m_hello(struct module from) {
|
2020-08-20 21:13:19 +02:00
|
|
|
assert(from.type != OBUS_TYPE_CONTROLLER);
|
2020-08-26 21:13:16 +02:00
|
|
|
struct message msg = _msg(from, false, OBUS_MSGTYPE_M_HELLO);
|
|
|
|
send(&msg);
|
2020-08-20 21:13:19 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Send a module "strike" OBUS message
|
|
|
|
*/
|
2020-08-26 21:13:16 +02:00
|
|
|
inline void send_m_strike(struct module from, uint8_t count) {
|
2020-08-20 21:13:19 +02:00
|
|
|
assert(from.type != OBUS_TYPE_CONTROLLER);
|
2020-08-26 21:13:16 +02:00
|
|
|
struct message msg = _msg(from, false, OBUS_MSGTYPE_M_STRIKE);
|
2020-08-25 21:47:58 +02:00
|
|
|
msg.count = count;
|
2020-08-26 21:13:16 +02:00
|
|
|
send(&msg);
|
2020-08-20 21:13:19 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Send a module "solved" OBUS message
|
|
|
|
*/
|
2020-08-26 21:13:16 +02:00
|
|
|
inline void send_m_solved(struct module from) {
|
2020-08-20 21:13:19 +02:00
|
|
|
assert(from.type != OBUS_TYPE_CONTROLLER);
|
2020-08-26 21:13:16 +02:00
|
|
|
struct message msg = _msg(from, false, OBUS_MSGTYPE_M_STRIKE);
|
|
|
|
send(&msg);
|
|
|
|
}
|
|
|
|
|
2020-08-20 21:13:19 +02:00
|
|
|
}
|
2020-08-20 17:47:32 +02:00
|
|
|
|
|
|
|
#endif /* end of include guard: OBUS_CAN_H */
|