Skip to content

Commit 91a77d7

Browse files
committed
With the old logic if Serial::writeable() was called before and/or used to block calls to Serial::putc() it would never write due to EVENT_TXDRDY trailing a write to TXD. Add a dummy write to TXD before pins are connected to the peripheral. This primes the EVENT_TXDRDY to lead future writes rather than trail. Since STOPTX isn't used this seems safe.
1 parent 3fb8590 commit 91a77d7

File tree

2 files changed

+21
-19
lines changed
  • libraries/mbed/targets
    • cmsis/TARGET_NORDIC/TARGET_MCU_NRF51822
    • hal/TARGET_NORDIC/TARGET_MCU_NRF51822

2 files changed

+21
-19
lines changed

libraries/mbed/targets/cmsis/TARGET_NORDIC/TARGET_MCU_NRF51822/nrf51.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,8 @@ typedef struct { /*!< UART Structure
376376
__IO uint32_t EVENTS_RXTO; /*!< Receiver timeout. */
377377
__I uint32_t RESERVED5[46];
378378
__IO uint32_t SHORTS; /*!< Shortcuts for TWI. */
379-
__I uint32_t RESERVED6[64];
379+
__I uint32_t RESERVED6[63];
380+
__IO uint32_t INTEN; /*!< Interrupt enable register. */
380381
__IO uint32_t INTENSET; /*!< Interrupt enable set register. */
381382
__IO uint32_t INTENCLR; /*!< Interrupt enable clear register. */
382383
__I uint32_t RESERVED7[93];
@@ -1213,4 +1214,3 @@ typedef struct { /*!< GPIO Structure
12131214

12141215

12151216
#endif /* nRF51_H */
1216-

libraries/mbed/targets/hal/TARGET_NORDIC/TARGET_MCU_NRF51822/serial_api.c

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -56,20 +56,12 @@ void serial_init(serial_t *obj, PinName tx, PinName rx) {
5656
obj->uart = (NRF_UART_Type *)uart;
5757

5858
//pin configurations --
59-
//outputs
6059
NRF_GPIO->DIR |= (1 << tx); //TX_PIN_NUMBER);
6160
NRF_GPIO->DIR |= (1 << RTS_PIN_NUMBER);
6261

6362
NRF_GPIO->DIR &= ~(1 << rx); //RX_PIN_NUMBER);
6463
NRF_GPIO->DIR &= ~(1 << CTS_PIN_NUMBER);
6564

66-
obj->uart->PSELRTS = RTS_PIN_NUMBER;
67-
obj->uart->PSELTXD = tx; //TX_PIN_NUMBER;
68-
69-
//inputs
70-
obj->uart->PSELCTS = CTS_PIN_NUMBER;
71-
obj->uart->PSELRXD = rx; //RX_PIN_NUMBER;
72-
7365

7466
// set default baud rate and format
7567
serial_baud (obj, 9600);
@@ -79,8 +71,16 @@ void serial_init(serial_t *obj, PinName tx, PinName rx) {
7971
obj->uart->TASKS_STARTTX = 1;
8072
obj->uart->TASKS_STARTRX = 1;
8173
obj->uart->EVENTS_RXDRDY = 0;
74+
// dummy write needed or TXDRDY trails write rather than leads write.
75+
// pins are disconnected so nothing is physically transmitted on the wire
76+
obj->uart->TXD = 0;
8277

8378
obj->index = 0;
79+
80+
obj->uart->PSELRTS = RTS_PIN_NUMBER;
81+
obj->uart->PSELTXD = tx; //TX_PIN_NUMBER;
82+
obj->uart->PSELCTS = CTS_PIN_NUMBER;
83+
obj->uart->PSELRXD = rx; //RX_PIN_NUMBER;
8484

8585
// set rx/tx pins in PullUp mode
8686
if (tx != NC) {
@@ -194,24 +194,27 @@ void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable)
194194
if (enable) {
195195
switch (irq) {
196196
case RxIrq:
197-
obj->uart->INTENSET |= (UART_INTENSET_RXDRDY_Msk);
197+
obj->uart->INTEN |= (UART_INTENSET_RXDRDY_Msk);
198198
break;
199199
case TxIrq:
200-
obj->uart->INTENSET |= (UART_INTENSET_TXDRDY_Msk);
200+
obj->uart->INTEN |= (UART_INTENSET_TXDRDY_Msk);
201201
break;
202202
}
203203
NVIC_SetPriority(irq_n, 3);
204204
NVIC_EnableIRQ(irq_n);
205205
} else { // disable
206+
// maseked writes to INTENSET dont disable and masked writes to
207+
// INTENCLR seemed to clear the entire register, not bits.
208+
// Added INTEN to memory map and seems to allow set and clearing of specific bits as desired
206209
int all_disabled = 0;
207210
switch (irq) {
208211
case RxIrq:
209-
obj->uart->INTENSET &= ~(UART_INTENSET_RXDRDY_Msk);
210-
all_disabled = (obj->uart->INTENSET & (UART_INTENSET_TXDRDY_Msk))==0;
212+
obj->uart->INTEN &= ~(UART_INTENCLR_RXDRDY_Msk);
213+
all_disabled = (obj->uart->INTENCLR & (UART_INTENCLR_TXDRDY_Msk)) == 0;
211214
break;
212215
case TxIrq:
213-
obj->uart->INTENSET &= ~(UART_INTENSET_TXDRDY_Msk);
214-
all_disabled = (obj->uart->INTENSET & (UART_INTENSET_RXDRDY_Msk))==0;
216+
obj->uart->INTEN &= ~(UART_INTENCLR_TXDRDY_Msk);
217+
all_disabled = (obj->uart->INTENCLR & (UART_INTENCLR_RXDRDY_Msk)) == 0;
215218
break;
216219
}
217220

@@ -236,12 +239,11 @@ int serial_getc(serial_t *obj)
236239

237240
void serial_putc(serial_t *obj, int c)
238241
{
239-
obj->uart->TXD = (uint8_t)c;
240-
241242
while (!serial_writable(obj)) {
242243
}
243244

244245
obj->uart->EVENTS_TXDRDY = 0;
246+
obj->uart->TXD = (uint8_t)c;
245247
}
246248

247249
int serial_readable(serial_t *obj)
@@ -251,7 +253,7 @@ int serial_readable(serial_t *obj)
251253

252254
int serial_writable(serial_t *obj)
253255
{
254-
return (obj->uart->EVENTS_TXDRDY ==1);
256+
return (obj->uart->EVENTS_TXDRDY == 1);
255257
}
256258

257259
void serial_break_set(serial_t *obj)

0 commit comments

Comments
 (0)