uint32_t USB_OTG_USBH_handle_hc_n_In_ISR(USB_OTG_CORE_HANDLE *pdev, uint32_t num) { USB_OTG_HCINTn_TypeDef hcint; USB_OTG_HCGINTMSK_TypeDef hcintmsk; USB_OTG_HCCHAR_TypeDef hcchar; USB_OTG_HCTSIZn_TypeDef hctsiz; USB_OTG_HC_REGS *hcreg; int ret = 0; hcreg = pdev->regs.HC_REGS[num]; hcint.d32 = USB_OTG_READ_REG32(&hcreg->HCINT); hcintmsk.d32 = USB_OTG_READ_REG32(&hcreg->HCGINTMSK); hcint.d32 = hcint.d32 &hcintmsk.d32; hcchar.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[num]->HCCHAR); hcintmsk.d32 = 0; if (hcint.b.ahberr) { CLEAR_HC_INT(hcreg, ahberr); UNMASK_HOST_INT_CHH(num); } else if (hcint.b.ack) { CLEAR_HC_INT(hcreg, ack); } else if (hcint.b.stall) { UNMASK_HOST_INT_CHH(num); pdev->host.HC_Status[num] = HC_STALL; CLEAR_HC_INT(hcreg, nak); /* Clear the NAK Condition */ CLEAR_HC_INT(hcreg, stall); /* Clear the STALL Condition */ hcint.b.nak = 0; /* NOTE: When there is a 'stall', reset also nak, else, the pdev->host.HC_Status = HC_STALL will be overwritten by 'nak' in code below */ USB_OTG_HC_Halt(pdev, num); } else if (hcint.b.datatglerr) { UNMASK_HOST_INT_CHH(num); USB_OTG_HC_Halt(pdev, num); CLEAR_HC_INT(hcreg, nak); pdev->host.HC_Status[num] = HC_DATATGLERR; CLEAR_HC_INT(hcreg, datatglerr); } if (hcint.b.frmovrun) { UNMASK_HOST_INT_CHH(num); USB_OTG_HC_Halt(pdev, num); CLEAR_HC_INT(hcreg, frmovrun); } else if (hcint.b.xfercompl) { pdev->host.HC_Status[num] = HC_XFRC; pdev->host.ErrCnt[num] = 0; CLEAR_HC_INT(hcreg, xfercompl); CLEAR_HC_INT(hcreg , nak); if (hcchar.b.eptype == EP_TYPE_BULK) { if (pdev->cfg.dma_enable == 1) { hctsiz.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[num]->HCTSIZ); pdev->host.XferCnt[num] = pdev->host.hc[num].xfer_len - hctsiz.b.xfersize; pdev->host.hc[num].packet_count = (pdev->host.XferCnt[num] + 63) / 64; } if (pdev->host.hc[num].packet_count & 1) pdev->host.hc[num].toggle_in ^= 1; } else if (hcchar.b.eptype == EP_TYPE_CTRL) { pdev->host.hc[num].toggle_in ^= 1; } else if (hcchar.b.eptype == EP_TYPE_INTR) { hcchar.b.oddfrm = 1; USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[num]->HCCHAR, hcchar.d32); pdev->host.URB_State[num] = URB_DONE; } UNMASK_HOST_INT_CHH(num); USB_OTG_HC_Halt(pdev, num); } else if (hcint.b.chhltd) { ret = 1; MASK_HOST_INT_CHH(num); if (pdev->host.HC_Status[num] == HC_XFRC) { pdev->host.URB_State[num] = URB_DONE; } else if (pdev->host.HC_Status[num] == HC_STALL) { pdev->host.URB_State[num] = URB_STALL; } else if ((pdev->host.HC_Status[num] == HC_XACTERR) || (pdev ->host.HC_Status[num] == HC_DATATGLERR)) { pdev->host.ErrCnt[num] = 0; pdev->host.URB_State[num] = URB_ERROR; }else ret = 0; /* else if (pdev->host.HC_Status[num] == HC_NAK) { pdev->host.URB_State[num] = URB_NAK; need_wake_up = 1; } */ CLEAR_HC_INT(hcreg, chhltd); } else if (hcint.b.xacterr) { UNMASK_HOST_INT_CHH(num); pdev->host.ErrCnt[num]++; pdev->host.HC_Status[num] = HC_XACTERR; USB_OTG_HC_Halt(pdev, num); CLEAR_HC_INT(hcreg, xacterr); } else if (hcint.b.nak) { if (hcchar.b.eptype == EP_TYPE_CTRL) { CLEAR_HC_INT(hcreg, nak); hcchar.b.chen = 1; hcchar.b.chdis = 0; USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[num]->HCCHAR, hcchar.d32); } else { UNMASK_HOST_INT_CHH(num); USB_OTG_HC_Halt(pdev, num); CLEAR_HC_INT(hcreg, nak); } pdev->host.HC_Status[num] = HC_NAK; } else { p_err("unkown in isr:%08x\n", hcint.d32); } return ret; }
/** * @brief USB_OTG_USBH_handle_hc_n_Out_ISR * Handles interrupt for a specific Host Channel * @param pdev: Selected device * @param hc_num: Channel number * @retval status */ uint32_t USB_OTG_USBH_handle_hc_n_Out_ISR (USB_OTG_CORE_HANDLE *pdev , uint32_t num) { USB_OTG_HCINTn_TypeDef hcint; USB_OTG_HCINTMSK_TypeDef hcintmsk; USB_OTG_HC_REGS *hcreg; USB_OTG_HCCHAR_TypeDef hcchar; hcreg = pdev->regs.HC_REGS[num]; hcint.d32 = USB_OTG_READ_REG32(&hcreg->HCINT); hcintmsk.d32 = USB_OTG_READ_REG32(&hcreg->HCINTMSK); hcint.d32 = hcint.d32 & hcintmsk.d32; hcchar.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[num]->HCCHAR); #ifdef USE_HOST_MODE if (hcint.b.ahberr) { CLEAR_HC_INT(hcreg ,ahberr); UNMASK_HOST_INT_CHH (num); } else if (hcint.b.ack) { CLEAR_HC_INT(hcreg , ack); } else if (hcint.b.frmovrun) { UNMASK_HOST_INT_CHH (num); USB_OTG_HC_Halt(pdev, num); CLEAR_HC_INT(hcreg ,frmovrun); } else if (hcint.b.xfercompl) { pdev->host.ErrCnt[num] = 0; UNMASK_HOST_INT_CHH (num); USB_OTG_HC_Halt(pdev, num); CLEAR_HC_INT(hcreg , xfercompl); pdev->host.HC_Status[num] = HC_XFRC; } else if (hcint.b.stall) { CLEAR_HC_INT(hcreg , stall); UNMASK_HOST_INT_CHH (num); USB_OTG_HC_Halt(pdev, num); pdev->host.HC_Status[num] = HC_STALL; } else if (hcint.b.nak) { pdev->host.ErrCnt[num] = 0; UNMASK_HOST_INT_CHH (num); USB_OTG_HC_Halt(pdev, num); CLEAR_HC_INT(hcreg , nak); pdev->host.HC_Status[num] = HC_NAK; } else if (hcint.b.xacterr) { UNMASK_HOST_INT_CHH (num); USB_OTG_HC_Halt(pdev, num); pdev->host.ErrCnt[num] ++; pdev->host.HC_Status[num] = HC_XACTERR; CLEAR_HC_INT(hcreg , xacterr); } else if (hcint.b.nyet) { pdev->host.ErrCnt[num] = 0; UNMASK_HOST_INT_CHH (num); USB_OTG_HC_Halt(pdev, num); CLEAR_HC_INT(hcreg , nyet); pdev->host.HC_Status[num] = HC_NYET; } else if (hcint.b.datatglerr) { UNMASK_HOST_INT_CHH (num); USB_OTG_HC_Halt(pdev, num); CLEAR_HC_INT(hcreg , nak); pdev->host.HC_Status[num] = HC_DATATGLERR; CLEAR_HC_INT(hcreg , datatglerr); } else if (hcint.b.chhltd) { MASK_HOST_INT_CHH (num); if(pdev->host.HC_Status[num] == HC_XFRC) { pdev->host.URB_State[num] = URB_DONE; if (hcchar.b.eptype == EP_TYPE_BULK) { pdev->host.hc[num].toggle_out ^= 1; } } else if(pdev->host.HC_Status[num] == HC_NAK) { pdev->host.URB_State[num] = URB_NOTREADY; } else if(pdev->host.HC_Status[num] == HC_NYET) { if(pdev->host.hc[num].do_ping == 1) { USB_OTG_HC_DoPing(pdev, num); } pdev->host.URB_State[num] = URB_NOTREADY; } else if(pdev->host.HC_Status[num] == HC_STALL) { pdev->host.URB_State[num] = URB_STALL; } else if(pdev->host.HC_Status[num] == HC_XACTERR) { if (pdev->host.ErrCnt[num] == 3) { pdev->host.URB_State[num] = URB_ERROR; pdev->host.ErrCnt[num] = 0; } } CLEAR_HC_INT(hcreg , chhltd); } #endif return 1; }
uint32_t USB_OTG_USBH_handle_hc_n_Out_ISR(USB_OTG_CORE_HANDLE *pdev, uint32_t num) { USB_OTG_HCINTn_TypeDef hcint; USB_OTG_HCGINTMSK_TypeDef hcintmsk; USB_OTG_HC_REGS *hcreg; USB_OTG_HCCHAR_TypeDef hcchar; int ret = 0; hcreg = pdev->regs.HC_REGS[num]; hcint.d32 = USB_OTG_READ_REG32(&hcreg->HCINT); hcintmsk.d32 = USB_OTG_READ_REG32(&hcreg->HCGINTMSK); hcint.d32 = hcint.d32 &hcintmsk.d32; hcchar.d32 = USB_OTG_READ_REG32(&hcreg->HCCHAR); // USB_OTG_WRITE_REG32(&hcreg->HCINT, hcint.d32|0x7f); //clear 0-10bit if (hcint.b.ahberr) { CLEAR_HC_INT(hcreg, ahberr); UNMASK_HOST_INT_CHH(num); } else if (hcint.b.ack) { CLEAR_HC_INT(hcreg, ack); } else if (hcint.b.xfercompl) { pdev->host.ErrCnt[num] = 0; UNMASK_HOST_INT_CHH(num); USB_OTG_HC_Halt(pdev, num); CLEAR_HC_INT(hcreg, xfercompl); pdev->host.HC_Status[num] = HC_XFRC; } else if (hcint.b.stall) { CLEAR_HC_INT(hcreg, stall); UNMASK_HOST_INT_CHH(num); USB_OTG_HC_Halt(pdev, num); pdev->host.HC_Status[num] = HC_STALL; } else if (hcint.b.nak) { pdev->host.ErrCnt[num] = 0; UNMASK_HOST_INT_CHH(num); USB_OTG_HC_Halt(pdev, num); CLEAR_HC_INT(hcreg, nak); pdev->host.HC_Status[num] = HC_NAK; } else if (hcint.b.xacterr) { UNMASK_HOST_INT_CHH(num); USB_OTG_HC_Halt(pdev, num); pdev->host.ErrCnt[num]++; pdev->host.HC_Status[num] = HC_XACTERR; CLEAR_HC_INT(hcreg, xacterr); } else if (hcint.b.nyet) { pdev->host.ErrCnt[num] = 0; UNMASK_HOST_INT_CHH(num); USB_OTG_HC_Halt(pdev, num); CLEAR_HC_INT(hcreg, nyet); pdev->host.HC_Status[num] = HC_NYET; } else if (hcint.b.datatglerr) { UNMASK_HOST_INT_CHH(num); USB_OTG_HC_Halt(pdev, num); CLEAR_HC_INT(hcreg, nak); pdev->host.HC_Status[num] = HC_DATATGLERR; CLEAR_HC_INT(hcreg, datatglerr); } else if (hcint.b.chhltd) { MASK_HOST_INT_CHH(num); ret = 1; if (pdev->host.HC_Status[num] == HC_XFRC) { pdev->host.URB_State[num] = URB_DONE; if (hcchar.b.eptype == EP_TYPE_BULK) { if (pdev->host.hc[num].packet_count & 1) pdev->host.hc[num].toggle_out ^= 1; } } else if (pdev->host.HC_Status[num] == HC_NAK) { pdev->host.URB_State[num] = URB_NOTREADY; } else if (pdev->host.HC_Status[num] == HC_NYET) { if (pdev->host.hc[num].do_ping == 1) { USB_OTG_HC_DoPing(pdev, num); } pdev->host.URB_State[num] = URB_NOTREADY; } else if (pdev->host.HC_Status[num] == HC_STALL) { pdev->host.URB_State[num] = URB_STALL; } else if (pdev->host.HC_Status[num] == HC_XACTERR) { if (pdev->host.ErrCnt[num] == 3) { pdev->host.URB_State[num] = URB_ERROR; pdev->host.ErrCnt[num] = 0; } }else ret = 0; CLEAR_HC_INT(hcreg, chhltd); } else { p_err("unkown out isr:%08x\n", hcint.d32); } return ret; }
/** * @brief USB_OTG_USBH_handle_hc_n_In_ISR * Handles interrupt for a specific Host Channel * @param pdev: Selected device * @param hc_num: Channel number * @retval status */ uint32_t USB_OTG_USBH_handle_hc_n_In_ISR (USB_OTG_CORE_HANDLE *pdev , uint32_t num) { USB_OTG_HCINTn_TypeDef hcint; USB_OTG_HCINTMSK_TypeDef hcintmsk; USB_OTG_HCCHAR_TypeDef hcchar; USB_OTG_HCTSIZn_TypeDef hctsiz; USB_OTG_HC_REGS *hcreg; hcreg = pdev->regs.HC_REGS[num]; hcint.d32 = USB_OTG_READ_REG32(&hcreg->HCINT); hcintmsk.d32 = USB_OTG_READ_REG32(&hcreg->HCINTMSK); hcint.d32 = hcint.d32 & hcintmsk.d32; hcchar.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[num]->HCCHAR); hcintmsk.d32 = 0; if (hcint.b.ahberr) { CLEAR_HC_INT(hcreg ,ahberr); UNMASK_HOST_INT_CHH (num); } else if (hcint.b.ack) { CLEAR_HC_INT(hcreg ,ack); } else if (hcint.b.stall) { UNMASK_HOST_INT_CHH (num); pdev->host.HC_Status[num] = HC_STALL; CLEAR_HC_INT(hcreg , nak); /* Clear the NAK Condition */ CLEAR_HC_INT(hcreg , stall); /* Clear the STALL Condition */ hcint.b.nak = 0; /* NOTE: When there is a 'stall', reset also nak, else, the pdev->host.HC_Status = HC_STALL will be overwritten by 'nak' in code below */ USB::USB_OTG_HC_Halt(pdev, num); } else if (hcint.b.datatglerr) { UNMASK_HOST_INT_CHH (num); USB::USB_OTG_HC_Halt(pdev, num); CLEAR_HC_INT(hcreg , nak); pdev->host.HC_Status[num] = HC_DATATGLERR; CLEAR_HC_INT(hcreg , datatglerr); } if (hcint.b.frmovrun) { UNMASK_HOST_INT_CHH (num); USB::USB_OTG_HC_Halt(pdev, num); CLEAR_HC_INT(hcreg ,frmovrun); } else if (hcint.b.xfercompl) { if (pdev->cfg.dma_enable == 1) { hctsiz.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[num]->HCTSIZ); pdev->host.XferCnt[num] = pdev->host.hc[num].xfer_len - hctsiz.b.xfersize; } pdev->host.HC_Status[num] = HC_XFRC; pdev->host.ErrCnt [num]= 0; CLEAR_HC_INT(hcreg , xfercompl); if ((hcchar.b.eptype == EP_TYPE_CTRL)|| (hcchar.b.eptype == EP_TYPE_BULK)) { UNMASK_HOST_INT_CHH (num); USB::USB_OTG_HC_Halt(pdev, num); CLEAR_HC_INT(hcreg , nak); if(pdev->host.hc[num].isEvenTimesToggle) { // even times packets has been transfered. pdev->host.hc[num].isEvenTimesToggle = 0; } else { // todo: 1. need to check why xfercompl happened when the request packets // not received completely. (happened only in MSC Mode Sense(6) command. uint32_t num_packets = (pdev->host.hc[num].xfer_count + pdev->host.hc[num].max_packet - 1) / pdev->host.hc[num].max_packet; if(num_packets & 0x1) pdev->host.hc[num].toggle_in ^= 1; } } else if(hcchar.b.eptype == EP_TYPE_INTR) { hcchar.b.oddfrm = 1; USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[num]->HCCHAR, hcchar.d32); pdev->host.URB_State[num] = URB_DONE; pdev->host.hc[num].toggle_in ^= 1; } } else if (hcint.b.chhltd) { MASK_HOST_INT_CHH (num); if(pdev->host.HC_Status[num] == HC_XFRC) { pdev->host.URB_State[num] = URB_DONE; } else if (pdev->host.HC_Status[num] == HC_STALL) { pdev->host.URB_State[num] = URB_STALL; } else if((pdev->host.HC_Status[num] == HC_XACTERR) || (pdev->host.HC_Status[num] == HC_DATATGLERR)) { pdev->host.ErrCnt[num] = 0; pdev->host.URB_State[num] = URB_ERROR; } else if (pdev->host.HC_Status[num] == HC_NAK) { //if(hcchar.b.eptype == EP_TYPE_INTR) // pdev->host.hc[num].toggle_in ^= 1; pdev->host.URB_State[num] = URB_DONE; // for nak case } CLEAR_HC_INT(hcreg , chhltd); } else if (hcint.b.xacterr) { UNMASK_HOST_INT_CHH (num); pdev->host.ErrCnt[num] ++; pdev->host.HC_Status[num] = HC_XACTERR; USB::USB_OTG_HC_Halt(pdev, num); CLEAR_HC_INT(hcreg , xacterr); } else if (hcint.b.nak) { pdev->host.hc[num].nak_count++; if(pdev->host.hc[num].nak_count == pdev->host.hc[num].nak_limit) { UNMASK_HOST_INT_CHH (num); USB::USB_OTG_HC_Halt(pdev, num); } else { /* just judge nak to decide if halt the channel if(hcchar.b.eptype == EP_TYPE_INTR) { UNMASK_HOST_INT_CHH (num); USB::USB_OTG_HC_Halt(pdev, num); } else if ((hcchar.b.eptype == EP_TYPE_CTRL)|| (hcchar.b.eptype == EP_TYPE_BULK)) {*/ /* re-activate the channel */ hcchar.b.chen = 1; hcchar.b.chdis = 0; USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[num]->HCCHAR, hcchar.d32); } pdev->host.HC_Status[num] = HC_NAK; CLEAR_HC_INT(hcreg , nak); } return 1; }