Duggle Posted March 15, 2012 Report Share Posted March 15, 2012 I've got some micro controllers in a sensor network attached to the I2C bus. The bus master is a STM32 core at the moment. Prior to talking with the sensors over the I2C (which is working great btw) I want to go into an "address assignment" mode. This involves placing a series of clock pulses on the SCL line. The sensors listen to the clock pulses and output (Open Drain) on the SDA line at the rising edge of the clock. They actually output a unique serial number over 32 clock pulses. On the falling edge they read the state of the SDA line. If the bit of the serial number is high, but the sensor reads low, then the sensor "drops out" until the next 32bits are clocked. If a sensor has not dropped out by the end of the 32nd bit, it's I2C address is the count. It then drops out. The core finishes enumerating when it reads 0xffffffff. This means that all of the devices on the bus has a unique I2C address. Ive searched the mios files and found a confusing array of GPIO functions and structures. I want to make SCL of I2C port 1 an open drain (or pushpull) output.make it go high and lowmake the SDA pin an inputread the state of the SDA pinInitialise the I2C port and use it in the usual wayAny hints greatfully accepted! Quote Link to comment Share on other sites More sharing options...
TK. Posted March 15, 2012 Report Share Posted March 15, 2012 For such a purpose you can re-use some code from MIOS32_IIC_TransferWait // added by wackazong // see also http://midibox.org/forums/topic/15770-sda-stuck-low-on-i2c-transfer/ // try to deblock a SDA line that is stuck low by bit-banging out a clock signal // and waiting until the send buffer of any slave is empty // disable interrupts I2C_ITConfig(iicx->base, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR, DISABLE); I2C_Cmd(I2C2, DISABLE); GPIO_InitTypeDef GPIO_InitStructure; // reconfigure IIC pins to push pull GPIO_StructInit(&GPIO_InitStructure); GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Pin = MIOS32_IIC0_SCL_PIN; GPIO_Init(MIOS32_IIC0_SCL_PORT, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = MIOS32_IIC0_SDA_PIN; GPIO_Init(MIOS32_IIC0_SDA_PORT, &GPIO_InitStructure); u32 i; for (i=0; i<16; i++) { /*Reset the SDA Pin*/ GPIO_ResetBits(GPIOB, MIOS32_IIC0_SDA_PIN); MIOS32_DELAY_Wait_uS(1000); /*Reset the SCL Pin*/ GPIO_ResetBits(GPIOB, MIOS32_IIC0_SCL_PIN); MIOS32_DELAY_Wait_uS(1000); /*Set the SCL Pin*/ GPIO_SetBits(GPIOB, MIOS32_IIC0_SCL_PIN); MIOS32_DELAY_Wait_uS(1000); /*Set the SDA Pin*/ GPIO_SetBits(GPIOB, MIOS32_IIC0_SDA_PIN); MIOS32_DELAY_Wait_uS(1000); } GPIO_StructInit(&GPIO_InitStructure); GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; GPIO_InitStructure.GPIO_Pin = MIOS32_IIC0_SCL_PIN; GPIO_Init(MIOS32_IIC0_SCL_PORT, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = MIOS32_IIC0_SDA_PIN; GPIO_Init(MIOS32_IIC0_SDA_PORT, &GPIO_InitStructure); I2C_Cmd(I2C2, ENABLE); // re-initialize peripheral MIOS32_IIC_InitPeripheral(iic_port); [/code] For Open Drain mode, use GPIO_Mode_Out_OD instead of GPIO_Mode_Out_PP For input mode, use GPIO_Mode_IN_FLOATING (No pull device necessary, since the pin is pulled externally) Reading the pin: e.g. with GPIO_ReadOutputDataBit(GPIOB, MIOS32_IIC0_SDA_PIN); If you want to use direct access instead of these low-level driver functions, have a look into the perfectly documented low-level driver under $MIOS32_PATH/drivers/STM32F10x/v3.3.0/STM32F10x_StdPeriph_Driver/src/stm32f10x_gpio.c For accessing the pins of the second port, use MIOS32_IIC1* defines instead. They are only defined in mios32_iic.c internally - you have to copy them into your application (they will make your application device dependent anyhow) Best Regards, Thorsten. Quote Link to comment Share on other sites More sharing options...
Duggle Posted March 15, 2012 Author Report Share Posted March 15, 2012 Thank you so much! I'll study this carefully, but a quick question I haven't been able to sort out: On what pins/port of core STM32 is the second IIC port? Quote Link to comment Share on other sites More sharing options...
TK. Posted March 18, 2012 Report Share Posted March 18, 2012 Thank you so much! I'll study this carefully, but a quick question I haven't been able to sort out: On what pins/port of core STM32 is the second IIC port? They are here: #define MIOS32_IIC1_SCL_PORT GPIOB #define MIOS32_IIC1_SCL_PIN GPIO_Pin_6 #define MIOS32_IIC1_SDA_PORT GPIOB #define MIOS32_IIC1_SDA_PIN GPIO_Pin_7 [/code] -> search in http://www.ucapps.de/mbhp/mbhp_core_stm32_v2.pdf for PB6 and PB7 -> J19:SI and J19:SC Best Regards, Thorsten. Quote Link to comment Share on other sites More sharing options...
Duggle Posted March 19, 2012 Author Report Share Posted March 19, 2012 Thanks, I think I'll change to using this second port for the sensor network. Im using an extra GPIO port pin to switch bus power on and off, in order to reset the sensors and put them in the address assignment state (part of their bootloader). This means just one connector for both IIC and power switch (J19 as it happens). The normal fixed address IIC devices can be attached to first IIC port. I've got the address assignment part working well using the Transferwait code as a template. Your hint has saved me LOTs of time, so thanks again! (I'll post some code soon in case anyone is interested). Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.