cancel
Showing results for 
Search instead for 
Did you mean: 

I2c event problem

niklascooke1
Associate II
Posted on August 31, 2009 at 15:14

I2c event problem

5 REPLIES 5
niklascooke1
Associate II
Posted on May 17, 2011 at 13:17

Hello everybody!

Im trying to communicate with a DAC5574ID, but im having truble with

the while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); it stays in this loop!

im using Crossworks 1.7 , FW lib 3.1

Code:

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

/* GPIOA clock enable */

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOD|

RCC_APB2Periph_ADC1|RCC_APB2Periph_TIM1|RCC_APB2Periph_USART1|RCC_APB2Periph_AFIO, ENABLE);

RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);

// i2c

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;

GPIO_Init(GPIOB, &GPIO_InitStructure);

I2C_DeInit(I2C1);

I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;

I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;

I2C_InitStructure.I2C_OwnAddress1 = 0x10;

I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;

I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;

I2C_InitStructure.I2C_ClockSpeed = 200000;

I2C_Init(I2C1, &I2C_InitStructure);

I2C_Cmd(I2C1,ENABLE);

void DAC5574Write(int addr, int data){

I2C_GenerateSTART(I2C1, ENABLE);

/* Test on EV5 and clear it */

while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));

/* Send EEPROM address for write */

I2C_Send7bitAddress(I2C1, addr, I2C_Direction_Transmitter);

/* Test on EV6 and clear it */

while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

/* Send the EEPROM's internal address to write to */

I2C_SendData(I2C1, 0x10);

/* Test on EV8 and clear it */

while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

/* Send the byte to be written */

I2C_SendData(I2C1, data);

/* Test on EV8 and clear it */

while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

/* Send the byte to be written */

I2C_SendData(I2C1, 0x80);

/* Test on EV8 and clear it */

while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

/* Send STOP condition */

I2C_GenerateSTOP(I2C1, ENABLE);

}

// Code

Help me please ! Ive seen that many others had problem with the flags but im a newbie with STM32!

Regards Niklas

jj
Associate II
Posted on May 17, 2011 at 13:17

Don't have a specific ''fix'' for you - perhaps this may help:

a) Ref Manual RM0008 may provide added detail/help for you

b) Read/re-read Errata for your specific device - maybe there is conflict upon one/several I2C pins

c) should (a & b) fail - why not ''comment out'' offending EV6 and see if remainder of code completes? (you may get lucky and really not need - or you can develop a work-around

d) perhaps your optimizations are too high. dial them back and see if offender then works

e) have you a simpler I2C device? We've ''lucked into solutions'' often by using the simplest test - slowly/methodically discovering what is needed to ''make it work'' - and then adapting to the ''real target'' device...

Good luck...

ccowdery9
Associate III
Posted on May 17, 2011 at 13:17

Search the forum for IIC threads. There's quite a few as the IIC interface is not particularly good.

Chris.

dmatheis
Associate II
Posted on May 17, 2011 at 13:17

Hi niklascooke,

could you solve the problem? I'm interested in your solution if you got one, because I'll have the same problem ... :-[

guyvo67
Associate II
Posted on May 17, 2011 at 13:17

Nicolas,

I did quit a lot on testing the I2C for cortex recently. My tests were limited to address an other cortex on the same bus using both I2C1/2 interfaces. One thing I can say it's very time critical on the cortex doing it with the native hardware registers.

In event mode you must be careful with timings in respect to the event polling. If you have eg also an RTOS running it's much better to move over the I2C completely interrupt based so you get no site effects of context switches and other RTOS related kernel tasks.

But I tested both event driven and interrupt driven. The event driven worked from cortex to cortex without any RTOS running. With eg free RTOS running I got some problems. My test was halted after a few minutes. Never got a nice running over night loop transferring 84 bytes of the BKP domain.

The interrupt based approach however works much better. You can have an RTOS running with high priorities masked out without any problem. But it must be done at the highest priority (zero on the cortex) especially on the receiver site when you have also other interrupts like ADC or timings running. But I ran a test TX/RX 84 bytes every 100ms started from a free RTOS task for 24h all interrupt based without any halts.

I can't see any problems in your code snippet you posted here. But be aware to feed the good address of your DAC5574. I saw that you put your cortex on the same address as the internal DAC address but that can be the problem as this is consider as data anyway. Although perhaps it's better to take another one for clearness.

I personally used pull-up resistor of 2.2K which gives good signal form with speeds like 100/200k. If you rather would like to work with 400k than it's better to lower the pull-up. Depends also on the distance and bus load of course.

But if are not running any other code just the test you showed in the main this should work. Maybe you can try with the interrupt approach too. It isn't that hard to start from a ST example and rework it I think. And check the specifications of DAC chip with respect in order and ACK to address / regs / data stream. I know there 're I2C devices that like to have restarts and stuffs so be careful.

Keep us posted on the results.

Cheers

Guy