diff --git a/lib/CPUs/MIPS/bsp/examples/hpi.c b/lib/CPUs/MIPS/bsp/examples/hpi.c new file mode 100644 index 0000000..3a21263 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/hpi.c @@ -0,0 +1,949 @@ +#include +#include +#include +#include +#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; +} + +// --------------------------------------------------------- diff --git a/lib/CPUs/MIPS/bsp/examples/hpi.h b/lib/CPUs/MIPS/bsp/examples/hpi.h new file mode 100644 index 0000000..58edabe --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/hpi.h @@ -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 diff --git a/lib/CPUs/MIPS/bsp/examples/test_hpi.c b/lib/CPUs/MIPS/bsp/examples/test_hpi.c new file mode 100644 index 0000000..4efe638 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/test_hpi.c @@ -0,0 +1,846 @@ +#include +#include +#include +#include +#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 (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);