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, ®_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, ®_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, ®_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, ®_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, ®_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, ®_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, ®_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, ®_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, ®_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 + -
显示快捷键?