diff --git a/Project/applications/smartcities/i2c.c b/Project/applications/smartcities/i2c.c new file mode 100644 index 0000000..86521f9 --- /dev/null +++ b/Project/applications/smartcities/i2c.c @@ -0,0 +1,136 @@ +#include +#include + +void I2C1_init() +{ + GPIO_InitTypeDef GPIO_InitStruct; + I2C_InitTypeDef I2C_InitStruct; + + RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE); + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); + + /* + * 1. SCL on PB6 or PB8 + * 2. SDA on PB7 or PB9 + */ + + GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_9; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_A + GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_InitStruct.GPIO_OType = GPIO_OType_OD; // set output to open drain + GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; // enable pull up resistors + GPIO_Init(GPIOB, &GPIO_InitStruct); // init GPIOB + + /* WARNING + * + * Check consistency with above configuration + * + * --Imanol + */ + + // Connect I2C1 pins to AF + GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_I2C1); // SCL + GPIO_PinAFConfig(GPIOB, GPIO_PinSource9, GPIO_AF_I2C1); // SDA + + // configure I2C1 + I2C_InitStruct.I2C_ClockSpeed = 100000; // 100kHz - STANDARD MODE + I2C_InitStruct.I2C_Mode = I2C_Mode_I2C; + I2C_InitStruct.I2C_DutyCycle = I2C_DutyCycle_2; + I2C_InitStruct.I2C_OwnAddress1 = 0x00; + I2C_InitStruct.I2C_Ack = I2C_Ack_Enable; + I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; + I2C_Init(I2C1, &I2C_InitStruct); + I2C_Cmd(I2C1, ENABLE); +} + +void I2C_start(I2C_TypeDef* I2Cx, uint8_t address, uint8_t direction) +{ + while(I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY)) + { + // wait until I2C1 is not busy any more + } + I2C_GenerateSTART(I2Cx, ENABLE); + + while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT)) + { + // wait for I2C1 EV5 --> Slave has acknowledged start condition + } + I2C_Send7bitAddress(I2Cx, address, direction); + + if(direction == I2C_Direction_Transmitter) + { + while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) + { + // wait for I2Cx EV6, check if Slave has acknowledged Master transmitter mode + } + } + else if(direction == I2C_Direction_Receiver) + { + while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)) + { + // wait for I2Cx EV6, check if Slave has acknowledged Master receiver mode + } + } +} + +void I2C_write(I2C_TypeDef* I2Cx, uint8_t data) +{ + /* WARNING + * + * OJITO QUE ESTÁ ESPERANDO EL EV8 Y NO EL EV8_2 + * + * --Imanol + */ + while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTING)) + { + // wait for I2C1 EV8 --> last byte is still being transmitted (last byte in SR, buffer empty), next byte can already be written + } + I2C_SendData(I2Cx, data); +} + +uint8_t I2C_read_ack(I2C_TypeDef* I2Cx) +{ + I2C_AcknowledgeConfig(I2Cx, ENABLE); + while( !I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED)) + { + // wait until one byte has been received + } + return I2C_ReceiveData(I2Cx); +} + +uint8_t I2C_read_nack(I2C_TypeDef* I2Cx) +{ + I2C_AcknowledgeConfig(I2Cx, DISABLE); + I2C_GenerateSTOP(I2Cx, ENABLE); + while( !I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED)) + { + // wait until one byte has been received + } + return I2C_ReceiveData(I2Cx); +} + +void I2C_stop(I2C_TypeDef* I2Cx) +{ + I2C_GenerateSTOP(I2Cx, ENABLE); + while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) + { + // wait for I2C1 EV8_2 --> byte has been transmitted + } +} + +/* SAMPLE CODE + * + * int main(void) + * { + * uint8_t received_data; + * I2C1_init(); // initialize I2C peripheral + * I2C_start(I2C1, SLAVE_ADDRESS<<1, I2C_Direction_Transmitter); // start a transmission in Master transmitter mode + * I2C_write(I2C1, 0x01); // write one byte to the slave + * I2C_stop(I2C1); // stop the transmission + * I2C_start(I2C1, SLAVE_ADDRESS<<1, I2C_Direction_Receiver); // start a transmission in Master receiver mode + * received_data = I2C_read_nack(I2C1); // read one byte and don't request another byte, stop transmission + * while(1); + * return 0; + * } + * --Imanol + */ diff --git a/Project/applications/smartcities/include/i2c.h b/Project/applications/smartcities/include/i2c.h new file mode 100644 index 0000000..b214b7c --- /dev/null +++ b/Project/applications/smartcities/include/i2c.h @@ -0,0 +1,12 @@ +#ifndef I2C_H +#define I2C_H + +void I2C1_init(); +void I2C_start(I2C_TypeDef* I2Cx, uint8_t address, uint8_t direction); +void I2C_stop(I2C_TypeDef* I2Cx); +void I2C_write(I2C_TypeDef* I2Cx, uint8_t data); +uint8_t I2C_read_ack(I2C_TypeDef* I2Cx); +uint8_t I2C_read_nack(I2C_TypeDef* I2Cx); + +#endif +