void I2C_SetMode(I2C_CHANNEL eCh, I2C_MODE eMode) { HW_REG32(g_aI2c[eCh].uBase, I2C_STAT) &= ~(0x1 << 4); // Disable I2C HW_REG32(g_aI2c[eCh].uBase, I2C_STAT) &= ~(0x3 << 6); // Clear Mode I2C_ClearIntStatus(eCh); I2C_DisableInt(eCh); // Disable Interrupt switch (eMode) { case MASTER_TX_MODE: HW_REG32(g_aI2c[eCh].uBase, I2C_STAT) |= (0x3 << 6); // Set Mode break; case MASTER_RX_MODE: HW_REG32(g_aI2c[eCh].uBase, I2C_STAT) |= (0x2 << 6); // Set Mode break; case SLAVE_TX_MODE: HW_REG32(g_aI2c[eCh].uBase, I2C_STAT) |= (0x1 << 6); // Set Mode break; case SLAVE_RX_MODE: HW_REG32(g_aI2c[eCh].uBase, I2C_STAT) |= (0x0 << 6); // Set Mode break; default: return; } I2C_EnableInt(eCh); HW_REG32(g_aI2c[eCh].uBase, I2C_STAT) |= (0x1 << 4); // Enable I2C }
/******************************************************************************* * Function Name: I2C_I2CMasterClearWriteBuf ******************************************************************************** * * Summary: * Resets the write buffer pointer back to the first byte in the buffer. * * Parameters: * None * * Return: * None * * Global variables: * I2C_mstrRdBufIndex - used to current index within master read * buffer. * I2C_mstrStatus - used to store current status of I2C Master. * *******************************************************************************/ void I2C_I2CMasterClearWriteBuf(void) { I2C_DisableInt(); /* Lock from interruption */ I2C_mstrWrBufIndex = 0u; I2C_mstrStatus &= (uint16) ~I2C_I2C_MSTAT_WR_CMPLT; I2C_EnableInt(); /* Release lock */ }
void I2C0_Init(void) { /* Open I2C0 and set clock to 100k */ I2C_Open(I2C0, 100000); /* Get I2C0 Bus Clock */ printf("I2C0 clock %d Hz\n", I2C_GetBusClockFreq(I2C0)); I2C_EnableInt(I2C0); NVIC_EnableIRQ(I2C0_IRQn); }
/******************************************************************************* * Function Name: I2C_Start ******************************************************************************** * * Summary: * Starts the I2C hardware. Enables Active mode power template bits or clock * gating as appropriate. It is required to be executed before I2C bus * operation. * * Parameters: * None. * * Return: * None. * * Side Effects: * This component automatically enables its interrupt. If I2C is enabled ! * without the interrupt enabled, it can lock up the I2C bus. * * Global variables: * I2C_initVar - This variable is used to check the initial * configuration, modified on the first * function call. * * Reentrant: * No. * *******************************************************************************/ void I2C_Start(void) { if (0u == I2C_initVar) { I2C_Init(); I2C_initVar = 1u; /* Component initialized */ } I2C_Enable(); I2C_EnableInt(); }
/******************************************************************************* * Function Name: I2C_Start ******************************************************************************** * * Summary: * Starts the I2C hardware. Enables Active mode power template bits or clock * gating as appropriate. It is required to be executed before I2C bus * operation. * The I2C interrupt remains disabled after this function call. * * Parameters: * None * * Return: * None * * Side Effects: * This component automatically enables it's interrupt. If I2C is enabled * without the interrupt enabled, it could lock up the I2C bus. * * Global variables: * I2C_initVar - used to check initial configuration, modified * on first function call. * * Reentrant: * No * *******************************************************************************/ void I2C_Start(void) { /* Initialize I2C registers, reset I2C buffer index and clears status */ if(0u == I2C_initVar) { I2C_Init(); I2C_initVar = 1u; /* Component initialized */ } I2C_Enable(); I2C_EnableInt(); }
void TwoWire::begin(uint8_t address) { IRQn_Type irq=I2C0_IRQn; NVIC_DisableIRQ(irq); NVIC_ClearPendingIRQ(irq); NVIC_SetPriority(irq, 3); NVIC_EnableIRQ(irq); I2C_Open(i2c,I2C_CLOCK); status = SLAVE_IDLE; I2C_SetSlaveAddr(i2c, 0, address, 0); /* Slave Address */ I2C_EnableInt(i2c); I2C_SET_CONTROL_REG(i2c, I2C_SI_AA); /* I2C enter no address SLV mode */ }
// ********************************************************************** // I2C Master Restart // ********************************************************************** void I2C_MS_Master_Restart() { /* Open I2C module and set bus clock */ I2C_Open(I2C_MS_PORT, 100000); /* Enable I2C interrupt */ I2C_EnableInt(I2C_MS_PORT); #ifdef I2C_MS_PORT0 NVIC_EnableIRQ(I2C0_IRQn); #else NVIC_EnableIRQ(I2C1_IRQn); #endif }
/******************************************************************************* * Function Name: I2C_I2CMasterClearStatus ******************************************************************************** * * Summary: * Clears all status flags and returns the master status. * * Parameters: * None * * Return: * Current status of I2C master. * * Global variables: * I2C_mstrStatus - used to store current status of I2C Master. * *******************************************************************************/ uint32 I2C_I2CMasterClearStatus(void) { uint32 status; I2C_DisableInt(); /* Lock from interruption */ /* Read and clear master status */ status = (uint32) I2C_mstrStatus; I2C_mstrStatus = I2C_I2C_MSTAT_CLEAR; I2C_EnableInt(); /* Release lock */ return(status); }
void I2C0_Init(void) { /* Open I2C0 and set clock to 100k */ I2C_Open(I2C0, 100000); /* Get I2C0 Bus Clock */ printf("I2C clock %d Hz\n", I2C_GetBusClockFreq(I2C0)); /* Set I2C0 2 Slave Addresses */ I2C_SetSlaveAddr(I2C0, 0, 0x15, I2C_GCMODE_DISABLE); /* Slave Address : 0x15 */ I2C_SetSlaveAddr(I2C0, 1, 0x35, I2C_GCMODE_DISABLE); /* Slave Address : 0x35 */ /* Enable I2C0 interrupt */ I2C_EnableInt(I2C0); NVIC_EnableIRQ(I2C0_IRQn); }
void I2C3_Init(void) { /* Open I2C3 and set clock to 100k */ I2C_Open(I2C3, 100000); /* Get I2C3 Bus Clock */ printf("I2C clock %d Hz\n", I2C_GetBusClockFreq(I2C3)); /* Set I2C3 4 Slave Addresses */ I2C_SetSlaveAddr(I2C3, 0, 0x15, I2C_GCMODE_DISABLE); /* Slave Address : 0x15 */ I2C_SetSlaveAddr(I2C3, 1, 0x35, I2C_GCMODE_DISABLE); /* Slave Address : 0x35 */ I2C_SetSlaveAddr(I2C3, 2, 0x55, I2C_GCMODE_DISABLE); /* Slave Address : 0x55 */ I2C_SetSlaveAddr(I2C3, 3, 0x75, I2C_GCMODE_DISABLE); /* Slave Address : 0x75 */ I2C_EnableInt(I2C3); NVIC_EnableIRQ(I2C3_IRQn); }
void I2C1_Init(void) { /* Open I2C1 and set clock to 100k */ I2C_Open(I2C1, 400000); /* Get I2C1 Bus Clock */ printf("I2C1 clock %d Hz\n", I2C_GetBusClockFreq(I2C1)); /* Set I2C1 2 Slave Addresses */ I2C_SetSlaveAddr(I2C1, 0, SLAVE_ADDRESS, I2C_GCMODE_DISABLE); /* Set Slave Address */ I2C_EnableInt(I2C1); NVIC_EnableIRQ(I2C1_IRQn); /* I2C enter no address SLV mode */ I2C_SET_CONTROL_REG(I2C1, I2C_SI | I2C_AA); }
/******************************************************************************* * Function Name: I2C_Wakeup ******************************************************************************** * * Summary: * Wakeup on address match enabled: enables I2C Master (if was enabled before go * to sleep) and disables I2C backup regulator. * Wakeup on address match disabled: Restores I2C configuration and * non-retention register values. Restores Active mode power template bits or * clock gating as appropriate. * The I2C interrupt remains disabled after function call. * * Parameters: * None * * Return: * None * * Reentrant: * No * *******************************************************************************/ void I2C_Wakeup(void) { I2C_RestoreConfig(); /* Restore I2C register settings */ /* Restore component enable state */ if(0u != I2C_backup.enableState) { I2C_Enable(); I2C_EnableInt(); } else { #if(I2C_TIMEOUT_ENABLED) I2C_TimeoutEnable(); #endif /* (I2C_TIMEOUT_ENABLED) */ } }
// ********************************************************************** // I2C Master Initialize // ********************************************************************** void I2C_MS_Master_Init() { // =============PIN SETTNG================== #ifdef I2C_MS_PORT0 CLK_EnableModuleClock(I2C0_MODULE); /* Set I2C PA multi-function pins */ SYS->GPE_MFPH &= ~(SYS_GPE_MFPH_PE12MFP_Msk | SYS_GPE_MFPH_PE13MFP_Msk); SYS->GPE_MFPH |= ( SYS_GPE_MFPH_PE12MFP_I2C0_SCL | SYS_GPE_MFPH_PE13MFP_I2C0_SDA); //GPIO_SetMode(PE, BIT12, GPIO_MODE_QUASI); //GPIO_SetMode(PE, BIT13, GPIO_MODE_QUASI); //SYS->GPA_MFPL &= ~(SYS_GPA_MFPL_PA2MFP_Msk | SYS_GPA_MFPL_PA3MFP_Msk); //SYS->GPA_MFPL |= (SYS_GPA_MFPL_PA2MFP_I2C0_SDA | SYS_GPA_MFPL_PA3MFP_I2C0_SCL); #else CLK_EnableModuleClock(I2C1_MODULE); /* Set I2C PA multi-function pins */ SYS->GPC_MFPL &= ~SYS_GPC_MFPL_PC4MFP_Msk; SYS->GPC_MFPL |= SYS_GPC_MFPL_PC4MFP_I2C1_SCL; SYS->GPE_MFPL &= ~SYS_GPE_MFPL_PE0MFP_Msk; SYS->GPE_MFPL |= SYS_GPE_MFPL_PE0MFP_I2C1_SDA; #endif /* Open I2C module and set bus clock */ I2C_Open(I2C_MS_PORT, 100000); /* Get I2C0 Bus Clock */ printf("I2C MS Master clock %d Hz\n", I2C_GetBusClockFreq(I2C_MS_PORT)); /* Enable I2C interrupt */ I2C_EnableInt(I2C_MS_PORT); #ifdef I2C_MS_PORT0 NVIC_EnableIRQ(I2C0_IRQn); #else NVIC_EnableIRQ(I2C1_IRQn); #endif I2CMstWakeupEndFlag = 0; //Master Wake up Flag I2CMstTRxEndFlag = 0; //Master Transfer/Receive End Flag I2CMstSleepEndFlag = 0; //Master sleep End Flag I2CMstWakeupEnStartFlag=1; I2CMstTRxEnStartFlag=1; I2CMstSleepEnStartFlag=1; I2CMstEndFlag=0; I2CMstTimeOutFlag = 0; }
void I2C0_Init(void) { /* Open I2C module and set bus clock */ I2C_Open(I2C0, 100000); /* Get I2C0 Bus Clock */ printf("I2C clock %d Hz\n", I2C_GetBusClockFreq(I2C0)); /* Set I2C 4 Slave Addresses */ I2C_SetSlaveAddr(I2C0, 0, 0x15, 0); /* Slave Address : 0x15 */ I2C_SetSlaveAddr(I2C0, 1, 0x35, 0); /* Slave Address : 0x35 */ I2C_SetSlaveAddr(I2C0, 2, 0x55, 0); /* Slave Address : 0x55 */ I2C_SetSlaveAddr(I2C0, 3, 0x75, 0); /* Slave Address : 0x75 */ /* Enable I2C interrupt */ I2C_EnableInt(I2C0); NVIC_EnableIRQ(I2C0_IRQn); }
/******************************************************************************* * Function Name: I2C_I2CMasterStatus ******************************************************************************** * * Summary: * Returns the master's communication status. * * Parameters: * None * * Return: * Current status of I2C master. * * Global variables: * I2C_mstrStatus - used to store current status of I2C Master. * *******************************************************************************/ uint32 I2C_I2CMasterStatus(void) { uint32 status; I2C_DisableInt(); /* Lock from interruption */ status = (uint32) I2C_mstrStatus; if (I2C_CHECK_I2C_MASTER_ACTIVE) { /* Add status of master pending transaction: MSTAT_XFER_INP */ status |= (uint32) I2C_I2C_MSTAT_XFER_INP; } I2C_EnableInt(); /* Release lock */ return(status); }
void HandleI2CNotifications(CYBLE_GATTC_HANDLE_VALUE_NTF_PARAM_T *I2CDataNotification) { uint8 i; /* Check if its I2C read notitifications */ if(I2CDataNotification->handleValPair.attrHandle == I2CReadDataCharHandle) { /* Disable I2C interrupts before updating the data */ I2C_DisableInt(); /* Update I2C read registers with the notification data*/ for(i=0;i<I2CDataNotification->handleValPair.value.len;i++) rdBuf[i] = I2CDataNotification->handleValPair.value.val[i]; /* Enable I2C interrupts after updating the data */ I2C_EnableInt(); } }
/******************************************************************************* * Function Name: I2C_SaveConfig ******************************************************************************** * * Summary: * Wakeup on address match enabled: disables I2C Master(if was enabled before go * to sleep), enables I2C backup regulator. Waits while on-going transaction be * will completed and I2C will be ready go to sleep. All incoming transaction * will be NACKed till power down will be asserted. The address match event * wakes up the chip. * Wakeup on address match disabled: saves I2C configuration and non-retention * register values. * * Parameters: * None * * Return: * None * * Global Variables: * I2C_backup - used to save component configuration and * none-retention registers before enter sleep mode. * * Reentrant: * No * *******************************************************************************/ void I2C_SaveConfig(void) { #if(I2C_FF_IMPLEMENTED) #if(I2C_WAKEUP_ENABLED) uint8 enableInterrupts; #endif /* (I2C_WAKEUP_ENABLED) */ /* Store regiters in either Sleep mode */ I2C_backup.cfg = I2C_CFG_REG; I2C_backup.xcfg = I2C_XCFG_REG; #if(I2C_MODE_SLAVE_ENABLED) I2C_backup.addr = I2C_ADDR_REG; #endif /* (I2C_MODE_SLAVE_ENABLED) */ #if(CY_PSOC5A) I2C_backup.clkDiv = I2C_CLKDIV_REG; #else I2C_backup.clkDiv1 = I2C_CLKDIV1_REG; I2C_backup.clkDiv2 = I2C_CLKDIV2_REG; #endif /* (CY_PSOC5A) */ #if(I2C_WAKEUP_ENABLED) /* Need to disable Master */ I2C_CFG_REG &= ((uint8) ~I2C_ENABLE_MASTER); /* Enable the I2C regulator backup */ enableInterrupts = CyEnterCriticalSection(); I2C_PWRSYS_CR1_REG |= I2C_PWRSYS_CR1_I2C_REG_BACKUP; CyExitCriticalSection(enableInterrupts); /* 1) Set force NACK to ignore I2C transactions 2) Wait while I2C will be ready go to Sleep 3) These bits are cleared on wake up */ I2C_XCFG_REG |= I2C_XCFG_FORCE_NACK; while(0u == (I2C_XCFG_REG & I2C_XCFG_RDY_TO_SLEEP)) { ; /* Wait when block is ready to Sleep */ } /* Setup wakeup interrupt */ I2C_DisableInt(); (void) CyIntSetVector(I2C_ISR_NUMBER, &I2C_WAKEUP_ISR); I2C_wakeupSource = 0u; I2C_EnableInt(); #endif /* (I2C_WAKEUP_ENABLED) */ #else /* Store only address match bit */ I2C_backup.control = (I2C_CFG_REG & I2C_CTRL_ANY_ADDRESS_MASK); #if(CY_UDB_V0) /* Store interrupt mask bits */ I2C_backup.intMask = I2C_INT_MASK_REG; #if(I2C_MODE & I2C_MODE_SLAVE) I2C_backup.addr = I2C_ADDR_REG; #endif /* (I2C_MODE & I2C_MODE_SLAVE) */ #endif /* (CY_UDB_V0) */ #endif /* (I2C_FF_IMPLEMENTED) */ #if(I2C_TIMEOUT_ENABLED) I2C_TimeoutSaveConfig(); /* Save Timeout config */ #endif /* (I2C_TIMEOUT_ENABLED) */ }
/******************************************************************************* * Function Name: I2C_I2CMasterWriteBuf ******************************************************************************** * * Summary: * Automatically writes an entire buffer of data to a slave device. * Once the data transfer is initiated by this function, further data transfer * is handled by the included ISR. * Enables the I2C interrupt and clears SCB_ I2C_MSTAT_WR_CMPLT status. * * Parameters: * slaveAddr: 7-bit slave address. * xferData: Pointer to buffer of data to be sent. * cnt: Size of buffer to send. * mode: Transfer mode defines: start or restart condition generation at * begin of the transfer and complete the transfer or halt before * generating a stop. * * Return: * Error status. * * Global variables: * I2C_mstrStatus - used to store current status of I2C Master. * I2C_state - used to store current state of software FSM. * I2C_mstrControl - used to control master end of transaction with * or without the Stop generation. * I2C_mstrWrBufPtr - used to store pointer to master write buffer. * I2C_mstrWrBufIndex - used to current index within master write * buffer. * I2C_mstrWrBufSize - used to store master write buffer size. * *******************************************************************************/ uint32 I2C_I2CMasterWriteBuf(uint32 slaveAddress, uint8 * wrData, uint32 cnt, uint32 mode) { uint32 errStatus; errStatus = I2C_I2C_MSTR_NOT_READY; if(NULL != wrData) /* Check buffer pointer */ { /* Check FSM state and bus before generating Start/ReStart condition */ if(I2C_CHECK_I2C_FSM_IDLE) { I2C_DisableInt(); /* Lock from interruption */ /* Check bus state */ errStatus = I2C_CHECK_I2C_STATUS(I2C_I2C_STATUS_BUS_BUSY) ? I2C_I2C_MSTR_BUS_BUSY : I2C_I2C_MSTR_NO_ERROR; } else if(I2C_CHECK_I2C_FSM_HALT) { I2C_mstrStatus &= (uint16) ~I2C_I2C_MSTAT_XFER_HALT; errStatus = I2C_I2C_MSTR_NO_ERROR; } else { /* Unexpected FSM state: exit */ } } /* Check if master is ready to start */ if(I2C_I2C_MSTR_NO_ERROR == errStatus) /* No error proceed */ { #if (!I2C_CY_SCBIP_V0 && \ I2C_I2C_MULTI_MASTER_SLAVE_CONST && I2C_I2C_WAKE_ENABLE_CONST) I2C_I2CMasterDisableEcAm(); #endif /* (!I2C_CY_SCBIP_V0) */ /* Set up write transaction */ I2C_state = I2C_I2C_FSM_MSTR_WR_ADDR; I2C_mstrWrBufIndexTmp = 0u; I2C_mstrWrBufIndex = 0u; I2C_mstrWrBufSize = cnt; I2C_mstrWrBufPtr = (volatile uint8 *) wrData; I2C_mstrControl = (uint8) mode; slaveAddress = I2C_GET_I2C_8BIT_ADDRESS(slaveAddress); I2C_mstrStatus &= (uint16) ~I2C_I2C_MSTAT_WR_CMPLT; I2C_ClearMasterInterruptSource(I2C_INTR_MASTER_ALL); I2C_ClearTxInterruptSource(I2C_INTR_TX_UNDERFLOW); /* The TX and RX FIFO have to be EMPTY */ /* Enable interrupt source to catch when address is sent */ I2C_SetTxInterruptMode(I2C_INTR_TX_UNDERFLOW); /* Generate Start or ReStart */ if(I2C_CHECK_I2C_MODE_RESTART(mode)) { I2C_I2C_MASTER_GENERATE_RESTART; I2C_TX_FIFO_WR_REG = slaveAddress; } else { I2C_TX_FIFO_WR_REG = slaveAddress; I2C_I2C_MASTER_GENERATE_START; } } I2C_EnableInt(); /* Release lock */ return(errStatus); }
/******************************************************************************* * Function Name: I2C_I2CMasterReadBuf ******************************************************************************** * * Summary: * Automatically reads an entire buffer of data from a slave device. * Once the data transfer is initiated by this function, further data transfer * is handled by the included ISR. * Enables the I2C interrupt and clears SCB_ I2C_MSTAT_RD_CMPLT status. * * Parameters: * slaveAddr: 7-bit slave address. * xferData: Pointer to buffer where to put data from slave. * cnt: Size of buffer to read. * mode: Transfer mode defines: start or restart condition generation at * begin of the transfer and complete the transfer or halt before * generating a stop. * * Return: * Error status. * * Global variables: * I2C_mstrStatus - used to store current status of I2C Master. * I2C_state - used to store current state of software FSM. * I2C_mstrControl - used to control master end of transaction with * or without the Stop generation. * I2C_mstrRdBufPtr - used to store pointer to master write buffer. * I2C_mstrRdBufIndex - used to current index within master write * buffer. * I2C_mstrRdBufSize - used to store master write buffer size. * *******************************************************************************/ uint32 I2C_I2CMasterReadBuf(uint32 slaveAddress, uint8 * rdData, uint32 cnt, uint32 mode) { uint32 errStatus; errStatus = I2C_I2C_MSTR_NOT_READY; if(NULL != rdData) { /* Check FSM state and bus before generating Start/ReStart condition */ if(I2C_CHECK_I2C_FSM_IDLE) { I2C_DisableInt(); /* Lock from interruption */ /* Check bus state */ errStatus = I2C_CHECK_I2C_STATUS(I2C_I2C_STATUS_BUS_BUSY) ? I2C_I2C_MSTR_BUS_BUSY : I2C_I2C_MSTR_NO_ERROR; } else if(I2C_CHECK_I2C_FSM_HALT) { I2C_mstrStatus &= (uint16) ~I2C_I2C_MSTAT_XFER_HALT; errStatus = I2C_I2C_MSTR_NO_ERROR; } else { /* Unexpected FSM state: exit */ } } /* Check master ready to proceed */ if(I2C_I2C_MSTR_NO_ERROR == errStatus) /* No error proceed */ { #if (!I2C_CY_SCBIP_V0 && \ I2C_I2C_MULTI_MASTER_SLAVE_CONST && I2C_I2C_WAKE_ENABLE_CONST) I2C_I2CMasterDisableEcAm(); #endif /* (!I2C_CY_SCBIP_V0) */ /* Set up read transaction */ I2C_state = I2C_I2C_FSM_MSTR_RD_ADDR; I2C_mstrRdBufIndex = 0u; I2C_mstrRdBufSize = cnt; I2C_mstrRdBufPtr = (volatile uint8 *) rdData; I2C_mstrControl = (uint8) mode; slaveAddress = (I2C_GET_I2C_8BIT_ADDRESS(slaveAddress) | I2C_I2C_READ_FLAG); I2C_mstrStatus &= (uint16) ~I2C_I2C_MSTAT_RD_CMPLT; I2C_ClearMasterInterruptSource(I2C_INTR_MASTER_ALL); /* TX and RX FIFO have to be EMPTY */ /* Prepare reading */ if(I2C_mstrRdBufSize < I2C_I2C_FIFO_SIZE) { /* Reading byte-by-byte */ I2C_SetRxInterruptMode(I2C_INTR_RX_NOT_EMPTY); } else { /* Receive RX FIFO chunks */ I2C_ENABLE_MASTER_AUTO_DATA_ACK; I2C_SetRxInterruptMode(I2C_INTR_RX_FULL); } /* Generate Start or ReStart */ if(I2C_CHECK_I2C_MODE_RESTART(mode)) { I2C_I2C_MASTER_GENERATE_RESTART; I2C_TX_FIFO_WR_REG = (slaveAddress); } else { I2C_TX_FIFO_WR_REG = (slaveAddress); I2C_I2C_MASTER_GENERATE_START; } } I2C_EnableInt(); /* Release lock */ return(errStatus); }
void AppCallBack(uint32 event, void *eventParam) { uint8 i; CYBLE_GATTS_WRITE_REQ_PARAM_T *wrReqParam; switch (event) { case CYBLE_EVT_STACK_ON: /* start advertising */ apiResult = CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST); if(apiResult == CYBLE_ERROR_OK) { #ifdef LED_INDICATION ADV_LED_ON(); #endif /* LED_INDICATION */ } break; case CYBLE_EVT_GAP_DEVICE_DISCONNECTED: sendNotifications = 0; #ifdef ENABLE_I2C_ONLY_WHEN_CONNECTED /* Stop I2C Slave operation */ I2C_Stop(); #endif #ifdef LED_INDICATION /* Indicate disconnect event to user */ DISCON_LED_ON(); CyDelay(3000); #endif /* LED_INDICATION */ /* start advertising */ apiResult = CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST); if(apiResult == CYBLE_ERROR_OK) { #ifdef LED_INDICATION ADV_LED_ON(); #endif /* LED_INDICATION */ } break; case CYBLE_EVT_GATT_CONNECT_IND: #ifdef LED_INDICATION CONNECT_LED_ON(); #endif /* LED_INDICATION */ #ifdef ENABLE_I2C_ONLY_WHEN_CONNECTED /* Start I2C Slave operation */ I2C_Start(); /* Initialize I2C write buffer */ I2C_I2CSlaveInitWriteBuf((uint8 *) wrBuf, I2C_WRITE_BUFFER_SIZE); /* Initialize I2C read buffer */ I2C_I2CSlaveInitReadBuf((uint8 *) rdBuf, I2C_READ_BUFFER_SIZE); #endif break; /* Client may do Write Value or Write Value without Response. Handle both */ case CYBLE_EVT_GATTS_WRITE_REQ: case CYBLE_EVT_GATTS_WRITE_CMD_REQ: wrReqParam = (CYBLE_GATTS_WRITE_REQ_PARAM_T *) eventParam; /* Handling Notification Enable */ if(wrReqParam->handleValPair.attrHandle == CYBLE_I2C_READ_I2C_READ_DATA_CLIENT_CHARACTERISTIC_CONFIGURATION_DESC_HANDLE) { CYBLE_GATT_HANDLE_VALUE_PAIR_T I2CNotificationCCDHandle; uint8 I2CCCDValue[2]; /* Extract CCCD Notification enable flag */ sendNotifications = wrReqParam->handleValPair.value.val[0]; /* Write the present I2C notification status to the local variable */ I2CCCDValue[0] = sendNotifications; I2CCCDValue[1] = 0x00; /* Update CCCD handle with notification status data*/ I2CNotificationCCDHandle.attrHandle = CYBLE_I2C_READ_I2C_READ_DATA_CLIENT_CHARACTERISTIC_CONFIGURATION_DESC_HANDLE; I2CNotificationCCDHandle.value.val = I2CCCDValue; I2CNotificationCCDHandle.value.len = 2; /* Report data to BLE component for sending data when read by Central device */ CyBle_GattsWriteAttributeValue(&I2CNotificationCCDHandle, 0, &cyBle_connHandle, CYBLE_GATT_DB_LOCALLY_INITIATED); } /* Handling Write data from Client */ else if(wrReqParam->handleValPair.attrHandle == CYBLE_I2C_WRITE_I2C_WRITE_DATA_CHAR_HANDLE) { /* Turn off I2C interrupt before updating read registers */ I2C_DisableInt(); /*The data received from I2C client is extracted */ for(i=0;i<(wrReqParam->handleValPair.value.len);i++) rdBuf[i] = wrReqParam->handleValPair.value.val[i]; /* Turn on I2C interrupt after updating read registers */ I2C_EnableInt(); } if (event == CYBLE_EVT_GATTS_WRITE_REQ) { CyBle_GattsWriteRsp(cyBle_connHandle); } break; default: break; } }
/******************************************************************************* * Function Name: I2C_RestoreConfig ******************************************************************************** * * Summary: * Wakeup on address match enabled: enables I2C Master (if was enabled before go * to sleep), disables I2C backup regulator. * Wakeup on address match disabled: Restores I2C configuration and * non-retention register values. * * Parameters: * None * * Return: * None * * Global Variables: * I2C_backup - used to save component configuration and * none-retention registers before exit sleep mode. * *******************************************************************************/ void I2C_RestoreConfig(void) { #if (I2C_IMPLEMENTATION == I2C_FF) #if (I2C_ENABLE_WAKEUP) uint8 enableInterrupts; /* Disable the I2C regulator backup */ enableInterrupts = CyEnterCriticalSection(); if (0u != (I2C_PWRSYS_CR1_I2C_REG_BACKUP & I2C_PWRSYS_CR1_REG)) { I2C_PWRSYS_CR1_REG &= ~I2C_PWRSYS_CR1_I2C_REG_BACKUP; CyExitCriticalSection(enableInterrupts); /* Need to re-enable Master */ #if (0u != (I2C_MODE & I2C_MODE_MASTER)) if (I2C_backup.enableState != 0u) { I2C_CFG_REG |= I2C_ENABLE_MASTER; /* Clear state of I2C Master */ I2C_backup.enableState = 0u; } #endif /* End (0u != (I2C_CFG_REG & I2C_ENABLE_MASTER)) */ } else { /* Disable power to I2C block before register restore */ I2C_ACT_PWRMGR_REG &= ~I2C_ACT_PWR_EN; I2C_STBY_PWRMGR_REG &= ~I2C_STBY_PWR_EN; /* The I2C_PWRSYS_CR1_I2C_REG_BACKUP already cleaned by PM APIs */ CyExitCriticalSection(enableInterrupts); /* Enable component after restore complete */ I2C_backup.enableState = 1u; #endif /* End (I2C_ENABLE_WAKEUP) */ /* Restore component registers */ I2C_XCFG_REG = I2C_backup.xcfg; I2C_CFG_REG = I2C_backup.cfg; #if (0u != (I2C_MODE & I2C_MODE_SLAVE)) I2C_ADDR_REG = I2C_backup.addr; #endif /* End (0u != (I2C_MODE & I2C_MODE_SLAVE)) */ #if (CY_PSOC3_ES2 || CY_PSOC5_ES1) I2C_CLKDIV_REG =I2C_backup.clk_div; #else I2C_CLKDIV1_REG = I2C_backup.clk_div1; I2C_CLKDIV2_REG = I2C_backup.clk_div2; #endif /* End (CY_PSOC3_ES2 || CY_PSOC5_ES1) */ #if (I2C_ENABLE_WAKEUP) } #endif /* End (I2C_ENABLE_WAKEUP) */ #else #if (CY_PSOC3_ES2 || CY_PSOC5_ES1) uint8 enableInterrupts; /* Enable interrupts from block */ enableInterrupts = CyEnterCriticalSection(); I2C_INT_ENABLE_REG |= I2C_INT_ENABLE_MASK; CyExitCriticalSection(enableInterrupts); /* Restore interrupt mask bits */ I2C_INT_MASK_REG |= I2C_backup.int_mask; #if (0u != (I2C_MODE & I2C_MODE_MASTER)) /* Restore Master Clock generator */ I2C_MCLK_PRD_REG = I2C_MCLK_PERIOD_VALUE; I2C_MCLK_CMP_REG = I2C_MCLK_COMPARE_VALUE; #endif /* End (0u != (I2C_MODE & I2C_MODE_MASTER)) */ #if (0u != (I2C_MODE & I2C_MODE_SLAVE)) /* Store slave address */ I2C_ADDR_REG = I2C_backup.addr; /* Restore slave bit counter period */ I2C_PERIOD_REG = I2C_PERIOD_VALUE; #endif /* End (0u != (I2C_MODE & I2C_MODE_SLAVE)) */ #else /* Retention registers for ES3: - Status Int mask: int_mask; - D0 register: addr; - Auxiliary Control: aux_ctl; - Period Register: always 7; - D0 and D1: clock generator 7, 15; */ #endif /* End (CY_PSOC3_ES2 || CY_PSOC5_ES1) */ /* Restore CFG register */ I2C_CFG_REG = I2C_backup.control; #endif /* End (I2C_IMPLEMENTATION == I2C_FF) */ /* Enable interrupts */ I2C_EnableInt(); }
/******************************************************************************* * Function Name: I2C_RestoreConfig ******************************************************************************** * * Summary: * Wakeup on address match enabled: enables I2C Master (if was enabled before go * to sleep), disables I2C backup regulator. * Wakeup on address match disabled: Restores I2C configuration and * non-retention register values. * * Parameters: * None * * Return: * None * * Global Variables: * I2C_backup - used to save component configuration and * none-retention registers before exit sleep mode. * *******************************************************************************/ void I2C_RestoreConfig(void) { #if(I2C_FF_IMPLEMENTED) uint8 enableInterrupts; if(I2C_CHECK_PWRSYS_I2C_BACKUP) /* Enabled if was in Sleep */ { /* Disable back-up regulator */ enableInterrupts = CyEnterCriticalSection(); I2C_PWRSYS_CR1_REG &= ((uint8) ~I2C_PWRSYS_CR1_I2C_REG_BACKUP); CyExitCriticalSection(enableInterrupts); /* Re-enable Master */ I2C_CFG_REG = I2C_backup.cfg; } else /* The I2C_REG_BACKUP was cleaned by PM API: it means Hibernate or wake-up not set */ { #if(I2C_WAKEUP_ENABLED) /* Disable power to I2C block before register restore */ enableInterrupts = CyEnterCriticalSection(); I2C_ACT_PWRMGR_REG &= ((uint8) ~I2C_ACT_PWR_EN); I2C_STBY_PWRMGR_REG &= ((uint8) ~I2C_STBY_PWR_EN); CyExitCriticalSection(enableInterrupts); /* Enable component after restore complete */ I2C_backup.enableState = I2C_ENABLE; #endif /* (I2C_WAKEUP_ENABLED) */ /* Restore component registers: Hibernate disable power */ I2C_XCFG_REG = I2C_backup.xcfg; I2C_CFG_REG = I2C_backup.cfg; #if(I2C_MODE_SLAVE_ENABLED) I2C_ADDR_REG = I2C_backup.addr; #endif /* (I2C_MODE_SLAVE_ENABLED) */ #if(CY_PSOC5A) I2C_CLKDIV_REG = I2C_backup.clkDiv; #else I2C_CLKDIV1_REG = I2C_backup.clkDiv1; I2C_CLKDIV2_REG = I2C_backup.clkDiv2; #endif /* (CY_PSOC5A) */ } #if(I2C_WAKEUP_ENABLED) I2C_DisableInt(); (void) CyIntSetVector(I2C_ISR_NUMBER, &I2C_ISR); if(0u != I2C_wakeupSource) { I2C_SetPendingInt(); /* Generate interrupt to process incomming transcation */ } I2C_EnableInt(); #endif /* (I2C_WAKEUP_ENABLED) */ #else #if(CY_UDB_V0) uint8 enableInterrupts; I2C_INT_MASK_REG |= I2C_backup.intMask; enableInterrupts = CyEnterCriticalSection(); I2C_INT_ENABLE_REG |= I2C_INT_ENABLE_MASK; CyExitCriticalSection(enableInterrupts); #if(I2C_MODE_MASTER_ENABLED) /* Restore Master Clock generator */ I2C_MCLK_PRD_REG = I2C_DEFAULT_MCLK_PRD; I2C_MCLK_CMP_REG = I2C_DEFAULT_MCLK_CMP; #endif /* (I2C_MODE_MASTER_ENABLED) */ #if(I2C_MODE_SLAVE_ENABLED) I2C_ADDR_REG = I2C_backup.addr; /* Restore slave bit counter period */ I2C_PERIOD_REG = I2C_DEFAULT_PERIOD; #endif /* (I2C_MODE_SLAVE_ENABLED) */ #endif /* (CY_UDB_V0) */ I2C_CFG_REG = I2C_backup.control; #endif /* (I2C_FF_IMPLEMENTED) */ #if(I2C_TIMEOUT_ENABLED) I2C_TimeoutRestoreConfig(); #endif /* (I2C_TIMEOUT_ENABLED) */ }
/******************************************************************************* * Function Name: I2C_MasterWriteBuf ******************************************************************************** * * Summary: * Automatically writes an entire buffer of data to a slave device. Once the * data transfer is initiated by this function, further data transfer is handled * by the included ISR in byte by byte mode. * * Parameters: * slaveAddr: 7-bit slave address. * xferData: Pointer to buffer of data to be sent. * cnt: Size of buffer to send. * mode: Transfer mode defines: start or restart condition generation at * begin of the transfer and complete the transfer or halt before * generating a stop. * * Return: * Status error - zero means no errors. * * Side Effects: * The included ISR will start transfer after start or restart condition will * be generated. * * Global variables: * I2C_mstrStatus - used to store current status of I2C Master. * I2C_state - used to store current state of software FSM. * I2C_mstrControl - used to control master end of transaction with * or without the Stop generation. * I2C_mstrWrBufPtr - used to store pointer to master write buffer. * I2C_mstrWrBufIndex - used to current index within master write * buffer. * I2C_mstrWrBufSize - used to store master write buffer size. * * Reentrant: * No * *******************************************************************************/ uint8 I2C_MasterWriteBuf(uint8 slaveAddress, uint8 * wrData, uint8 cnt, uint8 mode) { uint8 errStatus; errStatus = I2C_MSTR_NOT_READY; if(NULL != wrData) { /* Check I2C state before transfer: valid are IDLE or HALT */ if(I2C_SM_IDLE == I2C_state) { /* Check if free: Master is ready to transaction */ if(I2C_CHECK_BUS_FREE(I2C_MCSR_REG)) { errStatus = I2C_MSTR_NO_ERROR; } else { errStatus = I2C_MSTR_BUS_BUSY; } } else if(I2C_SM_MSTR_HALT == I2C_state) { errStatus = I2C_MSTR_NO_ERROR; CyIntClearPending(I2C_ISR_NUMBER); I2C_mstrStatus &= ((uint8) ~I2C_MSTAT_XFER_HALT); } else { /* errStatus = I2C_MSTR_NOT_READY was send before */ } if(I2C_MSTR_NO_ERROR == errStatus) { I2C_state = I2C_SM_MSTR_WR_ADDR; I2C_DATA_REG = ((uint8) (slaveAddress << I2C_SLAVE_ADDR_SHIFT)); I2C_mstrWrBufIndex = 0u; I2C_mstrWrBufSize = cnt; I2C_mstrWrBufPtr = (volatile uint8 *) wrData; I2C_mstrControl = mode; /* Save transaction mode */ /* Generate a Start or ReStart depends on mode */ if(I2C_CHECK_RESTART(mode)) { I2C_GENERATE_RESTART; } else { I2C_GENERATE_START; } I2C_mstrStatus &= ((uint8) ~I2C_MSTAT_WR_CMPLT); I2C_EnableInt(); /* Enable intr to complete transfer */ } } return(errStatus); }
// ********************************************************************** // I2C Slave Initialize called by I2CWakeUpInit // ********************************************************************** void I2C_MS_Slave_Init() { // =============PIN SETTNG================== #ifdef I2C_MS_PORT0 CLK_EnableModuleClock(I2C0_MODULE); /* Set I2C PA multi-function pins */ SYS->GPE_MFPH &= ~(SYS_GPE_MFPH_PE12MFP_Msk | SYS_GPE_MFPH_PE13MFP_Msk); SYS->GPE_MFPH |= ( SYS_GPE_MFPH_PE12MFP_I2C0_SCL | SYS_GPE_MFPH_PE13MFP_I2C0_SDA); #else CLK_EnableModuleClock(I2C1_MODULE); /* Set I2C PA multi-function pins */ SYS->GPC_MFPL &= ~SYS_GPC_MFPL_PC4MFP_Msk; SYS->GPC_MFPL |= SYS_GPC_MFPL_PC4MFP_I2C1_SCL; SYS->GPE_MFPL &= ~SYS_GPE_MFPL_PE0MFP_Msk; SYS->GPE_MFPL |= SYS_GPE_MFPL_PE0MFP_I2C1_SDA; #endif /* Open I2C module and set bus clock */ I2C_Open(I2C_MS_PORT, 100000); /* Get I2C0 Bus Clock */ printf("I2C MS Slave clock %d Hz\n", I2C_GetBusClockFreq(I2C_MS_PORT)); /* Set I2C 4 Slave Addresses */ #if 1 I2C_SetSlaveAddr(I2C_MS_PORT, 0, devNum+0x14, 0); #else if(devNum == 1) I2C_SetSlaveAddr(I2C_MS_PORT, 0, 0x15, 0); /* Slave Address : 21,Buzzer */ else if(devNum == 2) I2C_SetSlaveAddr(I2C_MS_PORT, 0, 0x16, 0); /* Slave Address : 22,Led */ else if(devNum == 3) I2C_SetSlaveAddr(I2C_MS_PORT, 0, 0x17, 0); /* Slave Address : 23,AHRS */ else if(devNum == 4) I2C_SetSlaveAddr(I2C_MS_PORT, 0, 0x18, 0); /* Slave Address : 24,SONAR */ else if(devNum == 5) I2C_SetSlaveAddr(I2C_MS_PORT, 0, 0x19, 0); /* Slave Address : 25,TEMPERATURE */ else if(devNum == 6) I2C_SetSlaveAddr(I2C_MS_PORT, 0, 0x1a, 0); /* Slave Address : 26,Gas */ else if(devNum == 7) I2C_SetSlaveAddr(I2C_MS_PORT, 0, 0x1b, 0); /* Slave Address : 27,IR */ else if(devNum == 8) I2C_SetSlaveAddr(I2C_MS_PORT, 0, 0x1c, 0); /* Slave Address : 28,KEY */ else if(devNum == 9) I2C_SetSlaveAddr(I2C_MS_PORT, 0, 0x1d, 0); /* Slave Address : 29, Reserved device 9 */ else if(devNum == 10) I2C_SetSlaveAddr(I2C_MS_PORT, 0, 0x1e, 0); /* Slave Address : 30, Reserved device 10 */ else if(devNum == 11) I2C_SetSlaveAddr(I2C_MS_PORT, 0, 0x1f, 0); /* Slave Address : 31, Reserved device 11 */ else if(devNum == 12) I2C_SetSlaveAddr(I2C_MS_PORT, 0, 0x20, 0); /* Slave Address : 32, Reserved device 12 */ else if(devNum == 13) I2C_SetSlaveAddr(I2C_MS_PORT, 0, 0x21, 0); /* Slave Address : 33, Reserved device 13 */ else if(devNum == 14) I2C_SetSlaveAddr(I2C_MS_PORT, 0, 0x22, 0); /* Slave Address : 34, Reserved device 14 */ #endif I2C_SetSlaveAddr(I2C_MS_PORT, 1, 0x35, 0); /* Slave Address : 0x35 */ I2C_SetSlaveAddr(I2C_MS_PORT, 2, 0x55, 0); /* Slave Address : 0x55 */ I2C_SetSlaveAddr(I2C_MS_PORT, 3, 0x75, 0); /* Slave Address : 0x75 */ /* Enable I2C interrupt */ I2C_EnableInt(I2C_MS_PORT); #ifdef I2C_MS_PORT0 NVIC_EnableIRQ(I2C0_IRQn); #else NVIC_EnableIRQ(I2C1_IRQn); #endif #ifdef I2C_MS_PORT0 s_I2C0HandlerFn = (I2C_FUNC)I2C_MS_Slave; #else s_I2C1HandlerFn = (I2C_FUNC)I2C_MS_Slave; #endif /* Enable I2C wake-up */ I2C_EnableWakeup(I2C_MS_PORT); /* Set I2C0 enter Not Address SLAVE mode */ I2C_SET_CONTROL_REG(I2C_MS_PORT, I2C_CTL_SI_AA); }
//--------------------------------------------------------------------------------------------------------- // Main Function //--------------------------------------------------------------------------------------------------------- INT32 main() { SYSCLK_INITIATE(); // Configure CPU clock source and operation clock frequency. // The configuration functions are in "SysClkConfig.h" CLK_EnableLDO(CLK_LDOSEL_3_3V); // Enable ISD9100 interl 3.3 LDO. if (! SPIFlash_Initiate()) // Initiate SPI interface and checking flows for accessing SPI flash. while(1); // loop here for easy debug OUTPUTPIN_INITIATE(); // Initiate output pin configuration. // The output pins configurations are defined in "ConfigIO.h". KEYPAD_INITIATE(); // Initiate keypad configurations including direct trigger key and matrix key // The keypad configurations are defined in "ConfigIO.h". ULTRAIO_INITIATE(); // Initiate ultraio output configurations. // The ultraio output pin configurations are defined in "ConfigUltraIO.h" PDMA_INITIATE(); // Initiate PDMA. // After initiation, the PDMA engine clock NVIC are enabled. // Use PdmaCtrl_Open() to set PDMA service channel for desired IP. // Use PdmaCtrl_Start() to trigger PDMA operation. // Reference "PdmaCtrl.h" for PDMA related APIs. // PDMA_INITIATE() must be call before SPK_INITIATE() and MIC_INITIATE(), if open MIC or speaker. SPK_INITIATE(); // Initiate speaker including pop-sound canceling. // After initiation, the APU is paused. // Use SPK_Resume(0) to start APU operation. // Reference "MicSpk.h" for speaker related APIs. MIC_INITIATE(); // Initiate MIC. // After initiation, the ADC is paused. // Use ADC_Resume() to start ADC operation. // Reference "MicSpk.h" for MIC related APIs. App_Initiate(); // Initiate application for audio decode. i2c_Init(); //need to excute before #define I2C_IRQ #ifdef I2C_IRQ I2C_EnableInt(I2C0); NVIC_EnableIRQ(I2C0_IRQn); NVIC_SetPriority(I2C0_IRQn, 0); #endif #ifdef OLED_ENABLE Init_LCD(); clear_LCD(); print_Line(0, "OscarNuLiteExEnc"); // print_Line(1, "2015.11.12 "); // print_Line(2, "Eric Yang "); // print_Line(3, "0.96 OLED 128x64"); #endif while (1) { if ( g_u8AppCtrl&APPCTRL_RECORD ) { if ( App_ProcessRec() == FALSE ) { App_StopRec(); #ifdef OLED_ENABLE print_Line(1, " REC Stop "); #endif } } else if ( g_u8AppCtrl&APPCTRL_PLAY ) { if ( App_ProcessPlay() == FALSE ) { App_StopPlay(); #ifdef OLED_ENABLE print_Line(1, " PLAY Stop "); #endif } } TRIGGER_KEY_CHECK(); // Check and execute direct trigger key actions defined in "InputKeyActions.c" // Default trigger key handler is "Default_KeyHandler()" // The trigger key configurations are defined in "ConfigIO.h". MATRIX_KEY_CHECK(); // Check and execute matrix key actions defined in "InputKeyActions.c" // Default matrix key handler is "Default_KeyHandler()" // The matrix key configurations are defined in "ConfigIO.h". TOUCH_KEY_CHECK(); // Check and execute touch key actions defined in "InputKeyActions.c" // Default touch key handler is "Default_KeyHandler()" // The touch key configurations are defined in "ConfigIO.h". } }