- initial import
git-svn-id: http://moon:8086/svn/mips@1 a8ebac50-d88d-4704-bea3-6648445a41b3
This commit is contained in:
+946
@@ -0,0 +1,946 @@
|
||||
#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 = 1;
|
||||
for (i=0; i <160; i++)
|
||||
{
|
||||
__asm __volatile
|
||||
(
|
||||
".set noreorder\n"
|
||||
"nop\n"
|
||||
"nop\n"
|
||||
"nop\n"
|
||||
"nop\n"
|
||||
".set reorder\n"
|
||||
);
|
||||
}
|
||||
|
||||
*pHpi = 0;
|
||||
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------
|
||||
Reference in New Issue
Block a user