Skip to content

Commit

Permalink
* Added read/write functions for s8, s16, s32, and s64. (#12)
Browse files Browse the repository at this point in the history
* Hotfix for UART-16550 driver and Arty-Managed example design.
  • Loading branch information
ooterness authored Oct 22, 2021
1 parent fc8fa85 commit ae783f1
Show file tree
Hide file tree
Showing 8 changed files with 105 additions and 17 deletions.
5 changes: 5 additions & 0 deletions doc/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@ This log will be updated for each new release, but may not reflect the latest de
* Reworked switch-core to allow rudimentary IGMP snooping.
* Reworked switch-core to allow traffic prioritization based on EtherType.

## v2.0.1

* Added read/write functions for s8, s16, s32, and s64.
* Hotfix for UART-16550 driver and Arty-Managed example design.

# Copyright Notice

Copyright 2019, 2020, 2021 The Aerospace Corporation
Expand Down
2 changes: 1 addition & 1 deletion examples/arty_managed/create_vivado.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ connect_bd_intf_net [get_bd_intf_ports text] [get_bd_intf_pins switch_aux_0/text
# Create address segments
create_bd_addr_seg -range 0x00010000 -offset 0x44A00000 \
[get_bd_addr_spaces ublaze/microblaze_0/Data] [get_bd_addr_segs ublaze/axi_uart16550_0/S_AXI/Reg] SEG_axi_uart16550_0_Reg
create_bd_addr_seg -range 0x00010000 -offset 0x44A10000 \
create_bd_addr_seg -range 0x00100000 -offset 0x44B00000 \
[get_bd_addr_spaces ublaze/microblaze_0/Data] [get_bd_addr_segs ublaze/cfgbus_host_axi_0/CtrlAxi/CtrlAxi_addr] SEG_cfgbus_host_axi_0_CtrlAxi_addr
create_bd_addr_seg -range 0x00010000 -offset 0x00000000 \
[get_bd_addr_spaces ublaze/microblaze_0/Data] [get_bd_addr_segs ublaze/ublaze_mem/dlmb_bram_if_cntlr/SLMB/Mem] SEG_dlmb_bram_if_cntlr_Mem
Expand Down
26 changes: 26 additions & 0 deletions sim/cpp/test_io_core.cc
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,32 @@ TEST_CASE("ArrayWrite") {
}
}

TEST_CASE("SignedInts") {
u8 buff[32];
io::ArrayWrite uut(buff, sizeof(buff));

uut.write_s8(-123);
uut.write_s8(+123);
uut.write_s16(-12345);
uut.write_s16(+12345);
uut.write_s32(-1234567890);
uut.write_s32(+1234567890);
uut.write_s64(-1234567890123456789ll);
uut.write_s64(+1234567890123456789ll);
uut.write_finalize();
CHECK(uut.written_len() == 30);

io::ArrayRead rd(buff, uut.written_len());
CHECK(rd.read_s8() == -123);
CHECK(rd.read_s8() == +123);
CHECK(rd.read_s16() == -12345);
CHECK(rd.read_s16() == +12345);
CHECK(rd.read_s32() == -1234567890);
CHECK(rd.read_s32() == +1234567890);
CHECK(rd.read_s64() == -1234567890123456789ll);
CHECK(rd.read_s64() == +1234567890123456789ll);
}

TEST_CASE("NullIO") {
SECTION("NullRead") {
NullRead uut;
Expand Down
7 changes: 4 additions & 3 deletions src/cpp/hal_ublaze/uart16550.cc
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ Uart16550::Uart16550(
| XUN_OPTION_RESET_TX_FIFO
| XUN_OPTION_RESET_RX_FIFO;
// Enable Rx-Data interrupt?
if (irq >= 0) options |= XUN_OPTION_DATA_INTR;
if (m_irq_idx >= 0) options |= XUN_OPTION_DATA_INTR;
// Set hardware option flags:
m_status = XUartNs550_SetOptions(&m_uart, options);
if (m_status != XST_SUCCESS) return;
Expand Down Expand Up @@ -95,7 +95,7 @@ void Uart16550::irq_event()
{
// Read and clear interrupt status register.
u8 isr_type = (u8)XUartNs550_ReadReg(m_uart.BaseAddress, XUN_IIR_OFFSET) & XUN_INT_ID_MASK;
XUartNs550_GetLineStatusReg(m_uart.BaseAddress);
u32 linereg = XUartNs550_GetLineStatusReg(m_uart.BaseAddress);

// Outgoing data ready to send?
u32 txbytes = m_tx.get_peek_ready();
Expand All @@ -117,8 +117,9 @@ void Uart16550::irq_event()

// Copy any new incoming data to the software buffer.
// Use the three-step zero-copy-write (ZCW) method.
constexpr u32 LSR_READ_ANY = XUN_LSR_BREAK_INT | XUN_LSR_DATA_READY;
u32 rxmax = m_rx.zcw_maxlen(); // Max safe to read?
if ((rxmax > 0) && (isr_type != UART_IRQ_NONE)) {
if ((rxmax > 0) && (linereg & LSR_READ_ANY)) {
u8* rxtmp = m_rx.zcw_start(); // Get pointer to buffer
u32 rcvd = XUartNs550_Recv(&m_uart, rxtmp, rxmax);
if (rcvd) {
Expand Down
59 changes: 47 additions & 12 deletions src/cpp/satcat5/io_core.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@

#include <cstring>
#include <satcat5/io_core.h>
#include <satcat5/utils.h>

using satcat5::util::reinterpret;

void satcat5::io::Writeable::write_u8(u8 data)
{
Expand Down Expand Up @@ -59,18 +62,34 @@ void satcat5::io::Writeable::write_u64(u64 data)
} else write_overflow();
}

void satcat5::io::Writeable::write_s8(s8 data)
{
write_u8(reinterpret<s8,u8>(data));
}

void satcat5::io::Writeable::write_s16(s16 data)
{
write_u16(reinterpret<s16,u16>(data));
}

void satcat5::io::Writeable::write_s32(s32 data)
{
write_u32(reinterpret<s32,u32>(data));
}

void satcat5::io::Writeable::write_s64(s64 data)
{
write_u64(reinterpret<s64,u64>(data));
}

void satcat5::io::Writeable::write_f32(float data)
{
union {float f; u32 u;} temp;
temp.f = data;
write_u32(temp.u);
write_u32(reinterpret<float,u32>(data));
}

void satcat5::io::Writeable::write_f64(double data)
{
union {double f; u64 u;} temp;
temp.f = data;
write_u64(temp.u);
write_u64(reinterpret<double,u64>(data));
}

void satcat5::io::Writeable::write_bytes(unsigned nbytes, const void* src)
Expand Down Expand Up @@ -157,18 +176,34 @@ u64 satcat5::io::Readable::read_u64()
}
}

s8 satcat5::io::Readable::read_s8()
{
return reinterpret<u8, s8>(read_u8());
}

s16 satcat5::io::Readable::read_s16()
{
return reinterpret<u16, s16>(read_u16());
}

s32 satcat5::io::Readable::read_s32()
{
return reinterpret<u32, s32>(read_u32());
}

s64 satcat5::io::Readable::read_s64()
{
return reinterpret<u64, s64>(read_u64());
}

float satcat5::io::Readable::read_f32()
{
union {float f; u32 u;} temp;
temp.u = read_u32();
return temp.f;
return reinterpret<u32, float>(read_u32());
}

double satcat5::io::Readable::read_f64()
{
union {double f; u64 u;} temp;
temp.u = read_u64();
return temp.f;
return reinterpret<u64, double>(read_u64());
}

bool satcat5::io::Readable::read_bytes(unsigned nbytes, void* dst)
Expand Down
8 changes: 8 additions & 0 deletions src/cpp/satcat5/io_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ namespace satcat5 {
void write_u16(u16 data);
void write_u32(u32 data);
void write_u64(u64 data);
void write_s8(s8 data);
void write_s16(s16 data);
void write_s32(s32 data);
void write_s64(s64 data);
void write_f32(float data);
void write_f64(double data);
void write_str(const char* str);
Expand Down Expand Up @@ -107,6 +111,10 @@ namespace satcat5 {
u16 read_u16();
u32 read_u32();
u64 read_u64();
s8 read_s8();
s16 read_s16();
s32 read_s32();
s64 read_s64();
float read_f32();
double read_f64();
virtual bool read_bytes(unsigned nbytes, void* dst);
Expand Down
1 change: 0 additions & 1 deletion src/cpp/satcat5/net_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,6 @@ namespace satcat5 {
: m_filter(type), m_next(0) {}
~Protocol() {}

public://???
satcat5::net::Type m_filter; // Incoming packet filter

private:
Expand Down
14 changes: 14 additions & 0 deletions src/cpp/satcat5/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

#pragma once

#include <cstring>
#include <satcat5/types.h>

namespace satcat5 {
Expand Down Expand Up @@ -193,5 +194,18 @@ namespace satcat5 {
enum {SATCAT5_LITTLE_ENDIAN = 0x03020100ul, SATCAT5_BIG_ENDIAN = 0x00010203ul};
constexpr union {u8 bytes[4]; u32 value;} HOST_ORDER_CANARY = {{0,1,2,3}};
inline u32 HOST_BYTE_ORDER() {return HOST_ORDER_CANARY.value;}

// In-place byte-for-byte format conversion, aka "type-punning".
template<typename T1, typename T2> inline T2 reinterpret(T1 x)
{
static_assert(sizeof(T1) == sizeof(T2), "Type size mismatch");
// Note: Using "memcpy" for type-punning is preferred safe-ish method.
// Most compilers will optimize this to a no-op, as desired. See also:
// https://gist.github.com/shafik/848ae25ee209f698763cffee272a58f8
// https://stackoverflow.com/questions/48803363/bitwise-casting-uint32-t-to-float-in-c-c
T2 y;
std::memcpy(&y, &x, sizeof(T1));
return y;
}
}
}

0 comments on commit ae783f1

Please sign in to comment.