cy7c67200_300_lcd.c

来自「linux嵌入式课程实践中的一个关于声卡驱动程序 。」· C语言 代码 · 共 2,069 行 · 第 1/5 页

C
2,069
字号
 *    opt_arg         - Optional argument to pass to the Callback Function *    cy_private_data - Private data structure pointer * *  DESCRIPTION: *    This function handles the requested command.  If the action will not *    be completed immediately, an optional "Callback" function can be utilized. * *    The valid commands are: *      LCD_OFFER_HNP *      LCD_INITIATE_SRP *      LCD_DISABLE_OTG_VBUS *      LCD_ENABLE_OTG_VBUS *      LCD_START_SOF *      LCD_STOP_SOF *      LCD_CHANGE_TO_PERIPHERAL_ROLE *      LCD_CHANGE_TO_HOST_ROLE *      LCD_REMOTE_WAKEUP *      LCD_DATALINE_RESISTOR_TERMINIATION * *  RETURNS: *    SUCCESS         - Success *    Error           - Failure */int lcd_command(int command,                int command_arg,                unsigned short port_number,                lcd_callback_t funcptr,                int opt_arg,                cy_priv_t * cy_private_data){    int response = ERROR;    unsigned short reg_addr;    unsigned short reg_value;    unsigned short tmp_reg_value;    lcd_lcp_entry_t * lcp;    switch(command) {        case LCD_OFFER_HNP:            /* Offer HNP only on Port 0 */            if (port_number == PORT0) {                if ((response = lcd_read_reg(USB1_CTL_REG, &reg_value,                                              cy_private_data)) == SUCCESS) {                    /* Make sure we are in host mode */                    if (reg_value & MODE_SEL) {                        /* Build Register Value */                        reg_value &= ~(A_SOF_EOP_EN | B_SOF_EOP_EN);                                                /* Stop SOFs on specified SIE */                        response = lcd_write_reg(USB1_CTL_REG, reg_value,                                                  cy_private_data);                    }                    else                        response = ERROR;                }            }            else                cy_err("lcd_command: LCD_OFFER_HNP invalid Port\n");            break;        case LCD_INITIATE_SRP:            /* Initiate SRP (Session Request Protocol) on specified SIE */            lcp = lcd_create_lcp_entry(COMM_EXEC_INT,                                       START_SRP_INT,0,0,0,0,                                       0,0,0,0,0,                                       0,0,0,0,0,                                       0,0,funcptr,                                       opt_arg,                                       cy_private_data);            /* Add lcp Entry */            if (lcp != NULL)                response = lcd_add_lcp_entry(lcp, cy_private_data);            break;        case LCD_DISABLE_OTG_VBUS:            /* Disable VBUS */            if (port_number == PORT0) {                if ((response = lcd_read_reg(OTG_CTL_REG, &reg_value,                                              cy_private_data)) == SUCCESS) {                    /* Build Register Value */                    reg_value &= ~(CHG_PUMP_EN);                     /* Turn OTG VBUS OFF */                    response = lcd_write_reg(OTG_CTL_REG, reg_value,                                              cy_private_data);                }            }            else                cy_err("lcd_command: LCD_DISABLE_OTG_VBUS invalid Port\n");            break;        case LCD_ENABLE_OTG_VBUS:            /* Enable VBUS */            if (port_number == PORT0) {                if ((response = lcd_read_reg(OTG_CTL_REG, &reg_value,                                              cy_private_data)) == SUCCESS) {                    /* Build Register Value */                    reg_value |= (CHG_PUMP_EN);                     /* Turn OTG VBUS ON */                    response = lcd_write_reg(OTG_CTL_REG, reg_value,                                              cy_private_data);                }            }            else                cy_err("lcd_command: LCD_ENABLE_OTG_VBUS invalid Port\n");            break;        case LCD_STOP_SOF:            /* Determine USB Control register address and value for              * specified SIE/port */            switch(port_number) {                case PORT0:                    reg_addr = USB1_CTL_REG;                    tmp_reg_value = ~(A_SOF_EOP_EN);                    break;                case PORT1:                                    reg_addr = USB1_CTL_REG;                    tmp_reg_value = ~(B_SOF_EOP_EN);                    break;                case PORT2:                                    reg_addr = USB2_CTL_REG;                    tmp_reg_value = ~(A_SOF_EOP_EN);                    break;                case PORT3:                    reg_addr = USB2_CTL_REG;                    tmp_reg_value = ~(B_SOF_EOP_EN);                    break;                default:                    /* Error */                    cy_err("lcd_command: LCD_STOP_SOF invalid Port 0x%X\n",                            port_number);                    return(response);            }                        /* Read previous register value */            if ((response = lcd_read_reg(reg_addr, &reg_value,                             cy_private_data)) == SUCCESS) {                /* Modify Register value */                reg_value &= tmp_reg_value;                /* Disable SOFs on specified SIE and Port */                response = lcd_write_reg(reg_addr, reg_value, cy_private_data);            }            else                cy_err("lcd_command: LCD_STOP_SOF error reading USB control"                       " register address 0x%X\n", reg_addr);            break;        case LCD_START_SOF:            /* Determine USB Control register address and value for              * specified SIE/port */            switch(port_number) {                case PORT0:                    reg_addr = USB1_CTL_REG;                    tmp_reg_value = (A_SOF_EOP_EN);                    break;                case PORT1:                                    reg_addr = USB1_CTL_REG;                    tmp_reg_value = (B_SOF_EOP_EN);                    break;                case PORT2:                                    reg_addr = USB2_CTL_REG;                    tmp_reg_value = (A_SOF_EOP_EN);                    break;                case PORT3:                    reg_addr = USB2_CTL_REG;                    tmp_reg_value = (B_SOF_EOP_EN);                    break;                default:                    /* Error */                    cy_err("lcd_command: LCD_START_SOF invalid Port 0x%X\n",                             port_number);                    return(response);            }                        /* Read previous register value */            if ((response = lcd_read_reg(reg_addr, &reg_value,                             cy_private_data)) == SUCCESS) {                /* Modify Register value */                reg_value |= tmp_reg_value;                /* Disable SOFs on specified SIE and Port */                response = lcd_write_reg(reg_addr, reg_value, cy_private_data);            }            else                cy_err("lcd_command: LCD_START_SOF error reading USB control"                       " register address 0x%X\n", reg_addr);            break;        case LCD_CHANGE_TO_PERIPHERAL_ROLE:            /* not used */            break;        case LCD_CHANGE_TO_HOST_ROLE:            /* Determine correct SIE interrupt */            if ((port_number == PORT0) || (port_number == PORT1))                reg_value = HUSB_SIE1_INIT_INT;            else                reg_value = HUSB_SIE2_INIT_INT;            lcp = lcd_create_lcp_entry(COMM_EXEC_INT,                                       reg_value,0,0,0,0,                                       0,0,0,0,0,                                       0,0,0,0,0,                                       0,0,funcptr,                                       opt_arg,                                       cy_private_data);            /* Add lcp Entry */            if (lcp != NULL)                response = lcd_add_lcp_entry(lcp, cy_private_data);            break;        case LCD_DATALINE_RESISTOR_TERMINATION:            /* Determine USB Control register address for specified SIE/port */            switch(port_number) {                case PORT0:                    // OTG SIE - Dataline pullups/pulldowns can be                     // controlled with the OTG control register                    if ((response = lcd_read_reg(OTG_CTL_REG, &reg_value,                                     cy_private_data)) == SUCCESS) {                        /* Mask */                        reg_value &= 0xFC00;                        if (command_arg & DPLUS_PULLUP)                            reg_value |= DPLUS_PULLUP_EN;                        if (command_arg & DMINUS_PULLUP)                            reg_value |= DMINUS_PULLUP_EN;                        if (command_arg & DPLUS_PULLDOWN)                            reg_value |= DPLUS_PULLDOWN_EN;                        if (command_arg & DMINUS_PULLDOWN)                            reg_value |= DMINUS_PULLDOWN_EN;                        /* Write OTG register */                        response = lcd_write_reg(OTG_CTL_REG, reg_value,                                                  cy_private_data);                    }                    break;                case PORT1:                                    if ((response = lcd_read_reg(USB1_CTL_REG, &reg_value,                                     cy_private_data)) == SUCCESS) {                        /* Mask */                        reg_value &= ~(B_RES_EN);                        /* If a host allow dataline pulldowns to be                          * enabled/disabled */                        if (reg_value & MODE_SEL) {                            /* The USB Control Reg only allows both                              * dataline pulldowns */                            if ((command_arg & DPLUS_PULLDOWN) ||                                 (command_arg & DMINUS_PULLDOWN))                                reg_value |= B_RES_EN;                            /* Make sure no pullups were asked for */                            if ((command_arg & DPLUS_PULLUP) ||                                 (command_arg & DMINUS_PULLUP))                                response = ERROR;                            else                                response = lcd_write_reg(USB1_CTL_REG,                                                          reg_value,                                                          cy_private_data);                        }                        else {                            /* Must be a peripheral - allow appropriate                              * dataline pullup */                                                        /* Check for correct Pullup */                            if ((!(reg_value & B_SPEED_SEL) &&                                  (command_arg & DPLUS_PULLUP)) ||                                ((reg_value & B_SPEED_SEL) &&                                  (command_arg & DMINUS_PULLUP)))                                reg_value |= B_RES_EN;                            if (((reg_value & B_SPEED_SEL) &&                                  (command_arg & DPLUS_PULLUP)) ||                                (!(reg_value & B_SPEED_SEL) &&                                  (command_arg & DMINUS_PULLUP)) ||                                (command_arg & DPLUS_PULLDOWN) ||                                 (command_arg & DMINUS_PULLDOWN))                                response = ERROR;                            else                                response = lcd_write_reg(USB1_CTL_REG,                                                          reg_value,                                                          cy_private_data);                        }                    }                    break;                case PORT2:                                    if ((response = lcd_read_reg(USB2_CTL_REG, &reg_value,                                     cy_private_data)) == SUCCESS) {                        /* Mask */                        reg_value &= ~(A_RES_EN);                        /* If a host allow dataline pulldowns to be                          * enabled/disabled */                        if (reg_value & MODE_SEL) {                            /* The USB Control Reg only allows both                              * dataline pulldowns */                            if ((command_arg & DPLUS_PULLDOWN) ||                                 (command_arg & DMINUS_PULLDOWN))                                reg_value |= A_RES_EN;                            /* Make sure no pullups were asked for */                            if ((command_arg & DPLUS_PULLUP) ||                                 (command_arg & DMINUS_PULLUP))                                response = ERROR;                            else                                response = lcd_write_reg(USB2_CTL_REG,                                                          reg_value,                                                          cy_private_data);                        }                        else {                            /* Must be a peripheral - allow appropriate                              * dataline pullup */                                                        /* Check for correct Pullup */                            if ((!(reg_value & A_SPEED_SEL) &&                                  (command_arg & DPLUS_PULLUP)) ||                                ((reg_value & A_SPEED_SEL) &&                                  (command_arg & DMINUS_PULLUP)))                                reg_value |= A_RES_EN;                            if (((reg_value & A_SPEED_SEL) &&                                  (command_arg & DPLUS_PULLUP)) ||                                (!(reg_value & A_SPEED_SEL) &&                                  (command_arg & DMINUS_PULLUP)) ||                                (command_arg & DPLUS_PULLDOWN) ||                                 (command_arg & DMINUS_PULLDOWN))                                response = ERROR;                            else                                response = lcd_write_reg(USB2_CTL_REG,                                                          reg_value,                                                          cy_private_data);                        }                    }                    break;                case PORT3:                    if ((response = lcd_read_reg(USB2_CTL_REG, &reg_value,                                     cy_private_data)) == SUCCESS) {                        /* Mask */                        reg_value &= ~(B_RES_EN);                        /* If a host allow dataline pulldowns to be                          * enabled/disabled */                        if (reg_value & MODE_SEL) {                            /* The USB Control Reg only allows both                              * dataline pulldowns */                            if ((command_arg & DPLUS_PULLDOWN) ||                                 (command_arg & DMINUS_PULLDOWN))                                reg_value |= B_RES_EN;                            /* Make sure no pullups were asked for */                            if ((command_arg & DPLUS_PULLUP) ||                                 (command_arg & DMINUS_PULLUP))                                response = ERROR;                            else                                response = lcd_write_reg(USB2_CTL_REG,                                                          reg_value,                                                          cy_private_data);                        }                        else {                            /* Must be a peripheral - allow appropriate                              * dataline pullup */                                                        /* Check for correct Pullup */                            if ((!(reg_value & B_SPEED_SEL) &&                                  (command_arg & DPLUS_PULLUP)) ||                                ((reg_value & B_SPEED_SEL) &&                                  (command_arg & DMINUS_PULLUP)))                                reg_value |= B_RES_EN;                            if (((reg_value & B_SPEED_SEL) &&                                  (command_arg & DPLUS_PULLUP)) ||                                (!(reg_value & B_SPEED_SEL) &&                                  (command_arg & DMINUS_PULLUP)) ||                                (command_arg & DPLUS_PULLDOWN) ||                                 (command_arg & DMINUS_PULLDOWN))                                response = ERROR;                            else                                response = lcd_write_reg(USB2_CTL_REG,                                                          reg_value,                                                          cy_private_data);                        }                    }                    break;                default:                    /* Unknown port */                              cy_err("lcd_command : LCD_DATALINE_TERMINATION"                           " invalid Port 0x%X\n", port_number);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?