Nice to see you are making progresses, I noticed all the commits you are doing but I haven't looked into the code yet, I am trying to finalize the USB driver right now.
There is no DMA sharing currently, this would require also IRQ sharing among different drivers but ISRs are statically linked in the current implementation.
DMA and ISR sharing is something I am thinking to implement during 2.3.0 by optionally relocating the ISR table into RAM, this will allow for hot ISR swapping.
Anyway the first implementation does not have to use DMA, it is more important to freeze the high level driver and the API.
Giovanni
I2C implementation for STM32
- Giovanni
- Site Admin
- Posts: 14891
- Joined: Wed May 27, 2009 8:48 am
- Has thanked: 1202 times
- Been thanked: 996 times
Re: I2C implementation for STM32
I need some help.
What happens in following call nesting:
start_condition{ ISR{ callback{ start_condition{ ISR{ ...etc}}}}}
infinite loop/nesting or something totally unpredicted?
Is it possible to recognize from where program jump to ISR function? I use several instruments: Eclipse, Codesourcery toolchain and OpenOCD.
What _exactly_ mean "asynchronous" driver?
What happens in following call nesting:
start_condition{ ISR{ callback{ start_condition{ ISR{ ...etc}}}}}
infinite loop/nesting or something totally unpredicted?
Is it possible to recognize from where program jump to ISR function? I use several instruments: Eclipse, Codesourcery toolchain and OpenOCD.
What _exactly_ mean "asynchronous" driver?
- Giovanni
- Site Admin
- Posts: 14891
- Joined: Wed May 27, 2009 8:48 am
- Has thanked: 1202 times
- Been thanked: 996 times
Re: I2C implementation for STM32
start_condition{ ISR{ callback{ start_condition{ ISR{ ...etc}}}}}
infinite loop/nesting or something totally unpredicted?
It cannot cause infinite nesting because an ISR can only be preempted by an higher priority ISR and the number of IRQ priority levels is finite.
It is correct to call a start_somethingI() from a callback. this is how most HAL drivers are supposed to work, the STM32VL-Discovery demo is a good example of multiple drivers "jumping" from callback to callback.
What _exactly_ mean "asynchronous" driver?
An asynchronous driver is a driver that operates in background asynchronously and invoke a callback when an operation is finished. Usually they have a xxxStartSomething() function that returns immediately, a callback is asynchronously invoked after some time.
Is it possible to recognize from where program jump to ISR function? I use several instruments: Eclipse, Codesourcery toolchain and OpenOCD.
You want to know where the ISR would return? This one is difficult because rescheduling, an ISR might not return inside the thread that it preempted but in some other thread context. This is not something you usually need to know in a device driver? why you asked this?
Anyway, from an interrupt handler, the PSP register (Cortex-Mx only) always points to an extctx structure, in the structure there is the ISR return address.
Giovanni
Re: I2C implementation for STM32
Hi Giovanni, hi Barthess
a few weeks ago i made for my use, a i2c (STM32) driver based on interrupt that currently works fine.
now i decided i'd make it available to avoid that Barthess do the same job i did.
(naturally, if he like it, can use this code freely in the most convenient mode)
http://www.megaupload.com/?d=VVRN9GUC
(22-02-2011 i've correct one mistake on serial_lld.c and reupload an new file)
It's close enough to the general driver specifications and the other drivers
for now it only works as master and only by interrupt, the master-receiver isr part meets the "method 2"
described in the reference manual, so it can be used with a lower interrupt priority instead of the highest.
It works asynchronously with events and callback and also with the bus lock (tested both)
optionally can also work in a synchronous mode (but it is really useful?)
Came with a easy, complete and tested configuration support .
An little issue is open about i2c_lld_wait_bus_free() wich now is blocking (for only about half sdc period in asynchronous mode)
exactly between the ack/nak (the last useful state of isr state machine) and the stop where the bus is fred.
i don't have already find an elegant solution for avoid this,
the exit could be triggered asynchronously by an exti on rising edge of sda? mhhh...
The protocol was verified in HW with a logic/protocol analyzer.
The 10-bit address has been implemented but not yet tested.
This driver was tested with two LM75 and one ADS1115 on the same bus with concurrent access.
Also i made a specific ADS1115 driver on top the I2C driver, but now is still under test.
as example, see ChibiOS_2.17\projects\i2c
In the attached file (an ChibiOS_2.17 minimal skeleton) there is also a USB serial driver
built on top of the usb ST libraries.
It's very easy to use, the driver came in the same manner of the other serial drivers
(some low level usb parts are merged in the serial_lld.c/h, instead serial.c/h is untouched)
It's temporaneous and should be used only while Giovanni still works on the official one.
as example, see ChibiOS_2.17\projects\vcom
it's a data exchange between SD2 and USBD1 and vice versa through events
Latest there is also a useful module for EXTI managing (only to make the life easy)
There isn't a driver now but i'm thinking of trying to make it.
as example, see ChibiOS_2.17\projects\Exti
Sorry for my poor english, i hope i was understood.
also i hope to be helpful to all the ChibiOS's friends
Alberto
a few weeks ago i made for my use, a i2c (STM32) driver based on interrupt that currently works fine.
now i decided i'd make it available to avoid that Barthess do the same job i did.
(naturally, if he like it, can use this code freely in the most convenient mode)
http://www.megaupload.com/?d=VVRN9GUC
(22-02-2011 i've correct one mistake on serial_lld.c and reupload an new file)
It's close enough to the general driver specifications and the other drivers
for now it only works as master and only by interrupt, the master-receiver isr part meets the "method 2"
described in the reference manual, so it can be used with a lower interrupt priority instead of the highest.
It works asynchronously with events and callback and also with the bus lock (tested both)
optionally can also work in a synchronous mode (but it is really useful?)
Came with a easy, complete and tested configuration support .
An little issue is open about i2c_lld_wait_bus_free() wich now is blocking (for only about half sdc period in asynchronous mode)
exactly between the ack/nak (the last useful state of isr state machine) and the stop where the bus is fred.
i don't have already find an elegant solution for avoid this,
the exit could be triggered asynchronously by an exti on rising edge of sda? mhhh...
The protocol was verified in HW with a logic/protocol analyzer.
The 10-bit address has been implemented but not yet tested.
This driver was tested with two LM75 and one ADS1115 on the same bus with concurrent access.
Also i made a specific ADS1115 driver on top the I2C driver, but now is still under test.
as example, see ChibiOS_2.17\projects\i2c
In the attached file (an ChibiOS_2.17 minimal skeleton) there is also a USB serial driver
built on top of the usb ST libraries.
It's very easy to use, the driver came in the same manner of the other serial drivers
(some low level usb parts are merged in the serial_lld.c/h, instead serial.c/h is untouched)
It's temporaneous and should be used only while Giovanni still works on the official one.
as example, see ChibiOS_2.17\projects\vcom
it's a data exchange between SD2 and USBD1 and vice versa through events
Latest there is also a useful module for EXTI managing (only to make the life easy)
There isn't a driver now but i'm thinking of trying to make it.
as example, see ChibiOS_2.17\projects\Exti
Sorry for my poor english, i hope i was understood.
also i hope to be helpful to all the ChibiOS's friends
Alberto
Last edited by albi on Tue Feb 22, 2011 6:37 pm, edited 5 times in total.
- Giovanni
- Site Admin
- Posts: 14891
- Joined: Wed May 27, 2009 8:48 am
- Has thanked: 1202 times
- Been thanked: 996 times
Re: I2C implementation for STM32
Hi Albi,
Thanks for the contribution, I hope that the best of the both works will go into the final driver, lets see what Barthess thinks about it. I decided to stay in spectator mode about this I2C development until the end, the process is even more important than the final result.
Giovanni
Thanks for the contribution, I hope that the best of the both works will go into the final driver, lets see what Barthess thinks about it. I decided to stay in spectator mode about this I2C development until the end, the process is even more important than the final result.
Giovanni
Re: I2C implementation for STM32
Hi Albi,
If in several words: "your kung fu is stronger than mine". If I will take your realization and supplement with my idea of user fillable personal config (hm... very low level driver?) on every slave device, than I will get almost wanted I2C driver (master part). But, is it really needed?
About i2c_lld_wait_bus_free(). May be better to insert sleep instruction in cycle instead of continuous decrement?
My English not perfect too. Google translate helps me some time.
Hi Giovanni,
Yes, the driver itself does not need to know, but I want to know for debug reason.
If in several words: "your kung fu is stronger than mine". If I will take your realization and supplement with my idea of user fillable personal config (hm... very low level driver?) on every slave device, than I will get almost wanted I2C driver (master part). But, is it really needed?
About i2c_lld_wait_bus_free(). May be better to insert sleep instruction in cycle instead of continuous decrement?
My English not perfect too. Google translate helps me some time.
Hi Giovanni,
This is not something you usually need to know in a device driver? why you asked this?
Yes, the driver itself does not need to know, but I want to know for debug reason.
- Giovanni
- Site Admin
- Posts: 14891
- Joined: Wed May 27, 2009 8:48 am
- Has thanked: 1202 times
- Been thanked: 996 times
Re: I2C implementation for STM32
OK Barthess just to know 
Few hints:
- Waits done through loops are generally a bad idea, it is "busy waiting".
- Sleep instructions are not OK either if you are trying to design an asynchronous driver, sleeping into interrupt handlers is not allowed.
It is better to think in terms of finite state machines, a "wait" is a transition from a state to another state, for example from a state "waiting for something" to another state "something just happened".
Giovanni
Few hints:
- Waits done through loops are generally a bad idea, it is "busy waiting".
- Sleep instructions are not OK either if you are trying to design an asynchronous driver, sleeping into interrupt handlers is not allowed.
It is better to think in terms of finite state machines, a "wait" is a transition from a state to another state, for example from a state "waiting for something" to another state "something just happened".
Giovanni
Re: I2C implementation for STM32
Hi
(i'm not sure i fully understood...)
I don't have the minimal idea about this, you can use it to your convenience.
IMHO the risk is to make the things most complicated in vain.
don't forget that for a best work you need the experience of use it with many different slave devices.
My personal suggestion is to make as first step a simple but complete (isr and dma) very strong driver,
on last you can think to details as an better or different configuration mode and other.
(e.g. i prefer a user friendly approach to config (as the i2c driver case) to avoid the need of open data-sheets, somebody instead prefer a raw approach passing the direct value to driver registers)
For continuous decrement, i think you refer to tmo variable, it's only an escape method (tmo mean timeout) to exit from the wait loop anyway.
the real wait is focused on the busy state of the i2c engine
i have already try to use sleep (in fraction of few mS) in to the wait loop but i think isn't a elegant solution,
but safe becouse i2c_lld_wait_bus_free() is called out of interrupt service, and the scheduler unlocked;
Really the scope of this function is only for security when there are two o more called to master_trasmit (and/or master_receive) one after the other
In deept, the last state of isr finite state machine is coincident with the end of NAK bus signal, a bit of time prior of effective
stop and de-assertion of the bus.
On this last state the thread is waked-up and the function end, the bus can be alredy asserted low by the stop period, but all data are sent/received
and the exit from the call is safe.
The problem can born only when you launch immediately another call to master_trasmit/master_receive without the security of bus released;
note that i have put the call to i2c_lld_wait_bus_free() at the begin of api, and not at the end, so this will not really wait when you run non contiguous calls.
good job Barthess
Alberto
If I will take your realization and supplement with my idea of user fillable personal config (hm... very low level driver?) on every slave device,
than I will get almost wanted I2C driver (master part). But, is it really needed?
(i'm not sure i fully understood...)
I don't have the minimal idea about this, you can use it to your convenience.
IMHO the risk is to make the things most complicated in vain.
don't forget that for a best work you need the experience of use it with many different slave devices.
My personal suggestion is to make as first step a simple but complete (isr and dma) very strong driver,
on last you can think to details as an better or different configuration mode and other.
(e.g. i prefer a user friendly approach to config (as the i2c driver case) to avoid the need of open data-sheets, somebody instead prefer a raw approach passing the direct value to driver registers)
About i2c_lld_wait_bus_free(). May be better to insert sleep instruction in cycle instead of continuous decrement?
For continuous decrement, i think you refer to tmo variable, it's only an escape method (tmo mean timeout) to exit from the wait loop anyway.
the real wait is focused on the busy state of the i2c engine
i have already try to use sleep (in fraction of few mS) in to the wait loop but i think isn't a elegant solution,
but safe becouse i2c_lld_wait_bus_free() is called out of interrupt service, and the scheduler unlocked;
Really the scope of this function is only for security when there are two o more called to master_trasmit (and/or master_receive) one after the other
In deept, the last state of isr finite state machine is coincident with the end of NAK bus signal, a bit of time prior of effective
stop and de-assertion of the bus.
On this last state the thread is waked-up and the function end, the bus can be alredy asserted low by the stop period, but all data are sent/received
and the exit from the call is safe.
The problem can born only when you launch immediately another call to master_trasmit/master_receive without the security of bus released;
note that i have put the call to i2c_lld_wait_bus_free() at the begin of api, and not at the end, so this will not really wait when you run non contiguous calls.
good job Barthess
Alberto
Re: I2C implementation for STM32
Hi.
Whats done:
- Driver works without BUSY wait lock. But with START wait and STOP wait lock.
Is there method to reset BTF RxNE TxE bits directly?
Something like i2cp->id_i2c->CR2 &= (~I2C_CR2_BTF).
There will help to eliminate my wait locks.
- Better way to work with I2C is to create sleeping thread in userspace and wake up it by callback.
From that tread user can send (re)start, stop, do some data handling, etc.
Whats in near planes:
- Add error hadling and frequency counting code from Alberto's driver.
- Create function from Alberto's ISR handler code that will properly abort communication.
Far planes:
- DMA
Whats done:
- Driver works without BUSY wait lock. But with START wait and STOP wait lock.
Is there method to reset BTF RxNE TxE bits directly?
Something like i2cp->id_i2c->CR2 &= (~I2C_CR2_BTF).
There will help to eliminate my wait locks.
- Better way to work with I2C is to create sleeping thread in userspace and wake up it by callback.
From that tread user can send (re)start, stop, do some data handling, etc.
Whats in near planes:
- Add error hadling and frequency counting code from Alberto's driver.
- Create function from Alberto's ISR handler code that will properly abort communication.
Far planes:
- DMA
- Giovanni
- Site Admin
- Posts: 14891
- Joined: Wed May 27, 2009 8:48 am
- Has thanked: 1202 times
- Been thanked: 996 times
Re: I2C implementation for STM32
Those bits cannot be cleared, may be you could mask the interrupt source instead?
A dedicated thread does not look like a good idea considering that the whole point of having an asynchronous driver is to not have to use a dedicated thread for I/O.
Giovanni
A dedicated thread does not look like a good idea considering that the whole point of having an asynchronous driver is to not have to use a dedicated thread for I/O.
Giovanni