espressif_tinyusb/src/host/ohci/ohci.h

303 lines
9.6 KiB
C
Raw Normal View History

2013-12-11 08:31:27 +01:00
/**************************************************************************/
/*!
@file ohci.h
@author hathach (tinyusb.org)
@section LICENSE
Software License Agreement (BSD License)
Copyright (c) 2013, hathach (tinyusb.org)
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holders nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This file is part of the tinyusb stack.
*/
/**************************************************************************/
2014-03-16 16:20:33 +01:00
/** \ingroup Group_HCD
2013-12-11 08:31:27 +01:00
* @{
* \defgroup OHCI
* \brief OHCI driver. All documents sources mentioned here (eg section 3.5) is referring to OHCI Specs unless state otherwise
2014-03-16 16:20:33 +01:00
* @{ */
2013-12-11 08:31:27 +01:00
#ifndef _TUSB_OHCI_H_
#define _TUSB_OHCI_H_
#ifdef __cplusplus
extern "C" {
#endif
2018-03-12 16:45:35 +01:00
#include "common/tusb_common.h"
2013-12-11 08:31:27 +01:00
//--------------------------------------------------------------------+
// OHCI CONFIGURATION & CONSTANTS
//--------------------------------------------------------------------+
#define HOST_HCD_XFER_INTERRUPT // TODO interrupt is used widely, should always be enalbed
#define OHCI_PERIODIC_LIST (defined HOST_HCD_XFER_INTERRUPT || defined HOST_HCD_XFER_ISOCHRONOUS)
// TODO merge OHCI with EHCI
enum {
OHCI_MAX_ITD = 4
};
2013-12-11 08:31:27 +01:00
enum {
OHCI_PID_SETUP = 0,
OHCI_PID_OUT,
OHCI_PID_IN,
};
2013-12-11 08:31:27 +01:00
//--------------------------------------------------------------------+
// OHCI Data Structure
//--------------------------------------------------------------------+
typedef struct {
uint32_t interrupt_table[32];
volatile uint16_t frame_number;
volatile uint16_t frame_pad;
volatile uint32_t done_head;
uint8_t reserved[116+4]; // TODO try to make use of this area if possible, extra 4 byte to make the whole struct size = 256
2013-12-11 08:31:27 +01:00
}ohci_hcca_t; // ATTR_ALIGNED(256)
TU_VERIFY_STATIC( sizeof(ohci_hcca_t) == 256, "size is not correct" );
typedef struct {
uint32_t reserved[2];
2018-12-11 10:29:43 +01:00
volatile uint32_t next;
uint32_t reserved2;
}ohci_td_item_t;
2018-12-11 10:18:56 +01:00
typedef struct ATTR_ALIGNED(16)
{
// Word 0
uint32_t used : 1;
uint32_t index : 4; // endpoint index the td belongs to, or device address in case of control xfer
uint32_t expected_bytes : 13; // TODO available for hcd
2013-12-11 08:31:27 +01:00
uint32_t buffer_rounding : 1;
uint32_t pid : 2;
uint32_t delay_interrupt : 3;
volatile uint32_t data_toggle : 2;
volatile uint32_t error_count : 2;
volatile uint32_t condition_code : 4;
2018-12-11 10:18:56 +01:00
// Word 1
2013-12-11 08:31:27 +01:00
volatile uint8_t* current_buffer_pointer;
2018-12-11 10:29:43 +01:00
// Word 2 : next TD
volatile uint32_t next;
2013-12-11 08:31:27 +01:00
2018-12-11 10:18:56 +01:00
// Word 3
2013-12-11 08:31:27 +01:00
uint8_t* buffer_end;
} ohci_gtd_t;
2013-12-11 08:31:27 +01:00
TU_VERIFY_STATIC( sizeof(ohci_gtd_t) == 16, "size is not correct" );
2013-12-11 08:31:27 +01:00
2018-12-11 10:29:43 +01:00
typedef struct ATTR_ALIGNED(16)
{
// Word 0
uint32_t dev_addr : 7;
uint32_t ep_number : 4;
uint32_t pid : 2; // 00b from TD, 01b Out, 10b In
uint32_t speed : 1;
uint32_t skip : 1;
uint32_t is_iso : 1;
uint32_t max_packet_size : 11;
// HCD: make use of 5 reserved bits
uint32_t used : 1;
uint32_t is_interrupt_xfer : 1;
uint32_t is_stalled : 1;
uint32_t : 2;
2018-12-11 10:29:43 +01:00
// Word 1
uint32_t td_tail;
2013-12-11 08:31:27 +01:00
2018-12-11 10:29:43 +01:00
// Word 2
volatile union {
uint32_t address;
2013-12-11 08:31:27 +01:00
struct {
uint32_t halted : 1;
uint32_t toggle : 1;
uint32_t : 30;
2013-12-11 08:31:27 +01:00
};
}td_head;
2013-12-11 08:31:27 +01:00
2018-12-11 10:29:43 +01:00
// Word 3: next ED (4 lsb bits are free to use )
uint32_t next;
} ohci_ed_t;
2013-12-11 08:31:27 +01:00
TU_VERIFY_STATIC( sizeof(ohci_ed_t) == 16, "size is not correct" );
2013-12-11 08:31:27 +01:00
2018-12-11 10:29:43 +01:00
typedef struct ATTR_ALIGNED(32)
{
2013-12-11 08:31:27 +01:00
/*---------- Word 1 ----------*/
uint32_t starting_frame : 16;
uint32_t : 5; // can be used
uint32_t delay_interrupt : 3;
uint32_t frame_count : 3;
uint32_t : 1; // can be used
volatile uint32_t condition_code : 4;
/*---------- Word 2 ----------*/
uint32_t buffer_page0; // 12 lsb bits can be used
/*---------- Word 3 ----------*/
2018-12-11 10:29:43 +01:00
volatile uint32_t next;
2013-12-11 08:31:27 +01:00
/*---------- Word 4 ----------*/
uint32_t buffer_end;
/*---------- Word 5-8 ----------*/
volatile uint16_t offset_packetstatus[8];
} ochi_itd_t;
2013-12-11 08:31:27 +01:00
TU_VERIFY_STATIC( sizeof(ochi_itd_t) == 32, "size is not correct" );
2013-12-11 08:31:27 +01:00
// structure with member alignment required from large to small
typedef struct ATTR_ALIGNED(256) {
2013-12-11 08:31:27 +01:00
ohci_hcca_t hcca;
2013-12-17 05:26:39 +01:00
ohci_ed_t bulk_head_ed; // static bulk head (dummy)
ohci_ed_t period_head_ed; // static periodic list head (dummy)
// control endpoints has reserved resources
2013-12-11 08:31:27 +01:00
struct {
ohci_ed_t ed;
2018-12-11 10:18:56 +01:00
ohci_gtd_t gtd;
2018-04-10 09:31:11 +02:00
}control[CFG_TUSB_HOST_DEVICE_MAX+1];
2013-12-11 08:31:27 +01:00
2018-12-11 10:18:56 +01:00
// ochi_itd_t itd[OHCI_MAX_ITD]; // itd requires alignment of 32
ohci_ed_t ed_pool[HCD_MAX_ENDPOINT];
ohci_gtd_t gtd_pool[HCD_MAX_XFER];
2013-12-11 08:31:27 +01:00
} ohci_data_t;
2013-12-11 08:31:27 +01:00
//--------------------------------------------------------------------+
// OHCI Operational Register
//--------------------------------------------------------------------+
//--------------------------------------------------------------------+
// OHCI Data Organization
//--------------------------------------------------------------------+
typedef volatile struct
{
uint32_t revision;
union {
uint32_t control;
struct {
uint32_t control_bulk_service_ratio : 2;
uint32_t periodic_list_enable : 1;
uint32_t isochronous_enable : 1;
uint32_t control_list_enable : 1;
uint32_t bulk_list_enable : 1;
uint32_t hc_functional_state : 2;
uint32_t interrupt_routing : 1;
uint32_t remote_wakeup_connected : 1;
uint32_t remote_wakeup_enale : 1;
uint32_t : 0;
}control_bit;
};
union {
uint32_t command_status;
struct {
uint32_t controller_reset : 1;
uint32_t control_list_filled : 1;
uint32_t bulk_list_filled : 1;
uint32_t ownership_change_request : 1;
uint32_t : 12;
uint32_t scheduling_overrun_count : 2;
}command_status_bit;
};
uint32_t interrupt_status;
uint32_t interrupt_enable;
uint32_t interrupt_disable;
uint32_t hcca;
uint32_t period_current_ed;
uint32_t control_head_ed;
uint32_t control_current_ed;
uint32_t bulk_head_ed;
uint32_t bulk_current_ed;
uint32_t done_head;
uint32_t frame_interval;
uint32_t frame_remaining;
uint32_t frame_number;
uint32_t periodic_start;
uint32_t lowspeed_threshold;
uint32_t rh_descriptorA;
uint32_t rh_descriptorB;
union {
uint32_t rh_status;
struct {
uint32_t local_power_status : 1; // read Local Power Status; write: Clear Global Power
uint32_t over_current_indicator : 1;
uint32_t : 13;
uint32_t device_remote_wakeup_enable : 1;
uint32_t local_power_status_change : 1;
uint32_t over_current_indicator_change : 1;
uint32_t : 13;
uint32_t clear_remote_wakeup_enable : 1;
}rh_status_bit;
};
union {
uint32_t rhport_status[2]; // TODO NXP OHCI controller only has 2 ports
struct {
uint32_t current_connect_status : 1;
uint32_t port_enable_status : 1;
uint32_t port_suspend_status : 1;
uint32_t port_over_current_indicator : 1;
uint32_t port_reset_status : 1;
uint32_t : 3;
uint32_t port_power_status : 1;
uint32_t low_speed_device_attached : 1;
uint32_t : 6;
uint32_t connect_status_change : 1;
uint32_t port_enable_status_change : 1;
uint32_t port_suspend_status_change : 1;
uint32_t port_over_current_indicator_change : 1;
uint32_t port_reset_status_change : 1;
uint32_t : 0;
}rhport_status_bit[2];
};
}ohci_registers_t;
TU_VERIFY_STATIC( sizeof(ohci_registers_t) == 0x5c, "size is not correct");
2013-12-11 08:31:27 +01:00
#ifdef __cplusplus
}
#endif
#endif /* _TUSB_OHCI_H_ */
/** @} */
/** @} */