void IOController_Output(uint16_t address, uint8_t data) { LsbA_Write(address & 0x00FF); MsbA_Write((address & 0xFF00) >> 8); CyPins_ClearPin(ExtBus_IoReq); CyPins_ClearPin(ExtBus_Wr); D_Write(data); SpinWaitIO(); CyPins_SetPin(ExtBus_Wr); CyPins_SetPin(ExtBus_IoReq); }
uint8_t IOController_Input(uint16_t address) { LsbA_Write(address & 0x00FF); MsbA_Write((address & 0xFF00) >> 8); CyPins_ClearPin(ExtBus_IoReq); CyPins_ClearPin(ExtBus_Rd); SpinWaitIO(); uint8_t data = D_Read(); CyPins_SetPin(ExtBus_Rd); CyPins_SetPin(ExtBus_IoReq); return data; }
void spi_setHighCS(spi_t *obj) { if (obj->port != NULL && !obj->port->hardwareCS) CyPins_SetPin(obj->cs); }
int main() { // This must be more dynamic in the future, but right now this IOREF is only used for the analog switches in the 10-pin connector // (UART pins are handled by SIORefGen, and that voltage has to be lower than this IORef voltage) //#define DYN_IOREF #ifdef DYN_IOREF // ~1.0V to 4.1V vref IOVoltGen_Start(); IOVoltGen_SetValue(0x80); IOVoltBuffer_Start(); #else // Results in 5V vref VDDIO2ref_SetDriveMode(VDDIO2ref_DM_STRONG); VDDIO2ref_Write(1); #endif NV_Init(); SIORefGen_Start(); SIORefGen_SetValue(62); // 1V GPIO_SetTXDrive(0); debuguart1_init(); CyGlobalIntEnable; /* Uncomment this line to enable global interrupts. */ CyPins_ClearPin(LED_Status_0); CyPins_SetPin(FanEna_0); if(NVREAD->USBserial[0] != 0 && NVREAD->USBserial[0] != 0xff) { for(uint8_t loopah=0; loopah<8; loopah++) { mySerial[2 + (loopah<<1)] = NVREAD->USBserial[loopah]; // Update USB descriptor Unicode values with our ASCII } USBFS_1_SerialNumString(mySerial); } USB_Init(); CyDelay(500); CyPins_ClearPin(FanEna_0); targetuart_init(); #ifdef SPECIAL_EDITION // Note that VtargetRef is in the 5V quadrant so that pin will always // output 5V when set high, no matter what the IOREF is set to! GPIO_SetPinState( TREF_PIN7, PIN_OUT_HIGH ); // Output on Vref GPIO_SetPinState( DFMS_PIN8, PIN_UART_TX ); // Send on DFMS pin, recv on DTMS! GPIO_SetPinState( DTMS_PIN9, PIN_UART_RX ); #else GPIO_SetPinState( DTMS_PIN9, PIN_UART_TX ); // Send on DTMS pin, recv on DFMS! GPIO_SetPinState( DFMS_PIN8, PIN_UART_RX ); #endif printf("\n\nWJ CDB Assist v3 controller init\n"); FB_init(); FB_clear(); disp_str("CDB ASSIST V3",13,(64-39),0,FONT6X6 | INVERT); disp_str("Sony Mobile",11,(64-33),64-12,FONT6X6); #ifdef SPECIAL_EDITION disp_str("Calibration Edition",19,(64-57),64-6,FONT6X6); #else disp_str("Open Devices",12,(64-36),64-6,FONT6X6); #endif FB_update(); GPIO_Init(); DummyLoad_Init(); USBMux_Init(); I2C_Init(); PWM_Init(); ADC_Init(); uint16_t ctr=0; for(;;) { char buffah[22]; uint8_t num; float vbatvolt,vbatcur,vbusvolt,vbuscur; I2C_Work(); vbatvolt=(float)I2C_Get_VBAT_VoltAvg() * 0.001f; vbatcur=I2C_Get_VBAT_CurAvg(); PWM_Work(I2C_Get_VBAT_Volt(),I2C_Get_VBAT_CurRaw()); DummyLoad_Work(I2C_Get_VBAT_Volt()); ADC_Work(); uint8_t vrefok = ADC_VtargetValid(); static uint8_t oldvrefok = 2; if( vrefok != oldvrefok ) { if( vrefok ) { CyPins_ClearPin(LED_Vref_0); GPIO_SetTXDrive( 1 ); } else { CyPins_SetPin(LED_Vref_0); GPIO_SetTXDrive( 0 ); SIORefGen_SetValue(62); // Default 1V ref } oldvrefok = vrefok; } if(ctr == 0) { vbusvolt=(float)I2C_Get_VBUS_Volt() * 0.001f; vbuscur=I2C_Get_VBUS_Cur(); USBMux_UpdateMeasurements(vbusvolt,vbuscur); num = snprintf(buffah, sizeof(buffah), "VBAT %5.2fV %6.1fmA", vbatvolt,vbatcur); disp_str(buffah, num, 0, 8, FONT6X6); num = snprintf(buffah, sizeof(buffah), "VBUS %5.2fV %6.1fmA", vbusvolt,vbuscur); disp_str(buffah, num, 0, 8+6, FONT6X6); DummyLoad_ADCWork(); float loadcur = DummyLoad_GetCur(); float loadtemp = DummyLoad_GetTemp(); num = snprintf(buffah, sizeof(buffah), "Load %5.1f` %6.1fmA", loadtemp,loadcur); disp_str(buffah, num, 0, 8+12, FONT6X6); float tmp = ADC_GetVoltage(VBATSENSE); num = snprintf(buffah, sizeof(buffah), "VBAT %5.2fV", tmp); disp_str(buffah, num, 0, 8+18, FONT6X6); tmp = ADC_GetVoltage(USB2SENSE); num = snprintf(buffah, sizeof(buffah), "USB2 %5.2fV", tmp); disp_str(buffah, num, 0, 8+24, FONT6X6); tmp = ADC_GetVoltage(USB3SENSE); num = snprintf(buffah, sizeof(buffah), "USB3 %5.2fV", tmp); disp_str(buffah, num, 0, 8+30, FONT6X6); tmp = ADC_GetVoltage(VTARGETSENSE); if( tmp > 4.5f ) { // Assume 5V, disable regulated output CY_SET_REG8(DTMS__SIO_CFG, (CY_GET_REG8(DTMS__SIO_CFG) & 0xcf) | 0x20); CY_SET_REG8(DTMS__SIO_DIFF, (CY_GET_REG8(DTMS__SIO_DIFF) & 0xcf) | 0x00); CY_SET_REG8(DTMS__SIO_HYST_EN, (CY_GET_REG8(DTMS__SIO_HYST_EN) & 0xcf) | 0x00); } else if( tmp > 0.89f ) { float val = tmp * 255.0f / 4.096f; if(val > 255.0f) val = 255.0f; SIORefGen_SetValue((uint8_t)val); CY_SET_REG8(DTMS__SIO_CFG, (CY_GET_REG8(DTMS__SIO_CFG) & 0xcf) | 0x30); // Regulated output buffer CY_SET_REG8(DTMS__SIO_DIFF, (CY_GET_REG8(DTMS__SIO_DIFF) & 0xcf) | 0x20); CY_SET_REG8(DTMS__SIO_HYST_EN, (CY_GET_REG8(DTMS__SIO_HYST_EN) & 0xcf) | 0x20); } num = snprintf(buffah, sizeof(buffah), "VTGT %5.2fV", tmp); disp_str(buffah, num, 0, 8+36, FONT6X6); FB_update(); UpdateCtrl(); ctr=256; } else { ctr--; } USB_Work(); } }
// uint8 cStatus,cIndex,cPosn; int main() { /* Initializations */ uint8 m_u8Data=0,m_u8DataPrev=0xf; // enable global interrupts CYGlobalIntEnable; // enable I2C interrupts // I2C_1_EnableInt(); //Start I2C // I2C_1_Start(); /* Clear All Relays */ CyPins_ClearPin(RL1_CTR_P0_2); CyPins_ClearPin(RL2_CTR_P0_1); CyPins_ClearPin(RL3_CTR_P0_0); CyPins_ClearPin(RL4_CTR_P4_1); CyPins_ClearPin(RL5_CTR_P4_0); CyPins_ClearPin(RL6_CTR_P12_3); CyPins_ClearPin(RL7_CTR_P12_2); /* Set AC & DC Voltage as Default */ CyPins_SetPin(RL2_CTR_P0_1); CyDelay(10);// 10 milli seconds delay for(;;) { m_u8Data=0; if(CyPins_ReadPin(ISO_DI0_P15_3)!=0) m_u8Data |= 1; else m_u8Data |= 0; if(CyPins_ReadPin(ISO_DI1_P15_2)!=0) m_u8Data |= 1<<1; else m_u8Data |= 0<<1; if(CyPins_ReadPin(ISO_DI2_P3_7)!=0) m_u8Data |= 1<<2; else m_u8Data |= 0<<2; if((m_u8Data != m_u8DataPrev) && (m_u8Data != 0x07) ){ m_u8DataPrev = m_u8Data; switch(m_u8Data) { case 0x00: //ACV & DCV Mode CyPins_ClearPin(RL1_CTR_P0_2); CyPins_ClearPin(RL3_CTR_P0_0); CyPins_ClearPin(RL4_CTR_P4_1); CyPins_ClearPin(RL5_CTR_P4_0); CyPins_ClearPin(RL6_CTR_P12_3); CyPins_ClearPin(RL7_CTR_P12_2); CyDelay(10);// 10 milli seconds delay CyPins_SetPin(RL2_CTR_P0_1); CyDelay(10);// 10 milli seconds delay break; case 0x01: //ACmV & DCmV Mode CyPins_ClearPin(RL2_CTR_P0_1); CyPins_ClearPin(RL3_CTR_P0_0); CyPins_ClearPin(RL4_CTR_P4_1); CyPins_ClearPin(RL5_CTR_P4_0); CyPins_ClearPin(RL6_CTR_P12_3); CyPins_ClearPin(RL7_CTR_P12_2); CyDelay(10);// 10 milli seconds delay CyPins_SetPin(RL1_CTR_P0_2); CyDelay(10);// 10 milli seconds delay break; case 0x02: //ACI & DCI Mode - Amps CyPins_ClearPin(RL1_CTR_P0_2); CyPins_ClearPin(RL2_CTR_P0_1); CyPins_ClearPin(RL3_CTR_P0_0); CyPins_ClearPin(RL4_CTR_P4_1); CyPins_ClearPin(RL5_CTR_P4_0); CyPins_ClearPin(RL7_CTR_P12_2); CyDelay(10);// 10 milli seconds delay CyPins_ClearPin(RL6_CTR_P12_3);//changed for direct 10A on 22/11/2014 CyDelay(10);// 10 milli seconds delay break; case 0x03: //ACI & DCI Mode - mA CyPins_ClearPin(RL1_CTR_P0_2); CyPins_ClearPin(RL2_CTR_P0_1); CyPins_ClearPin(RL3_CTR_P0_0); CyPins_ClearPin(RL4_CTR_P4_1); CyPins_ClearPin(RL6_CTR_P12_3); CyPins_ClearPin(RL7_CTR_P12_2); CyDelay(10);// 10 milli seconds delay CyPins_SetPin(RL5_CTR_P4_0); CyDelay(10);// 10 milli seconds delay break; case 0x04: //ACI & DCI Mode - uA CyPins_ClearPin(RL1_CTR_P0_2); CyPins_ClearPin(RL2_CTR_P0_1); CyPins_ClearPin(RL3_CTR_P0_0); CyPins_ClearPin(RL5_CTR_P4_0); CyPins_ClearPin(RL6_CTR_P12_3); CyPins_ClearPin(RL7_CTR_P12_2); CyDelay(10);// 10 milli seconds delay CyPins_SetPin(RL4_CTR_P4_1); CyDelay(10);// 10 milli seconds delay break; case 0x05: //Resistor,Continuity,Diode&Capacitor CyPins_ClearPin(RL2_CTR_P0_1); CyPins_ClearPin(RL3_CTR_P0_0); CyPins_ClearPin(RL4_CTR_P4_1); CyPins_ClearPin(RL5_CTR_P4_0); CyPins_ClearPin(RL6_CTR_P12_3); CyPins_ClearPin(RL7_CTR_P12_2); CyDelay(10);// 10 milli seconds delay CyPins_SetPin(RL1_CTR_P0_2); CyPins_SetPin(RL6_CTR_P12_3);//changed on 22/11/2014 CyDelay(10);// 10 milli seconds delay break; case 0x06: //Frequency CyPins_ClearPin(RL2_CTR_P0_1); CyPins_ClearPin(RL4_CTR_P4_1); CyPins_ClearPin(RL5_CTR_P4_0); CyPins_ClearPin(RL6_CTR_P12_3); CyPins_ClearPin(RL7_CTR_P12_2); CyDelay(10);// 10 milli seconds delay CyPins_SetPin(RL3_CTR_P0_0); CyDelay(10);// 10 milli seconds delay CyPins_SetPin(RL1_CTR_P0_2); CyDelay(10);// 10 milli seconds delay break; case 0x07: CyPins_ClearPin(RL1_CTR_P0_2); CyPins_ClearPin(RL2_CTR_P0_1); CyPins_SetPin(RL3_CTR_P0_0); CyPins_ClearPin(RL4_CTR_P4_1); CyPins_ClearPin(RL5_CTR_P4_0); CyPins_ClearPin(RL6_CTR_P12_3); CyDelay(10);// 10 milli seconds delay CyPins_SetPin(RL7_CTR_P12_2); CyDelay(10);// 10 milli seconds delay break; } } else if(m_u8Data == 0x07 && m_u8DataPrev==0x05){ m_u8DataPrev = m_u8Data; CyPins_ClearPin(RL2_CTR_P0_1); CyPins_ClearPin(RL3_CTR_P0_0); CyPins_ClearPin(RL4_CTR_P4_1); CyPins_ClearPin(RL5_CTR_P4_0); CyPins_ClearPin(RL6_CTR_P12_3); CyPins_SetPin(RL7_CTR_P12_2); CyDelay(10);// 10 milli seconds delay } } //~~~~~~~~~~~~~~~~~~~~~I2C MEMORY~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // I2C_1_MasterClearStatus(); /* Clear any previous status */ //Following API writes the data from PSoC3 RAM buffer to EEPROM //SLAVE_ADDR is the slave address in this API //cMessage is the pointer to array which contains the data to be written to EEPROM. //cLength is the number of bytes which have to be written to EEPROM //I2C_MODE_COMPLETE_XFER, is to send data completly before sending stop command. //The macro definition for 1) I2C_MODE_REPEAT_START = 0x01 // 2) I2C_MODE_COMPLETE_XFER = 0x00 // 3) I2C_MODE_NO_STOP = 0x02. //I2C_1_MasterWriteBuf(SLAVE_ADDR, cMessage, 3, I2C_1_MODE_COMPLETE_XFER); //wait until Transfer is complete //while((I2C_1_MasterStatus() & I2C_1_MSTAT_WR_CMPLT )==0); // delay to complete the write operation(twr) //CyDelay(10); //write a dummy byte to initialize the address word counter of //eeprom to start address for read back operation. First location //of cMessage array has word address. // I2C_1_MasterWriteBuf(SLAVE_ADDR, dummy, 2, I2C_1_MODE_COMPLETE_XFER); //wait until Transfer is complete // while((I2C_1_MasterStatus() & I2C_1_MSTAT_WR_CMPLT )==0); //Delay for setting address in EEPROM // CyDelayUs(1); //Read the 16 bytes from slave, staring from word address specified by iMessage //SLAVE_ADDR is the slave address in this API //cRx_Buffer is the pointer to array where data has to be stored after reading from EEPROM. //cLength-1 is the number of bytes which have to be read from EEPROM //I2C_MODE_COMPLETE_XFER, is to read data completly before sending stop command. // I2C_1_MasterReadBuf(SLAVE_ADDR, cRx_Buffer,1, I2C_1_MODE_COMPLETE_XFER ); //wait until Transfer is complete // while((I2C_1_MasterStatus() & I2C_1_MSTAT_RD_CMPLT )==0); */ }
/******************************************************************************* * Function Name: ServiceUSB ******************************************************************************** * Summary: This routine performs tasks that should be done soon after USB * enumeration is completed (configure DMA, initialize state machine etc). * When the USB configuration is changed, this routine reinitializes all * the USB endpoints as required by the application. * * Parameters: * void * * Return: * void * *******************************************************************************/ void ServiceUSB(void) { CYBIT macPC_flag=FALSE; if(USB_INTERFACE_INACTIVE == USBDeviceState) { USBDeviceState = USB_INIT_AFTER_ENUMERATION_REQUIRED; } /* Initialization sequence for every USB host enumeration event */ if(USBDeviceState == USB_INIT_AFTER_ENUMERATION_REQUIRED) { uint16 index = 0; USBDeviceState = USB_INIT_AFTER_ENUMERATION_COMPLETED; SetAppleDeviceAudioSource(AUDIO_SOURCE_DIGITAL); macPC_flag = IsMacPCConnected(); #if(USBFS_EP_MM == USBFS__EP_DMAAUTO) /* USER_CODE: [Audio Buffers] Add a separate for loop if the playback and recording audio buffer size are * not equal */ for(index=0; index< OUT_AUDIOMAXPKT; index++) { #ifndef ENABLE_DIGITAL_AUDIO_OUT_ONLY inRam[index] = 0; #endif #ifndef ENABLE_DIGITAL_AUDIO_IN_ONLY outRam[index] = 0; #endif } #ifndef ENABLE_DIGITAL_AUDIO_OUT_ONLY inCnt = IN_AUDIOMAXPKT; #endif #endif #ifdef CDC_ENABLED USBUARTStart(); /* Initializes the USB UART interface */ #endif /* Configure the HID input endpoint buffer for Mac/PC playlist control */ if(macPC_flag) { USBFS_LoadInEP(MAC_PC_HID_CONTROL_ENDPOINT, (uint8 *)&playlistControlReport, sizeof(playlistControlReport)); #ifdef PHONE_CONTROL_ENABLED USBFS_ReadOutEP(MAC_PC_HID_OUT_ENDPOINT, &hidOutReport, sizeof(hidOutReport)); USBFS_EnableOutEP(MAC_PC_HID_OUT_ENDPOINT); #endif } /* If Aux is not currently configured, then switch to digital audio mode */ if(IS_AUX_NOT_SELECTED()) { ConfigureDigitalAudioDMA(); } else { #ifdef LCD_MODULE_ENABLED /* Else Display Aux Configured message on the LCD */ LCD2LineDisplay("Analog Loopback ", " "); #endif } /* USER_CODE: [USB enumeration] placeholder for initializing custom user code after the USB host enumerates the * accessory. This routine will be called once per accessory connection after the host issues SET_CONFIGURATION * request */ } #ifdef MIDI_ENABLED if (midiEPInitialized == FALSE || usbReset) { /* Initialize MIDI only when a valid USB host is connected */ if ((IsUSBConfigured() && IsMacPCConnected())) { USBFS_MIDI_EP_Init(); /* USB Component internally sets the priority of the UART TX and RX ISRs to 4 and 2 respectively, change the * interrupt priority in the application code to match the system interrupt setup */ CyIntSetPriority(MIDI1_UART_TX_VECT_NUM, MIDI_UART_INTERRUPT_PRIORITY_SIX); CyIntSetPriority(MIDI1_UART_RX_VECT_NUM, MIDI_UART_INTERRUPT_PRIORITY_FIVE); #if (USBFS_MIDI_EXT_MODE >= USBFS_TWO_EXT_INTRF) CyIntSetPriority(MIDI2_UART_TX_VECT_NUM, MIDI_UART_INTERRUPT_PRIORITY_SIX); CyIntSetPriority(MIDI2_UART_RX_VECT_NUM, MIDI_UART_INTERRUPT_PRIORITY_FIVE); #endif midiEPInitialized = TRUE; usbReset = 0; } } if(USBFS_midiInPointer%USBFS_EVENT_LENGTH == 0 && USBFS_midiInPointer!=0) { if(midiInWaitTimer == 0) { midiInWaitTimer = MIDI_IN_EP_WAIT_TIME; USBFS_MIDI_IN_EP_Service(); } } else { midiInWaitTimer = MIDI_IN_EP_WAIT_TIME; } #endif /* USBFS_IsConfigurationChanged() is a clear on read status update therefore, only one read of * USBFS_IsConfigurationChanged() should ever exist in user code */ if(USBFS_IsConfigurationChanged()) { macPC_flag = IsMacPCConnected(); #ifndef ENABLE_DIGITAL_AUDIO_IN_ONLY /* Get Alternate setting */ altSetting[AUDIO_OUT_INTERFACE_INDEX] = (macPC_flag? USBFS_GetInterfaceSetting(1):USBFS_GetInterfaceSetting(2)); /* ByteSwap control register bit is set to 1 if alt setting 2 is selected so that * Byte swap digital logic processes data as 16 bits. ByteSwap control register is set to 0 * if alt setting 1 is selected and byte swap processes data as 24 bits */ if (altSetting[AUDIO_OUT_INTERFACE_INDEX]==ALT_SETTING_ACTIVE_24_BIT) { ByteSwap_Tx_CONTROL_REG = ByteSwap_Tx_CONTROL_REG & (~ByteSwap_Tx_RES_CTRL_16); } else if (altSetting[AUDIO_OUT_INTERFACE_INDEX]==ALT_SETTING_ACTIVE_16_BIT) { ByteSwap_Tx_CONTROL_REG = ByteSwap_Tx_CONTROL_REG | ByteSwap_Tx_RES_CTRL_16; } /* Arming the audio out EP if it is not zero bandwidth alt setting */ if (altSetting[AUDIO_OUT_INTERFACE_INDEX]!= ALT_SETTING_ZERO_BANDWIDTH && (CY_GET_REG8(USBFS_SIE_EP1_CR0_PTR + ((AUDIO_OUT_ENDPOINT - USBFS_EP1) << USBFS_EPX_CNTX_ADDR_SHIFT)) & USBFS_MODE_MASK) == USBFS_MODE_NAK_IN_OUT) { /* Init DMA configurations for audio OUT EP */ USBFS_ReadOutEP(AUDIO_OUT_ENDPOINT, &outRam[0], OUT_AUDIOMAXPKT); USBFS_EnableOutEP(AUDIO_OUT_ENDPOINT); } #endif #ifndef ENABLE_DIGITAL_AUDIO_OUT_ONLY #ifndef ENABLE_DIGITAL_AUDIO_IN_ONLY if(altSetting[AUDIO_IN_INTERFACE_INDEX] != (macPC_flag? USBFS_GetInterfaceSetting(2):USBFS_GetInterfaceSetting(3))) { altSetting[AUDIO_IN_INTERFACE_INDEX] = (macPC_flag? USBFS_GetInterfaceSetting(2):USBFS_GetInterfaceSetting(3)); #else if(altSetting[AUDIO_IN_INTERFACE_INDEX] != (macPC_flag? USBFS_GetInterfaceSetting(1):USBFS_GetInterfaceSetting(2))) { altSetting[AUDIO_IN_INTERFACE_INDEX] = (macPC_flag? USBFS_GetInterfaceSetting(1):USBFS_GetInterfaceSetting(2)); #endif /* Setting the ByteSwap control register bit to 0 regardless of alt setting is selected. Because audio in * interface both the alternate settings alt setting1 and alt setting 2 both use 3 byte subframe size. */ ByteSwap_Rx_CONTROL_REG = ByteSwap_Rx_CONTROL_REG & (~ByteSwap_Rx_RES_CTRL_16); /* Arming the audio in EP if it is not zero bandwidth alt setting */ if (altSetting[AUDIO_IN_INTERFACE_INDEX]!= ALT_SETTING_ZERO_BANDWIDTH && (CY_GET_REG8(USBFS_SIE_EP1_CR0_PTR + ((AUDIO_IN_ENDPOINT - USBFS_EP1) << USBFS_EPX_CNTX_ADDR_SHIFT)) & USBFS_MODE_MASK) == USBFS_MODE_NAK_IN_OUT) { /* Init DMA configurations for audio IN EP */ inCnt = IN_AUDIOMAXPKT; USBFS_LoadInEP(AUDIO_IN_ENDPOINT, &inRam[0], inCnt); /* Pre-arm first audio IN request */ USBFS_LoadInEP(AUDIO_IN_ENDPOINT, USBFS_NULL, inCnt); } } #endif /* USER_CODE: [USB configuration changed] Placeholder for adding additional USB endpoint initialization code * when the host issues either a SET_INTERFACE or SET_CONFIGURATION request to the accessory. After receiving * a SET_INTERFACE request from the host, the endpoint belonging to the alternate setting being configured * by the USB host is reset and must be reinitialized here for proper operation of the USB block */ } } /******************************************************************************* * Function Name: ServiceUSBSuspend ******************************************************************************** * Summary: * This function handles USB suspend event from USB host and forces PSoC 3 * to enter low power mode. Once the USB resume event is detected, PSoC3 * wakes up and starts operating in normal mode. * * Parameters: * void * * Return: * void * *******************************************************************************/ #ifdef HANDLE_USB_SUSPEND void ServiceUSBSuspend(void) { if(!IsMacPCConnected() || ! USBFS_initVar) { return; } /* Check if the host is active */ if(USBFS_bCheckActivity() != 0 ) { usbActivityCounter = 0; } else { usbActivityCounter++; } /* USB Suspend event is lack of greater than 3 consecutive SOF's */ if(usbActivityCounter > USB_SUSPEND_TIME_TICKS ) { /* The debounce delay is taken care by increasing the suspend time to 40ms (5 * 8ms) */ if(IsMacPCConnected() && IsUSBConfigured()) { /* USER_CODE: [USB suspend] Placeholder for configuring ALL the additional components added by the user in * sleep mode before calling USB suspend/PSoC 3 sleep API */ #ifdef LCD_MODULE_ENABLED LCD_Position(0,0); LCD_PrintString(" USB Suspend "); #endif /* If the accessory is not in low power mode, enter low power mode on seeing a USB suspend */ if(!lowPowerIdle) { lowPowerIdle = TRUE; StopAudioComponents(); /* Changes to 24 MHz IMO for USB */ StopAnalogAudioComponents(); /* Turn OFF Analog path for Audio-In/iPod Analog */ } if(!midiPowerIdle) { if(!lowPowerIdle) { StopAudioComponents(); /* Changes to 24 MHz IMO for USB */ } CyPins_SetPin(PSOC_MIDI_PWR_0); /* Turn off the MIDI I/O hardware */ midiPowerIdle = TRUE; /* MIDI low power mode enabled */ } CyPins_ClearPin(PSOC_CODEC_PWR_0); /* Turn off the regulator to reduce suspend mode current */ USBFS_Suspend(); I2C_Master_Sleep(); /* Configure I2C master block in sleep mode */ #ifdef CAPSENSE_ENABLED while(CapSense_IsBusy()); /* Wait for current scan to complete */ CapSense_Sleep(); #endif #ifdef MIDI_ENABLED MIDI1_UART_Sleep(); #if (USBFS_MIDI_EXT_MODE >= USBFS_TWO_EXT_INTRF) MIDI2_UART_Sleep(); #endif #endif CyPmSaveClocks(); CyPmSleep(PM_SLEEP_TIME_NONE, PM_SLEEP_SRC_PICU); /* PSoC 3 is in sleep mode */ CyPmRestoreClocks(); USBFS_Resume(); I2C_Master_Wakeup(); #ifdef CAPSENSE_ENABLED CapSense_Wakeup(); CapSense_IntClock_SetSource(CYCLK_SRC_SEL_IMO); #endif #ifdef MIDI_ENABLED MIDI1_UART_Wakeup(); #if (USBFS_MIDI_EXT_MODE >= USBFS_TWO_EXT_INTRF) MIDI2_UART_Wakeup(); #endif #endif CyPins_SetPin(PSOC_CODEC_PWR_0); /* Turn ON the CODEC regulator after wake up */ #ifdef WINDOWS7_WORKAROUND if(USBFS_GetConfiguration() != 0) { USBFS_configurationChanged = USBFS_TRUE; USBFS_Config(USBFS_FALSE); } #endif #ifdef LCD_MODULE_ENABLED LCD_Position(0,0); LCD_PrintString("Mac/PC Interface"); #endif /* USER_CODE: [USB wakeup] Placeholder for re-configuring ALL the additional components added by the user in * wakeup mode after calling USB wakeup */ } usbActivityCounter = 0; /* After coming out of USB suspend, MIDI end point should be re-initialized */ midiEPInitialized = 0; } } #endif /******************************************************************************* * Function Name: HandlePCMacUSBInterface ******************************************************************************** * Summary: Checks if PC/Mac is connected/disconnected and start the USB component * * Parameters: * void * * Return: * void * *******************************************************************************/ void HandlePCMacUSBInterface(void) { /* If Aux mode is enabled, then Mac/PC connection disconnection is handled only when the system is not in * aux In mode. For self powered case, Apple device connection is also checked before starting the Mac/PC * interface */ if(IS_AUX_NOT_SELECTED() && !USBFS_initVar && IsMacPCConnected()) { /* Switch the PSoC USB D+ and D- lines to USB Mini B */ CyPins_ClearPin(PSOC_USB_SEL_0); /* Start the USB component when PC/Mac is connected */ USBFS_Start(PC_MAC_AUDIO_WITH_VOLUME_DEVICE, USBFS_DWR_VDDD_OPERATION); USBDeviceState = USB_INIT_AFTER_ENUMERATION_REQUIRED; #ifdef LCD_MODULE_ENABLED if(IS_AUX_NOT_SELECTED()) { LCD2LineDisplay("Mac/PC Interface", " "); } #endif #ifdef ENABLE_VOLUME_CONTROL currentLCDVolume--; /* dirty the LCD volume and mute update flag to update volume and mute info on the LCD */ currentLCDMute--; #endif usbMiniBActive = TRUE; /* USER_CODE: [Mac/PC connection] Placeholder for initializing components or external peripherals when the * accessory is plugged into Mac/PC (USB VBus = High) */ } /* Check for PC/Mac USB Audio device disconnection in self powered mode. * In device powered mode project, no need of checking disconnection event as power is shut off * as soon as USB cable is disconnected from USB mini connector. */ else if(usbMiniBActive && (USBFS_bGetConfiguration() || USBDeviceState == USB_INIT_AFTER_ENUMERATION_REQUIRED)) { /* If VBUS voltage from mini B is now gone and was previous present then stop USB interface */ if(!IsMacPCConnected()) { if(USBFS_initVar) { USBFS_Stop(); } CyPins_SetPin(PSOC_USB_SEL_0); /* Switch the PSoC USB D+ and D- lines back to Apple device */ /* If Aux was not configured when PC is unplugged, then switch off CODEC */ if(!auxConfigured) { CyPins_ClearPin(PSOC_CODEC_RST_0); /* Hold CODEC in reset */ codecInit = FALSE; } usbMiniBActive = FALSE; /* USER_CODE: [Mac/PC disconnection] Placeholder for shutting down components or external peripherals when * the accessory is disconnected from Mac/PC (USB VBus transitioned from High to Low) */ } } } /******************************************************************************* * Function Name: EnableNAKBulkIN ******************************************************************************** * Summary: Enables the NAK interrupt on a USB endpoint * * Parameters: * Endpoint number for which NAK interrupt is to be enabled * * Return: * void * *******************************************************************************/ void EnableNAKBulkIN(uint8 bEPNumber) { uint8 index = (bEPNumber - USBFS_EP1) << USBFS_EPX_CNTX_ADDR_SHIFT; if((CY_GET_REG8(&USBFS_SIE_EP1_CR0_PTR[index]) & USBFS_MODE_MASK) != USBFS_MODE_ACK_IN) { CY_SET_REG8(&USBFS_SIE_EP1_CR0_PTR[index], CY_GET_REG8(&USBFS_SIE_EP1_CR0_PTR[index]) | NAK_IN_INTERRUPT_ENABLE_MASK); } }