Here is the code that is declaring a lot of constants:
#define TD_DATA_PID 0 /* control pipe state for td_sie_done */
#define TD_STATUS_PID 2 /* control pipe state for td_sie_done */
#define TD_DONE_PID 4 /* control pipe state for td_sie_done */
#define TD_DELETE_PID 0xee /* pipe command for td_sie_done */
#define TD_SETUP_PID 0xd /* also used for control pipe state for tf_sie_done */
#define TD_IN_PID 0x9
#define TD_OUT_PID 0x1
#define TD_SOF_PID 0x5
#define TD_PREAMBLE_PID 0xc
#define TD_NAK_PID 0xa
#define TD_STALL_PID 0xe
#define TD_DATA0_PID 0x3
#define TD_DATA1_PID 0xb
#define TD_NORMAL_TIMEOUT 0
#define TD_LONG_TIMEOUT 1
enum TD_CTRL_BITS
{
TD_CTRL_ARM = 0x01,
TD_CTRL_ISOCH = 0x10,
TD_CTRL_SYNC_SOF = 0x20,
TD_CTRL_DTOGGLE = 0x40,
TD_CTRL_PREAMBLE = 0x80
};
enum TD_STATUS_BITS
{
TD_STATUS_ACK = 0x01,
TD_STATUS_ERROR = 0x02,
TD_STATUS_TIMEOUT = 0x04,
TD_STATUS_SEQ = 0x08,
TD_STATUS_SETUP = 0x10,
TD_STATUS_OVERFLOW = 0x20,
TD_STATUS_NAK = 0x40,
TD_STATUS_STALL = 0x80
};
This code is for a USB OTG controller, low level embedded systems stuff and thus uses C rather than C++.
All the #define valus are used to assign value to a single one byte variable. The variable is packet ID, thus all the #define constants end with _PID. That is clear.
However, the part of enums is not clear.
Basically, there is a single byte long register that contains TD_CONTROL_BITS and may want to read/write it. Each bit effects behaviour of the hardware. The values given to each constant inside the enum is the bit that corresponds to that function e.g ARM bit is bit 0 and isochronous transfer bit is bit 2 e.t.c. This register is read and also written to.
Similar applies to TD_STATUS_BITS also. Each bit in the byte long status register provides independant information about the status of transfer. Thus, the constants TD_STATUS_ACK, TD_STATUS_ERROR e.t.c can be used as bit masks to read the status register. This register is only read back as it is updated by external hardware and only a value of 0 is written to reset it.
Now my question is, why not use #define constants for everything? What benefit does enum bring in this case? Also, in case of TD_CTRL_BITS we may want to logically OR bits together e.g TD_CTRL_ARM | TD_CTRL_DTOGGLE. I do not think that enums allow that.