Skip to content

Commit

Permalink
Adds drain ioctl. (#539)
Browse files Browse the repository at this point in the history
* Adds an IOCTL to the CC32xx UART driver that allows getting a notification
when transmission has completed.

* Adds comment.

* removes unnecessary volatile tag
  • Loading branch information
balazsracz authored May 8, 2021
1 parent f3f1882 commit 3ccdbb7
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 0 deletions.
5 changes: 5 additions & 0 deletions include/freertos/tc_ioctl.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,5 +47,10 @@
#define TCPARONE IO(TERMIOS_IOC_MAGIC, 0xF3)
#define TCPARZERO IO(TERMIOS_IOC_MAGIC, 0xF4)

/// Argument is a Notifiable* pointer. This notifiable will be invoked when all
/// bytes have completed transferring and the transmit engine is idle.
#define TCDRAINNOTIFY IOW(TERMIOS_IOC_MAGIC, 0xE0, 4)


#endif // _FREERTOS_TC_IOCTL_H_

30 changes: 30 additions & 0 deletions src/freertos_drivers/ti/CC32xxUart.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,14 @@
#include "driverlib/prcm.h"
#include "driverlib/utils.h"
#include "freertos/tc_ioctl.h"
#include "executor/Notifiable.hxx"

#include "CC32xxUart.hxx"

/** Instance pointers help us get context from the interrupt handler(s) */
static CC32xxUart *instances[2] = {NULL};
/** Critical section lock between ISR and ioctl */
static Atomic isr_lock;

/** Constructor.
* @param name name of this device instance in the file system
Expand Down Expand Up @@ -155,6 +158,27 @@ int CC32xxUart::ioctl(File *file, unsigned long int key, unsigned long data)
case TCPARZERO:
MAP_UARTParityModeSet(base, UART_CONFIG_PAR_ZERO);
break;
case TCDRAINNOTIFY:
{
Notifiable* arg = (Notifiable*)data;
{
AtomicHolder h(&isr_lock);
if (txComplete != nullptr)
{
return -EBUSY;
}
if (txPending)
{
txComplete = arg;
arg = nullptr;
}
}
if (arg)
{
arg->notify();
}
break;
}
}

return 0;
Expand Down Expand Up @@ -254,6 +278,12 @@ void CC32xxUart::interrupt_handler()
txEnableDeassert();
}
txPending = false;
if (txComplete)
{
Notifiable *t = txComplete;
txComplete = nullptr;
t->notify_from_isr();
}
MAP_UARTIntDisable(base, UART_INT_TX);
}
}
Expand Down
5 changes: 5 additions & 0 deletions src/freertos_drivers/ti/CC32xxUart.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@

#include "driverlib/uart.h"

class Notifiable;

/** Specialization of Serial driver for CC32xx UART.
*/
class CC32xxUart : public Serial
Expand Down Expand Up @@ -110,6 +112,9 @@ private:
/** function pointer to a method that deasserts the transmit enable. */
TxEnableMethod txEnableDeassert;

/** Notifiable to invoke when the transmit engine has finished operation. */
Notifiable* txComplete{nullptr};

unsigned long base; /**< base address of this device */
unsigned long interrupt; /**< interrupt of this device */
bool txPending; /**< transmission currently pending */
Expand Down

0 comments on commit 3ccdbb7

Please sign in to comment.