Initial version
Committed on the Free edition of March Hare Software CVSNT Server. Upgrade to CVS Suite for more features and support: http://march-hare.com/cvsnt/ git-svn-id: http://moon:8086/svn/vhdl/trunk@640 cc03376c-175c-47c8-b038-4cd826a8556b
This commit is contained in:
@@ -0,0 +1,949 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include "libsys.h"
|
||||
#include "hpi.h"
|
||||
|
||||
static volatile UINT32 _g_int_active;
|
||||
static volatile UINT32 _g_mbx_return;
|
||||
static volatile UINT32 _g_mbx_in_flag;
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// Globals
|
||||
// ---------------------------------------------------------
|
||||
typedef struct _susb_t
|
||||
{
|
||||
fp_t fptr_ept[USB_MAX_NUM_EPT];
|
||||
void *aptr_ept[USB_MAX_NUM_EPT];
|
||||
|
||||
fp_t fptr_rst;
|
||||
void *aptr_rst;
|
||||
|
||||
fp_t fptr_sof;
|
||||
void *aptr_sof;
|
||||
|
||||
fp_t fptr_cfg;
|
||||
void *aptr_cfg;
|
||||
|
||||
fp_t fptr_sus;
|
||||
void *aptr_sus;
|
||||
|
||||
fp_t fptr_id;
|
||||
void *aptr_id;
|
||||
|
||||
fp_t fptr_vbus;
|
||||
void *aptr_vbus;
|
||||
|
||||
} usb_t;
|
||||
|
||||
static usb_t _g_usb[USB_MAX_NUM_PORTS];
|
||||
//static usb_irp_t *_g_usb_irp_ptr[USB_MAX_NUM_PORTS][USB_MAX_NUM_EPT];
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// HPI ISR
|
||||
// ---------------------------------------------------------
|
||||
void cy67k3_isr(void)
|
||||
{
|
||||
INT32 i;
|
||||
UINT16 sie_msg, hpi_status;
|
||||
UINT32 port, siemsg_handled, int_handled;
|
||||
_g_int_active = 1;
|
||||
// sputs("--------------------------------------------------------\n");
|
||||
// sputs("USB-Interrupt(4)\n");
|
||||
// sputs("HPI Status : ");
|
||||
hpi_status = cy67k3_read_HPI_STATUS();
|
||||
// print_word(hpi_status);
|
||||
// sputs("\n");
|
||||
|
||||
// sputs("MAILBOX (REG): ");
|
||||
|
||||
// cy67k3_write(HPI_ADDRESS, HPI_REG_MAILBOX);
|
||||
// print_word(cy67k3_read_HPI_DATA());
|
||||
// sputs("\n");
|
||||
|
||||
int_handled = 0;
|
||||
if (hpi_status & HPI_STATUS_MBX_IN)
|
||||
{
|
||||
int_handled = 1;
|
||||
// sputs("MAILBOX (HPI): ");
|
||||
_g_mbx_return = cy67k3_read_HPI_MAILBOX();
|
||||
_g_mbx_in_flag = 1;
|
||||
// print_word(_g_mbx_return);
|
||||
// sputs("\n");
|
||||
}
|
||||
|
||||
if (hpi_status & HPI_STATUS_RESET1)
|
||||
{
|
||||
int_handled = 1;
|
||||
hpi_read_reg(SUSB1_REG_STATUS);
|
||||
hpi_comm_exec_int(SUSB_INIT_INT, 2, R1, 0, R2, 1);
|
||||
// sputs("RESET 1\n");
|
||||
}
|
||||
|
||||
if (hpi_status & HPI_STATUS_RESET2)
|
||||
{
|
||||
int_handled = 1;
|
||||
hpi_read_reg(SUSB2_REG_STATUS);
|
||||
hpi_comm_exec_int(SUSB_INIT_INT, 2, R1, 0, R2, 2);
|
||||
// sputs("RESET 2\n");
|
||||
}
|
||||
|
||||
if (hpi_status & HPI_STATUS_DONE1)
|
||||
{
|
||||
int_handled = 1;
|
||||
// sputs("DONE 1\n");
|
||||
}
|
||||
|
||||
if (hpi_status & HPI_STATUS_DONE2)
|
||||
{
|
||||
int_handled = 1;
|
||||
// sputs("DONE 2\n");
|
||||
}
|
||||
|
||||
if (hpi_status & HPI_STATUS_SOFEOP1)
|
||||
{
|
||||
int_handled = 1;
|
||||
hpi_read_reg(SUSB1_REG_STATUS);
|
||||
// sputs("SOF/EOP 1\n");
|
||||
}
|
||||
|
||||
if (hpi_status & HPI_STATUS_SOFEOP2)
|
||||
{
|
||||
int_handled = 1;
|
||||
hpi_read_reg(SUSB2_REG_STATUS);
|
||||
// sputs("SOF/EOP 2\n");
|
||||
}
|
||||
|
||||
port = 0;
|
||||
siemsg_handled = 0;
|
||||
if (hpi_status & HPI_STATUS_SIEMSG1)
|
||||
{
|
||||
int_handled = 1;
|
||||
sie_msg = hpi_read_reg(HPI_REG_SIE1MSG);
|
||||
|
||||
// Reset message register
|
||||
hpi_write_reg(HPI_REG_SIE1MSG, 0x0000);
|
||||
|
||||
if (sie_msg & SUSB_RST_MSG)
|
||||
{
|
||||
siemsg_handled = 1;
|
||||
if (_g_usb[port].fptr_rst)
|
||||
(_g_usb[port].fptr_rst)(_g_usb[port].aptr_rst);
|
||||
}
|
||||
|
||||
if (sie_msg & SUSB_SOF_MSG)
|
||||
{
|
||||
siemsg_handled = 1;
|
||||
if (_g_usb[port].fptr_sof)
|
||||
(_g_usb[port].fptr_sof)(_g_usb[port].aptr_sof);
|
||||
}
|
||||
|
||||
if (sie_msg & SUSB_CFG_MSG)
|
||||
{
|
||||
siemsg_handled = 1;
|
||||
if (_g_usb[port].fptr_cfg)
|
||||
(_g_usb[port].fptr_cfg)(_g_usb[port].aptr_cfg);
|
||||
}
|
||||
|
||||
if (sie_msg & SUSB_SUS_MSG)
|
||||
{
|
||||
siemsg_handled = 1;
|
||||
if (_g_usb[port].fptr_sus)
|
||||
(_g_usb[port].fptr_sus)(_g_usb[port].aptr_sus);
|
||||
}
|
||||
|
||||
if (sie_msg & SUSB_ID_MSG)
|
||||
{
|
||||
siemsg_handled = 1;
|
||||
if (_g_usb[port].fptr_id)
|
||||
(_g_usb[port].fptr_id)(_g_usb[port].aptr_id);
|
||||
}
|
||||
|
||||
if (sie_msg & SUSB_VBUS_MSG)
|
||||
{
|
||||
siemsg_handled = 1;
|
||||
if (_g_usb[port].fptr_vbus)
|
||||
(_g_usb[port].fptr_vbus)(_g_usb[port].aptr_vbus);
|
||||
}
|
||||
|
||||
for (i=0; i < 8; i++)
|
||||
{
|
||||
if (sie_msg & (SUSB_EP0_MSG << i))
|
||||
{
|
||||
siemsg_handled = 1;
|
||||
if (_g_usb[port].fptr_ept[i])
|
||||
(_g_usb[port].fptr_ept[i])(_g_usb[port].aptr_ept[i]);
|
||||
}
|
||||
}
|
||||
if (!siemsg_handled)
|
||||
{
|
||||
sputs("Unhandled SIE1 message ");
|
||||
print_word(sie_msg);
|
||||
sputs("!\n");
|
||||
}
|
||||
|
||||
}
|
||||
port = 1;
|
||||
siemsg_handled = 0;
|
||||
if (hpi_status & HPI_STATUS_SIEMSG2)
|
||||
{
|
||||
int_handled = 1;
|
||||
sie_msg = hpi_read_reg(HPI_REG_SIE2MSG);
|
||||
|
||||
// Reset message register
|
||||
hpi_write_reg(HPI_REG_SIE2MSG, 0x0000);
|
||||
|
||||
if (sie_msg & SUSB_RST_MSG)
|
||||
{
|
||||
siemsg_handled = 1;
|
||||
if (_g_usb[port].fptr_rst)
|
||||
(_g_usb[port].fptr_rst)(_g_usb[port].aptr_rst);
|
||||
}
|
||||
|
||||
if (sie_msg & SUSB_SOF_MSG)
|
||||
{
|
||||
siemsg_handled = 1;
|
||||
if (_g_usb[port].fptr_sof)
|
||||
(_g_usb[port].fptr_sof)(_g_usb[port].aptr_sof);
|
||||
}
|
||||
|
||||
if (sie_msg & SUSB_CFG_MSG)
|
||||
{
|
||||
siemsg_handled = 1;
|
||||
if (_g_usb[port].fptr_cfg)
|
||||
(_g_usb[port].fptr_cfg)(_g_usb[port].aptr_cfg);
|
||||
}
|
||||
|
||||
if (sie_msg & SUSB_SUS_MSG)
|
||||
{
|
||||
siemsg_handled = 1;
|
||||
if (_g_usb[port].fptr_sus)
|
||||
(_g_usb[port].fptr_sus)(_g_usb[port].aptr_sus);
|
||||
}
|
||||
|
||||
if (sie_msg & SUSB_ID_MSG)
|
||||
{
|
||||
siemsg_handled = 1;
|
||||
if (_g_usb[port].fptr_id)
|
||||
(_g_usb[port].fptr_id)(_g_usb[port].aptr_id);
|
||||
}
|
||||
|
||||
if (sie_msg & SUSB_VBUS_MSG)
|
||||
{
|
||||
siemsg_handled = 1;
|
||||
if (_g_usb[port].fptr_vbus)
|
||||
(_g_usb[port].fptr_vbus)(_g_usb[port].aptr_vbus);
|
||||
}
|
||||
|
||||
for (i=0; i < 8; i++)
|
||||
{
|
||||
if (sie_msg & (SUSB_EP0_MSG << i))
|
||||
{
|
||||
siemsg_handled = 1;
|
||||
if (_g_usb[port].fptr_ept[i])
|
||||
(_g_usb[port].fptr_ept[i])(_g_usb[port].aptr_ept[i]);
|
||||
}
|
||||
}
|
||||
if (!siemsg_handled)
|
||||
{
|
||||
sputs("Unhandled SIE2 message ");
|
||||
print_word(sie_msg);
|
||||
sputs("!\n");
|
||||
}
|
||||
|
||||
}
|
||||
if (!int_handled)
|
||||
{
|
||||
sputs("Unhandled interrupt (status = ");
|
||||
print_word(hpi_status);
|
||||
sputs(")!\n");
|
||||
}
|
||||
|
||||
// sputs("--------------------------------------------------------\n");
|
||||
_g_int_active = 0;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// CY7C67300 low-level routines
|
||||
// ---------------------------------------------------------
|
||||
void cy67k3_reset(void)
|
||||
{
|
||||
int i;
|
||||
volatile UINT32 *pHpi = (UINT32*)SYS_USB_CTRL;
|
||||
|
||||
*pHpi = 3;
|
||||
for (i=0; i <160; i++)
|
||||
{
|
||||
__asm __volatile
|
||||
(
|
||||
".set noreorder\n"
|
||||
"nop\n"
|
||||
"nop\n"
|
||||
"nop\n"
|
||||
"nop\n"
|
||||
".set reorder\n"
|
||||
);
|
||||
}
|
||||
|
||||
*pHpi = 2;
|
||||
|
||||
}
|
||||
|
||||
UINT16 cy67k3_read_HPI_DATA(void)
|
||||
{
|
||||
volatile UINT32 *pHpi = (UINT32*)SYS_USB_DATA;
|
||||
|
||||
return (UINT16)*pHpi;
|
||||
}
|
||||
|
||||
UINT16 cy67k3_read_HPI_MAILBOX(void)
|
||||
{
|
||||
volatile UINT32 *pHpi = (UINT32*)SYS_USB_MBX;
|
||||
|
||||
return (UINT16)*pHpi;
|
||||
}
|
||||
|
||||
UINT16 cy67k3_read_HPI_ADDRESS(void)
|
||||
{
|
||||
volatile UINT32 *pHpi = (UINT32*)SYS_USB_ADDR;
|
||||
|
||||
return (UINT16)*pHpi;
|
||||
}
|
||||
|
||||
UINT16 cy67k3_read_HPI_STATUS(void)
|
||||
{
|
||||
volatile UINT32 *pHpi = (UINT32*)SYS_USB_STATUS;
|
||||
|
||||
return (UINT16)*pHpi;
|
||||
}
|
||||
|
||||
void cy67k3_write_HPI_DATA(UINT16 data)
|
||||
{
|
||||
volatile UINT32 *pHpi = (UINT32*)SYS_USB_DATA;
|
||||
|
||||
*pHpi = (UINT32)data;
|
||||
}
|
||||
|
||||
void cy67k3_write_HPI_MAILBOX(UINT16 data)
|
||||
{
|
||||
volatile UINT32 *pHpi = (UINT32*)SYS_USB_MBX;
|
||||
|
||||
*pHpi = (UINT32)data;
|
||||
}
|
||||
|
||||
void cy67k3_write_HPI_ADDRESS(UINT16 data)
|
||||
{
|
||||
volatile UINT32 *pHpi = (UINT32*)SYS_USB_ADDR;
|
||||
|
||||
*pHpi = (UINT32)data;
|
||||
}
|
||||
|
||||
void cy67k3_write_HPI_STATUS(UINT16 data)
|
||||
{
|
||||
volatile UINT32 *pHpi = (UINT32*)SYS_USB_STATUS;
|
||||
|
||||
*pHpi = (UINT32)data;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// HPI API
|
||||
// ---------------------------------------------------------
|
||||
UINT32 hpi_init(void)
|
||||
{
|
||||
volatile UINT32 *pHpi = (UINT32*)SYS_USB_CTRL;
|
||||
int i;
|
||||
UINT16 reg;
|
||||
|
||||
// ToDo: Enable HPI interrupt
|
||||
_g_int_active = 0;
|
||||
|
||||
hpi_write_reg(HPI_REG_SIE1MSG, 0x0000);
|
||||
hpi_write_reg(HPI_REG_SIE2MSG, 0x0000);
|
||||
hpi_write_reg(SUSB1_REG_STATUS, 0xFFFF);
|
||||
hpi_write_reg(SUSB2_REG_STATUS, 0xFFFF);
|
||||
|
||||
// Init 1
|
||||
for(i=0; i < USB_MAX_NUM_EPT; i++)
|
||||
{
|
||||
hpi_write_reg(SUSB1_REG_EP_ADDR0 + 16*i, 0);
|
||||
hpi_write_reg(SUSB1_REG_EP_CNTRES0 + 16*i, 0);
|
||||
hpi_write_reg(SUSB1_REG_EP_COUNT0 + 16*i, 0);
|
||||
hpi_write_reg(SUSB1_REG_EP_CTRL0 + 16*i, 0);
|
||||
hpi_write_reg(SUSB1_REG_EP_STATUS0 + 16*i, 0);
|
||||
}
|
||||
// Init 2
|
||||
for(i=0; i < USB_MAX_NUM_EPT; i++)
|
||||
{
|
||||
hpi_write_reg(SUSB2_REG_EP_ADDR0 + 16*i, 0);
|
||||
hpi_write_reg(SUSB2_REG_EP_CNTRES0 + 16*i, 0);
|
||||
hpi_write_reg(SUSB2_REG_EP_COUNT0 + 16*i, 0);
|
||||
hpi_write_reg(SUSB2_REG_EP_CTRL0 + 16*i, 0);
|
||||
hpi_write_reg(SUSB2_REG_EP_STATUS0 + 16*i, 0);
|
||||
}
|
||||
|
||||
hpi_write_reg(HPI_REG_INTROUTE, 0x0000);
|
||||
reg = hpi_read_reg(HPI_REG_INTROUTE);
|
||||
// hpi_write_reg(HPI_REG_INTROUTE, reg | 0x0202); // Route reset {1,2} to HPI only
|
||||
// hpi_write_reg(HPI_REG_INTROUTE, reg | 0x2800); // Route SOF/EOP {1,2} to HPI only
|
||||
// hpi_write_reg(HPI_REG_INTROUTE, reg | 0x1400); // Route SOF/EOP {1,2} to CY16 only
|
||||
hpi_write_reg(HPI_REG_INTROUTE, reg | 0x3C00); // Route SOF/EOP {1,2} to HPI and CY16
|
||||
|
||||
|
||||
interrupt_register(4, cy67k3_isr);
|
||||
interrupt_enable(4);
|
||||
*pHpi = 0x02;
|
||||
|
||||
return HPI_NOERROR;
|
||||
}
|
||||
|
||||
void hpi_mbx_write(UINT16 msgcode)
|
||||
{
|
||||
_g_mbx_in_flag = 0;
|
||||
cy67k3_write_HPI_MAILBOX(msgcode);
|
||||
}
|
||||
|
||||
UINT32 hpi_mbx_read(void)
|
||||
{
|
||||
UINT32 err;
|
||||
UINT16 cy_return;
|
||||
|
||||
if (_g_int_active)
|
||||
{
|
||||
while (!(cy67k3_read_HPI_STATUS() & HPI_STATUS_MBX_IN));
|
||||
cy_return = cy67k3_read_HPI_MAILBOX();
|
||||
}
|
||||
else
|
||||
{
|
||||
while(!_g_mbx_in_flag);
|
||||
cy_return = _g_mbx_return;
|
||||
}
|
||||
|
||||
switch (cy_return)
|
||||
{
|
||||
case COMM_ACK:
|
||||
err = cy_return;
|
||||
break;
|
||||
|
||||
case COMM_NAK:
|
||||
case COMM_ASYNC:
|
||||
err = HPI_ERR_PREFIX_MBX | cy_return;
|
||||
break;
|
||||
|
||||
default:
|
||||
err = HPI_ERR_PREFIX_MBX | cy_return;
|
||||
break;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
UINT32 hpi_check_addr(UINT16 addr)
|
||||
{
|
||||
if ((addr >= 0x0000) && (addr < 0x4000))
|
||||
return 0;
|
||||
|
||||
if ((addr >= 0xC080) && (addr < 0xC0BC))
|
||||
return 0;
|
||||
|
||||
if (addr >= 0xE000)
|
||||
return 0;
|
||||
|
||||
sputs("Invalid address for HPI direct access! Use LCP-command instead!\n");
|
||||
return HPI_ERR_INVPARAM;
|
||||
}
|
||||
|
||||
UINT32 hpi_read_reg(UINT16 addr)
|
||||
{
|
||||
UINT32 result;
|
||||
|
||||
result = hpi_check_addr(addr);
|
||||
if (IS_ERROR(result))
|
||||
return result;
|
||||
|
||||
cy67k3_write_HPI_ADDRESS(addr);
|
||||
return cy67k3_read_HPI_DATA();
|
||||
}
|
||||
|
||||
UINT32 hpi_write_reg(UINT16 addr, UINT16 data)
|
||||
{
|
||||
UINT32 result;
|
||||
|
||||
result = hpi_check_addr(addr);
|
||||
if (IS_ERROR(result))
|
||||
return result;
|
||||
|
||||
cy67k3_write_HPI_ADDRESS(addr);
|
||||
cy67k3_write_HPI_DATA(data);
|
||||
}
|
||||
|
||||
UINT32 hpi_write_ram(UINT16 addr, UINT16 *pData, UINT32 len)
|
||||
{
|
||||
int i, num_words;
|
||||
|
||||
if (addr > 0x3FFE)
|
||||
return HPI_ERR_INVPARAM;
|
||||
|
||||
if (addr & 1) // Not 16bit aligned?
|
||||
return HPI_ERR_INVPARAM;
|
||||
|
||||
cy67k3_write_HPI_ADDRESS(addr);
|
||||
|
||||
num_words = len/2;
|
||||
if (len % 2)
|
||||
num_words++;
|
||||
|
||||
for (i=0; i < num_words; i++)
|
||||
cy67k3_write_HPI_DATA(pData[i]);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
UINT32 hpi_read_ram(UINT16 addr, UINT16 *pData, UINT32 len)
|
||||
{
|
||||
int i, num_words;
|
||||
|
||||
if (addr > 0x3FFE)
|
||||
return HPI_ERR_INVPARAM;
|
||||
|
||||
if (addr & 1) // Not 16bit aligned?
|
||||
return HPI_ERR_INVPARAM;
|
||||
|
||||
cy67k3_write_HPI_ADDRESS(addr);
|
||||
|
||||
num_words = len/2;
|
||||
if (len % 2)
|
||||
num_words++;
|
||||
|
||||
for (i=0; i < num_words; i++)
|
||||
pData[i] = cy67k3_read_HPI_DATA();
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
UINT32 hpi_comm_reset(void)
|
||||
{
|
||||
hpi_mbx_write(COMM_RESET);
|
||||
|
||||
return hpi_mbx_read();
|
||||
}
|
||||
|
||||
UINT32 hpi_comm_jump2code(UINT16 addr)
|
||||
{
|
||||
cy67k3_write_HPI_ADDRESS(addr);
|
||||
hpi_mbx_write(COMM_JUMP2CODE);
|
||||
|
||||
return hpi_mbx_read();
|
||||
}
|
||||
|
||||
UINT32 hpi_comm_callcode(UINT16 addr)
|
||||
{
|
||||
hpi_write_reg(COMM_CODE_ADDR, addr);
|
||||
|
||||
hpi_mbx_write(COMM_CALL_CODE);
|
||||
|
||||
return hpi_mbx_read();
|
||||
}
|
||||
|
||||
UINT32 hpi_comm_write_ctrl_reg(UINT16 addr, UINT16 data, UINT16 logic)
|
||||
{
|
||||
|
||||
hpi_write_reg(COMM_CTRL_REG_ADDR, addr);
|
||||
hpi_write_reg(COMM_CTRL_REG_DATA, data);
|
||||
hpi_write_reg(COMM_CTRL_REG_LOGIC, logic);
|
||||
|
||||
hpi_mbx_write(COMM_WRITE_CTRL_REG);
|
||||
|
||||
return hpi_mbx_read();
|
||||
}
|
||||
|
||||
UINT32 hpi_comm_read_ctrl_reg(UINT16 addr)
|
||||
{
|
||||
UINT32 result;
|
||||
|
||||
hpi_write_reg(COMM_CTRL_REG_ADDR, addr);
|
||||
|
||||
hpi_mbx_write(COMM_READ_CTRL_REG);
|
||||
|
||||
result = hpi_mbx_read();
|
||||
if (IS_ERROR(result))
|
||||
return result;
|
||||
|
||||
cy67k3_write_HPI_ADDRESS(COMM_CTRL_REG_DATA);
|
||||
return (UINT32)cy67k3_read_HPI_DATA();
|
||||
|
||||
}
|
||||
|
||||
UINT32 hpi_comm_write_xmem(UINT16 addr, UINT8 *pData, UINT16 len)
|
||||
{
|
||||
return HPI_ERR_NOTIMPL;
|
||||
|
||||
}
|
||||
|
||||
UINT32 hpi_comm_read_xmem(UINT16 addr, UINT8 *pData, UINT16 len)
|
||||
{
|
||||
return HPI_ERR_NOTIMPL;
|
||||
|
||||
}
|
||||
|
||||
typedef struct _sreg_param_t
|
||||
{
|
||||
UINT32 id;
|
||||
UINT16 val;
|
||||
|
||||
} reg_param_t;
|
||||
|
||||
UINT32 hpi_comm_exec_int(UINT16 intnum, UINT32 nargs, ...)
|
||||
{
|
||||
int i;
|
||||
UINT32 result;
|
||||
va_list args;
|
||||
reg_param_t reg_param[MAX_NUM_REGS];
|
||||
|
||||
va_start(args, nargs);
|
||||
|
||||
if (nargs > MAX_NUM_REGS)
|
||||
{
|
||||
fprintf(stderr, "hpi_comm_exec_int(): Number (%d), of arguments exceeds %d!\n", nargs, MAX_NUM_REGS);
|
||||
return HPI_ERR_INVPARAM;
|
||||
}
|
||||
|
||||
for (i=0; i < nargs; i++)
|
||||
{
|
||||
reg_param[i].id = va_arg(args, UINT32);
|
||||
if (reg_param[i].id > MAX_NUM_REGS)
|
||||
{
|
||||
fprintf(stderr, "hpi_comm_exec_int(): Invalid register R%d!\n", reg_param[i].id);
|
||||
return HPI_ERR_INVPARAM;
|
||||
}
|
||||
|
||||
reg_param[i].val = (UINT16)va_arg(args, UINT32);
|
||||
}
|
||||
va_end(args);
|
||||
|
||||
hpi_write_reg(COMM_INT_NUM, intnum);
|
||||
|
||||
for (i=0; i < nargs; i++)
|
||||
{
|
||||
hpi_write_reg(COMM_R0 + 2*reg_param[i].id, reg_param[i].val);
|
||||
}
|
||||
|
||||
hpi_mbx_write(COMM_EXEC_INT);
|
||||
|
||||
result = hpi_mbx_read();
|
||||
if (IS_ERROR(result))
|
||||
return result;
|
||||
|
||||
return (UINT32)hpi_read_reg(COMM_R0);
|
||||
}
|
||||
|
||||
UINT32 usb_init(void)
|
||||
{
|
||||
INT32 i;
|
||||
|
||||
for (i=0; i < USB_MAX_NUM_PORTS; i++)
|
||||
{
|
||||
memset(&_g_usb[i], 0, sizeof(usb_t));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
UINT32 usb_callback_register(UINT32 port, UINT32 type, fp_t pFunc, void *pArg)
|
||||
{
|
||||
UINT32 result;
|
||||
if (port >= USB_MAX_NUM_PORTS)
|
||||
return -1;
|
||||
|
||||
result = 0;
|
||||
switch (type)
|
||||
{
|
||||
case SUSB_EP0_MSG:
|
||||
_g_usb[port].fptr_ept[0] = pFunc;
|
||||
_g_usb[port].aptr_ept[0] = pArg;
|
||||
break;
|
||||
|
||||
case SUSB_EP1_MSG:
|
||||
_g_usb[port].fptr_ept[1] = pFunc;
|
||||
_g_usb[port].aptr_ept[1] = pArg;
|
||||
break;
|
||||
|
||||
case SUSB_EP2_MSG:
|
||||
_g_usb[port].fptr_ept[2] = pFunc;
|
||||
_g_usb[port].aptr_ept[2] = pArg;
|
||||
break;
|
||||
|
||||
case SUSB_EP3_MSG:
|
||||
_g_usb[port].fptr_ept[3] = pFunc;
|
||||
_g_usb[port].aptr_ept[3] = pArg;
|
||||
break;
|
||||
|
||||
case SUSB_EP4_MSG:
|
||||
_g_usb[port].fptr_ept[4] = pFunc;
|
||||
_g_usb[port].aptr_ept[4] = pArg;
|
||||
break;
|
||||
|
||||
case SUSB_EP5_MSG:
|
||||
_g_usb[port].fptr_ept[5] = pFunc;
|
||||
_g_usb[port].aptr_ept[5] = pArg;
|
||||
break;
|
||||
|
||||
case SUSB_EP6_MSG:
|
||||
_g_usb[port].fptr_ept[6] = pFunc;
|
||||
_g_usb[port].aptr_ept[6] = pArg;
|
||||
break;
|
||||
|
||||
case SUSB_EP7_MSG:
|
||||
_g_usb[port].fptr_ept[7] = pFunc;
|
||||
_g_usb[port].aptr_ept[7] = pArg;
|
||||
break;
|
||||
|
||||
case SUSB_RST_MSG:
|
||||
_g_usb[port].fptr_rst = pFunc;
|
||||
_g_usb[port].aptr_rst = pArg;
|
||||
break;
|
||||
|
||||
case SUSB_SOF_MSG:
|
||||
_g_usb[port].fptr_sof = pFunc;
|
||||
_g_usb[port].aptr_sof = pArg;
|
||||
break;
|
||||
|
||||
case SUSB_CFG_MSG:
|
||||
_g_usb[port].fptr_cfg = pFunc;
|
||||
_g_usb[port].aptr_cfg = pArg;
|
||||
break;
|
||||
|
||||
case SUSB_SUS_MSG:
|
||||
_g_usb[port].fptr_sus = pFunc;
|
||||
_g_usb[port].aptr_sus = pArg;
|
||||
break;
|
||||
|
||||
case SUSB_ID_MSG:
|
||||
_g_usb[port].fptr_id = pFunc;
|
||||
_g_usb[port].aptr_id = pArg;
|
||||
break;
|
||||
|
||||
case SUSB_VBUS_MSG:
|
||||
_g_usb[port].fptr_vbus = pFunc;
|
||||
_g_usb[port].aptr_vbus = pArg;
|
||||
break;
|
||||
|
||||
default:
|
||||
result = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
UINT32 usb_irp_register(usb_irp_t *pIRP, UINT32 port, UINT32 ept, UINT32 size, UINT32 is_out)
|
||||
{
|
||||
|
||||
if (!pIRP)
|
||||
return -1;
|
||||
|
||||
if (port >= USB_MAX_NUM_PORTS)
|
||||
return -1;
|
||||
|
||||
if (ept >= USB_MAX_NUM_EPT)
|
||||
return -1;
|
||||
|
||||
if (size >= USB_MAX_IMG_SIZE)
|
||||
return -1;
|
||||
|
||||
memset(pIRP, 0, sizeof(usb_irp_t));
|
||||
pIRP->is_out = is_out;
|
||||
pIRP->is_in = !is_out;
|
||||
pIRP->tsize = size;
|
||||
pIRP->port = port;
|
||||
pIRP->ept = ept;
|
||||
pIRP->cy_irp_addr = USB_IRP_BASE + port*USB_MAX_NUM_EPT*sizeof(cy_req_t) + ept*sizeof(cy_req_t);
|
||||
pIRP->cy_req.next = 0;
|
||||
pIRP->cy_req.addr = USB_IMG_BASE + port*USB_MAX_NUM_EPT*USB_MAX_IMG_SIZE + ept*USB_MAX_IMG_SIZE;
|
||||
pIRP->cy_req.size = size;
|
||||
pIRP->cy_req.callback = 0;
|
||||
fifo_alloc(&pIRP->fifo, 8*USB_MAX_IMG_SIZE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
UINT32 usb_irp_enqueue(usb_irp_t *pIRP)
|
||||
{
|
||||
UINT32 result;
|
||||
|
||||
if (!pIRP)
|
||||
{
|
||||
// sputs ("usb_irp_enqueue(): Invalid IRP!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// printf("cy_addr: %4.4X, Next: %4.4X, Addr: %4.4X, Size: %4.4X, CB: %4.4X\n", pIRP->cy_irp_addr, pIRP->cy_req.next, pIRP->cy_req.addr, pIRP->cy_req.size, pIRP->cy_req.callback);
|
||||
|
||||
if (pIRP->is_out)
|
||||
{
|
||||
hpi_write_ram(pIRP->cy_irp_addr, (UINT16*)&pIRP->cy_req, sizeof(cy_req_t));
|
||||
if (pIRP->port == 0)
|
||||
result = hpi_comm_exec_int(SUSB1_RECEIVE_INT, 2, R1, pIRP->ept, R8, pIRP->cy_irp_addr);
|
||||
|
||||
if (pIRP->port == 1)
|
||||
result = hpi_comm_exec_int(SUSB2_RECEIVE_INT, 2, R1, pIRP->ept, R8, pIRP->cy_irp_addr);
|
||||
}
|
||||
if (pIRP->is_in)
|
||||
{
|
||||
pIRP->tx_in_progress = 1;
|
||||
hpi_write_ram(pIRP->cy_irp_addr, (UINT16*)&pIRP->cy_req, sizeof(cy_req_t));
|
||||
if (pIRP->port == 0)
|
||||
result = hpi_comm_exec_int(SUSB1_SEND_INT, 2, R1, pIRP->ept, R8, pIRP->cy_irp_addr);
|
||||
|
||||
if (pIRP->port == 1)
|
||||
result = hpi_comm_exec_int(SUSB2_SEND_INT, 2, R1, pIRP->ept, R8, pIRP->cy_irp_addr);
|
||||
}
|
||||
|
||||
// if (result)
|
||||
// printf ("usb_irp_enqueue(): Result = %8.8X\n", result);
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
UINT32 fifo_alloc(fifo_t *pObj, UINT32 size)
|
||||
{
|
||||
pObj->pBuf = (UINT8*)malloc(size);
|
||||
if (!pObj->pBuf)
|
||||
{
|
||||
// printf ("fifo_alloc(): Error allocating memory!\n");
|
||||
return -1;
|
||||
}
|
||||
// printf ("fifo_alloc(): pBuf at %8.8X\n", (UINT32)pObj->pBuf);
|
||||
pObj->size = size;
|
||||
pObj->pPtr_wr = pObj->pBuf;
|
||||
pObj->pPtr_rd = pObj->pBuf;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
UINT32 fifo_free(fifo_t *pObj)
|
||||
{
|
||||
if (pObj->pBuf)
|
||||
free(pObj->pBuf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
UINT32 fifo_flush(fifo_t *pObj)
|
||||
{
|
||||
pObj->pPtr_wr = pObj->pBuf;
|
||||
pObj->pPtr_rd = pObj->pBuf;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
UINT32 fifo_is_empty(fifo_t *pObj)
|
||||
{
|
||||
return (pObj->pPtr_wr == pObj->pPtr_rd);
|
||||
}
|
||||
|
||||
UINT32 fifo_is_full(fifo_t *pObj)
|
||||
{
|
||||
UINT8 *pNext, *pEnd;
|
||||
|
||||
pEnd = pObj->pBuf + pObj->size;
|
||||
pNext = pObj->pPtr_wr + 1;
|
||||
if (pNext == pEnd)
|
||||
pNext = pObj->pBuf;
|
||||
|
||||
return (pNext == pObj->pPtr_rd);
|
||||
}
|
||||
|
||||
UINT32 fifo_read(fifo_t *pObj, UINT8 *pData, UINT32 size, UINT32 timeout, UINT32 do_block)
|
||||
{
|
||||
UINT32 i;
|
||||
UINT32 wait_4ever, timeout_cnt, cnt;
|
||||
UINT8 *pEnd;
|
||||
|
||||
pEnd = pObj->pBuf + pObj->size;
|
||||
wait_4ever = (timeout == 0);
|
||||
|
||||
cnt = 0;
|
||||
while(size)
|
||||
{
|
||||
timeout_cnt = timeout;
|
||||
|
||||
while(fifo_is_empty(pObj))
|
||||
{
|
||||
if (!do_block)
|
||||
return cnt;
|
||||
|
||||
if (!wait_4ever)
|
||||
{
|
||||
if (timeout_cnt)
|
||||
{
|
||||
timeout_cnt--;
|
||||
sleep(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
return cnt;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pData)
|
||||
pData[cnt] = *(pObj->pPtr_rd);
|
||||
|
||||
cnt++;
|
||||
pObj->pPtr_rd++;
|
||||
if (pObj->pPtr_rd == pEnd)
|
||||
pObj->pPtr_rd = pObj->pBuf;
|
||||
|
||||
size--;
|
||||
}
|
||||
|
||||
return cnt;
|
||||
}
|
||||
|
||||
UINT32 fifo_write(fifo_t *pObj, UINT8 *pData, UINT32 size, UINT32 timeout, UINT32 do_block)
|
||||
{
|
||||
UINT32 wait_4ever, timeout_cnt, cnt;
|
||||
UINT8 *pEnd;
|
||||
|
||||
pEnd = pObj->pBuf + pObj->size;
|
||||
wait_4ever = (timeout == 0);
|
||||
|
||||
cnt = 0;
|
||||
while(size)
|
||||
{
|
||||
timeout_cnt = timeout;
|
||||
|
||||
while(fifo_is_full(pObj))
|
||||
{
|
||||
if (!do_block)
|
||||
return cnt;
|
||||
|
||||
if (!wait_4ever)
|
||||
{
|
||||
if (timeout_cnt)
|
||||
{
|
||||
timeout_cnt--;
|
||||
sleep(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
return cnt;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pData)
|
||||
*(pObj->pPtr_wr) = pData[cnt];
|
||||
|
||||
cnt++;
|
||||
pObj->pPtr_wr++;
|
||||
if (pObj->pPtr_wr == pEnd)
|
||||
pObj->pPtr_wr = pObj->pBuf;
|
||||
|
||||
size--;
|
||||
}
|
||||
|
||||
return cnt;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------
|
||||
@@ -0,0 +1,384 @@
|
||||
#ifndef HPI_H
|
||||
#define HPI_H
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// API related
|
||||
// ---------------------------------------------------------
|
||||
//#define IS_ERROR(e) (0 != (e & HPI_ERROR))
|
||||
#define HPI_NOERROR 0
|
||||
#define HPI_ERROR 0x80000000
|
||||
#define HPI_ERR_NOTIMPL (HPI_ERROR + 1)
|
||||
#define HPI_ERR_INVPARAM (HPI_ERROR + 2)
|
||||
#define HPI_ERR_TIMEOUT (HPI_ERROR + 3)
|
||||
#define HPI_ERR_PREFIX_MBX (HPI_ERROR + 0x00010000)
|
||||
|
||||
#define MAX_NUM_REGS 14
|
||||
#define R0 0
|
||||
#define R1 1
|
||||
#define R2 2
|
||||
#define R3 3
|
||||
#define R4 4
|
||||
#define R5 5
|
||||
#define R6 6
|
||||
#define R7 7
|
||||
#define R8 8
|
||||
#define R9 9
|
||||
#define R10 10
|
||||
#define R11 11
|
||||
#define R12 12
|
||||
#define R13 13
|
||||
|
||||
#define USB_MAX_NUM_PORTS 2
|
||||
#define USB_MAX_NUM_EPT 8
|
||||
#define USB_MAX_IMG_SIZE 512
|
||||
#define USB_IRP_BASE 0x0F80
|
||||
#define USB_IMG_BASE 0x1000
|
||||
|
||||
typedef void (*fp_t)(void*);
|
||||
|
||||
// Receive buffer on EP
|
||||
typedef struct _scy_req_t
|
||||
{
|
||||
UINT16 next;
|
||||
UINT16 addr;
|
||||
UINT16 size;
|
||||
UINT16 callback;
|
||||
} cy_req_t;
|
||||
|
||||
typedef struct _sfifo_t
|
||||
{
|
||||
UINT32 size;
|
||||
UINT8 *pBuf;
|
||||
UINT8 * volatile pPtr_wr, * volatile pPtr_rd;
|
||||
|
||||
} fifo_t;
|
||||
|
||||
typedef struct _susb_irp_t
|
||||
{
|
||||
UINT16 tsize;
|
||||
UINT32 is_in, is_out;
|
||||
UINT32 port, ept;
|
||||
UINT16 cy_irp_addr;
|
||||
fifo_t fifo;
|
||||
UINT32 tx_in_progress;
|
||||
cy_req_t cy_req;
|
||||
} usb_irp_t;
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// CY7C67300 related
|
||||
// ---------------------------------------------------------
|
||||
#define HPI_WAITACK 1
|
||||
#define HPI_NOWAIT 0
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// HPI status flags
|
||||
#define HPI_STATUS_MBX_IN 0x0001
|
||||
#define HPI_STATUS_RESET1 0x0002
|
||||
#define HPI_STATUS_DONE1 0x0004
|
||||
#define HPI_STATUS_DONE2 0x0008
|
||||
#define HPI_STATUS_SIEMSG1 0x0010
|
||||
#define HPI_STATUS_SIEMSG2 0x0020
|
||||
#define HPI_STATUS_RESUME1 0x0040
|
||||
#define HPI_STATUS_RESUME2 0x0080
|
||||
#define HPI_STATUS_MBX_OUT 0x0100
|
||||
#define HPI_STATUS_RESET2 0x0200
|
||||
#define HPI_STATUS_SOFEOP1 0x0400
|
||||
#define HPI_STATUS_SOFEOP2 0x1000
|
||||
#define HPI_STATUS_ID 0x4000
|
||||
#define HPI_STATUS_VBUS 0x8000
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// LCP command codes
|
||||
#define COMM_RESET 0xFA50
|
||||
#define COMM_JUMP2CODE 0xCE00
|
||||
#define COMM_EXEC_INT 0xCE01
|
||||
#define COMM_READ_CTRL_REG 0xCE02
|
||||
#define COMM_WRITE_CTRL_REG 0xCE03
|
||||
#define COMM_CALL_CODE 0xCE04
|
||||
#define COMM_READ_XMEM 0xCE05
|
||||
#define COMM_WRITE_XMEM 0xCE06
|
||||
#define C0MM_CONFIG 0xCE07
|
||||
#define COMM_READ_MEM 0xCE08
|
||||
#define COMM_WRITE_MEM 0xCE09
|
||||
// LCP response codes
|
||||
#define COMM_ACK 0x0FED
|
||||
#define COMM_NAK 0xDEAD
|
||||
#define COMM_ASYNC 0xF00D
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// LCP memory addresses
|
||||
#define COMM_PORT_CMD 0x01BA // For PORT Command
|
||||
#define COMM_MEM_ADDR 0x01BC // Address for COMM_RD/WR_MEM
|
||||
#define COMM_MEM_LEN 0x01BE // Address for COMM_RD/WR_MEM
|
||||
#define COMM_LAST_DATA 0x01C0 // memory pointer for xmem
|
||||
#define COMM_CTRL_REG_ADDR 0x01BC // Address for COMM_RD/WR_CTRL_REG
|
||||
#define COMM_CTRL_REG_DATA 0x01BE // Address for COMM_RD/WR_CTRL_REG
|
||||
#define COMM_CTRL_REG_LOGIC 0x01C0 // Address used for AND/OR
|
||||
#define REG_WRITE_FLG 0x0000 // Value for COMM_CTRL_REG_LOGIC
|
||||
#define REG_AND_FLG 0x0001 // Value for COMM_CTRL_REG_LOGIC
|
||||
#define REG_OR_FLG 0x0002 // Value for COMM_CTRL_REG_LOGIC
|
||||
#define COMM_TIMEOUT 0x01BE // Address setting Timeout for sending response to host
|
||||
#define COMM_CODE_ADDR 0x01BC // Address for COMM_CALL_CODE and COMM_JUMP2CODE
|
||||
#define COMM_INT_NUM 0x01C2 // Address used for COMM_EXEC_INT
|
||||
#define COMM_R0 0x01C4 // CY16-R0 register
|
||||
#define COMM_R1 0x01C6 // CY16-R1 register
|
||||
#define COMM_R2 0x01C8 // CY16-R2 register
|
||||
#define COMM_R3 0x01CA // CY16-R3 register
|
||||
#define COMM_R4 0x01CC // CY16-R4 register
|
||||
#define COMM_R5 0x01CE // CY16-R5 register
|
||||
#define COMM_R6 0x01D0 // CY16-R6 register
|
||||
#define COMM_R7 0x01D2 // CY16-R7 register
|
||||
#define COMM_R8 0x01D4 // CY16-R8 register
|
||||
#define COMM_R9 0x01D6 // CY16-R9 register
|
||||
#define COMM_R10 0x01D8 // CY16-R10 register
|
||||
#define COMM_R11 0x01DA // CY16-R11 register
|
||||
#define COMM_R12 0x01DC // CY16-R12 register
|
||||
#define COMM_R13 0x01DE // CY16-R13 register
|
||||
|
||||
// for COMM_CTRL_REG_LOGIC
|
||||
#define LOGIC_DIRECT 0
|
||||
#define LOGIC_AND 1
|
||||
#define LOGIC_OR 2
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// Software interrupts
|
||||
#define SUSB_INIT_INT 113
|
||||
// USB 1
|
||||
#define SUSB1_DEVICE_DESCRIPTOR_VEC 90
|
||||
#define SUSB1_CONFIGURATION_DESCRIPTOR_VEC 91
|
||||
#define SUSB1_STRING_DESCRIPTOR_VEC 92
|
||||
#define SUSB1_FINISH_INT 89
|
||||
#define SUSB1_STALL_INT 82
|
||||
#define SUSB1_STANDARD_INT 83
|
||||
#define SUSB1_SEND_INT 80
|
||||
#define SUSB1_RECEIVE_INT 81
|
||||
#define SUSB1_VENDOR_INT 85
|
||||
#define SUSB1_CLASS_INT 87
|
||||
#define SUSB1_LOADER_INT 94
|
||||
#define SUSB1_DELTA_CONFIG_INT 95
|
||||
|
||||
// USB 2
|
||||
#define SUSB2_DEVICE_DESCRIPTOR_VEC 106
|
||||
#define SUSB2_CONFIGURATION_DESCRIPTOR_VEC 107
|
||||
#define SUSB2_STRING_DESCRIPTOR_VEC 108
|
||||
#define SUSB2_FINISH_INT 105
|
||||
#define SUSB2_STALL_INT 98
|
||||
#define SUSB2_STANDARD_INT 99
|
||||
#define SUSB2_SEND_INT 96
|
||||
#define SUSB2_RECEIVE_INT 97
|
||||
#define SUSB2_VENDOR_INT 101
|
||||
#define SUSB2_CLASS_INT 103
|
||||
#define SUSB2_LOADER_INT 110
|
||||
#define SUSB2_DELTA_CONFIG_INT 111
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// General USB Registers
|
||||
#define USB_REG_FLAGS 0xC000 // CPU Flags
|
||||
#define USB_REG_BANK 0xC002 // Register Bank
|
||||
#define USB_REG_REVISON 0xC004 // Hardware Revision
|
||||
#define USB_REG_SPEED 0xC008 // CPU Speed
|
||||
#define USB_REG_PWRCTRL 0xC00A // Power Control
|
||||
#define USB_REG_INTEN 0xC00E // Interrupt Enable
|
||||
#define USB_REG_BP 0xC014 // Breakpoint
|
||||
#define USB_REG_USBDIAG 0xC03C // USB Diagnostic
|
||||
#define USB_REG_MEMDIAG 0xC03E // Memory Diagnostic
|
||||
|
||||
// HPI registers
|
||||
#define HPI_REG_BP 0x0140 // HPI Breakpoint
|
||||
#define HPI_REG_INTROUTE 0x0142 // Interrupt Routing
|
||||
#define HPI_REG_SIE1MSG 0x0144 // SIE1msg
|
||||
#define HPI_REG_SIE2MSG 0x0148 // SIE2msg
|
||||
#define HPI_REG_MAILBOX 0xC0C6 // HPI Mailbox
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// General Device Registers
|
||||
// Device 1
|
||||
#define SUSB1_REG_PORTSEL 0xC084 // Port select
|
||||
#define SUSB1_REG_USBCTRL 0xC08A // USB control
|
||||
#define SUSB1_REG_INTEN 0xC08C // Interrupt enable
|
||||
#define SUSB1_REG_ADDR 0xC08E // Address
|
||||
#define SUSB1_REG_STATUS 0xC090 // Status
|
||||
#define SUSB1_REG_FRAMENUM 0xC092 // Frame number
|
||||
#define SUSB1_REG_SOFEOPCNT 0xC094 // SOF/EOP count
|
||||
|
||||
// Device 2
|
||||
#define SUSB2_REG_PORTSEL 0xC0A4 // Port select
|
||||
#define SUSB2_REG_USBCTRL 0xC0AA // USB control
|
||||
#define SUSB2_REG_INTEN 0xC0AC // Interrupt enable
|
||||
#define SUSB2_REG_ADDR 0xC0AE // Address
|
||||
#define SUSB2_REG_STATUS 0xC0B0 // Status
|
||||
#define SUSB2_REG_FRAMENUM 0xC0B2 // Frame number
|
||||
#define SUSB2_REG_SOFEOPCNT 0xC0B4 // SOF/EOP count
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// Endpoint Registers
|
||||
// Device 1 Control
|
||||
#define SUSB1_REG_EP_CTRL0 0x0200
|
||||
#define SUSB1_REG_EP_CTRL1 0x0210
|
||||
#define SUSB1_REG_EP_CTRL2 0x0220
|
||||
#define SUSB1_REG_EP_CTRL3 0x0230
|
||||
#define SUSB1_REG_EP_CTRL4 0x0240
|
||||
#define SUSB1_REG_EP_CTRL5 0x0250
|
||||
#define SUSB1_REG_EP_CTRL6 0x0260
|
||||
#define SUSB1_REG_EP_CTRL7 0x0270
|
||||
// Device 1 Address
|
||||
#define SUSB1_REG_EP_ADDR0 0x0202
|
||||
#define SUSB1_REG_EP_ADDR1 0x0212
|
||||
#define SUSB1_REG_EP_ADDR2 0x0222
|
||||
#define SUSB1_REG_EP_ADDR3 0x0232
|
||||
#define SUSB1_REG_EP_ADDR4 0x0242
|
||||
#define SUSB1_REG_EP_ADDR5 0x0252
|
||||
#define SUSB1_REG_EP_ADDR6 0x0262
|
||||
#define SUSB1_REG_EP_ADDR7 0x0272
|
||||
// Device 1 Count
|
||||
#define SUSB1_REG_EP_COUNT0 0x0204
|
||||
#define SUSB1_REG_EP_COUNT1 0x0214
|
||||
#define SUSB1_REG_EP_COUNT2 0x0224
|
||||
#define SUSB1_REG_EP_COUNT3 0x0234
|
||||
#define SUSB1_REG_EP_COUNT4 0x0244
|
||||
#define SUSB1_REG_EP_COUNT5 0x0254
|
||||
#define SUSB1_REG_EP_COUNT6 0x0264
|
||||
#define SUSB1_REG_EP_COUNT7 0x0274
|
||||
// Device 1 Status
|
||||
#define SUSB1_REG_EP_STATUS0 0x0206
|
||||
#define SUSB1_REG_EP_STATUS1 0x0216
|
||||
#define SUSB1_REG_EP_STATUS2 0x0226
|
||||
#define SUSB1_REG_EP_STATUS3 0x0236
|
||||
#define SUSB1_REG_EP_STATUS4 0x0246
|
||||
#define SUSB1_REG_EP_STATUS5 0x0256
|
||||
#define SUSB1_REG_EP_STATUS6 0x0266
|
||||
#define SUSB1_REG_EP_STATUS7 0x0276
|
||||
// Device 1 Count result
|
||||
#define SUSB1_REG_EP_CNTRES0 0x0208
|
||||
#define SUSB1_REG_EP_CNTRES1 0x0218
|
||||
#define SUSB1_REG_EP_CNTRES2 0x0228
|
||||
#define SUSB1_REG_EP_CNTRES3 0x0238
|
||||
#define SUSB1_REG_EP_CNTRES4 0x0248
|
||||
#define SUSB1_REG_EP_CNTRES5 0x0258
|
||||
#define SUSB1_REG_EP_CNTRES6 0x0268
|
||||
#define SUSB1_REG_EP_CNTRES7 0x0278
|
||||
|
||||
// Device 2 Control
|
||||
#define SUSB2_REG_EP_CTRL0 0x0280
|
||||
#define SUSB2_REG_EP_CTRL1 0x0290
|
||||
#define SUSB2_REG_EP_CTRL2 0x02A0
|
||||
#define SUSB2_REG_EP_CTRL3 0x02B0
|
||||
#define SUSB2_REG_EP_CTRL4 0x02C0
|
||||
#define SUSB2_REG_EP_CTRL5 0x02D0
|
||||
#define SUSB2_REG_EP_CTRL6 0x02E0
|
||||
#define SUSB2_REG_EP_CTRL7 0x02F0
|
||||
// Device 2 Address
|
||||
#define SUSB2_REG_EP_ADDR0 0x0282
|
||||
#define SUSB2_REG_EP_ADDR1 0x0292
|
||||
#define SUSB2_REG_EP_ADDR2 0x02A2
|
||||
#define SUSB2_REG_EP_ADDR3 0x02B2
|
||||
#define SUSB2_REG_EP_ADDR4 0x02C2
|
||||
#define SUSB2_REG_EP_ADDR5 0x02D2
|
||||
#define SUSB2_REG_EP_ADDR6 0x02E2
|
||||
#define SUSB2_REG_EP_ADDR7 0x02F2
|
||||
// Device 2 Count
|
||||
#define SUSB2_REG_EP_COUNT0 0x0284
|
||||
#define SUSB2_REG_EP_COUNT1 0x0294
|
||||
#define SUSB2_REG_EP_COUNT2 0x02A4
|
||||
#define SUSB2_REG_EP_COUNT3 0x02B4
|
||||
#define SUSB2_REG_EP_COUNT4 0x02C4
|
||||
#define SUSB2_REG_EP_COUNT5 0x02D4
|
||||
#define SUSB2_REG_EP_COUNT6 0x02E4
|
||||
#define SUSB2_REG_EP_COUNT7 0x02F4
|
||||
// Device 2 Status
|
||||
#define SUSB2_REG_EP_STATUS0 0x0286
|
||||
#define SUSB2_REG_EP_STATUS1 0x0296
|
||||
#define SUSB2_REG_EP_STATUS2 0x02A6
|
||||
#define SUSB2_REG_EP_STATUS3 0x02B6
|
||||
#define SUSB2_REG_EP_STATUS4 0x02C6
|
||||
#define SUSB2_REG_EP_STATUS5 0x02D6
|
||||
#define SUSB2_REG_EP_STATUS6 0x02E6
|
||||
#define SUSB2_REG_EP_STATUS7 0x02F6
|
||||
// Device 2 Count result
|
||||
#define SUSB2_REG_EP_CNTRES0 0x0288
|
||||
#define SUSB2_REG_EP_CNTRES1 0x0298
|
||||
#define SUSB2_REG_EP_CNTRES2 0x02A8
|
||||
#define SUSB2_REG_EP_CNTRES3 0x02B8
|
||||
#define SUSB2_REG_EP_CNTRES4 0x02C8
|
||||
#define SUSB2_REG_EP_CNTRES5 0x02D8
|
||||
#define SUSB2_REG_EP_CNTRES6 0x02E8
|
||||
#define SUSB2_REG_EP_CNTRES7 0x02F8
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// others
|
||||
#define HUSB_TDLISTDONE 0x1000
|
||||
#define HUSB_SOF 0x2000
|
||||
#define HUSB_ARMV 0x0001
|
||||
#define HUSB_AINS_FS 0x0002
|
||||
#define HUSB_AINS_LS 0x0004
|
||||
#define HUSB_AWAKEUP 0x0008
|
||||
#define HUSB_BRMV 0x0010
|
||||
#define HUSB_BINS_FS 0x0020
|
||||
#define HUSB_BINS_LS 0x0040
|
||||
#define HUSB_BWAKEUP 0x0080
|
||||
|
||||
#define SUSB_EP0_MSG 0x0001
|
||||
#define SUSB_EP1_MSG 0x0002
|
||||
#define SUSB_EP2_MSG 0x0004
|
||||
#define SUSB_EP3_MSG 0x0008
|
||||
#define SUSB_EP4_MSG 0x0010
|
||||
#define SUSB_EP5_MSG 0x0020
|
||||
#define SUSB_EP6_MSG 0x0040
|
||||
#define SUSB_EP7_MSG 0x0080
|
||||
#define SUSB_RST_MSG 0x0100
|
||||
#define SUSB_SOF_MSG 0x0200
|
||||
#define SUSB_CFG_MSG 0x0400
|
||||
#define SUSB_SUS_MSG 0x0800
|
||||
#define SUSB_ID_MSG 0x4000
|
||||
#define SUSB_VBUS_MSG 0x8000
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// Functions
|
||||
// ---------------------------------------------------------
|
||||
|
||||
// HPI low-level routines
|
||||
void cy67k3_isr(void);
|
||||
void cy67k3_reset(void);
|
||||
UINT16 cy67k3_read_HPI_DATA(void);
|
||||
UINT16 cy67k3_read_HPI_MAILBOX(void);
|
||||
UINT16 cy67k3_read_HPI_ADDRESS(void);
|
||||
UINT16 cy67k3_read_HPI_STATUS(void);
|
||||
void cy67k3_write_HPI_DATA(UINT16 data);
|
||||
void cy67k3_write_HPI_MAILBOX(UINT16 data);
|
||||
void cy67k3_write_HPI_ADDRESS(UINT16 data);
|
||||
void cy67k3_write_HPI_STATUS(UINT16 data);
|
||||
|
||||
// HPI API
|
||||
UINT32 hpi_init(void);
|
||||
void hpi_mbx_write(UINT16 msgcode);
|
||||
UINT32 hpi_mbx_read(void);
|
||||
UINT32 hpi_read_reg(UINT16 addr);
|
||||
UINT32 hpi_write_reg(UINT16 addr, UINT16 data);
|
||||
UINT32 hpi_write_ram(UINT16 addr, UINT16 *pData, UINT32 num_words);
|
||||
UINT32 hpi_read_ram(UINT16 addr, UINT16 *pData, UINT32 num_words);
|
||||
UINT32 hpi_comm_reset(void);
|
||||
UINT32 hpi_comm_jump2code(UINT16 addr);
|
||||
UINT32 hpi_comm_callcode(UINT16 addr);
|
||||
UINT32 hpi_comm_write_ctrl_reg(UINT16 addr, UINT16 data, UINT16 logic);
|
||||
UINT32 hpi_comm_read_ctrl_reg(UINT16 addr);
|
||||
UINT32 hpi_comm_write_xmem(UINT16 addr, UINT8 *pData, UINT16 len);
|
||||
UINT32 hpi_comm_read_xmem(UINT16 addr, UINT8 *pData, UINT16 len);
|
||||
UINT32 hpi_comm_exec_int(UINT16 intnum, UINT32 nargs, ...);
|
||||
|
||||
// USB API
|
||||
UINT32 usb_init(void);
|
||||
UINT32 usb_irp_register(usb_irp_t *pIRP, UINT32 port, UINT32 ept, UINT32 size, UINT32 is_out);
|
||||
UINT32 usb_irp_enqueue(usb_irp_t *pIRP);
|
||||
UINT32 usb_callback_register(UINT32 port, UINT32 type, fp_t pFunc, void *pArg);
|
||||
|
||||
#define FIFO_BLOCK 1
|
||||
#define FIFO_NONBLOCK 0
|
||||
UINT32 fifo_alloc(fifo_t *pObj, UINT32 size);
|
||||
UINT32 fifo_free(fifo_t *pObj);
|
||||
UINT32 fifo_flush(fifo_t *pObj);
|
||||
UINT32 fifo_is_full(fifo_t *pObj);
|
||||
UINT32 fifo_is_empty(fifo_t *pObj);
|
||||
UINT32 fifo_read(fifo_t *pObj, UINT8 *pData, UINT32 size, UINT32 timeout, UINT32 do_block);
|
||||
UINT32 fifo_write(fifo_t *pObj, UINT8 *pData, UINT32 size, UINT32 timeout, UINT32 do_block);
|
||||
|
||||
#endif // HPI_H
|
||||
@@ -0,0 +1,846 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include "libsys.h"
|
||||
#include "cfiflash.h"
|
||||
#include "hpi.h"
|
||||
|
||||
static volatile UINT32 _g_uart_msg;
|
||||
static volatile UINT32 _g_rst;
|
||||
static volatile UINT32 _g_sus;
|
||||
static volatile UINT32 _g_cfg;
|
||||
|
||||
void uart_handler(void)
|
||||
{
|
||||
volatile UINT32 *pUART_stat = (UINT32*)SYS_UART_STAT;
|
||||
volatile UINT32 *pUART_data = (UINT32*)SYS_UART_DATA;
|
||||
|
||||
while((SYS_PS2_BIT_RX_AVAIL & *pUART_stat))
|
||||
{
|
||||
_g_uart_msg = *pUART_data;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void PrintDevRegs(UINT devid)
|
||||
{
|
||||
int i;
|
||||
UINT32 reg_base1, reg_base2, reg_addr;
|
||||
|
||||
if ((devid < 1) || (devid > 2))
|
||||
return;
|
||||
|
||||
printf("********************************************************\n");
|
||||
printf("Device %d status\n", devid);
|
||||
printf("********************************************************\n");
|
||||
reg_base1 = 0x0200 + (devid-1)*0x80;
|
||||
reg_base2 = 0xC080 + (devid-1)*0x20;
|
||||
reg_addr = reg_base2 + 4;
|
||||
printf("Port select (%4.4X) : %4.4X\n", reg_addr, hpi_read_reg(reg_addr));
|
||||
|
||||
reg_addr = reg_base2 + 10;
|
||||
printf("USB control (%4.4X) : %4.4X\n", reg_addr, hpi_read_reg(reg_addr));
|
||||
|
||||
reg_addr = reg_base2 + 12;
|
||||
printf("Int. enable (%4.4X) : %4.4X\n", reg_addr, hpi_read_reg(reg_addr));
|
||||
|
||||
reg_addr = reg_base2 + 14;
|
||||
printf("Address (%4.4X) : %4.4X\n", reg_addr, hpi_read_reg(reg_addr));
|
||||
|
||||
reg_addr = reg_base2 + 16;
|
||||
printf("Status (%4.4X) : %4.4X\n", reg_addr, hpi_read_reg(reg_addr));
|
||||
|
||||
reg_addr = reg_base2 + 18;
|
||||
printf("Frame # reg (%4.4X) : %4.4X\n", reg_addr, hpi_read_reg(reg_addr));
|
||||
|
||||
reg_addr = reg_base2 + 20;
|
||||
printf("SOF/EOP cnt (%4.4X) : %4.4X\n", reg_addr, hpi_read_reg(reg_addr));
|
||||
|
||||
for (i=0; i < 8; i++)
|
||||
{
|
||||
printf("EP# %d\n", i);
|
||||
reg_addr = reg_base1 + 16*i + 0;
|
||||
printf("Control (%4.4X) : %4.4X\n", reg_addr, hpi_read_reg(reg_addr));
|
||||
|
||||
reg_addr = reg_base1 + 16*i + 2;
|
||||
printf("Address (%4.4X) : %4.4X\n", reg_addr, hpi_read_reg(reg_addr));
|
||||
|
||||
reg_addr = reg_base1 + 16*i + 4;
|
||||
printf("Count (%4.4X) : %4.4X\n", reg_addr, hpi_read_reg(reg_addr));
|
||||
|
||||
reg_addr = reg_base1 + 16*i + 6;
|
||||
printf("Status (%4.4X) : %4.4X\n", reg_addr, hpi_read_reg(reg_addr));
|
||||
|
||||
reg_addr = reg_base1 + 16*i + 8;
|
||||
printf("Count result (%4.4X) : %4.4X\n", reg_addr, hpi_read_reg(reg_addr));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct _sdev_descr_t
|
||||
{
|
||||
UINT8 size; // length
|
||||
UINT8 type; // desc type
|
||||
UINT16 usb_spec; // USB spec
|
||||
UINT8 devclass; // device class
|
||||
UINT8 subclass; // sub class
|
||||
UINT8 protocol; // protocol
|
||||
UINT8 max_packet_size; // max packet size for endpoint 0
|
||||
UINT16 vendor_id; // Vendor ID
|
||||
UINT16 product_id; // Product ID
|
||||
UINT16 device_id; // device release number
|
||||
UINT8 man_str_index; // index of manufacture string
|
||||
UINT8 prod_str_index; // index of product string
|
||||
UINT8 sn_str_index; // index of serial number string
|
||||
UINT8 nconfs; // number of configurations
|
||||
} __attribute__ ((__packed__)) dev_descr_t;
|
||||
|
||||
typedef struct _sconf_descr_t
|
||||
{
|
||||
UINT8 size; // length of this config
|
||||
UINT8 type; // desc type
|
||||
UINT16 total_size; // Total configuration desc length including this config and following descriptions
|
||||
UINT8 nifaces; // Number of interface descriptions following this
|
||||
UINT8 conf_id; // config number
|
||||
UINT8 conf_str_index; // index of string describing config
|
||||
UINT8 attr; // attributes (e.g. bus powered)
|
||||
UINT8 current; // 2mA x <current> (max. 250 => 500mA)
|
||||
} __attribute__ ((__packed__)) conf_descr_t;
|
||||
|
||||
typedef struct _siface_descr_t
|
||||
{
|
||||
UINT8 size; // length of this config
|
||||
UINT8 type; // desc type
|
||||
UINT8 base; // base number
|
||||
UINT8 alt; // alt
|
||||
UINT8 neps; // number of endpoint description following this
|
||||
UINT8 iface_class; // interface class (vendor)
|
||||
UINT8 subclass; // subclass
|
||||
UINT8 iface_proto; // interface proto (vendor)
|
||||
UINT8 iface_str_index;
|
||||
} __attribute__ ((__packed__)) iface_descr_t;
|
||||
|
||||
typedef struct _sep_descr_t
|
||||
{
|
||||
UINT8 size; // length of this config
|
||||
UINT8 type; // type (endpoint)
|
||||
UINT8 type_num; // type/number (Host use WriteFile)
|
||||
UINT8 bulk; // Bulk
|
||||
UINT16 pkt_size; // packet size
|
||||
UINT8 interval; // interval
|
||||
} __attribute__ ((__packed__)) ep_descr_t;
|
||||
|
||||
typedef struct _sotg_descr_t
|
||||
{
|
||||
UINT8 size; // length of this config
|
||||
UINT8 type; // type (OTG)
|
||||
UINT8 hnp_srp; // HNP|SRP support
|
||||
} __attribute__ ((__packed__)) otg_descr_t;
|
||||
|
||||
typedef struct _sstr_descr_hdr_t
|
||||
{
|
||||
UINT8 size; // length of this config
|
||||
UINT8 type; // type
|
||||
} __attribute__ ((__packed__)) str_descr_hdr_t;
|
||||
|
||||
typedef struct _scfg_inst_t
|
||||
{
|
||||
usb_irp_t *pIRP_rx;
|
||||
usb_irp_t *pIRP_tx;
|
||||
} cfg_inst_t;
|
||||
|
||||
UINT32 conf_write(UINT8 *pConfDescr, UINT32 neps, ep_descr_t *pEP)
|
||||
{
|
||||
UINT32 pos, size;
|
||||
conf_descr_t cfg;
|
||||
iface_descr_t iface;
|
||||
otg_descr_t otg_descr;
|
||||
|
||||
// Fill config description
|
||||
cfg.size = sizeof(conf_descr_t);
|
||||
cfg.type = 2;
|
||||
cfg.total_size = sizeof(conf_descr_t) + sizeof(iface_descr_t) + neps*sizeof(ep_descr_t) + sizeof(otg_descr_t);
|
||||
cfg.nifaces = 1; // can handle only one interface per config
|
||||
cfg.conf_id = 1;
|
||||
cfg.conf_str_index = 0;
|
||||
cfg.attr = 0x80;
|
||||
cfg.current = 50;
|
||||
|
||||
// Copy config description
|
||||
pos = 0;
|
||||
size = sizeof(conf_descr_t);
|
||||
memcpy(&pConfDescr[pos], &cfg, size);
|
||||
|
||||
// Fill interface description
|
||||
iface.size = sizeof(iface_descr_t);
|
||||
iface.type = 4;
|
||||
iface.base = 0;
|
||||
iface.alt = 0;
|
||||
iface.neps = neps;
|
||||
iface.iface_class = 0;
|
||||
iface.subclass = 0;
|
||||
iface.iface_proto = 0;
|
||||
iface.iface_str_index = 0;
|
||||
|
||||
// Copy interface description
|
||||
pos += size;
|
||||
size = sizeof(iface_descr_t);
|
||||
memcpy(&pConfDescr[pos], &iface, size);
|
||||
|
||||
// Copy N end point descriptions
|
||||
pos += size;
|
||||
size = neps*sizeof(ep_descr_t);
|
||||
memcpy(&pConfDescr[pos], pEP, size);
|
||||
|
||||
// Fill OTG description
|
||||
otg_descr.size = sizeof(otg_descr_t);
|
||||
otg_descr.type = 9; // OTG
|
||||
otg_descr.hnp_srp = 3; // HNP|SRP supported
|
||||
|
||||
// Copy OTG description
|
||||
pos += size;
|
||||
size = sizeof(ep_descr_t);
|
||||
memcpy(&pConfDescr[pos], &otg_descr, size);
|
||||
|
||||
pos += size;
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
UINT32 str_write(UINT8 *pStrDescr, UINT8 *pStr0, UINT8 *pStr1, UINT8 *pStr2)
|
||||
{
|
||||
int i;
|
||||
UINT32 pos, size, strsize;
|
||||
str_descr_hdr_t *pStrHdr;
|
||||
UINT16 *pStr;
|
||||
|
||||
pos = 0;
|
||||
size = sizeof(str_descr_hdr_t);
|
||||
strsize = 2;
|
||||
pStrHdr = (str_descr_hdr_t*)&pStrDescr[pos];
|
||||
pStrHdr->size = size + strsize;
|
||||
pStrHdr->type = 3;
|
||||
|
||||
pos += size;
|
||||
pStr = (UINT16*)&pStrDescr[pos];
|
||||
|
||||
*pStr = 0x0409;
|
||||
|
||||
// String 0
|
||||
pos += size;
|
||||
size = sizeof(str_descr_hdr_t);
|
||||
strsize = strlen(pStr0);
|
||||
|
||||
pStrHdr = (str_descr_hdr_t*)&pStrDescr[pos];
|
||||
pStrHdr->size = sizeof(str_descr_hdr_t) + 2*strsize;
|
||||
pStrHdr->type = 3;
|
||||
|
||||
pos += size;
|
||||
size = 2*strsize;
|
||||
pStr = (UINT16*)&pStrDescr[pos];
|
||||
|
||||
for (i=0; i < strsize; i++)
|
||||
pStr[i] = (UINT16)pStr0[i];
|
||||
|
||||
// String 1
|
||||
pos += size;
|
||||
size = sizeof(str_descr_hdr_t);
|
||||
strsize = strlen(pStr1);
|
||||
|
||||
pStrHdr = (str_descr_hdr_t*)&pStrDescr[pos];
|
||||
pStrHdr->size = sizeof(str_descr_hdr_t) + 2*strsize;
|
||||
pStrHdr->type = 3;
|
||||
|
||||
pos += size;
|
||||
size = 2*strsize;
|
||||
pStr = (UINT16*)&pStrDescr[pos];
|
||||
|
||||
for (i=0; i < strsize; i++)
|
||||
pStr[i] = (UINT16)pStr1[i];
|
||||
|
||||
// String 2
|
||||
pos += size;
|
||||
size = sizeof(str_descr_hdr_t);
|
||||
strsize = strlen(pStr2);
|
||||
|
||||
pStrHdr = (str_descr_hdr_t*)&pStrDescr[pos];
|
||||
pStrHdr->size = sizeof(str_descr_hdr_t) + 2*strsize;
|
||||
pStrHdr->type = 3;
|
||||
|
||||
pos += size;
|
||||
size = 2*strsize;
|
||||
pStr = (UINT16*)&pStrDescr[pos];
|
||||
|
||||
for (i=0; i < strsize; i++)
|
||||
pStr[i] = (UINT16)pStr2[i];
|
||||
|
||||
pos += size;
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
void ep0_func(void *pArg)
|
||||
{
|
||||
UINT32 result;
|
||||
UINT16 buf[USB_MAX_IMG_SIZE/2], ep_cntres, ep_status, ep_count, tsize;
|
||||
usb_irp_t *pIRP = (usb_irp_t*)pArg;
|
||||
|
||||
// printf("Callback with pArg = %8.8X\n", (UINT32)pArg);
|
||||
ep_status = hpi_read_reg (SUSB2_REG_EP_STATUS0);
|
||||
ep_cntres = hpi_read_reg (SUSB2_REG_EP_CNTRES0);
|
||||
ep_count = hpi_read_reg (SUSB2_REG_EP_COUNT0);
|
||||
|
||||
if (ep_status & 0x10)
|
||||
{
|
||||
printf("Setup-flag detected. Status = %4.4X\n", ep_status);
|
||||
}
|
||||
}
|
||||
|
||||
void ep1_func(void *pArg)
|
||||
{
|
||||
UINT32 result;
|
||||
UINT16 buf[USB_MAX_IMG_SIZE/2], ep_cntres, ep_status, ep_count, tsize;
|
||||
usb_irp_t *pIRP = (usb_irp_t*)pArg;
|
||||
|
||||
// printf("Callback with pArg = %8.8X\n", (UINT32)pArg);
|
||||
ep_status = hpi_read_reg (SUSB2_REG_EP_STATUS1);
|
||||
ep_cntres = hpi_read_reg (SUSB2_REG_EP_CNTRES1);
|
||||
ep_count = hpi_read_reg (SUSB2_REG_EP_COUNT1);
|
||||
|
||||
tsize = pIRP->tsize;
|
||||
if (ep_status & 0x0020)
|
||||
{
|
||||
printf("Length exception result %4.4X with count = %d\n", ep_status, (INT16)ep_cntres);
|
||||
if (ep_status & 0x0400)
|
||||
tsize = (UINT16)((INT16)tsize - (INT16)ep_cntres);
|
||||
if (ep_status & 0x0800)
|
||||
tsize = (UINT16)((INT16)tsize - (INT16)ep_cntres);
|
||||
|
||||
}
|
||||
result = hpi_read_ram(pIRP->cy_req.addr, buf, tsize);
|
||||
usb_irp_enqueue(pIRP);
|
||||
fifo_write(&pIRP->fifo, (UINT8*)buf, result, 0, FIFO_BLOCK);
|
||||
|
||||
// printf("Read %d bytes\n", result);
|
||||
|
||||
}
|
||||
|
||||
void ep2_func(void *pArg)
|
||||
{
|
||||
UINT32 result;
|
||||
UINT16 buf[USB_MAX_IMG_SIZE/2], ep_cntres, ep_status, ep_count, tsize;
|
||||
usb_irp_t *pIRP = (usb_irp_t*)pArg;
|
||||
|
||||
// printf("Callback with pArg = %8.8X\n", (UINT32)pArg);
|
||||
ep_status = hpi_read_reg (SUSB2_REG_EP_STATUS2);
|
||||
ep_cntres = hpi_read_reg (SUSB2_REG_EP_CNTRES2);
|
||||
ep_count = hpi_read_reg (SUSB2_REG_EP_COUNT2);
|
||||
|
||||
tsize = pIRP->tsize;
|
||||
if (ep_status & 0x0020)
|
||||
{
|
||||
printf("Length exception result %4.4X with count = %d\n", ep_status, (INT16)ep_cntres);
|
||||
if (ep_status & 0x0400)
|
||||
tsize = (UINT16)((INT16)tsize - (INT16)ep_cntres);
|
||||
if (ep_status & 0x0800)
|
||||
tsize = (UINT16)((INT16)tsize - (INT16)ep_cntres);
|
||||
}
|
||||
|
||||
pIRP->tx_in_progress = 0;
|
||||
result = fifo_read(&pIRP->fifo, (UINT8*)buf, pIRP->tsize, 0, FIFO_NONBLOCK);
|
||||
if (!result)
|
||||
return;
|
||||
|
||||
pIRP->cy_req.size = result;
|
||||
hpi_write_ram(pIRP->cy_req.addr, (UINT16*)buf, result);
|
||||
|
||||
usb_irp_enqueue(pIRP);
|
||||
|
||||
// printf("Wrote %d bytes\n", result);
|
||||
|
||||
}
|
||||
|
||||
void rst_func(void *pArg)
|
||||
{
|
||||
volatile int *pLED = (int*)SYS_LED_PORT;
|
||||
|
||||
// printf("Callback with pArg = %8.8X\n", (UINT32)pArg);
|
||||
sputs("SUSB_RST_MSG\n");
|
||||
/// hpi_comm_reset();
|
||||
|
||||
_g_rst = 1;
|
||||
|
||||
*pLED = 0x40000000 + 1;
|
||||
|
||||
}
|
||||
|
||||
void sof_func(void *pArg)
|
||||
{
|
||||
volatile int *pLED = (int*)SYS_LED_PORT;
|
||||
|
||||
// printf("Callback with pArg = %8.8X\n", (UINT32)pArg);
|
||||
sputs("SUSB_SOF_MSG\n");
|
||||
|
||||
*pLED = 0x40000000 + 2;
|
||||
|
||||
}
|
||||
|
||||
void cfg_func(void *pArg)
|
||||
{
|
||||
volatile int *pLED = (int*)SYS_LED_PORT;
|
||||
cfg_inst_t *pCFG = (cfg_inst_t*)pArg;
|
||||
usb_irp_t *pIRP_rx = (usb_irp_t*)pCFG->pIRP_rx;
|
||||
usb_irp_t *pIRP_tx = (usb_irp_t*)pCFG->pIRP_tx;
|
||||
|
||||
// printf("Callback with pArg = %8.8X\n", (UINT32)pArg);
|
||||
sputs("SUSB_CFG_MSG\n");
|
||||
_g_cfg = 1;
|
||||
usb_irp_enqueue(pIRP_rx);
|
||||
fifo_flush(&pIRP_rx->fifo);
|
||||
fifo_flush(&pIRP_tx->fifo);
|
||||
pIRP_tx->tx_in_progress = 0;
|
||||
*pLED = 0;
|
||||
|
||||
}
|
||||
|
||||
void sus_func(void *pArg)
|
||||
{
|
||||
volatile int *pLED = (int*)SYS_LED_PORT;
|
||||
|
||||
// printf("Callback with pArg = %8.8X\n", (UINT32)pArg);
|
||||
sputs("SUSB_SUS_MSG\n");
|
||||
|
||||
*pLED = 0x40000000 + 3;
|
||||
|
||||
_g_sus = 1;
|
||||
|
||||
}
|
||||
|
||||
void id_func(void *pArg)
|
||||
{
|
||||
volatile int *pLED = (int*)SYS_LED_PORT;
|
||||
|
||||
// printf("Callback with pArg = %8.8X\n", (UINT32)pArg);
|
||||
sputs("SUSB_ID_MSG\n");
|
||||
|
||||
*pLED = 0x40000000 + 4;
|
||||
|
||||
}
|
||||
|
||||
void vbus_func(void *pArg)
|
||||
{
|
||||
volatile int *pLED = (int*)SYS_LED_PORT;
|
||||
|
||||
// printf("Callback with pArg = %8.8X\n", (UINT32)pArg);
|
||||
sputs("SUSB_VBUS_MSG\n");
|
||||
|
||||
*pLED = 0x40000000 + 5;
|
||||
|
||||
}
|
||||
|
||||
UINT32 usb_init_descr(void)
|
||||
{
|
||||
UINT32 result;
|
||||
|
||||
UINT16 buffer16[0x100];
|
||||
UINT16 addr;
|
||||
dev_descr_t dev_descr = {sizeof(dev_descr_t), 1, 0x0200, 0xFF, 0, 0, 8, 0x04B4, 0x7200, 0x0099, 1, 2, 3, 1};
|
||||
ep_descr_t ep_descr[2] = {{sizeof(ep_descr_t), 5, 1, 2, 64, 0}, {sizeof(ep_descr_t), 5, 0x82, 2, 64, 0}};
|
||||
|
||||
// Set device descriptor
|
||||
addr = 0xf516; // default
|
||||
addr = 0xA00;
|
||||
hpi_write_ram(addr, (UINT16*)&dev_descr, sizeof(dev_descr_t));
|
||||
hpi_write_reg(2*SUSB2_DEVICE_DESCRIPTOR_VEC, addr);
|
||||
|
||||
// Set new configuration descriptor
|
||||
|
||||
// Write config and interface descriptor
|
||||
result = conf_write((UINT8*)buffer16, sizeof(ep_descr)/sizeof(ep_descr_t), ep_descr);
|
||||
|
||||
addr = 0xf528; // default
|
||||
addr = 0xB00;
|
||||
hpi_write_ram(addr, (UINT16*)buffer16, result);
|
||||
hpi_write_reg(2*SUSB2_CONFIGURATION_DESCRIPTOR_VEC, addr);
|
||||
|
||||
// Set string description
|
||||
result = str_write((UINT8*)buffer16, "JDI Inc.", "JDI-USB (MIPS)", "311070");
|
||||
addr = 0xf528; // default
|
||||
addr = 0xC00;
|
||||
hpi_write_ram(addr, (UINT16*)buffer16, result);
|
||||
hpi_write_reg(2*SUSB2_STRING_DESCRIPTOR_VEC, addr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
UINT32 usb_force_reconnect(UINT32 port)
|
||||
{
|
||||
UINT32 result;
|
||||
UINT16 addr;
|
||||
|
||||
if (port >= USB_MAX_NUM_PORTS)
|
||||
return -1;
|
||||
|
||||
if (port == 0)
|
||||
{
|
||||
// R1 = 0 : Full speed
|
||||
// R2 = 1 : SIE1
|
||||
addr = hpi_read_reg(SUSB1_REG_USBCTRL);
|
||||
hpi_write_reg(SUSB1_REG_USBCTRL, addr | 0x0010);
|
||||
result = hpi_comm_exec_int(SUSB_INIT_INT, 2, R1, 0, R2, 1);
|
||||
hpi_write_reg(SUSB1_REG_USBCTRL, addr);
|
||||
}
|
||||
else
|
||||
{
|
||||
// R1 = 0 : Full speed
|
||||
// R2 = 2 : SIE2
|
||||
addr = hpi_read_reg(SUSB2_REG_USBCTRL);
|
||||
hpi_write_reg(SUSB2_REG_USBCTRL, addr | 0x0010);
|
||||
result = hpi_comm_exec_int(SUSB_INIT_INT, 2, R1, 0, R2, 2);
|
||||
hpi_write_reg(SUSB2_REG_USBCTRL, addr);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
UINT32 usb_recv(usb_irp_t *pObj, UINT8 *pData, UINT32 len, UINT32 timeout)
|
||||
{
|
||||
UINT32 result;
|
||||
|
||||
result = fifo_read(&pObj->fifo, pData, len, timeout, FIFO_BLOCK);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
UINT32 usb_send(usb_irp_t *pObj, UINT8 *pData, UINT32 len, UINT32 timeout)
|
||||
{
|
||||
UINT32 result;
|
||||
UINT8 buf[USB_MAX_IMG_SIZE];
|
||||
|
||||
// Fill-up FIFO
|
||||
result = fifo_write(&pObj->fifo, pData, len, 0, FIFO_NONBLOCK);
|
||||
if (!result)
|
||||
return 0;
|
||||
|
||||
// Trigger TX
|
||||
if (!pObj->tx_in_progress)
|
||||
{
|
||||
pObj->cy_req.size = fifo_read(&pObj->fifo, (UINT8*)buf, pObj->tsize, 0, FIFO_NONBLOCK);
|
||||
hpi_write_ram(pObj->cy_req.addr, (UINT16*)buf, pObj->cy_req.size);
|
||||
usb_irp_enqueue(pObj);
|
||||
}
|
||||
|
||||
// If necessary, write rest to FIFO
|
||||
result += fifo_write(&pObj->fifo, &pData[result], len - result, timeout, FIFO_BLOCK);
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
#define TEST_SIZE (2*1024*1024)
|
||||
#define TRANSFER_SIZE 64
|
||||
#define FLASH_IMAGE_SIZE (2*1024*1024)
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int i;
|
||||
UINT32 result, sync, cmd, len, buf_count, led_count, remain, tx_cnt, flash_offset;
|
||||
UINT8 buffer8[2048];
|
||||
UINT16 buffer16[0x2000];
|
||||
UINT16 addr;
|
||||
volatile UINT32 *pLED = (UINT32*)SYS_LED_PORT;
|
||||
volatile UINT32 *pUART0_stat = (UINT32*)SYS_UART0_STAT;
|
||||
UINT32 start, end;
|
||||
UINT32 *pFlash32;
|
||||
UINT8 *pFlash8;
|
||||
UINT32 buffer32[16], *pBuf;
|
||||
UINT64 *pBuf64;
|
||||
usb_irp_t irp_rx, irp_tx;
|
||||
fifo_t fifo_rx, fifo_tx;
|
||||
cfg_inst_t cfg_inst;
|
||||
flash_t flash;
|
||||
volatile UINT32 *pVGA_ctrl = (UINT32*)SYS_VGA_CTRL;
|
||||
volatile UINT32 *pVGA_moffs = (UINT32*)SYS_VGA_MOFFS;
|
||||
|
||||
_g_rst = 0;
|
||||
_g_sus = 0;
|
||||
_g_cfg = 0;
|
||||
|
||||
usb_init();
|
||||
|
||||
// enable EP#0 callback
|
||||
usb_callback_register(1, SUSB_EP0_MSG, ep0_func, NULL);
|
||||
|
||||
// enable EP#1 callback
|
||||
usb_irp_register(&irp_rx, 1, 1, TRANSFER_SIZE, 1);
|
||||
usb_callback_register(1, SUSB_EP1_MSG, ep1_func, &irp_rx);
|
||||
|
||||
// enable EP#2 callback
|
||||
usb_irp_register(&irp_tx, 1, 2, TRANSFER_SIZE, 0);
|
||||
usb_callback_register(1, SUSB_EP2_MSG, ep2_func, &irp_tx);
|
||||
|
||||
usb_callback_register(1, SUSB_RST_MSG, rst_func, NULL);
|
||||
usb_callback_register(1, SUSB_SOF_MSG, sof_func, NULL);
|
||||
cfg_inst.pIRP_rx = &irp_rx;
|
||||
cfg_inst.pIRP_tx = &irp_tx;
|
||||
usb_callback_register(1, SUSB_CFG_MSG, cfg_func, &cfg_inst);
|
||||
usb_callback_register(1, SUSB_SUS_MSG, sus_func, NULL);
|
||||
usb_callback_register(1, SUSB_ID_MSG, id_func, NULL);
|
||||
usb_callback_register(1, SUSB_VBUS_MSG, vbus_func, NULL);
|
||||
|
||||
printf("HPI-Test\n\n");
|
||||
|
||||
if (IS_ERROR(hpi_init()))
|
||||
{
|
||||
sputs("hpi_init(): error\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("cy67k3_reset\n");
|
||||
cy67k3_reset();
|
||||
|
||||
while(!_g_rst);
|
||||
|
||||
printf("hpi_comm_reset\n");
|
||||
hpi_comm_reset();
|
||||
|
||||
while(!_g_sus);
|
||||
|
||||
printf("usb_init_descr\n");
|
||||
usb_init_descr();
|
||||
printf("hpi_comm_exec_int\n");
|
||||
hpi_comm_exec_int(SUSB_INIT_INT, 2, R1, 0, R2, 2);
|
||||
printf("usb_force_reconnect\n");
|
||||
usb_force_reconnect(1);
|
||||
|
||||
while(!_g_cfg);
|
||||
|
||||
printf("USB-Ready\n");
|
||||
|
||||
printf("CY-Read..");
|
||||
start = clock();
|
||||
for (i=0; i < TEST_SIZE; i+=0x2000)
|
||||
hpi_read_ram(0x2000, buffer16, 0x2000);
|
||||
|
||||
end = clock();
|
||||
printf("done (%.2f Mbyte/s)\n", (double)TEST_SIZE/(1000*(end-start)));
|
||||
|
||||
printf("CY-Write..");
|
||||
start = clock();
|
||||
for (i=0; i < TEST_SIZE; i+=0x2000)
|
||||
hpi_write_ram(0x2000, buffer16, 0x2000);
|
||||
|
||||
end = clock();
|
||||
printf("done (%.2f Mbyte/s)\n", (double)TEST_SIZE/(1000*(end-start)));
|
||||
|
||||
sputs("HPI-Status : ");
|
||||
print_word(cy67k3_read_HPI_STATUS());
|
||||
sputs("\n");
|
||||
|
||||
sputs("HPI BP : ");
|
||||
print_word(hpi_read_reg(HPI_REG_BP));
|
||||
sputs("\n");
|
||||
|
||||
sputs("HPI IRR : ");
|
||||
print_word(hpi_read_reg(HPI_REG_INTROUTE));
|
||||
sputs("\n");
|
||||
|
||||
sputs("CPU Revision : ");
|
||||
print_word(hpi_comm_read_ctrl_reg(USB_REG_REVISON));
|
||||
sputs("\n");
|
||||
|
||||
hpi_comm_write_ctrl_reg(USB_REG_SPEED, 0x0000, LOGIC_DIRECT);
|
||||
sputs("CPU Speed : ");
|
||||
print_word(hpi_comm_read_ctrl_reg(USB_REG_SPEED));
|
||||
sputs("\n");
|
||||
|
||||
// usb_init_descr();
|
||||
// usb_force_reconnect(1);
|
||||
|
||||
// enable RX interrupt
|
||||
*pUART0_stat |= (1 << 6);
|
||||
interrupt_register(3, uart_handler);
|
||||
interrupt_enable(3);
|
||||
|
||||
// Enable EP#1
|
||||
hpi_write_reg(SUSB2_REG_EP_COUNT1, TRANSFER_SIZE);
|
||||
hpi_write_reg(SUSB2_REG_EP_CTRL1, 2);
|
||||
hpi_write_reg(SUSB2_REG_EP_CNTRES1, 0);
|
||||
hpi_write_reg(SUSB2_REG_EP_STATUS1, 0);
|
||||
|
||||
// Enable EP#2
|
||||
hpi_write_reg(SUSB2_REG_EP_COUNT2, TRANSFER_SIZE);
|
||||
hpi_write_reg(SUSB2_REG_EP_CTRL2, 2);
|
||||
hpi_write_reg(SUSB2_REG_EP_CNTRES2, 0);
|
||||
hpi_write_reg(SUSB2_REG_EP_STATUS2, 0);
|
||||
|
||||
led_count = 0;
|
||||
buf_count = 0;
|
||||
|
||||
pBuf64 = (UINT64*)malloc(FLASH_IMAGE_SIZE);
|
||||
pBuf = (UINT32*)pBuf64;
|
||||
|
||||
*pVGA_moffs = (UINT32)pBuf64;
|
||||
*pVGA_ctrl |= SYS_VGA_BIT_MSTEN;
|
||||
|
||||
if (IS_ERROR(flash_find(&flash, SYS_FLASH_IO)))
|
||||
{
|
||||
printf("Cannot find flash device. Exit now!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Get flash offset by value of DIP-switch
|
||||
flash_offset = flash_get_offset_by_blocknum(&flash, flash.info.nblocks-FLASH_IMAGE_SIZE/flash.info.blocksize);
|
||||
printf("flash_offset: %08X\n", flash_offset);
|
||||
pFlash32 = (UINT32*)(SYS_FLASH_IO + flash_offset);
|
||||
pFlash8 = (UINT8*)pFlash32;
|
||||
|
||||
while(1)
|
||||
{
|
||||
switch (_g_uart_msg)
|
||||
{
|
||||
case '1':
|
||||
_g_uart_msg = 0;
|
||||
PrintDevRegs(1);
|
||||
printf("\nSIEmsg1: %4.4X\n", hpi_read_reg(HPI_REG_SIE1MSG));
|
||||
break;
|
||||
|
||||
case '2':
|
||||
_g_uart_msg = 0;
|
||||
PrintDevRegs(2);
|
||||
printf("\nSIEmsg2: %4.4X\n", hpi_read_reg(HPI_REG_SIE2MSG));
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
result = usb_recv(&irp_rx, (UINT8*)&sync, 4, 100);
|
||||
if (!result)
|
||||
continue;
|
||||
|
||||
*pLED = led_count++;
|
||||
|
||||
if (sync == 0xC24755AA)
|
||||
{
|
||||
printf("Sync found\n");
|
||||
result = usb_recv(&irp_rx, (UINT8*)&cmd, 4, 1000);
|
||||
if (!result)
|
||||
continue;
|
||||
|
||||
result = usb_recv(&irp_rx, (UINT8*)&len, 4, 1000);
|
||||
if (!result)
|
||||
continue;
|
||||
|
||||
printf("Command %d with len %d found\n",cmd, len);
|
||||
switch(cmd)
|
||||
{
|
||||
case 0x00000001:
|
||||
result = usb_recv(&irp_rx, NULL, len, 1000);
|
||||
if (result)
|
||||
{
|
||||
printf("Read %d bytes\n", result);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x00000002:
|
||||
remain = len;
|
||||
tx_cnt = 0;
|
||||
while(remain)
|
||||
{
|
||||
len = sizeof(buffer8);
|
||||
if (remain < len)
|
||||
len = remain;
|
||||
|
||||
for (i=0; i < len; i++)
|
||||
buffer8[i] = buf_count+i;
|
||||
|
||||
result = usb_send(&irp_tx, buffer8, len, 1000);
|
||||
if (!result)
|
||||
break;
|
||||
tx_cnt += result;
|
||||
remain -= result;
|
||||
buf_count++;
|
||||
}
|
||||
printf("Wrote %d bytes\n", tx_cnt);
|
||||
break;
|
||||
|
||||
case 0x00000003:
|
||||
remain = len;
|
||||
tx_cnt = 0;
|
||||
while(remain)
|
||||
{
|
||||
len = 256;
|
||||
if (remain < len)
|
||||
len = remain;
|
||||
|
||||
result = usb_send(&irp_tx, (UINT8*)&pFlash8[tx_cnt], len, 1000);
|
||||
if (!result)
|
||||
break;
|
||||
tx_cnt += result;
|
||||
remain -= result;
|
||||
buf_count++;
|
||||
}
|
||||
printf("Wrote %d bytes\n", tx_cnt);
|
||||
break;
|
||||
|
||||
case 0x00000004:
|
||||
*pVGA_ctrl &= ~SYS_VGA_BIT_MSTEN;
|
||||
result = usb_recv(&irp_rx, (UINT8*)pBuf, len, 1000);
|
||||
if (result)
|
||||
{
|
||||
printf("Read %d bytes\n", result);
|
||||
}
|
||||
|
||||
len = result;
|
||||
if (len > FLASH_IMAGE_SIZE)
|
||||
{
|
||||
printf("Cannot write flash: image to large!\n");
|
||||
break;
|
||||
}
|
||||
|
||||
printf("Flash erase...");
|
||||
result = flash_erase(&flash, flash_offset, len);
|
||||
if (IS_ERROR(result))
|
||||
{
|
||||
printf("failed (%08X)\n", result);
|
||||
break;
|
||||
}
|
||||
printf("done\n");
|
||||
|
||||
printf("Flash write...");
|
||||
result = flash_program(&flash, flash_offset, (UINT8*)pBuf, len);
|
||||
if (IS_ERROR(result))
|
||||
{
|
||||
printf("failed (%08X)\n", result);
|
||||
break;
|
||||
}
|
||||
printf("done\n");
|
||||
|
||||
printf("Flash verify...");
|
||||
result = flash_verify(&flash, flash_offset, (UINT8*)pBuf, len);
|
||||
if (IS_ERROR(result))
|
||||
{
|
||||
printf("failed (%08X)\n", result);
|
||||
break;
|
||||
}
|
||||
printf("passed\n");
|
||||
*pVGA_ctrl |= SYS_VGA_BIT_MSTEN;
|
||||
break;
|
||||
|
||||
case 0x000000FF:
|
||||
usb_force_reconnect(1);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// pMem = (UINT8*)0x40000000;
|
||||
// result = fifo_write(&fifo_tx, pMem, 640, 0, FIFO_NONBLOCK);
|
||||
// pMem += result;
|
||||
// usb_irp_enqueue(&irp_tx);
|
||||
Reference in New Issue
Block a user