To answer your question below with more questions:
For example, how would tell that for my Olimex board, I want
to use pin X as input for my ADC? Or that my PWM for sysid 0 should go out
to pin Y?
Here are three questions after reflecting on yours (yours is the first one
below)
1) How to I tell the ADC on sysid 0 that its supposed to read from Pin 5?
2) Am I using ping 6 as ADC input, PWM output or just GPIO?
3) which SYSID is the ADC port that is on pin 5?
My sense from the chips I have looked at so far is that there are internal
channels of GPIO, ADC, PWM, SPI etc which are not necessarily tied to
pins. There is some muxing that connect them, but the driver
implementation itself doesn¹t really care except for setup. So I suspect
question 3 is not valid to ask in general. Question two may be valid to
ask, but the answer must be really platform specific since every part
(even in the same family) has lots of differences. So to agree with you
in a really long-winded way, question #1 is the right question to
consider.
What I was envisioning is similar to what we have now. The MCU (or any
peripheral) would have to get info from the BSP. Info is part specific,
but here¹s some ideas of what there could be.
GPIO
The pin to connect to
The input settings (pull strength) if applicable
The output settings, drive strength etc
ADC
The resolution to set to
The sample time/rate
The reference voltage source
The clock source
PWM
The pin
The drive settings
The clock source
First, I don¹t believe we can create an abstract interface for such
settings. That kind of thing is only making things harder. There¹s no way
I could write a library for a battery monitor using GPIO, PWN, and ADC and
have it configure stuff like the output drive levels and input pull
config. Its has to be done in the place where the board designer knows
how things are hooked up.
So I am thinking about two different ways:
1) The internal driver has some kind of iotctl function that the BSP when
initializing calls to set stuff that is driver dependent. I don¹t
generally like this because its a lot of code and trouble to yank custom
stuff in and out of a void* interface.
2) The MCU specifies a function that the BSP must implement. I like #2
the best, except that often default values are great. My first thought is
that we have something like this
int bsp_get_mcu_hal_xxx_settings(int devid, struct hal_xxx_driver_s *pdrv,
struct hal_xxx_settings *pout_set);
pout_set should be initialed to some defaults, and then the bps could
change this based on its own setting choices.
The devid/pdrv part would only be so that the bsp can identify this device
type (pdrv) and specific id.
Imagine that I have 3 port interfaces each with 16 bits of GPIO. That¹s
why I need both the devid and the pdrv since they will uniquely specify a
device and port.
More to come in a follow on email.
Paul
On 3/23/16, 4:03 PM, "marko kiiskila" <[email protected]> wrote:
>Good stuff.
>
>> On Mar 22, 2016, at 5:21 PM, [email protected] wrote:
>>
>> All,
>>
>> I'm having so much fun with my newt. Please comment and help me improve
>>this work.
>>
>> I've submitted two HAL API pull requests. They are to add new
>>HAL_xxx.h files for two new sets of core functionality: ADC and PWM.
>>
>> When designing these hal_xxx.h interfaces, I considered the APIs from
>>mbed-hal and from arduino-hal. I treated these as "enough" with a few
>>caveats.
>>
>> 1. Generally, APIs that set specific state of devices seems hard to
>>maintain and the system designer will have to know about them anyway.
>>So I made Apis in the ADC hal to query the resolution and reference
>>voltage rather than set them. They will be set by the MCU unless
>>configurable, then they can be set by the BSP
>> 2. There were duplicate ways in mbed to set PWM duty cycle. Rather
>>than implement them all, I implemented a sufficient subset. Future
>>versions could expand on this, or someone could write a helper library
>>on top of it to covert between the various methods.
>>
>> https://github.com/apache/incubator-mynewt-core/pull/22 - this is a
>>pull requests for the hal api for the Pulse Width Modulation. .
>> https://github.com/apache/incubator-mynewt-core/pull/21 - this is the
>>pull request for the hal API for the Analog to Digital Converters.
>>
>> Underlying HAL philosophy. I tried to following this philosophy when
>>doing the interface.
>>
>> 1. A given device may support multiple channels (I.e. One ADC
>>controller can sample 8 ports). Its needs a single driver since its one
>>device multiplexed.
>> 2. A number of different PWM/ADC devices can be supported at the same
>>time.
>> 3. Its possible and likely that there will be N instances of the same
>>Device driver with just different state (e.g. Two ADC devices with 8
>>channels each that are identical except for memory map).
>
>That¹s good.
>
>> So I implemented the HAL as follows:
>>
>> 1. for each hal_xxx.h there is a set of sysid (system_ids). These
>>represent individual xxx (e.g. ADC) resources in the system. The
>>adc_sysid and pwm_sydid are different number spaces.
>> 2. The hal_xxx apis all take a sysid to reference the device and port.
>> 3. There is an underlying hal_xxx.c implementation in the hal that
>>resolves the sysid into a device_id and a driver interface. This is
>>not the implementation of the hal, just a shim to call the BSP to get
>>the driver and devid before calling back into the driver itself.
>> 4. There is an underlying driver that implements the driver interface
>>that can support up to N device Ids.
>>
>> As a concrete example, imagine a system with two ADC devices.
>> 1. A SPI ADC with 10-bits precision and 8 pins
>> 2. An internal MCU ADC with 8 bits precision 16 pins
>>
>> The BSP will be in charge of mapping a system ID into the device
>>drivers and Ids. For example:
>>
>> 1. sysID 0-7 belong to SPIADC 0-7
>> 2. sysID 8-24 belong to MCUADC 0-15
>>
>> Each individual driver will manage their devices and not need to know
>>how they map to system Ids.
>
>How do you map from devid to particulars of HW configuration? For
>example, how would tell that for my Olimex board, I want
>to use pin X as input for my ADC? Or that my PWM for sysid 0 should go
>out to pin Y?
>
>
>