#include "can-jf0815.h"

#include <why-irq.h>


CAN_JF0815::CAN_JF0815(const std::string& can_iface)
: _controller(can_iface),
  _sem_xmit_done(Why::Semaphore(0)),
  _sem_recv_ready(Why::Semaphore(0))
{
    Why::IRQ::connect(CAN_JF0815_HW::IRQ_XMIT_DONE, [this](int irqnum){_isr_xmit_done();});
    Why::IRQ::connect(CAN_JF0815_HW::IRQ_RECV_READY, [this](int irqnum){_isr_recv_ready();});
}

void CAN_JF0815::xmit(const CANFrame& frame)
{
    _controller.begin_xmit(frame);
    _sem_xmit_done.take();                             // <-- block until xmitted
}

CANFrame CAN_JF0815::recv()
{
    _sem_recv_ready.take();                            // <-- block until frame in recv buffer
    return _controller.commit_recv();
}

void CAN_JF0815::_isr_xmit_done()
{
    _sem_xmit_done.give();                             // <-- wakeup xmitter thread
}

void CAN_JF0815::_isr_recv_ready()
{
    _sem_recv_ready.give();                            // <-- wakeup receiver thread
}
