Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 176829e

Browse files
Merge pull request #465 from maidnl/soft_serial_missing_end_fix
Added end() function to Soft Serial - fix for #463
2 parents 16bdbea + 84fb637 commit 176829e

File tree

4 files changed

+82
-30
lines changed

4 files changed

+82
-30
lines changed

‎cores/arduino/FspLinkIrq.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ typedef enum {
1616

1717
extern int attachIrq2Link(uint32_t pin, PinStatus mode);
1818
extern int detachIrq2Link(pin_size_t pinNumber);
19+
extern int getIrqIndexFromPin(uint32_t pin);
1920

2021
/* Wrapper class for FSP ELC
2122
at the present only support the link of an external Irq to a peripheral */

‎cores/arduino/Interrupts.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,21 @@ void attachInterrupt(pin_size_t pinNumber, voidFuncPtr func, PinStatus mode) {
193193
attachInterruptParam(pinNumber, (voidFuncPtrParam)func, mode, NULL);
194194
}
195195

196+
197+
int getIrqIndexFromPin(uint32_t pinNumber) {
198+
CIrq *irq_context = nullptr;
199+
int rv = -1;
200+
int ch = pin2IrqChannel(pinNumber);
201+
if(ch >= 0 && ch < MAX_IRQ_CHANNEL) {
202+
irq_context = IrqChannel.get(ch,false);
203+
if(irq_context != nullptr) {
204+
rv = irq_context->cfg.irq;
205+
}
206+
}
207+
return rv;
208+
}
209+
210+
196211
int attachIrq2Link(uint32_t pinNumber, PinStatus mode) {
197212
CIrq *irq_context = nullptr;
198213
int ch = pin2IrqChannel(pinNumber);

‎libraries/SoftwareSerial/src/SoftwareSerial.cpp

Lines changed: 64 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ void dma_tx_callback(dmac_callback_args_t *args);
4848
void dma_rx_callback(dmac_callback_args_t *args);
4949

5050
extern int attachIrq2Link(uint32_t pin, PinStatus mode);
51+
extern int getIrqIndexFromPin(uint32_t pin);
5152
typedef void (*fsp_dma_callback_t) (dmac_callback_args_t *args);
5253

5354
static uint32_t tx_get_sample(bsp_io_port_pin_t tx, ioport_size_t value)
@@ -192,6 +193,7 @@ SoftwareSerial::SoftwareSerial(uint8_t rx_pin, uint8_t tx_pin, size_t bufsize):
192193
assert(rx_pin < NUM_DIGITAL_PINS);
193194
_tx_pin = tx_pin;
194195
_rx_pin = rx_pin;
196+
initialized = false;
195197
}
196198

197199
SoftwareSerial::~SoftwareSerial()
@@ -228,17 +230,26 @@ int SoftwareSerial::begin(uint32_t baudrate, uint32_t sconfig, bool inverted)
228230
IOPORT_CFG_PORT_DIRECTION_OUTPUT | IOPORT_CFG_PORT_OUTPUT_HIGH);
229231
#endif
230232

233+
/* TX pin configuration */
234+
231235
R_IOPORT_PinCfg(&g_ioport_ctrl, tx_descr.pin, IOPORT_CFG_PORT_DIRECTION_OUTPUT
232236
| IOPORT_CFG_PULLUP_ENABLE | IOPORT_CFG_PORT_OUTPUT_HIGH);
233237

234-
// Enable RX pin IRQ.
235-
rx_descr.irq_chan = attachIrq2Link(_rx_pin, CHANGE);
236-
if (rx_descr.irq_chan != -1) {
237-
// TODO: workaround for the core not setting pull-ups.
238-
R_IOPORT_PinCfg(&g_ioport_ctrl, rx_descr.pin, IOPORT_CFG_PORT_DIRECTION_INPUT
239-
| IOPORT_CFG_PULLUP_ENABLE | IOPORT_CFG_IRQ_ENABLE);
238+
/* RX pin configuration */
239+
240+
/* avoid to call attachIrq2Link if already used because it "consumes" irq
241+
indexes in the NVIC */
242+
int irq_index = getIrqIndexFromPin(_rx_pin);
243+
if(irq_index == -1) {
244+
rx_descr.irq_chan = attachIrq2Link(_rx_pin, CHANGE); // Enable RX pin IRQ.
245+
} else {
246+
R_BSP_IrqEnable ((IRQn_Type)irq_index);
240247
}
241248

249+
R_IOPORT_PinCfg(&g_ioport_ctrl, rx_descr.pin, IOPORT_CFG_PORT_DIRECTION_INPUT
250+
| IOPORT_CFG_PULLUP_ENABLE | IOPORT_CFG_IRQ_ENABLE);
251+
252+
242253
// Set serial configuration.
243254
config.bitshift = (rx_descr.pin & 0xFF);
244255
config.polarity = (inverted) ? 1 : 0;
@@ -279,34 +290,36 @@ int SoftwareSerial::begin(uint32_t baudrate, uint32_t sconfig, bool inverted)
279290
// be calculated, and the start/stop samples can be prepopulated in the DMA TX buffer.
280291
config.nsamples = (1 + config.databits + (!!config.parity) + config.stopbits);
281292

282-
// Prepopulate start and stop bits samples.
283-
tx_descr.dmabuf[0][0] = tx_get_sample(tx_descr.pin, 0);
284-
for (size_t i=0; i<config.stopbits; i++) {
285-
tx_descr.dmabuf[0][config.nsamples-1-i] = tx_get_sample(tx_descr.pin, 1);
286-
}
293+
if(!initialized) {
294+
// Prepopulate start and stop bits samples.
295+
tx_descr.dmabuf[0][0] = tx_get_sample(tx_descr.pin, 0);
296+
for (size_t i=0; i<config.stopbits; i++) {
297+
tx_descr.dmabuf[0][config.nsamples-1-i] = tx_get_sample(tx_descr.pin, 1);
298+
}
287299

288-
// Configure the TX DMA and its tigger timer.
289-
R_PORT0_Type *tx_port = SS_PORT_ADDR(((tx_descr.pin >> 8) & 0xFF));
290-
if (fsp_tim_config(&tx_descr.tim, config.baudrate, false) != 0) {
291-
return 0;
292-
}
300+
// Configure the TX DMA and its tigger timer.
301+
R_PORT0_Type *tx_port = SS_PORT_ADDR(((tx_descr.pin >> 8) & 0xFF));
302+
if (fsp_tim_config(&tx_descr.tim, config.baudrate, false) != 0) {
303+
return 0;
304+
}
293305

294-
if (fsp_dma_config(&tx_descr.dma, SS_DMA_CHANNEL_TX,
295-
fsp_tim_to_elc_event(tx_descr.tim.get_channel()), tx_descr.dmabuf[0],
296-
(void *) &tx_port->PCNTR3, config.nsamples, dma_tx_callback, this) != 0) {
297-
return 0;
298-
}
306+
if (fsp_dma_config(&tx_descr.dma, SS_DMA_CHANNEL_TX,
307+
fsp_tim_to_elc_event(tx_descr.tim.get_channel()), tx_descr.dmabuf[0],
308+
(void *) &tx_port->PCNTR3, config.nsamples, dma_tx_callback, this) != 0) {
309+
return 0;
310+
}
299311

300-
// Configure the RX DMA and its trigger timer.
301-
R_PORT0_Type *rx_port = SS_PORT_ADDR(((rx_descr.pin >> 8) & 0xFF));
302-
if (fsp_tim_config(&rx_descr.tim, config.baudrate, true) != 0) {
303-
return 0;
304-
}
312+
// Configure the RX DMA and its trigger timer.
313+
R_PORT0_Type *rx_port = SS_PORT_ADDR(((rx_descr.pin >> 8) & 0xFF));
314+
if (fsp_tim_config(&rx_descr.tim, config.baudrate, true) != 0) {
315+
return 0;
316+
}
305317

306-
if (fsp_dma_config(&rx_descr.dma, SS_DMA_CHANNEL_RX,
307-
fsp_tim_to_elc_event(rx_descr.tim.get_channel()), rx_descr.dmabuf[0],
308-
(void *) &rx_port->PCNTR2, config.nsamples, dma_rx_callback, this) != 0) {
309-
return 0;
318+
if (fsp_dma_config(&rx_descr.dma, SS_DMA_CHANNEL_RX,
319+
fsp_tim_to_elc_event(rx_descr.tim.get_channel()), rx_descr.dmabuf[0],
320+
(void *) &rx_port->PCNTR2, config.nsamples, dma_rx_callback, this) != 0) {
321+
return 0;
322+
}
310323
}
311324

312325
// Configure and enable the ELC.
@@ -324,6 +337,27 @@ int SoftwareSerial::begin(uint32_t baudrate, uint32_t sconfig, bool inverted)
324337
tx_descr.pin, rx_descr.pin, config.bitshift, (config.polarity) ? "Inverted" : "Normal",
325338
config.nsamples, config.baudrate, config.databits, parity_tostr[config.parity], config.stopbits);
326339
#endif
340+
341+
initialized = true;
342+
return 1;
343+
}
344+
345+
int SoftwareSerial::end() {
346+
int irq_index = getIrqIndexFromPin(_rx_pin);
347+
348+
if(irq_index != -1) {
349+
R_BSP_IrqDisable((IRQn_Type)irq_index);
350+
R_BSP_IrqStatusClear((IRQn_Type)irq_index);
351+
}
352+
353+
if(initialized) {
354+
// put rx and tx pin as input
355+
R_IOPORT_PinCfg(&g_ioport_ctrl, tx_descr.pin, IOPORT_CFG_PORT_DIRECTION_INPUT);
356+
R_IOPORT_PinCfg(&g_ioport_ctrl, rx_descr.pin, IOPORT_CFG_PORT_DIRECTION_INPUT);
357+
358+
R_ELC_Disable(&elc_ctrl);
359+
R_ELC_Close(&elc_ctrl);
360+
}
327361
return 1;
328362
}
329363

‎libraries/SoftwareSerial/src/SoftwareSerial.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ class SoftwareSerial : public Stream, public arduino::Printable {
7070
ss_descr_t<2> rx_descr;
7171
uint8_t _tx_pin, _rx_pin;
7272
void rx_process();
73+
bool initialized;
7374

7475
public:
7576
using Print::write;
@@ -83,6 +84,7 @@ class SoftwareSerial : public Stream, public arduino::Printable {
8384
int peek();
8485
virtual size_t write(uint8_t byte);
8586
virtual int available();
87+
virtual int end();
8688
};
8789

8890
#endif //__SOFTWARE_SERIAL_H__

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /