I2C Problem

Hi all

I have a problem width 2406B i2c mode . I now alway get a error message -1 (WM_BUS_MODE_UNKNOWN_TYPE)

WHY ?

I not understood these problem .

So what Open Mode type are you using?

Hi,

In fact, I have the same problem on my Q2501B.
I call :
adl_busSubscribe(ADL_BUS_TYPE_I2C_SOFT | adresse, ADL_IO_ID_U32_TO_U16(SDA_IO) | (ADL_IO_ID_U32_TO_U16(SCL_IO)<<16) );

and when I try a adl_busWrite or a adl_busRead I have this WM_BUS_MODE_UNKNOWN_TYPE answer.

I see no way to specify a BUS MODE in ADL library.

Is that the same problem as yours?
Have you already solved it?

I also tried to use wm functions to indicate clearly the bus mode, but as all my program use ADL, I have links errors.
Do you know a way to link with wm library without making multiple references errors?

Thanks in advance for your help

Hello…

I am facing the same problem with a Q2406B module with 6.57c firmware version (ADL version 3.12) when trying to use an I2C_HARD_BUS. Although adl_busSubscribe function succeeds subsequent adl_busRead and adl_busWrite function calls return -1 (WM_BUS_MODE_UNKNOWN_TYPE). I really don’t know what this error might be suggesting… As david says, there is no obvious way to specify a bus mode for I2C communication through ADL bus service routines…

Any hint would be really appreciated… :confused:
George

Hi All,
Can any one help on this issue please. I am also facing the same problem. adl_busSubscribe return 0 as handle for this code.

BusHandle =  adl_busSubscribe ( ADL_BUS_TYPE_I2C_SOFT  | BusSettings.Addr,ADL_IO_ID_U32_TO_U16 ( BusSettings.I2CSDA)
                                 | ( ADL_IO_ID_U32_TO_U16 (BusSettings.I2CSCL ) << 16 ) );

But when I attempt to write/read the bus it return -1 (WM_BUS_MODE_UNKNOWN_TYPE )

may I know what’s wrong with the following code?

u8 WriteData;
	
	writeReturn  = adl_busRead ( (u8)BusHandle, (adl_busAccess_t *)NULL,( u32) DATA_LENGTH , (void *) &WriteData);
	change = !change;
	if (change)
	{
		WriteData = 0x08;
		writeReturn = adl_busWrite ( (u8)BusHandle, (adl_busAccess_t *)NULL,( u32) DATA_LENGTH , (void *) &WriteData );

Do wavecom have any documentation on this? Is this a bug in Open AT

Rather than spamming this all over the forums:
wavecom.com/modules/movie/sc … php?p=6788
wavecom.com/modules/movie/sc … php?t=1858

How about adding some of the missing details, like:

:question: How is BusHandle defined?

:question: How is BusSettings defined?

:question: What values have you set into BusSettings.I2CSDA and BusSettings.I2CSCL ?

:question: How is writeReturn defined?

etc, etc…

Dear ALL,
here is the Working code avaialable for I2C, Great Thanks to C. GURUPRASAD ,Manager all INDIA(Technical) from Fargo Telecom. India,Bangalore. Code is Written for PCF8574,4port as Input & for as Output

#include "adl_global.h"

#define DATA_LENGTH 1	//Bytes	

u32 wm_apmCustomStack [ 256 ];
const u16 wm_apmCustomStackSize = sizeof ( wm_apmCustomStack );


s8 BusHandle ;					//	i2c bus handle

union 
{
	u8 sByte;
	struct
	{
		u8 P00 :1;
		u8 P01 :1;
		u8 P02 :1;
		u8 P03 :1;
		u8 P04 :1;
		u8 P05 :1;
		u8 P06 :1;
		u8 P07 :1;
	}portBit;
	

}WriteData,tempWriteData;   /////// This is to address the Individual Bits of the Port.

s8 IO_ExpanderSlvAddr;
s8 writeReturn=0;

ascii port[2];

bool myhandler(ascii *UnSostr, adl_atUnSoHandler_t UnSohdl)
{

	TRACE (( 1, "Wind 12" ));

	adl_busRead ( (u8)BusHandle, (adl_busAccess_t *)NULL,( u32) DATA_LENGTH , (void *) &tempWriteData);

	if(WriteData.portBit.P00!=tempWriteData.portBit.P00)
	{
		TRACE (( 1, "Port 0 Status Changed" ));
		WriteData.portBit.P00=tempWriteData.portBit.P00;
		return TRUE;
	}
	
	if(WriteData.portBit.P01!=tempWriteData.portBit.P01)
	{
		TRACE (( 1, "Port 1 Status Changed" ));
		WriteData.portBit.P01=tempWriteData.portBit.P01;
		return TRUE;
	}

	if(WriteData.portBit.P02!=tempWriteData.portBit.P02)
	{
		TRACE (( 1, "Port 2 Status Changed" ));
		WriteData.portBit.P02=tempWriteData.portBit.P02;
		return TRUE;
	}

	if(WriteData.portBit.P03!=tempWriteData.portBit.P03)
	{
		TRACE (( 1, "Port 3 Status Changed" ));
		WriteData.portBit.P03 = tempWriteData.portBit.P03;
		return TRUE;
	}
}


bool bootConfig(u8 ID)
{

	IO_ExpanderSlvAddr	= 0x20;						  // Slave address ( Expander )  

	BusHandle =  adl_busSubscribe ( ADL_BUS_TYPE_I2C_HARD|IO_ExpanderSlvAddr,ADL_BUS_I2C_HARD_CLK_FAST );

	
	
	adl_atUnSoSubscribe("+WIND: 12",myhandler);

	return TRUE;  
}
void makeHighhandler(adl_atCmdPreParser_t *command)
{
	u8 switchCase;

	TRACE (( 1, "Inside High Handler" ));
	
	wm_strcpy(port,ADL_GET_PARAM(command,0));
	

	switchCase =(u8)port[0];


	switch(switchCase)
	{
		case '4':
			WriteData.portBit.P04=1;
			TRACE((1,"%d",WriteData.sByte));
			adl_busWrite ( 
							(u8)BusHandle, 
							(adl_busAccess_t *)NULL,
							( u32) DATA_LENGTH , 
							(void *) &WriteData 
						 );
		break;

		case '5':
			WriteData.portBit.P05=1;
			adl_busWrite ( 
							(u8)BusHandle, 
							(adl_busAccess_t *)NULL,
							( u32) DATA_LENGTH , 
							(void *) &WriteData 
						 );
			TRACE((1,"%d",WriteData.sByte));
		break;
		case '6':
			WriteData.portBit.P06=1;
			adl_busWrite ( 
							(u8)BusHandle, 
							(adl_busAccess_t *)NULL,
							( u32) DATA_LENGTH , 
							(void *) &WriteData 
						 );
			TRACE((1,"%d",WriteData.sByte));
		break;
		case '7':
			WriteData.portBit.P07=1;
			adl_busWrite ( 
							(u8)BusHandle, 
							(adl_busAccess_t *)NULL,
							( u32) DATA_LENGTH , 
							(void *) &WriteData 
						 );
			TRACE((1,"%d",WriteData.sByte));
		break;
	}
}  


void makeLowhandler(adl_atCmdPreParser_t *command)
{
	u8 switchCase;

	TRACE (( 1, "Inside Low Handler" ));
	
	wm_strcpy(port,ADL_GET_PARAM(command,0));
	

	switchCase =(u8)port[0];


	switch(switchCase)
	{
		case '4':
			WriteData.portBit.P04=0;
			TRACE((1,"%d",WriteData.sByte));
			adl_busWrite ( 
							(u8)BusHandle, 
							(adl_busAccess_t *)NULL,
							( u32) DATA_LENGTH , 
							(void *) &WriteData 
						 );
		break;

		case '5':
			WriteData.portBit.P05=0;
			adl_busWrite ( 
							(u8)BusHandle, 
							(adl_busAccess_t *)NULL,
							( u32) DATA_LENGTH , 
							(void *) &WriteData 
						 );
			TRACE((1,"%d",WriteData.sByte));
		break;
		case '6':
			WriteData.portBit.P06=0;
			adl_busWrite ( 
							(u8)BusHandle, 
							(adl_busAccess_t *)NULL,
							( u32) DATA_LENGTH , 
							(void *) &WriteData 
						 );
			TRACE((1,"%d",WriteData.sByte));
		break;
		case '7':
			WriteData.portBit.P07=0;
			adl_busWrite ( 
							(u8)BusHandle, 
							(adl_busAccess_t *)NULL,
							( u32) DATA_LENGTH , 
							(void *) &WriteData 
						 );
			TRACE((1,"%d",WriteData.sByte));
		break;
	}
}  



void adl_main ( adl_InitType_e InitType )
{
    TRACE (( 1, "Embedded Application : Main" ));
    // TO DO : Add your initialization code here
	adl_tmrSubscribe(FALSE,10,ADL_TMR_TYPE_100MS,(adl_tmrHandler_t) bootConfig );
	if(adl_atCmdSubscribe("AT+HIGH",makeHighhandler,ADL_CMD_TYPE_PARA|0x0011)==OK)
		TRACE((1,"AT+HIGH subscribed successfully"));
	if(adl_atCmdSubscribe("AT+LOW",makeLowhandler,ADL_CMD_TYPE_PARA|0x0011)==OK)
		TRACE((1,"AT+LOW subscribed successfully"));
	WriteData.sByte = 255;

	adl_busWrite ( 
					(u8)BusHandle, 
					(adl_busAccess_t *)NULL,
					( u32) DATA_LENGTH , 
					(void *) &WriteData );
	
				 
	wm_strcpy(port,"GU");
}
[/quote]

ALL,

seems like I’ve posted my question in wrong forum (viewtopic.php?f=37&t=1899). It is about safe block size that can be sent over hardware I2C to an LCD. So far even small amounts of data (8 bytes or less) sometimes are not transferred properly, with the sequence being aborted after a few bytes have been sent, and sometimes right in the middle of the data byte.

The module is Q24PL, firmware is 6.57c, OAT 3.13.

Has anyone seen similar problems? Is there any hope to see I2C working properly, or shall we switch to SPI instead?

Hello…

If error -1 is what you get, take a look at Wavecom support team’s answer to my question about this error…
It is a known bug and they have already planned a solution (not soon enough, I am afraid…)

This is because, there is a known limitation about the adl_busRead () and adl_busWrite () returning error -1 when the adl_busRead () and adl_busWrite () for the I2C Hard bus are called repeatedly (even when using a timer). In this case, the adl_busRead () starts failing randomly after a number of successful bus reads.

It should be noted that the ADL library returns the error -1 as a result of adl_busRead () or adl_busWrite () when it does not receive an acknowledgement from the external I2C device within a predefined time interval.

For your information, when the reading from the I2C bus has to be performed, internally, the I2C block driver sends the start bit followed by the address, followed by the R/W bit. After sending this information, it starts waiting for a response from the I2C block driver to acknowledge that the address and start stop bit and R/W bit is received by the connected device. The I2C block driver waits for 700 microseconds for receiving the response from the I2C block. In case, no response is received, it returns error -1.

When the writing to the I2C bus has to be performed, internally, the I2C block driver sends the start bit followed by the address followed by the R/W bit. After sending this information, it starts waiting for a response from the I2C block driver to acknowledge the address , start/stop and R/W bit. If the response is not received within 200 microseconds, the driver sends the error -1.

The current limitation occurs because of the predefined timeouts that are used by the I2C block. Once, these timeouts are removed and we use an interrupt based scheme (where instead of timeout the acknowledgement will provide an interrupt), all work fine!

And in another e-mail they say that the problem will be fixed at version 6.57f :open_mouth: :angry:

The final solution will be provided only when the tracker CUS41064 is fixed (planed for 6.57f)
The correction is not available yet, I will let you know as soon as I get it.

We have decided to use the software I2C bus instead, at least for the time being… It may be much slower but it at least works… :frowning:

George

Hello George,

Thanks for answering. Now that it took quite a while for 6.57e to come out (this December), I’m afraid 6.57f won’t appear anytime soon.

As for software I2C, do you mean using ADL bus service with ADL_BUS_TYPE_I2C_SOFT, or writing own implementation of I2C protocol using couple of spare GPIOs? We cannot use ADL_BUS_TYPE_I2C_SOFT since our software takes use of both UARTs, 1 and 2, and this leaves us no available GPIO pins on a Q24PL (please correct me if I am wrong here).

Hello t9

What we did was the second option you mention (used a couple of spare GPIO pins).
I suppose that it depends on your hardware if there are any available GPIO pins in your case…
We don’t use UART2 but as the ADL user’s manual mentions, 4 GPIO pins are occupied when UART2 is used.
How about the remaining 4 GPIO pins?

George

Hello George,

according to “AT Commands Interface Guide for Open AT Firmware v6.57d”, 15.9.1, when UART2 is activated, GPIO 0 and GPIO 5 as well as GPO 2 and GPI can no longer be used.

The only GPIO left (not multiplexed) is GPIO 4. GPIO 1, GPIO 2 and GPIO 3 are said to be busy with FLASH LED, RI1 and DCD1 signals.

GPO 0 (SPI_AUX) and GPO 3 (SPI_EN) probably would fit, provided SPI bus is not used. I’ll check them out, thanks!

Hello t9

I’m afraid you can’t use 2 output GPIO pins (GPO) for I2C operation… One of them (the I2C data pin) has to be an input/output pin…
Are you sure about GPIO pins 1-4? I can’t find any special feature for them in “ADL User Guide for Open AT OS v3.13”…

George

Hello t9

I think you are right about pins GPIO 1, GPIO 2 and GPIO 3…
On the other hand, pin GPIO 4 is probably available…

George

Hello George,

I wonder if SPI_AUX and SPI_EN pins can be used as non-dedicated General Purpose IO. Will give them a try.