随手记,实测可在100KHz下运行
1 /*********************************************************************************************************//** 2 * @brief This function handles EXTI 4~15 interrupt. 3 * @retval None 4 * @remark Bridge I2C slaver: Write data & Read data 5 ************************************************************************************************************/ 6 void EXTI4_15_IRQHandler(void) 7 { 8 /******************************************* SDA *******************************************/ 9 if ((HT_EXTI->EDGEFLGR & (1UL << BRIDGE_EXTI_CHANNEL_SDA))) /*< EXTI_GetEdgeFlag() >*/ 10 { 11 /*---------------------------*/ 12 /* SDA Negative edge: START */ 13 /*---------------------------*/ 14 if (GetBit_BB((u32)&HT_EXTI->EDGESR, BRIDGE_EXTI_CHANNEL_SDA) ^ EXTI_EDGE_NEGATIVE) /*< EXTI_GetEdgeStatus() >*/ 15 { 16 if (I2C_Slaver_SCL_Status) /*< if SCL high level >*/ 17 I2C_Slaver.bState = STA_START; 18 } 19 /*-------------------------*/ 20 /* SDA Positive edge: STOP */ 21 /*-------------------------*/ 22 //else if (GetBit_BB((u32)&HT_EXTI->EDGESR, BRIDGE_EXTI_CHANNEL_SDA) ^ EXTI_EDGE_POSITIVE) /*< EXTI_GetEdgeStatus() >*/ 23 else 24 { 25 if (I2C_Slaver_SCL_Status) /*< if SCL high level >*/ 26 { 27 I2C_Slaver.bState = STA_STOP; 28 I2C_Slaver.gGetAddr = I2C_Addr_Mismatch; 29 I2C_Slaver.gGetRW = I2C_Master_Write; 30 I2C_Slaver.gGetAck = I2C_Master_Send_NACK; 31 I2C_Slaver.gACKofDATA = FALSE; 32 I2C_Slaver.SCL.bPositiveEdge_num = 0; 33 } 34 } 35 } 36 37 /******************************************* SCL *******************************************/ 38 if ((HT_EXTI->EDGEFLGR & (1UL << BRIDGE_EXTI_CHANNEL_SCL))) /*< EXTI_GetEdgeFlag() >*/ 39 { 40 /*----------------------------------------------------*/ 41 /* SCL Negative edge: SDA change level to Update data */ 42 /*----------------------------------------------------*/ 43 if (GetBit_BB((u32)&HT_EXTI->EDGESR, BRIDGE_EXTI_CHANNEL_SCL) ^ EXTI_EDGE_NEGATIVE) /*< EXTI_GetEdgeStatus() >*/ 44 { 45 switch (I2C_Slaver.bState) 46 { 47 // SCL Negative edge when I2C start or restart 48 case STA_START: 49 { 50 RingBuffer_Init(&I2CRx_Ring, I2CRx_Ring.pMemory); 51 I2C_Slaver.bState = STA_ADDR; 52 break; 53 } 54 // SCL Negative edge when master send address 55 case STA_ADDR: 56 { 57 if (I2C_Slaver.SCL.bPositiveEdge_num == 8) /*< SCL Positive Edge num 8 >*/ 58 { 59 DIR_SDA_OUT; 60 if (I2C_Slaver.gGetAddr == I2C_Addr_Match) /*< Address match? >*/ 61 { 62 I2C_Slaver_SendACK; // Y 63 I2C_Slaver.bState = STA_ACK; 64 } 65 else 66 { 67 I2C_Slaver_SendNACK; // N 68 I2C_Slaver.bState = STA_STOP; 69 } 70 } 71 break; 72 } 73 // SCL Negative edge when I2C transmit data 74 case STA_DATA: 75 { 76 if (I2C_Slaver.SCL.bPositiveEdge_num == 8) /*< SCL Positive Edge num 8 >*/ 77 { 78 if (I2C_Slaver.gGetRW == I2C_Master_Write) /*< if Master writer -> Slaver send ACK >*/ 79 { 80 DIR_SDA_OUT; 81 I2C_Slaver_SendACK; 82 I2C_Slaver.gACKofDATA = TRUE; 83 } 84 else /*< if Master read -> Slaver receive ACK >*/ 85 { 86 DIR_SDA_IN; 87 I2C_Slaver_SDA_Receive; 88 if (I2CTx_Ring.Head != I2CTx_Ring.Tail) // And ready to send the next byte 89 { 90 I2CTx_Ring.Head++; 91 I2CTx_Ring.Length--; 92 } 93 } 94 I2C_Slaver.bState = STA_ACK; 95 } 96 else if (I2C_Slaver.SCL.bPositiveEdge_num < 8) /*< SCL Positive Edge num 1~7 >*/ 97 { 98 if (I2C_Slaver.gGetRW == I2C_Master_Read) /*< if Master read -> Slaver write data >*/ 99 { 100 DIR_SDA_OUT; 101 if (I2CTx_Ring.pMemory[I2CTx_Ring.Head] & (0x80 >> I2C_Slaver.SCL.bPositiveEdge_num)) 102 { 103 I2C_Slaver_SDA_SendH; // Slaver change SDA level to H 104 } 105 else 106 { 107 I2C_Slaver_SDA_SendL; // Slaver change SDA level to L 108 } 109 } 110 } 111 break; 112 } 113 // SCL Negative edge when I2C transmit ack 114 case STA_ACK: 115 { 116 I2C_Slaver.SCL.bPositiveEdge_num = 0; 117 if (I2C_Slaver.gGetRW == I2C_Master_Write) /*< if Master writer -> Slaver send ack >*/ 118 { 119 DIR_SDA_IN; 120 I2C_Slaver_SDA_Receive; 121 122 if (I2C_Slaver.gACKofDATA) 123 { 124 I2CRx_Ring.Tail++; 125 I2CRx_Ring.Length++; 126 } 127 } 128 else /*< if Master read -> Slaver first change SDA level after send ACK >*/ 129 { 130 DIR_SDA_OUT; 131 if (I2CTx_Ring.pMemory[I2CTx_Ring.Head] & 0x80) 132 { 133 I2C_Slaver_SDA_SendH; // Slaver change SDA level to H 134 } 135 else 136 { 137 I2C_Slaver_SDA_SendL; // Slaver change SDA level to L 138 } 139 } 140 I2C_Slaver.bState = STA_DATA; 141 break; 142 } 143 // SCL Negative edge when I2C transmit nack 144 case STA_NACK: 145 { 146 I2C_Slaver.SCL.bPositiveEdge_num = 0; 147 DIR_SDA_IN; 148 I2C_Slaver_SDA_Receive; 149 break; 150 } 151 default : break; 152 } 153 } 154 /*-------------------*/ 155 /* SCL Positive edge */ 156 /*-------------------*/ 157 //else if (GetBit_BB((u32)&HT_EXTI->EDGESR, BRIDGE_EXTI_CHANNEL_SCL) ^ EXTI_EDGE_POSITIVE) /*< EXTI_GetEdgeStatus() >*/ 158 else 159 { 160 switch (I2C_Slaver.bState) 161 { 162 // SCL Negative edge when master send address 163 case STA_ADDR: 164 { 165 I2C_Slaver.SCL.bPositiveEdge_num++; 166 if (I2C_Slaver.SCL.bPositiveEdge_num <= 8) /*< if Master write -> Slaver read byte >*/ 167 { 168 I2CRx_Ring.pMemory[0] = (I2CRx_Ring.pMemory[0] << 1) | I2C_Slaver_SDA_Status ; // Slaver sampling bit (read byte) 169 if ((I2CRx_Ring.pMemory[0] >> 1) == I2C_Slaver.bAddr_SW) 170 { 171 I2C_Slaver.gGetAddr = I2C_Addr_Match; // Address match 172 I2C_Slaver.gGetRW = I2CRx_Ring.pMemory[0] & 0x01; // Master read or write 173 } 174 } 175 break; 176 } 177 // SCL Positive edge when I2C Master write data 178 case STA_DATA: 179 { 180 I2C_Slaver.SCL.bPositiveEdge_num++; // SCL Negative Edge num ++ in "STA_DATA" 181 if ((I2C_Slaver.gGetRW == I2C_Master_Write) && (I2C_Slaver.SCL.bPositiveEdge_num <= 8)) /*< if Master write -> Slaver read byte >*/ 182 { 183 I2CRx_Ring.pMemory[I2CRx_Ring.Tail] = (I2CRx_Ring.pMemory[I2CRx_Ring.Tail] << 1) | I2C_Slaver_SDA_Status ; // Slaver sampling bit (read byte) 184 } 185 break; 186 } 187 // SCL Positive edge when I2C Master write ACK 188 case STA_ACK: 189 { 190 if (I2C_Slaver.gGetRW == I2C_Master_Read) 191 { 192 if (I2C_Slaver_SDA_Status) 193 I2C_Slaver.bState = STA_NACK; // Slaver ready to receive RESTART or STOP 194 } 195 break; 196 } 197 default : break; 198 } 199 } 200 } 201 202 /************************** Clear edge flag together at the end **************************/ 203 HT_EXTI->EDGEFLGR = HT_EXTI->EDGESR = 1 << BRIDGE_EXTI_CHANNEL_SDA; // EXTI_ClearEdgeFlag() 204 HT_EXTI->EDGEFLGR = HT_EXTI->EDGESR = 1 << BRIDGE_EXTI_CHANNEL_SCL; // EXTI_ClearEdgeFlag() 205 }