PropWare  3.0.0.229
C++ objects and CMake build system for Parallax Propeller
uarttx.h
Go to the documentation of this file.
1 
26 #pragma once
27 
30 #include <PropWare/gpio/pin.h>
31 
32 namespace PropWare {
33 
34 #ifdef __PROPELLER_COG__
35 #define virtual
36 #endif
37 
38 class UARTTX : public UART
39 #ifndef __PROPELLER_COG__
40  , public PrintCapable
41 #endif
42 {
43  public:
44  UARTTX ()
45  : UART() {
46  this->set_tx_mask((const Port::Mask) (1 << _cfg_txpin));
47  }
48 
49  UARTTX (const Pin::Mask tx)
50  : UART() {
51  this->set_tx_mask(tx);
52  }
53 
54  virtual void set_tx_mask (const Port::Mask tx) {
55  // Reset the old pin
56  this->m_pin.set_dir_in();
57  this->m_pin.clear();
58 
59  this->m_pin.set_mask(tx);
60  this->m_pin.set();
61  this->m_pin.set_dir_out();
62  }
63 
64  Port::Mask get_tx_mask () const {
65  return this->m_pin.get_mask();
66  }
67 
68  virtual void send (uint16_t originalData) const {
69  uint32_t wideData = originalData;
70 
71  // Add parity bit
72  if (Parity::EVEN_PARITY == this->m_parity) {
73  __asm__ volatile("test %[_data], %[_dataMask] wc \n\t"
74  "muxc %[_data], %[_parityMask]"
75  : [_data] "+r"(wideData)
76  : [_dataMask] "r"(this->m_dataMask),
77  [_parityMask] "r"(this->m_parityMask));
78  } else if (Parity::ODD_PARITY == this->m_parity) {
79  __asm__ volatile("test %[_data], %[_dataMask] wc \n\t"
80  "muxnc %[_data], %[_parityMask]"
81  : [_data] "+r"(wideData)
82  : [_dataMask] "r"(this->m_dataMask),
83  [_parityMask] "r"(this->m_parityMask));
84  }
85 
86  // Add stop bits
87  wideData |= this->m_stopBitMask;
88 
89  // Add start bit
90  wideData <<= 1;
91 
92  this->shift_out_data(wideData, this->m_totalBits, this->m_bitCycles, this->m_pin.get_mask());
93  }
94 
95  virtual void send_array (const char array[], uint32_t words) const {
96  char *arrayPtr = (char *) array;
97  uint32_t data = 0, waitCycles = 0, bits = 0;
98 
99 #ifndef DOXYGEN_IGNORE
100  switch (this->m_parity) {
101  case Parity::NO_PARITY:
102  __asm__ volatile (
103  FC_START("SendArrayStart%=", "SendArrayEnd%=")
104  // Prepare next word
105  "sendArrayLoop%=: \n\t"
106  " rdbyte %[_data], %[_arrayPtr] \n\t"
107  // Set start & stop bits
108  " or %[_data], %[_stopBitMask] \n\t"
109  " shl %[_data], #1 \n\t"
110 
111  // Send one word
112  " mov %[_bits], %[_totalBits] \n\t"
113  " mov %[_waitCycles], %[_bitCycles] \n\t"
114  " add %[_waitCycles], CNT \n\t"
115  "sendWordLoop%=: \n\t"
116  " waitcnt %[_waitCycles], %[_bitCycles] \n\t"
117  " shr %[_data],#1 wc \n\t"
118  " muxc outa, %[_mask] \n\t"
119  " djnz %[_bits], #" FC_ADDR("sendWordLoop%=", "SendArrayStart%=") " \n\t"
120 
121  // Increment the pointer and loop
122  " add %[_arrayPtr], #1 \n\t"
123  " djnz %[_words], #" FC_ADDR("sendArrayLoop%=", "SendArrayStart%=") " \n\t"
124  FC_END("SendArrayEnd%=")
125  : [_data] "+r"(data),
126  [_waitCycles] "+r"(waitCycles),
127  [_arrayPtr] "+r"(arrayPtr),
128  [_bits] "+r"(bits),
129  [_words] "+r"(words)
130  : [_mask] "r"(this->m_pin.get_mask()),
131  [_bitCycles] "r"(this->m_bitCycles),
132  [_totalBits] "r"(this->m_totalBits),
133  [_stopBitMask] "r"(this->m_stopBitMask));
134  break;
135  case Parity::ODD_PARITY:
136  __asm__ volatile (
137  FC_START("SendArrayStart%=", "SendArrayEnd%=")
138  // Prepare next word
139  "sendArrayLoop%=:"
140  " rdbyte %[_data], %[_arrayPtr] \n\t"
141  // Set parity
142  " test %[_data], %[_dataMask] wc \n\t"
143  " muxnc %[_data], %[_parityMask] \n\t"
144  // Set start & stop bits
145  " or %[_data], %[_stopBitMask] \n\t"
146  " shl %[_data], #1 \n\t"
147 
148  // Send one word
149  " mov %[_bits], %[_totalBits] \n\t"
150  " mov %[_waitCycles], %[_bitCycles] \n\t"
151  " add %[_waitCycles], CNT \n\t"
152  "sendWordLoop%=: \n\t"
153  " waitcnt %[_waitCycles], %[_bitCycles] \n\t"
154  " shr %[_data],#1 wc \n\t"
155  " muxc outa, %[_mask] \n\t"
156  " djnz %[_bits], #" FC_ADDR("sendWordLoop%=", "SendArrayStart%=") " \n\t"
157 
158  // Increment the pointer and loop
159  " add %[_arrayPtr], #1 \n\t"
160  " djnz %[_words], #" FC_ADDR("sendArrayLoop%=", "SendArrayStart%=") " \n\t"
161  FC_END("SendArrayEnd%=")
162  : [_data] "+r"(data),
163  [_waitCycles] "+r"(waitCycles),
164  [_arrayPtr] "+r"(arrayPtr),
165  [_bits] "+r"(bits),
166  [_words] "+r"(words)
167  : [_mask] "r"(this->m_pin.get_mask()),
168  [_bitCycles] "r"(this->m_bitCycles),
169  [_totalBits] "r"(this->m_totalBits),
170  [_stopBitMask] "r"(this->m_stopBitMask),
171  [_dataMask] "r"(this->m_dataMask),
172  [_parityMask] "r"(this->m_parityMask));
173  break;
174  case Parity::EVEN_PARITY:
175  __asm__ volatile (
176  FC_START("SendArrayStart%=", "SendArrayEnd%=")
177  // Prepare next word
178  "sendArrayLoop%=:"
179  " rdbyte %[_data], %[_arrayPtr] \n\t"
180  // Set parity
181  " test %[_data], %[_dataMask] wc \n\t"
182  " muxc %[_data], %[_parityMask] \n\t"
183  // Set start & stop bits
184  " or %[_data], %[_stopBitMask] \n\t"
185  " shl %[_data], #1 \n\t"
186 
187  // Send one word
188  " mov %[_bits], %[_totalBits] \n\t"
189  " mov %[_waitCycles], %[_bitCycles] \n\t"
190  " add %[_waitCycles], CNT \n\t"
191  "sendWordLoop%=: \n\t"
192  " waitcnt %[_waitCycles], %[_bitCycles] \n\t"
193  " shr %[_data],#1 wc \n\t"
194  " muxc outa, %[_mask] \n\t"
195  " djnz %[_bits], #" FC_ADDR("sendWordLoop%=", "SendArrayStart%=") " \n\t"
196 
197  // Increment the pointer and loop
198  " add %[_arrayPtr], #1 \n\t"
199  " djnz %[_words], #" FC_ADDR("sendArrayLoop%=", "SendArrayStart%=") " \n\t"
200  FC_END("SendArrayEnd%=")
201  : [_data] "+r"(data),
202  [_waitCycles] "+r"(waitCycles),
203  [_arrayPtr] "+r"(arrayPtr),
204  [_bits] "+r"(bits),
205  [_words] "+r"(words)
206  : [_mask] "r"(this->m_pin.get_mask()),
207  [_bitCycles] "r"(this->m_bitCycles),
208  [_totalBits] "r"(this->m_totalBits),
209  [_stopBitMask] "r"(this->m_stopBitMask),
210  [_dataMask] "r"(this->m_dataMask),
211  [_parityMask] "r"(this->m_parityMask));
212  break;
213  }
214 #endif
215  }
216 
217  virtual void put_char (const char c) {
218  this->send((uint16_t) c);
219  }
220 
221  virtual void puts (const char string[]) {
222  const uint32_t length = strlen(string);
223  if (length)
224  this->send_array(string, length);
225  }
226 
227  protected:
236  inline void shift_out_data (uint32_t data, uint32_t bits, const uint32_t bitCycles,
237  const uint32_t txMask) const {
238 #ifndef DOXYGEN_IGNORE
239  volatile uint32_t waitCycles = bitCycles;
240  __asm__ volatile (
241  FC_START("ShiftOutDataStart%=", "ShiftOutDataEnd%=")
242  " add %[_waitCycles], CNT \n\t"
243 
244  "loop%=: \n\t"
245  " waitcnt %[_waitCycles], %[_bitCycles] \n\t"
246  " shr %[_data],#1 wc \n\t"
247  " muxc outa, %[_mask] \n\t"
248  " djnz %[_bits], #" FC_ADDR("loop%=", "ShiftOutDataStart%=") " \n\t"
249  FC_END("ShiftOutDataEnd%=")
250  : [_data] "+r"(data),
251  [_waitCycles] "+r"(waitCycles),
252  [_bits] "+r"(bits)
253  : [_mask] "r"(txMask),
254  [_bitCycles] "r"(bitCycles));
255 #endif
256  }
257 
258  protected:
259  Pin m_pin;
260 };
261 
262 #ifdef __PROPELLER_COG__
263 #undef virtual
264 #endif
265 
266 }
PropWare::UARTTX::put_char
virtual void put_char(const char c)
Print a single character.
Definition: uarttx.h:217
PropWare::UART::Parity::ODD_PARITY
@ ODD_PARITY
PropWare::Port::set_dir_out
void set_dir_out() const
Set the port for output.
Definition: port.h:210
uart.h
PropWare::Pin::set_mask
void set_mask(const Pin::Mask mask)
Definition: pin.h:80
PropWare::UART::Parity::NO_PARITY
@ NO_PARITY
PropWare::UART
Abstract base class for all unbuffered UART devices.
Definition: uart.h:86
PropWare::Port::Mask
Mask
Definition: port.h:43
PropWare::UARTTX::puts
virtual void puts(const char string[])
Send a null-terminated character array. Though this method could be created using put_char,...
Definition: uarttx.h:221
PropWare::UARTTX
Definition: uarttx.h:38
PropWare::Port::set_dir_in
void set_dir_in() const
Set the port for input.
Definition: port.h:217
PropWare::PrintCapable
Interface for all classes capable of printing.
Definition: printcapable.h:38
PropWare::Port::set
void set() const
Set selected output port high (set all pins to 1)
Definition: port.h:226
PropWare::UART::Parity::EVEN_PARITY
@ EVEN_PARITY
printcapable.h
pin.h
PropWare
Generic definitions and functions for the Parallax Propeller.
Definition: runnable.h:33
PropWare::Port::clear
void clear() const
Clear selected output port (set it to 0)
Definition: port.h:249