⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usbs_upd985xx.c

📁 NEC的USB接口驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
#define EPtx_CR_MAXPx_MASK              (0x7F << 0)#define EPtx_CR_MAXPx_SHIFT             0#define EPrx_CR_EPxEN                   (0x01 << 31)#define EPrx_CR_SSx                     (0x01 << 18)#define EPrx_CR_NHSKx                   (0x01 << 17)#define EPrx_CR_NAKx                    (0x01 << 16)#define EPrx_CR_MAXPx_MASK              (0x7F << 0)#define EPrx_CR_MAXPx_SHIFT             0// USB command register#define USBS_CMR_BUSY                   (0x01 << 31)#define USBS_CMR_COMMAND_MASK           (0x07 << 24)#define USBS_CMR_COMMAND_SHIFT          24#define USBS_CMR_COMMAND_TX_EP0         (0x00 << 24)#define USBS_CMR_COMMAND_TX_EP1         (0x01 << 24)#define USBS_CMR_COMMAND_TX_EP3         (0x02 << 24)#define USBS_CMR_COMMAND_TX_EP5         (0x03 << 24)#define USBS_CMR_COMMAND_ADD_POOL0      (0x04 << 24)#define USBS_CMR_COMMAND_ADD_POOL1      (0x05 << 24)#define USBS_CMR_COMMAND_ADD_POOL2      (0x06 << 24)#define USBS_CMR_SIZE_MASK              (0x0FFFF << 0)#define USBS_CMR_SIZE_SHIFT             0// TX Endpoint status#define USBS_TEPSR_EP5TS_MASK           (0x03 << 24)#define USBS_TEPSR_EP5TS_SHIFT          24#define USBS_TEPSR_EP5TS_IDLE           (0x00 << 24)#define USBS_TEPSR_EP5TS_ONE            (0x01 << 24)#define USBS_TEPSR_EP5TS_TWO            (0x02 << 24)#define USBS_TEPSR_EP3TS_MASK           (0x03 << 16)#define USBS_TEPSR_EP3TS_SHIFT          16#define USBS_TEPSR_EP3TS_IDLE           (0x00 << 16)#define USBS_TEPSR_EP3TS_ONE            (0x01 << 16)#define USBS_TEPSR_EP3TS_TWO            (0x02 << 16)#define USBS_TEPSR_EP1TS_MASK           (0x03 << 8)#define USBS_TEPSR_EP1TS_SHIFT          8#define USBS_TEPSR_EP1TS_IDLE           (0x00 << 8)#define USBS_TEPSR_EP1TS_ONE            (0x01 << 8)#define USBS_TEPSR_EP1TS_TWO            (0x02 << 8)#define USBS_TEPSR_EP0TS_MASK           (0x03 << 0)#define USBS_TEPSR_EP0TS_SHIFT          0#define USBS_TEPSR_EP0TS_IDLE           (0x00 << 0)#define USBS_TEPSR_EP0TS_ONE            (0x01 << 0)#define USBS_TEPSR_EP0TS_TWO            (0x02 << 0)// Receive pools. The RP0IR, RP1IR and RP2IR registers// all use the same bits.#define USBS_RPxIR_AL_MASK              (0x07 << 28)#define USBS_RPxIR_AL_SHIFT             28#define USBS_RPxIR_AL_NONE              (0 << 28)#define USBS_RPxIR_RNOD_MASK            (0x0FFFF << 0)#define USBS_RPxIR_RNOD_SHIFT           0// The other registers do not have special bits.// Data transfers involve buffer descriptors and mailboxes. The// relevant data structures and fields need to be defined. For now// assume 32-bit mode of operation, i.e. there will be no padding// between two successive 32-bit entities// A transmit packet directory consists of up to 255 buffer// descriptors. Each buffer descriptor specifies a buffer and a size// of up to 64K. typedef struct TxBufferDescriptor {    cyg_uint32  control;    void*       buffer;} TxBufferDescriptor;#define TXBUFDESC_CTRL_LAST                     (0x01 << 31)#define TXBUFDESC_CTRL_BUFDESC_MASK             (0x01 << 30)#define TXBUFDESC_CTRL_BUFDESC_SHIFT            30#define TXBUFDESC_CTRL_BUFDESC_LINK             (0x00 << 30)#define TXBUFDESC_CTRL_BUFDESC_BUFDESC          (0x01 << 30)#define TXBUFDESC_CTRL_SIZE_MASK                (0x0FFFF << 0)#define TXBUFDESC_CTRL_SIZE_SHIFT               0// The result of a transmit operation gets written to a mailbox// structure in memory.typedef struct TxMailbox {    cyg_uint32  status;} TxMailbox;#define TXMBOX_STATUS_IBUS_ERROR                (0x01 << 10)#define TXMBOX_STATUS_UNDERRUN                  (0x01 << 9)#define TXMBOX_STATUS_MODE_MASK                 (0x01 << 8)#define TXMBOX_STATUS_MODE_SHIFT                8#define TXMBOX_STATUS_MODE_SZLP                 (0x00 << 8)#define TXMBOX_STATUS_MODE_NZLP                 (0x01 << 8)#define TXMBOX_STATUS_EPN_MASK                  (0x07 << 0)#define TXMBOX_STATUS_EPN_SHIFT                 0#define TXMBOX_STATUS_EPN_EP0                   (0x00 << 0)#define TXMBOX_STATUS_EPN_EP1                   (0x02 << 0)#define TXMBOX_STATUS_EPN_EP3                   (0x04 << 0)#define TXMBOX_STATUS_EPN_EP5                   (0x06 << 0)// Now for receive operations. This involves adding buffer descriptors// to one of three pools. The pools are managed by registers.typedef struct RxBufferDescriptor {    cyg_uint32          control;    void*               buffer;} RxBufferDescriptor;#define RXBUFDESC_CTRL_LAST                     (0x01 << 31)#define RXBUFDESC_CTRL_BUFDESC_MASK             (0x01 << 30)#define RXBUFDESC_CTRL_BUFDESC_SHIFT            30#define RXBUFDESC_CTRL_BUFDESC_LINK             (0x00 << 30)#define RXBUFDESC_CTRL_BUFDESC_BUFDESC          (0x01 << 30)#define RXBUFDESC_CTRL_SIZE_MASK                (0x0FFFF << 0)#define RXBUFDESC_CTRL_SIZE_SHIFT               0typedef struct RxMailbox {    cyg_uint32          status;    void*               address;} RxMailbox;#define RXMBOX_STATUS_EPN_MASK                  (0x07 << 29)#define RXMBOX_STATUS_EPN_SHIFT                 29#define RXMBOX_STATUS_EPN_EP0                   (0x01 << 29)#define RXMBOX_STATUS_EPN_EP2                   (0x03 << 29)#define RXMBOX_STATUS_EPN_EP4                   (0x05 << 29)#define RXMBOX_STATUS_EPN_EP6                   (0x07 << 29)#define RXMBOX_STATUS_CORRUPTION                (0x01 << 25)#define RXMBOX_STATUS_IBUS_ERROR                (0x01 << 24)#define RXMBOX_STATUS_SETUP_MASK                (0x01 << 23)#define RXMBOX_STATUS_SETUP_SHIFT               23#define RXMBOX_STATUS_SETUP_NORMAL              (0x00 << 23)#define RXMBOX_STATUS_SETUP_SETUP               (0x01 << 23)#define RXMBOX_STATUS_OVERRUN                   (0x01 << 22)#define RXMBOX_STATUS_DATA_TOGGLE               (0x01 << 21)#define RXMBOX_STATUS_CRC                       (0x01 << 20)#define RXMBOX_STATUS_BIT_STUFFING              (0x01 << 19)#define RXMBOX_STATUS_64K                       (0x01 << 18)#define RXMBOX_STATUS_MODE_MASK                 (0x03 << 16)#define RXMBOX_STATUS_MODE_SHIFT                16#define RXMBOX_STATUS_MODE_NORMAL               (0x00 << 16)#define RXMBOX_STATUS_MODE_NORMAL2              (0x01 << 16)#define RXMBOX_STATUS_MODE_ASSEMBLE             (0x02 << 16)#define RXMBOX_STATUS_MODE_SEPARATE             (0x03 << 16)#define RXMBOX_STATUS_SIZE_MASK                 (0x0FFFF << 0)#define RXMBOX_STATUS_SIZE_SHIFT                0// ----------------------------------------------------------------------------// Hardware work around - see NEC erratum S1, CPU to IBUS write restriction.// Reading back from the USB device after every write prevents any problems.// Strictly speaking it is only necessary to do this after every three// writes, but if there is concurrent ethernet activity then doing it// after eveyr write is safer. The frame number/version register seems// like a good one to read back from.#ifdef CYGIMP_DEVS_USB_UPD985XX_IBUS_WRITE_LIMIT# define FLUSH_IBUS()   \      CYG_MACRO_START   \      (void)*USBS_VER;  \      CYG_MACRO_END#else# define FLUSH_IBUS()       CYG_EMPTY_STATEMENT#endif// ----------------------------------------------------------------------------// Static data. There is a data structure for each endpoint. The// implementation is essentially a private class that inherits from// common classes for control and data endpoints, but device drivers// are supposed to be written in C so some ugliness is required.//// Devtab entries are defined in usbs_upd985xx_data.cxx to make sure// that the linker does not garbage-collect them.// Support for the interrupt handling code.static cyg_interrupt usbs_upd985xx_intr_data;static cyg_handle_t  usbs_upd985xx_intr_handle;// The various bits in the two interrupt status registers are read-once,// i.e. reading the register clears the bits. Since much of the processing// is deferred to DSR level, it is necessary to keep track of pending// interrupts in separate variables. If another interrupt happens during// DSR processing, these variables will be updated. The main DSR loops// until there are no interesting bits left. Interrupts have to be// disabled briefly when clearing bits.static volatile cyg_uint32 usbs_upd985xx_gsr1   = 0;static volatile cyg_uint32 usbs_upd985xx_gsr2   = 0;// Many of the interrupt bits are of no interest and it is convenient// to mask them out in the ISR, thus avoiding unnecessary dsr// invocations.static cyg_uint32 usbs_upd985xx_gsr1_mask       = 0;static cyg_uint32 usbs_upd985xx_gsr2_mask       = 0;// Sizes for the receive and transmit mboxes.// NOTE: it is not clear what the optimal size for these// mailboxes is. For receives maybe one per rx endpoint,// plus a spare. For transmits maybe just two, since only// one transmit at a time is supported. Mailboxes are// relatively small, so for now four each should be ok.#define RXMBOX_COUNT    4#define TXMBOX_COUNT    4// There is one instance of this data structure. It is allocated// in kseg0 cached memory, but during initialization a separate// pointer value is set to the kseg1 uncached equivalent. This// makes it easier to point the hardware at uncached memory without// having to worry about cache line boundaries everywhere.typedef struct uncached_data {    // This partial cacheline does not actually store any data.    // However it ensures that the data does not share a cacheline    // with some other static, with updates to that other static    // causing funny side effects on the uncached data. There is a    // memory optimisation of subtracting sizeof(RxMailbox.status),    // i.e. exploit knowledge of alignment.    unsigned char       cacheline_start[HAL_DCACHE_LINE_SIZE - sizeof(cyg_uint32)];    RxMailbox           rx_mboxes[RXMBOX_COUNT];    TxMailbox           tx_mboxes[TXMBOX_COUNT];    // For transmits a single buffer descriptor per endpoint suffices.    // If transmit locking is enabled then actually a single buffer    // descriptor for the whole system would suffice.    TxBufferDescriptor  ep0_tx_bufdesc;#ifdef CYGPKG_DEVS_USB_UPD985XX_EP3    TxBufferDescriptor  ep3_tx_bufdesc;#endif#ifdef CYGPKG_DEVS_USB_UPD985XX_EP5    TxBufferDescriptor  ep5_tx_bufdesc;#endif            // More buffer descriptors are needed than might be expected, see    // the start_rx routines.     RxBufferDescriptor  ep0_rx_bufdescs[4];#ifdef CYGPKG_DEVS_USB_UPD985XX_EP4    RxBufferDescriptor  ep4_rx_bufdescs[8];#endif        #ifdef CYGPKG_DEVS_USB_UPD985XX_EP4    // Space for the start and end of a transfer, avoiding problems    // with invalidating partial cache lines.    unsigned char       ep4_head[HAL_DCACHE_LINE_SIZE];    unsigned char       ep4_tail[HAL_DCACHE_LINE_SIZE];#endif        // The "big" buffers come last, reducing the offsets for the previous    // structures. It is not clear this really matters for MIPS.    //    // Endpoint 0 receive and transmit buffers. A transmit buffer is    // convenient because the hardware pretty much expects all of the    // data to be in contiguous memory, as opposed to the normal eCos    // USB driver model with refill buffers etc. An alternative    // implementation would keep the data in separate areas but would    // require lots of TxBufferDescriptors, so in memory terms the    // overheads of a single transmit buffer are not as big as might    // seem. It might be possible to get things working eight bytes    // at a time since the hardware appears to depend on zero-byte    // terminating packets in places, but that has not been attempted.    //    // A separate receive buffer is useful because it can be placed in    // uncached memory, avoiding the need for invalidation and    // worrying about other data in the cache lines. Note that this    // buffer may also get used for endpoint 6 interrupt receives    // because the two endpoints share a single pool.    unsigned char       ep0_rx_buffer[CYGNUM_DEVS_USB_UPD985XX_EP0_RXBUFSIZE];    unsigned char       ep0_tx_buffer[CYGNUM_DEVS_USB_UPD985XX_EP0_TXBUFSIZE];    // Another cacheline to prevent overlap with other statics.    // This has to be full-sized since the previous field is only byte-aligned.    unsigned char       cacheline_end[HAL_DCACHE_LINE_SIZE];} uncached_data;// This data structure is quite large so making it all uninitialized// means a potentially big saving in ROM-booting systems. This// requires additional effort by the endpoint initialization routines.static uncached_data    cached_copy;static uncached_data*   uncached        = (uncached_data*)0;// Endpoint 0. See the description below.static void usbs_upd985xx_ep0_start(usbs_control_endpoint*);static void usbs_upd985xx_poll(usbs_control_endpoint*);typedef struct ep0_impl {    usbs_control_endpoint       common;    cyg_bool                    rx_expecting_data;    cyg_bool                    rx_indicator_valid;    RxMailbox                   rx_indicator;    cyg_bool                    tx_indicator_valid;    TxMailbox                   tx_indicator;    cyg_bool                    tx_needs_zero_transfer;    cyg_uint32                  tx_size;} ep0_impl;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -