8 #include <satcat5/port_mailmap.h>
20 static constexpr
unsigned DEBUG_VERBOSE = 0;
24 #ifndef SATCAT5_PTP_ENABLE
25 #define SATCAT5_PTP_ENABLE 1
28 static const char* LBL_MAP =
"MAP";
29 static const unsigned REGADDR_IRQ = 510;
30 static const unsigned REGADDR_CLK = 1012;
33 inline Time get_timestamp(
volatile u32* addr) {
36 u32 nanoSec = addr[2];
37 u16 subNanoSec = addr[3];
38 u64 sec = ((u64)secMSB) << 32 | secLSB;
39 return Time(sec, nanoSec, subNanoSec);
43 : satcat5::cfg::Interrupt(cfg, devaddr, REGADDR_IRQ)
44 , m_ctrl((
ctrl_reg*)cfg->get_device_mmap(devaddr))
45 , m_clock_reg(cfg->get_register(devaddr, REGADDR_CLK))
62 return SATCAT5_MAILMAP_BYTES - m_wridx;
69 memcpy(m_ctrl->tx_buff + m_wridx, src, nbytes);
92 m_ctrl->tx_ctrl = m_wridx;
109 return m_rdlen - m_rdidx;
118 memcpy(dst, m_ctrl->rx_buff + m_rdidx, nbytes);
138 m_ctrl->tx_buff[m_wridx++] = data;
142 return m_ctrl->rx_buff[m_rdidx++];
147 m_rdlen = m_ctrl->rx_ctrl;
148 if (!m_rdlen)
return;
150 if (SATCAT5_PTP_ENABLE &&
ptp_dispatch(m_ctrl->rx_buff, m_rdlen)) {
158 if (!SATCAT5_PTP_ENABLE)
return satcat5::ptp::TIME_ZERO;
160 m_ctrl->rt_clk_ctrl[4] = 0x01;
161 Time tmp = get_timestamp(m_ctrl->rt_clk_ctrl);
162 if (DEBUG_VERBOSE > 0)
Log(DEBUG,
"ptp_time_now").
write_obj(tmp);
167 if (!SATCAT5_PTP_ENABLE)
return satcat5::ptp::TIME_ZERO;
169 m_ctrl->ptp_status = 0x01;
170 Time tmp = get_timestamp(m_ctrl->rt_clk_ctrl);
171 if (DEBUG_VERBOSE > 0)
Log(DEBUG,
"ptp_tx_start").
write_obj(tmp);
176 if (!SATCAT5_PTP_ENABLE)
return satcat5::ptp::TIME_ZERO;
178 Time tmp = get_timestamp(m_ctrl->tx_ptp_time);
179 if (DEBUG_VERBOSE > 0)
Log(DEBUG,
"ptp_tx_timestamp").
write_obj(tmp);
184 if (!SATCAT5_PTP_ENABLE)
return satcat5::ptp::TIME_ZERO;
186 Time tmp = get_timestamp(m_ctrl->rx_ptp_time);
187 if (DEBUG_VERBOSE > 0)
Log(DEBUG,
"ptp_rx_timestamp").
write_obj(tmp);
200 :
Mailmap(cfg, devaddr), m_wrtmp(0) {}
203 const u8* src8 = (
const u8*)src;
207 if ((m_wridx % 4) || (nbytes < 4)) {
212 const u32* src32 = (
const u32*)src8;
213 volatile u32* dst32 = (
volatile u32*)(m_ctrl->tx_buff + m_wridx);
215 src8 += 4; m_wridx += 4; nbytes -= 4;
226 if ((m_rdidx % 4) || (nbytes < 4)) {
231 volatile u32* src32 = (
volatile u32*)(m_ctrl->rx_buff + m_rdidx);
232 u32* dst32 = (u32*)dst8;
234 dst8 += 4; m_rdidx += 4; nbytes -= 4;
246 unsigned offset = m_wridx % 4;
247 if (offset == 0) m_wrtmp = 0;
248 u8* tmp8 = (u8*)(&m_wrtmp);
251 volatile u32* dst32 = (
volatile u32*)(m_ctrl->tx_buff + m_wridx - offset);
258 unsigned offset = m_rdidx % 4;
259 volatile u32* src32 = (
volatile u32*)(m_ctrl->rx_buff + m_rdidx - offset);
260 const u32 tmp32 = *src32;
263 const u8* tmp8 = (
const u8*)(&tmp32);
Memory-mapped local ConfigBus.
Abstract API for reading byte-streams and packets.
Abstract API for writing byte-streams and packets.
The Log class creates and formats one log message.
Log & write_obj(const T &obj)
Templated wrapper for custom output formatting.
void request_poll()
Call this method to request polling at a later time.
Alternate MailMap driver using word-aligned access only.
u8 read_next() override
Read the next byte from the underlying buffer or device.
void write_next(u8 data) override
Write the next byte to the underlying buffer or device.
void write_bytes(unsigned nbytes, const void *src) override
Write 0 or more bytes from a buffer.
MailmapAligned(satcat5::cfg::ConfigBusMmap *cfg, unsigned devaddr)
Constructor links this driver to a ConfigBus address.
bool read_bytes(unsigned nbytes, void *dst) override
Read 0 or more bytes into a buffer.
Driver for the internal "MailMap" Ethernet port.
void write_overflow() override
Optional error handling for write overflow.
void read_underflow() override
Optional error handling for read underflow.
satcat5::io::Readable * ptp_rx_read() override
Return an object suitable for reading the next PTP frame.
void write_next(u8 data) override
Write the next byte to the underlying buffer or device.
unsigned get_read_ready() const override
How many bytes can be read without blocking?
satcat5::ptp::Time ptp_tx_start() override
Begin sending a timestamped message.
u8 read_next() override
Read the next byte from the underlying buffer or device.
satcat5::ptp::Time ptp_tx_timestamp() override
Return timestamp of the most recent outgoing message.
void irq_event() override
Interrupt service routine.
void write_abort() override
If possible, abort the current partially-written packet.
bool write_finalize() override
Mark end of frame and release temporary working data.
void read_finalize() override
Consume any remaining bytes in this frame, if applicable.
satcat5::io::Writeable * ptp_tx_write() override
Return an object suitable for writing the next PTP frame.
unsigned get_write_space() const override
How many bytes can be written without blocking?
void write_bytes(unsigned nbytes, const void *src) override
Write 0 or more bytes from a buffer.
bool read_bytes(unsigned nbytes, void *dst) override
Read 0 or more bytes into a buffer.
satcat5::ptp::Time ptp_rx_timestamp() override
Return timestamp of the current incoming message.
satcat5::ptp::Time ptp_time_now() override
Return the best available estimate of the current time.
bool ptp_dispatch(const u8 *peek, unsigned length)
Determine if an incoming packet is a PTP message.
void ptp_notify_req()
Notify the PTP callback object in deferred mode.
High-precision timestamp for use with PTP / IEEE1588.
Diagnostic logging to UART and/or Ethernet ports.
constexpr s8 DEBUG
Define basic priority codes for log messages.
High-precision "Time" object for use with PTP / IEEE1588.