32 #ifdef PIOS_INCLUDE_IBUS 
   35 #define PIOS_IBUS_CHANNELS 10 
   37 #define PIOS_IBUS_BUFLEN (1 + 1 + PIOS_IBUS_CHANNELS * 2 + 8 + 2) 
   38 #define PIOS_IBUS_SYNCBYTE 0x20 
   39 #define PIOS_IBUS_MAGIC 0x84fd9a39 
   44 struct pios_ibus_dev {
 
   50         uint16_t channel_data[PIOS_IBUS_CHANNELS];
 
   51         uint8_t rx_buf[PIOS_IBUS_BUFLEN];
 
   58 static struct pios_ibus_dev *PIOS_IBus_Alloc(
void);
 
   64 static bool PIOS_IBus_Validate(
const struct pios_ibus_dev *dev);
 
   71 static int32_t PIOS_IBus_Read(uintptr_t 
id, uint8_t channel);
 
   77 static void PIOS_IBus_SetAllChannels(
struct pios_ibus_dev *dev, uint16_t 
value);
 
   87 static uint16_t PIOS_IBus_Receive(uintptr_t context, uint8_t *buf, uint16_t buf_len,
 
   88                 uint16_t *headroom, 
bool *task_woken);
 
   93 static void PIOS_IBus_ResetBuffer(
struct pios_ibus_dev *dev);
 
   98 static void PIOS_IBus_UnpackFrame(
struct pios_ibus_dev *dev);
 
  103 static void PIOS_IBus_Supervisor(uintptr_t context);
 
  107         .
read = PIOS_IBus_Read,
 
  111 static struct pios_ibus_dev *PIOS_IBus_Alloc(
void)
 
  117         memset(dev, 0, 
sizeof(*dev));
 
  118         dev->magic = PIOS_IBUS_MAGIC;
 
  123 static bool PIOS_IBus_Validate(
const struct pios_ibus_dev *dev)
 
  125         return dev && dev->magic == PIOS_IBUS_MAGIC;
 
  131         struct pios_ibus_dev *dev = PIOS_IBus_Alloc();
 
  136         *ibus_id = (uintptr_t)dev;
 
  143         (driver->
bind_rx_cb)(uart_id, PIOS_IBus_Receive, *ibus_id);
 
  148 static int32_t PIOS_IBus_Read(uintptr_t context, uint8_t channel)
 
  150         if (channel > PIOS_IBUS_CHANNELS)
 
  153         struct pios_ibus_dev *dev = (
struct pios_ibus_dev *)context;
 
  154         if (!PIOS_IBus_Validate(dev))
 
  157         return dev->channel_data[channel];
 
  160 static void PIOS_IBus_SetAllChannels(
struct pios_ibus_dev *dev, uint16_t 
value)
 
  162         for (
int i = 0; 
i < PIOS_IBUS_CHANNELS; 
i++)
 
  163                 dev->channel_data[
i] = value;
 
  166 static uint16_t PIOS_IBus_Receive(uintptr_t context, uint8_t *buf, uint16_t buf_len,
 
  167                 uint16_t *headroom, 
bool *task_woken)
 
  169         struct pios_ibus_dev *dev = (
struct pios_ibus_dev *)context;
 
  170         if (!PIOS_IBus_Validate(dev))
 
  173         for (
int i = 0; 
i < buf_len; 
i++) {
 
  174                 if (dev->buf_pos == 0 && buf[
i] != PIOS_IBUS_SYNCBYTE)
 
  177                 dev->rx_buf[dev->buf_pos++] = buf[
i];
 
  178                 if (dev->buf_pos <= PIOS_IBUS_BUFLEN - 2)
 
  179                         dev->checksum -= buf[
i];
 
  180                 else if (dev->buf_pos == PIOS_IBUS_BUFLEN)
 
  181                         PIOS_IBus_UnpackFrame(dev);
 
  187                 *headroom = PIOS_IBUS_BUFLEN - dev->buf_pos;
 
  208 static void PIOS_IBus_ResetBuffer(
struct pios_ibus_dev *dev)
 
  210         dev->checksum = 0xffff;
 
  214 static void PIOS_IBus_UnpackFrame(
struct pios_ibus_dev *dev)
 
  216         uint16_t rxsum = dev->rx_buf[PIOS_IBUS_BUFLEN - 1] << 8 |
 
  217                         dev->rx_buf[PIOS_IBUS_BUFLEN - 2];
 
  218         if (dev->checksum != rxsum)
 
  221         uint16_t *chan = (uint16_t *)&dev->rx_buf[2];
 
  222         for (
int i = 0; 
i < PIOS_IBUS_CHANNELS; 
i++)
 
  223                 dev->channel_data[
i] = *chan++;
 
  225         dev->failsafe_timer = 0;
 
  228         PIOS_IBus_ResetBuffer(dev);
 
  231 static void PIOS_IBus_Supervisor(uintptr_t context)
 
  233         struct pios_ibus_dev *dev = (
struct pios_ibus_dev *)context;
 
  236         if (++dev->rx_timer > 3)
 
  237                 PIOS_IBus_ResetBuffer(dev);
 
  240         if (++dev->failsafe_timer > 156)
 
  244 #endif // PIOS_INCLUDE_IBUS 
int32_t(* read)(uintptr_t id, uint8_t channel)
 
int PIOS_IBus_Init(uintptr_t *ibus_id, const struct pios_com_driver *driver, uintptr_t uart_id)
Initialises the IBus Rx driver with a serial port. 
 
bool PIOS_RTC_RegisterTickCallback(void(*fn)(uintptr_t id), uintptr_t data)
 
void * PIOS_malloc_no_dma(size_t size)
 
const struct pios_rcvr_driver pios_ibus_rcvr_driver
 
void(* bind_rx_cb)(uintptr_t id, pios_com_callback rx_in_cb, uintptr_t context)
 
#define PIOS_Assert(test)