I2C for LM3S devices

classic Classic list List threaded Threaded
4 messages Options
Laurent Dufrechou Laurent Dufrechou
Reply | Threaded
Open this post in threaded view
|

I2C for LM3S devices

Hi all,

 

I’m new to this dev list.

I’ve just ported eLua for LM3S9B96 and my board.

I’m willing to put I2C code in place for lm3s devices.

 

I’ve got a little problem with current API definition.

lm3s have a sort of i2c automata that don’t give you direct control of sending start/stop signals.

 

Quoting the doc:

**************************************************************************

Master Operations

When using this API to drive the I2C master module, the user must first initialize the I2C master

module with a call to ROM_I2CMasterInitExpClk(). That function will set the bus speed and enable

the master module.

The user may transmit or receive data after the successful initialization of the I2C master module.

Data is transferred by first setting the slave address using ROM_I2CMasterSlaveAddrSet(). That

function is also used to define whether the transfer is a send (a write to the slave from the master) or

a receive (a read from the slave by the master). Then, if connected to an I2C bus that has multiple

masters, the Stellaris I2C master must first call ROM_I2CMasterBusBusy() before attempting to

initiate the desired transaction. After determining that the bus is not busy, if trying to send data, the

user must call the ROM_I2CMasterDataPut() function. The transaction can then be initiated on the

bus by calling the ROM_I2CMasterControl() function with any of the following commands:

I2C_MASTER_CMD_SINGLE_SEND

I2C_MASTER_CMD_SINGLE_RECEIVE

I2C_MASTER_CMD_BURST_SEND_START

I2C_MASTER_CMD_BURST_RECEIVE_START

Any of those commands will result in the master arbitrating for the bus, driving the start sequence

onto the bus, and sending the slave address and direction bit across the bus. The remainder of the

transaction can then be driven using either a polling or interrupt-driven method.

For the single send and receive cases, the polling method will involve looping on the return

from ROM_I2CMasterBusy(). Once that function indicates that the I2C master is

no longer busy, the bus transaction has been completed and can be checked for errors

March 21, 2011 123

Inter-Integrated Circuit (I2C)

using ROM_I2CMasterErr(). If there are no errors, then the data has been sent or is

ready to be read using ROM_I2CMasterDataGet(). For the burst send and receive cases,

the polling method also involves calling the ROM_I2CMasterControl() function for each

byte transmitted or received (using either the I2C_MASTER_CMD_BURST_SEND_CONT

or I2C_MASTER_CMD_BURST_RECEIVE_CONT commands), and for the last byte

sent or received (using either the I2C_MASTER_CMD_BURST_SEND_FINISH or

I2C_MASTER_CMD_BURST_RECEIVE_FINISH commands). If any error is detected

during the burst transfer, the ROM_I2CMasterControl() function should be called using

the appropriate stop command (I2C_MASTER_CMD_BURST_SEND_ERROR_STOP or

I2C_MASTER_CMD_BURST_RECEIVE_ERROR_STOP).

For the interrupt-driven transaction, the user must register an interrupt handler for the I2C devices

and enable the I2C master interrupt; the interrupt will occur when the master is no longer busy.

**************************************************************************

 

As you can see,

A better API for _it_ would be something like:

setI2C address( address, read_write)

send_byte( data)

send_multiples_bytes( *data[], length )

receive_byte( data)

receive_multiples_bytes( *data[], length )

 

Is there a strict need of giving user access to start/stop control?

I mean start/stop can be easily embedded into send/receive function no?

 

Any suggestions welcomed J

 

Regards,

 

Laurent


_______________________________________________
eLua-dev mailing list
[hidden email]
https://lists.berlios.de/mailman/listinfo/elua-dev
Laurent Dufrechou Laurent Dufrechou
Reply | Threaded
Open this post in threaded view
|

Re: I2C for LM3S devices

Just to add more idea, I got a I2C lib with these functions:

 

extern tBool I2CC0M_ReadRegister(u32 base, u8 address, u8 reg, u8* pdata);

extern tBool I2CC0M_ReadMultiple(u32 base, u8 address, u8 reg, u8* pdata, u8 length);

extern tBool I2CCOM_WriteRegister(u32 base, u8 address, u8 reg, u8 data);

extern tBool I2CC0M_WriteMultiple(u32 base, u8 address, u8 reg, u8* pdata, u8 length);

 

Low level protocol handling is hidden inside these functions.

In my usecase, user only want to send to and read from a specific address.

 

This can also be reduced to a set of two function if length is set to 1.

And as Lua seems to support variable length function, it could be quite interesting…

 

Laurent

 

De : Laurent Dufrechou [mailto:[hidden email]]
Envoyé : dimanche 5 juin 2011 14:16
À : '[hidden email]'
Objet : I2C for LM3S devices

 

Hi all,

 

I’m new to this dev list.

I’ve just ported eLua for LM3S9B96 and my board.

I’m willing to put I2C code in place for lm3s devices.

 

I’ve got a little problem with current API definition.

lm3s have a sort of i2c automata that don’t give you direct control of sending start/stop signals.

 

Quoting the doc:

**************************************************************************

Master Operations

When using this API to drive the I2C master module, the user must first initialize the I2C master

module with a call to ROM_I2CMasterInitExpClk(). That function will set the bus speed and enable

the master module.

The user may transmit or receive data after the successful initialization of the I2C master module.

Data is transferred by first setting the slave address using ROM_I2CMasterSlaveAddrSet(). That

function is also used to define whether the transfer is a send (a write to the slave from the master) or

a receive (a read from the slave by the master). Then, if connected to an I2C bus that has multiple

masters, the Stellaris I2C master must first call ROM_I2CMasterBusBusy() before attempting to

initiate the desired transaction. After determining that the bus is not busy, if trying to send data, the

user must call the ROM_I2CMasterDataPut() function. The transaction can then be initiated on the

bus by calling the ROM_I2CMasterControl() function with any of the following commands:

I2C_MASTER_CMD_SINGLE_SEND

I2C_MASTER_CMD_SINGLE_RECEIVE

I2C_MASTER_CMD_BURST_SEND_START

I2C_MASTER_CMD_BURST_RECEIVE_START

Any of those commands will result in the master arbitrating for the bus, driving the start sequence

onto the bus, and sending the slave address and direction bit across the bus. The remainder of the

transaction can then be driven using either a polling or interrupt-driven method.

For the single send and receive cases, the polling method will involve looping on the return

from ROM_I2CMasterBusy(). Once that function indicates that the I2C master is

no longer busy, the bus transaction has been completed and can be checked for errors

March 21, 2011 123

Inter-Integrated Circuit (I2C)

using ROM_I2CMasterErr(). If there are no errors, then the data has been sent or is

ready to be read using ROM_I2CMasterDataGet(). For the burst send and receive cases,

the polling method also involves calling the ROM_I2CMasterControl() function for each

byte transmitted or received (using either the I2C_MASTER_CMD_BURST_SEND_CONT

or I2C_MASTER_CMD_BURST_RECEIVE_CONT commands), and for the last byte

sent or received (using either the I2C_MASTER_CMD_BURST_SEND_FINISH or

I2C_MASTER_CMD_BURST_RECEIVE_FINISH commands). If any error is detected

during the burst transfer, the ROM_I2CMasterControl() function should be called using

the appropriate stop command (I2C_MASTER_CMD_BURST_SEND_ERROR_STOP or

I2C_MASTER_CMD_BURST_RECEIVE_ERROR_STOP).

For the interrupt-driven transaction, the user must register an interrupt handler for the I2C devices

and enable the I2C master interrupt; the interrupt will occur when the master is no longer busy.

**************************************************************************

 

As you can see,

A better API for _it_ would be something like:

setI2C address( address, read_write)

send_byte( data)

send_multiples_bytes( *data[], length )

receive_byte( data)

receive_multiples_bytes( *data[], length )

 

Is there a strict need of giving user access to start/stop control?

I mean start/stop can be easily embedded into send/receive function no?

 

Any suggestions welcomed J

 

Regards,

 

Laurent


_______________________________________________
eLua-dev mailing list
[hidden email]
https://lists.berlios.de/mailman/listinfo/elua-dev
Laurent Dufrechou Laurent Dufrechou
Reply | Threaded
Open this post in threaded view
|

Re: I2C for LM3S devices

In reply to this post by Laurent Dufrechou
Forget my previous email it is too specific to my i2c chips.

 

Just to clarify my issue,

 

LM3S device works like this:

 

setI2C address( address, read_write) -> set address in a specific register

 

then you do either:

sendSingle/receive single -> send start, address and send or receive a
single byte and send stop

 

or in case of long transfer you would do:

 

sendStart or receiveStart -> send start + address + send/receive data

then do multiple times:

sendContinous or receiveContinous -> start(?) + send/receive next data

then finish with:

sendfinish or receiveFinish -> send/receive next data + stop bit

 

As you can see the idea of start/stop is merged with send/receiving notion,
and I hardly see how to match current API.

(Current API is ok for me (quite logical), just LM3S behavior is hard to
match with it...)

 

Any idea welcomed...

Ps: Perhaps I'm wrong somewhere, I'm open to any remarks.

 

Laurent

 

De : Laurent Dufrechou [mailto:[hidden email]]
Envoyé : dimanche 5 juin 2011 15:03
À : 'Laurent Dufrechou'; [hidden email]
Objet : RE: I2C for LM3S devices

 

Just to add more idea, I got a I2C lib with these functions:

 

extern tBool I2CC0M_ReadRegister(u32 base, u8 address, u8 reg, u8* pdata);

extern tBool I2CC0M_ReadMultiple(u32 base, u8 address, u8 reg, u8* pdata, u8
length);

extern tBool I2CCOM_WriteRegister(u32 base, u8 address, u8 reg, u8 data);

extern tBool I2CC0M_WriteMultiple(u32 base, u8 address, u8 reg, u8* pdata,
u8 length);

 

Low level protocol handling is hidden inside these functions.

In my usecase, user only want to send to and read from a specific address.

 

This can also be reduced to a set of two function if length is set to 1.

And as Lua seems to support variable length function, it could be quite
interesting...

 

Laurent

 

De : Laurent Dufrechou [mailto:[hidden email]]
Envoyé : dimanche 5 juin 2011 14:16
À : '[hidden email]'
Objet : I2C for LM3S devices

 

Hi all,

 

I'm new to this dev list.

I've just ported eLua for LM3S9B96 and my board.

I'm willing to put I2C code in place for lm3s devices.

 

I've got a little problem with current API definition.

lm3s have a sort of i2c automata that don't give you direct control of
sending start/stop signals.

 

Quoting the doc:

**************************************************************************

Master Operations

When using this API to drive the I2C master module, the user must first
initialize the I2C master

module with a call to ROM_I2CMasterInitExpClk(). That function will set the
bus speed and enable

the master module.

The user may transmit or receive data after the successful initialization of
the I2C master module.

Data is transferred by first setting the slave address using
ROM_I2CMasterSlaveAddrSet(). That

function is also used to define whether the transfer is a send (a write to
the slave from the master) or

a receive (a read from the slave by the master). Then, if connected to an
I2C bus that has multiple

masters, the Stellaris I2C master must first call ROM_I2CMasterBusBusy()
before attempting to

initiate the desired transaction. After determining that the bus is not
busy, if trying to send data, the

user must call the ROM_I2CMasterDataPut() function. The transaction can then
be initiated on the

bus by calling the ROM_I2CMasterControl() function with any of the following
commands:

I2C_MASTER_CMD_SINGLE_SEND

I2C_MASTER_CMD_SINGLE_RECEIVE

I2C_MASTER_CMD_BURST_SEND_START

I2C_MASTER_CMD_BURST_RECEIVE_START

Any of those commands will result in the master arbitrating for the bus,
driving the start sequence

onto the bus, and sending the slave address and direction bit across the
bus. The remainder of the

transaction can then be driven using either a polling or interrupt-driven
method.

For the single send and receive cases, the polling method will involve
looping on the return

from ROM_I2CMasterBusy(). Once that function indicates that the I2C master
is

no longer busy, the bus transaction has been completed and can be checked
for errors

March 21, 2011 123

Inter-Integrated Circuit (I2C)

using ROM_I2CMasterErr(). If there are no errors, then the data has been
sent or is

ready to be read using ROM_I2CMasterDataGet(). For the burst send and
receive cases,

the polling method also involves calling the ROM_I2CMasterControl() function
for each

byte transmitted or received (using either the
I2C_MASTER_CMD_BURST_SEND_CONT

or I2C_MASTER_CMD_BURST_RECEIVE_CONT commands), and for the last byte

sent or received (using either the I2C_MASTER_CMD_BURST_SEND_FINISH or

I2C_MASTER_CMD_BURST_RECEIVE_FINISH commands). If any error is detected

during the burst transfer, the ROM_I2CMasterControl() function should be
called using

the appropriate stop command (I2C_MASTER_CMD_BURST_SEND_ERROR_STOP or

I2C_MASTER_CMD_BURST_RECEIVE_ERROR_STOP).

For the interrupt-driven transaction, the user must register an interrupt
handler for the I2C devices

and enable the I2C master interrupt; the interrupt will occur when the
master is no longer busy.

**************************************************************************

 

As you can see,

A better API for _it_ would be something like:

setI2C address( address, read_write)

send_byte( data)

send_multiples_bytes( *data[], length )

receive_byte( data)

receive_multiples_bytes( *data[], length )

 

Is there a strict need of giving user access to start/stop control?

I mean start/stop can be easily embedded into send/receive function no?

 

Any suggestions welcomed J

 

Regards,

 

Laurent


_______________________________________________
eLua-dev mailing list
[hidden email]
https://lists.berlios.de/mailman/listinfo/elua-dev

winmail.dat (17K) Download Attachment
Laurent Dufrechou Laurent Dufrechou
Reply | Threaded
Open this post in threaded view
|

Re: I2C for LM3S devices

In reply to this post by Laurent Dufrechou
Ok here is a proposal to allow the lm3s and str912 to work altogether:

 

void platform_i2c_send_start( unsigned id )

void platform_i2c_send_stop( unsigned id )

int platform_i2c_send_address( unsigned id, u16 address, int direction )

int platform_i2c_send_byte( unsigned id, u8 data )

int platform_i2c_recv_byte( unsigned id, int ack )

+

int platform_i2c_send_byte_and_stop( unsigned id, u8 data )

int platform_i2c_recv_byte_and_stop( unsigned id, int ack )

 

Adding the 2 functions xxx_and_stop  I was able to implement everything.

On LM3S send_start and send_stop is automatic.

On STR912 it could be added inside the functions thus we could end with:

 

int platform_i2c_start_and_send_address( unsigned id, u16 address, int
direction )

+

int platform_i2c_send_byte( unsigned id, u8 data )

int platform_i2c_recv_byte( unsigned id, int ack )

+

int platform_i2c_send_byte_and_stop( unsigned id, u8 data )

int platform_i2c_recv_byte_and_stop( unsigned id, int ack )

 

As a proposal we could put send_start inside start_and_send_address for
str912

And send_stop when user use the xxxx_and_stop.

 

So usage could be:

platform_i2c_start_and_send_address()

platform_i2c_send_byte_and_stop()

 

for address + single byte send

 

or

platform_i2c_start_and_send_address()

platform_i2c_send_byte()

platform_i2c_recv_byte()

platform_i2c_recv_byte()

platform_i2c_recv_byte()

platform_i2c_recv_byte_and_stop()

 

to send address + 1 data and receiving 4 data.

 

Am I missing any use case?

 

Laurent

 

De : Laurent Dufrechou [mailto:[hidden email]]
Envoyé : dimanche 5 juin 2011 16:34
À : '[hidden email]'
Objet : RE: I2C for LM3S devices

 

Forget my previous email it is too specific to my i2c chips.

 

Just to clarify my issue,

 

LM3S device works like this:

 

setI2C address( address, read_write) -> set address in a specific register

 

then you do either:

sendSingle/receive single -> send start, address and send or receive a
single byte and send stop

 

or in case of long transfer you would do:

 

sendStart or receiveStart -> send start + address + send/receive data

then do multiple times:

sendContinous or receiveContinous -> start(?) + send/receive next data

then finish with:

sendfinish or receiveFinish -> send/receive next data + stop bit

 

As you can see the idea of start/stop is merged with send/receiving notion,
and I hardly see how to match current API.

(Current API is ok for me (quite logical), just LM3S behavior is hard to
match with it...)

 

Any idea welcomed...

Ps: Perhaps I'm wrong somewhere, I'm open to any remarks.

 

Laurent

 

De : Laurent Dufrechou [mailto:[hidden email]]
Envoyé : dimanche 5 juin 2011 15:03
À : 'Laurent Dufrechou'; [hidden email]
Objet : RE: I2C for LM3S devices

 

Just to add more idea, I got a I2C lib with these functions:

 

extern tBool I2CC0M_ReadRegister(u32 base, u8 address, u8 reg, u8* pdata);

extern tBool I2CC0M_ReadMultiple(u32 base, u8 address, u8 reg, u8* pdata, u8
length);

extern tBool I2CCOM_WriteRegister(u32 base, u8 address, u8 reg, u8 data);

extern tBool I2CC0M_WriteMultiple(u32 base, u8 address, u8 reg, u8* pdata,
u8 length);

 

Low level protocol handling is hidden inside these functions.

In my usecase, user only want to send to and read from a specific address.

 

This can also be reduced to a set of two function if length is set to 1.

And as Lua seems to support variable length function, it could be quite
interesting...

 

Laurent

 

De : Laurent Dufrechou [mailto:[hidden email]]
Envoyé : dimanche 5 juin 2011 14:16
À : '[hidden email]'
Objet : I2C for LM3S devices

 

Hi all,

 

I'm new to this dev list.

I've just ported eLua for LM3S9B96 and my board.

I'm willing to put I2C code in place for lm3s devices.

 

I've got a little problem with current API definition.

lm3s have a sort of i2c automata that don't give you direct control of
sending start/stop signals.

 

Quoting the doc:

**************************************************************************

Master Operations

When using this API to drive the I2C master module, the user must first
initialize the I2C master

module with a call to ROM_I2CMasterInitExpClk(). That function will set the
bus speed and enable

the master module.

The user may transmit or receive data after the successful initialization of
the I2C master module.

Data is transferred by first setting the slave address using
ROM_I2CMasterSlaveAddrSet(). That

function is also used to define whether the transfer is a send (a write to
the slave from the master) or

a receive (a read from the slave by the master). Then, if connected to an
I2C bus that has multiple

masters, the Stellaris I2C master must first call ROM_I2CMasterBusBusy()
before attempting to

initiate the desired transaction. After determining that the bus is not
busy, if trying to send data, the

user must call the ROM_I2CMasterDataPut() function. The transaction can then
be initiated on the

bus by calling the ROM_I2CMasterControl() function with any of the following
commands:

I2C_MASTER_CMD_SINGLE_SEND

I2C_MASTER_CMD_SINGLE_RECEIVE

I2C_MASTER_CMD_BURST_SEND_START

I2C_MASTER_CMD_BURST_RECEIVE_START

Any of those commands will result in the master arbitrating for the bus,
driving the start sequence

onto the bus, and sending the slave address and direction bit across the
bus. The remainder of the

transaction can then be driven using either a polling or interrupt-driven
method.

For the single send and receive cases, the polling method will involve
looping on the return

from ROM_I2CMasterBusy(). Once that function indicates that the I2C master
is

no longer busy, the bus transaction has been completed and can be checked
for errors

March 21, 2011 123

Inter-Integrated Circuit (I2C)

using ROM_I2CMasterErr(). If there are no errors, then the data has been
sent or is

ready to be read using ROM_I2CMasterDataGet(). For the burst send and
receive cases,

the polling method also involves calling the ROM_I2CMasterControl() function
for each

byte transmitted or received (using either the
I2C_MASTER_CMD_BURST_SEND_CONT

or I2C_MASTER_CMD_BURST_RECEIVE_CONT commands), and for the last byte

sent or received (using either the I2C_MASTER_CMD_BURST_SEND_FINISH or

I2C_MASTER_CMD_BURST_RECEIVE_FINISH commands). If any error is detected

during the burst transfer, the ROM_I2CMasterControl() function should be
called using

the appropriate stop command (I2C_MASTER_CMD_BURST_SEND_ERROR_STOP or

I2C_MASTER_CMD_BURST_RECEIVE_ERROR_STOP).

For the interrupt-driven transaction, the user must register an interrupt
handler for the I2C devices

and enable the I2C master interrupt; the interrupt will occur when the
master is no longer busy.

**************************************************************************

 

As you can see,

A better API for _it_ would be something like:

setI2C address( address, read_write)

send_byte( data)

send_multiples_bytes( *data[], length )

receive_byte( data)

receive_multiples_bytes( *data[], length )

 

Is there a strict need of giving user access to start/stop control?

I mean start/stop can be easily embedded into send/receive function no?

 

Any suggestions welcomed J

 

Regards,

 

Laurent


_______________________________________________
eLua-dev mailing list
[hidden email]
https://lists.berlios.de/mailman/listinfo/elua-dev

winmail.dat (24K) Download Attachment