57#ifndef _FREERTOS_DRIVERS_TI_TIVARAILCOM_HXX_
58#define _FREERTOS_DRIVERS_TI_TIVARAILCOM_HXX_
60#if (!defined(TIVADCC_TIVA)) && (!defined(TIVADCC_CC3200))
61#error must define either TIVADCC_TIVA or TIVADCC_CC3200
64#include "freertos_drivers/common/RailcomImpl.hxx"
107 static uint8_t sample() {
109 if (!CH1_Pin::get()) ret |= 1;
110 if (!CH2_Pin::get()) ret |= 2;
111 if (!CH3_Pin::get()) ret |= 4;
112 if (!CH4_Pin::get()) ret |= 8;
117// The weak attribute is needed if the definition is put into a header file.
118const uint32_t RailcomHw::UART_BASE[] __attribute__((weak)) = {UART4_BASE, UART3_BASE, UART2_BASE, UART7_BASE};
119const uint32_t RailcomHw::UART_PERIPH[]
120__attribute__((weak)) = {SYSCTL_PERIPH_UART4, SYSCTL_PERIPH_UART3, SYSCTL_PERIPH_UART2, SYSCTL_PERIPH_UART7};
136 MAP_IntPrioritySet(HW::OS_INTERRUPT, configKERNEL_INTERRUPT_PRIORITY);
137 MAP_IntEnable(HW::OS_INTERRUPT);
142 MAP_IntDisable(HW::OS_INTERRUPT);
155 MAP_IntPendSet(int_nr);
161 for (
unsigned i = 0; i <
ARRAYSIZE(HW::UART_BASE); ++i)
164 MAP_SysCtlPeripheralEnable(HW::UART_PERIPH[i]);
165#elif defined(TIVADCC_CC3200)
166 MAP_PRCMPeripheralClkEnable(HW::UART_PERIPH[i], PRCM_RUN_MODE_CLK);
168 MAP_UARTConfigSetExpClk(HW::UART_BASE[i], cm3_cpu_clock_hz, 250000,
169 UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
170 UART_CONFIG_PAR_NONE);
171 MAP_UARTFIFOEnable(HW::UART_BASE[i]);
173 HWREGBITW(HW::UART_BASE[i] + UART_O_CTL, UART_CTL_RXE) = 0;
174 MAP_UARTEnable(HW::UART_BASE[i]);
179 for (
unsigned i = 0; i <
ARRAYSIZE(HW::UART_BASE); ++i)
181 MAP_UARTDisable(HW::UART_BASE[i]);
187 HW::enable_measurement(
true);
189 HW::disable_measurement();
194 HW::enable_measurement(
false);
195 const bool need_ch1_cutout = HW::need_ch1_cutout() || (this->
feedbackKey_ < 11000);
196 Debug::RailcomRxActivate::set(
true);
197 for (
unsigned i = 0; i <
ARRAYSIZE(HW::UART_BASE); ++i)
201 HWREG(HW::UART_BASE[i] + UART_O_CTL) |= UART_CTL_RXE;
206 while (MAP_UARTCharGetNonBlocking(HW::UART_BASE[i]) >= 0)
210 Debug::RailcomDriverCutout::set(
true);
215 Debug::RailcomDriverCutout::set(
false);
216 for (
unsigned i = 0; i <
ARRAYSIZE(HW::UART_BASE); ++i)
218 while (MAP_UARTCharsAvail(HW::UART_BASE[i]))
220 Debug::RailcomDataReceived::toggle();
221 Debug::RailcomAnyData::set(
true);
230 long data = MAP_UARTCharGetNonBlocking(HW::UART_BASE[i]);
231 if (data < 0 || data > 0xff) {
240 HWREG(HW::UART_BASE[i] + UART_O_CTL) &= ~UART_CTL_RXE;
241 Debug::RailcomError::toggle();
247 HWREG(HW::UART_BASE[i] + UART_O_CTL) |= UART_CTL_RXE;
249 HW::middle_cutout_hook();
250 Debug::RailcomDriverCutout::set(
true);
255 HW::disable_measurement();
256 bool have_packets =
false;
257 for (
unsigned i = 0; i <
ARRAYSIZE(HW::UART_BASE); ++i)
259 while (MAP_UARTCharsAvail(HW::UART_BASE[i]))
261 Debug::RailcomDataReceived::toggle();
262 Debug::RailcomAnyData::set(
true);
263 Debug::RailcomCh2Data::set(
true);
272 long data = MAP_UARTCharGetNonBlocking(HW::UART_BASE[i]);
273 if (data < 0 || data > 0xff) {
274 Debug::RailcomError::toggle();
279 Debug::RailcomE0::toggle();
283 HWREG(HW::UART_BASE[i] + UART_O_CTL) &= ~UART_CTL_RXE;
284 Debug::RailcomRxActivate::set(
false);
289 Debug::RailcomPackets::toggle();
291 MAP_IntPendSet(HW::OS_INTERRUPT);
302 Debug::RailcomPackets::toggle();
303 MAP_IntPendSet(HW::OS_INTERRUPT);
306 Debug::RailcomCh2Data::set(
false);
307 Debug::RailcomDriverCutout::set(
false);
312 for (
unsigned i = 0; i <
ARRAYSIZE(HW::UART_BASE); ++i)
321 Debug::RailcomPackets::toggle();
323 MAP_IntPendSet(HW::OS_INTERRUPT);
void commit_back()
Commits the oldest entry reserved by noncommit_back.
Base class for railcom drivers.
dcc::Feedback * returnedPackets_[HW::CHANNEL_COUNT]
Stores pointers to packets we are filling right now, one for each channel.
uint32_t feedbackKey_
Stores the key for the next packets to read.
dcc::Feedback * alloc_new_packet(uint8_t channel)
Takes a new empty packet at the front of the queue, fills in feedback key and channel information.
void add_sample(int sample)
Adds a sample for a preamble bit.
FixedQueue< dcc::Feedback, HW::Q_SIZE > feedbackQueue_
The packets we have read so far.
Railcom driver for TI Tiva-class microcontrollers using the TivaWare peripheral library.
bool inCutout_
True when we are currently within a cutout.
TivaRailcomDriver(const char *path)
Constructor.
void int_set_pending(unsigned int_nr) override
Sets a given software interrupt pending.
void start_cutout() OVERRIDE
Instructs the driver that the railcom cutout is starting now.
void disable() OVERRIDE
This will be called when reference count goes from non-zero to 0.
void end_cutout() OVERRIDE
Instructs the driver that the railcom cutout is over now.
void no_cutout() OVERRIDE
Called instead of start/mid/end-cutout at the end of the current packet if there was no cutout reques...
void enable() OVERRIDE
This will be called once when reference-count goes from 0 to positive.
void middle_cutout() OVERRIDE
Notifies the driver that the railcom cutout has reached the middle point, i.e., the first window is p...
void feedback_sample() OVERRIDE
Call to the driver for sampling the current sensors.
#define OVERRIDE
Function attribute for virtual functions declaring that this funciton is overriding a funciton that s...
#define ARRAYSIZE(a)
Returns the number of elements in a statically defined array (of static size)
void add_ch1_data(uint8_t data)
Appends a byte to the channel 1 payload.
void add_ch2_data(uint8_t data)
Appends a byte to the channel 2 payload.