Open Model Railroad Network (OpenMRN)
Loading...
Searching...
No Matches
TivaTestPacketSource.hxx
Go to the documentation of this file.
1
36#ifndef _FREERTOS_DRIVERS_TI_TIVATESTPACKETSOURCE_HXX_
37#define _FREERTOS_DRIVERS_TI_TIVATESTPACKETSOURCE_HXX_
38
40#include <fcntl.h>
41#include <sys/select.h>
42#include "hardware.hxx"
43#include "driverlib/timer.h"
44#include "driverlib/interrupt.h"
45#include "inc/hw_ints.h"
46#include "utils/Ewma.hxx"
47
50{
53 static constexpr auto TIMER_BASE = TIMER3_BASE;
55 static constexpr auto TIMER_PERIPH = SYSCTL_PERIPH_TIMER3;
57 using ENABLE_Pin = SW1_Pin;
59 static constexpr auto ENABLE_PIN_TRUE = false;
61 static constexpr auto TIMER_INTERRUPT = INT_TIMER3A;
64 static constexpr unsigned MAX_BUFFER_VALUE = 20000;
66 static constexpr unsigned PACKET_SIZE = 1500;
68 static constexpr unsigned BANDWIDTH = 30000 * 29 / 7;
70 static constexpr unsigned TIMER_PERIOD = UINT64_C(80000000) * PACKET_SIZE / BANDWIDTH;
71};
72
75template <class HW> class TivaTestPacketSource : public Node
76{
77public:
81 : Node(name)
82 {
83 MAP_SysCtlPeripheralEnable(HW::TIMER_PERIPH);
84 MAP_TimerDisable(HW::TIMER_BASE, TIMER_A);
86 }
87
89 void timer_isr()
90 {
91 MAP_TimerIntClear(HW::TIMER_BASE, TIMER_TIMA_TIMEOUT);
92 int woken;
93 if (HW::ENABLE_Pin::get() == HW::ENABLE_PIN_TRUE &&
94 bufferedBytes_ < HW::MAX_BUFFER_VALUE)
95 {
96 bufferedBytes_ += HW::PACKET_SIZE;
98 }
99 }
100
102 unsigned absolute_offset() {
103 return absoluteOffset_;
104 }
105
106protected:
108 void enable() override
109 {
110 MAP_SysCtlPeripheralEnable(HW::TIMER_PERIPH);
111 MAP_TimerDisable(HW::TIMER_BASE, TIMER_A);
112
113 MAP_TimerClockSourceSet(HW::TIMER_BASE, TIMER_CLOCK_SYSTEM);
114 MAP_TimerConfigure(HW::TIMER_BASE, TIMER_CFG_PERIODIC);
115
116 MAP_TimerLoadSet(HW::TIMER_BASE, TIMER_A, HW::TIMER_PERIOD);
117
118 MAP_IntDisable(HW::TIMER_INTERRUPT);
119 MAP_IntPrioritySet(
120 HW::TIMER_INTERRUPT, configKERNEL_INTERRUPT_PRIORITY);
121 MAP_TimerIntEnable(HW::TIMER_BASE, TIMER_TIMA_TIMEOUT);
122 MAP_TimerEnable(HW::TIMER_BASE, TIMER_A);
123 MAP_IntEnable(HW::TIMER_INTERRUPT);
124 }
125
127 void disable() override
128 {
129 MAP_TimerDisable(HW::TIMER_BASE, TIMER_A);
130 }
131
133 void flush_buffers() override
134 {
135 }
136
138 ssize_t write(File *, const void *, size_t len) override
139 {
140 // Swallow all data.
141 return len;
142 }
143
145 ssize_t read(File *file, void *vtgt, size_t len) override
146 {
147 char *tgt = (char *)vtgt;
148 unsigned rd = 0;
149 while (rd < len)
150 {
151 if (bufferedBytes_ == 0)
152 {
153 if (file->flags & O_NONBLOCK)
154 {
155 if (rd > 0)
156 return rd;
157 return -EAGAIN;
158 }
159 fd_set fds;
160 FD_ZERO(&fds);
161 int fd = Device::fd_lookup(file);
162 FD_SET(fd, &fds);
163
164 ::select(fd + 1, &fds, NULL, NULL, NULL);
165 }
166 portENTER_CRITICAL();
167 if (bufferedBytes_ == 0)
168 {
169 portEXIT_CRITICAL();
170 continue;
171 }
172 while (rd < len && bufferedBytes_ > 0)
173 {
174 unsigned tocp = std::min(len - rd, inputPacketLen_ - offset_);
175 tocp = std::min(tocp, bufferedBytes_);
176 memcpy(tgt, packet_ + offset_, tocp);
177 offset_ += tocp;
178 rd += tocp;
179 bufferedBytes_ -= tocp;
180 tgt += tocp;
181 absoluteOffset_ += tocp;
183 {
184 reset_packet();
185 }
186 }
187 portEXIT_CRITICAL();
188 }
189 if (bufferedBytes_)
190 {
192 }
193 return rd;
194 }
195
197 bool select(File *file, int mode) override
198 {
199 switch (mode)
200 {
201 case FWRITE:
202 return true;
203 case FREAD:
204 portENTER_CRITICAL();
205 if (bufferedBytes_)
206 {
207 portEXIT_CRITICAL();
208 return true;
209 }
211 portEXIT_CRITICAL();
212 return false;
213 }
214 return true;
215 }
216
220 {
221 offset_ = 0;
222 snprintf(packet_, sizeof(packet_), ":X1F555444N%016d;\n", cnt_);
223 ++cnt_;
224 inputPacketLen_ = strlen(packet_);
225 }
226
230 unsigned offset_{0};
232 unsigned bufferedBytes_{0};
234 unsigned cnt_{0};
236 char packet_[40];
240 uint32_t absoluteOffset_{0};
241};
242
243#endif // _FREERTOS_DRIVERS_TI_TIVATESTPACKETSOURCE_HXX_
static int fd_lookup(File *file)
Looks up a file descriptor corresponding to a given File reference.
Definition Fileio.cxx:101
const char * name
device name
Definition Devtab.hxx:266
Node information.
Definition Devtab.hxx:549
A dummy device driver that spews out a lot of GC packets when a button is held.
unsigned offset_
Which is the next byte from the INPUT_PACKET to send back.
unsigned cnt_
Index of the next packet.
TivaTestPacketSource(const char *name)
Constructor.
SelectInfo readSelect_
Helper structure for select() support.
void flush_buffers() override
Unused.
ssize_t read(File *file, void *vtgt, size_t len) override
Performs generating the fake data and/or blocking the caller as needed.
void enable() override
Turns on the device.
char packet_[40]
Text-rendered form of the next packet.
void timer_isr()
Call this function from extern "C" void timer3a_interrupt_handler()
void reset_packet()
Helper function to clear the input packet buffer and fill in with the next packet in line.
bool select(File *file, int mode) override
Implementation of device-specific select() functionality.
unsigned bufferedBytes_
How many bytes we have accumulated to send back.
uint32_t absoluteOffset_
How many bytes in total have been read from this driver since boot.
void disable() override
Turns off the device.
ssize_t write(File *, const void *, size_t len) override
Unused.
unsigned inputPacketLen_
Length of packet_;.
#define FWRITE
Workaround for missing header defines on some newlib versions.
Definition fcntl.h:58
#define FREAD
Workaround for missing header defines on some newlib versions.
Definition fcntl.h:53
Select wakeup information.
Definition Devtab.hxx:491
static void select_wakeup_from_isr(SelectInfo *info, int *woken)
Wakeup the list of clients needing woken.
Definition Select.cxx:224
static void select_insert(SelectInfo *info)
Add client to list of clients needing woken.
Definition Select.cxx:197
static void select_wakeup(SelectInfo *info)
Wakeup the list of clients needing woken.
Definition Select.cxx:210
File information.
Definition Devtab.hxx:52
int flags
open flags
Definition Devtab.hxx:63
Example hardware specification for the TivaTestPacketSource device driver.
static constexpr unsigned BANDWIDTH
Bytes/sec to generate in total as input.
static constexpr auto TIMER_PERIPH
Peripheral to enable the clock output to.
SW1_Pin ENABLE_Pin
GPIO pin structure that turns on the input feed.
static constexpr auto TIMER_BASE
Which timer resource to use.
static constexpr auto ENABLE_PIN_TRUE
Defines whether the enabe pin is active-high or active-low.
static constexpr unsigned TIMER_PERIOD
Number of clock cycles to wait between generating two packets.
static constexpr auto TIMER_INTERRUPT
Interrupt number of the timer resource.
static constexpr unsigned MAX_BUFFER_VALUE
How may bytes maximum can be accumulated as pending if the reader is not consuming data fast enough.
static constexpr unsigned PACKET_SIZE
How many bytes to generate in one go.