Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hardware control APIs #110

Closed
seanshpark opened this issue Jun 30, 2015 · 25 comments
Closed

Hardware control APIs #110

seanshpark opened this issue Jun 30, 2015 · 25 comments

Comments

@seanshpark
Copy link
Contributor

As of today, nodejs is on the discuss to support hardware and libuv is ready with uv_device_t PR.
For IoT.js, how are we going to support hardware control and manage devices?
First PR #105 needs some more adjustments and we need to discuss how to provide the API and manage H/W boards and devices. GPIO-control-ideas is prepared to draw everyones sketch.
Please add comments and write down to WiKi page.

@seanshpark
Copy link
Contributor Author

As wrote in PR #113, process.iotjs can be used for distinguishing between iotjs and others.
it may also have other properties, such as running product class, H/W board, and network or other environments that is needed to make application to decide better.
If this seems to be a bad idea, please add comments.

@ILyoan
Copy link
Contributor

ILyoan commented Jul 2, 2015

I think we may need API reference for device control.
And for new module features will be introduced later on, how about consensus of API first and then implementation?

@ILyoan
Copy link
Contributor

ILyoan commented Jul 2, 2015

@ILyoan
Copy link
Contributor

ILyoan commented Jul 2, 2015

What type of mode could be exist for a pin of GPIO?

As far as I know there is only one; direction. Direction of a pin could be either input or output at one time thus rw pin is not possible right?

Is there any other type of mode besides direction?

@seanshpark
Copy link
Contributor Author

I've prepared a short page https://github.com/Samsung/iotjs/wiki/GPIO-control-ideas few days ago, and pin mode is described in summary. If you jump to link http://coactionos.com/embedded%20design%20tips/2013/10/21/Tips-Understanding-Microcontroller-Pin-Input-Output-Modes/ there is more. Hope this helps.

@ILyoan
Copy link
Contributor

ILyoan commented Jul 3, 2015

@seanshpark The page you referred are only saying there are input and output mode(direction). Then can we assume that there are no other type of mode?

@seanshpark
Copy link
Contributor Author

@ILyoan , If you let mode to be input/output, one more thing is floating that is something like disconnected.

Is there any other type of mode besides direction?

Besides direction, to the pin,

  • Pull up or down or open-drain(open collector)
  • Rise up or down edge detection
  • input in digital or analog

@ILyoan
Copy link
Contributor

ILyoan commented Jul 3, 2015

Let's summarize what pin configuration are commonly definable so we can design our GPIO API more usable for anyone.

I see configurable options are:

Direction / mode

input

  • floating
  • pull-up
  • pull-down

output

  • open-drain
  • push-pul

Frequency

Ports

@seanshpark
Copy link
Contributor Author

Mode control depends on H/W. Is it ok to define actual mode in iotjs? Previous your comment was not to.

@ILyoan
Copy link
Contributor

ILyoan commented Jul 3, 2015

I'm not sure about it.
My first thought was that mode configuration API might be sufficient if it enable user to select direction("input" or "output"). but you mentioned there are other modes besides it. so I listed it up.

If detailed configuration(like pull-do/down, open-drain, etc.) was up to hardware (for example, if target architecture was fixed, modes will also be fixed), then we don't need to expose the APIs for control it for user. On the other hand, if some user application should choose detailed mode, we need to provide APIs for it.

My intention is that I want to know minimum set of APIs that is enough for controlling GPIO for majority of use case.

@ILyoan
Copy link
Contributor

ILyoan commented Jul 15, 2015

What about GPIO API like below:

gpio.set(pin, direction[, callback])

  • pin: Number - pin number.
  • direction: String - direction of the gpio pin 'in' | 'out'.
  • callback: Function(err: Exception | null)

gpio.write(pin, value[, callback])

  • pin: Number - pin number.
  • value: Boolean - true to turn on false to turn off.
  • callback: Function(err)

gpio.read(pin[, callback])

  • pin: Number - pin number.
  • callback: Function(err: Exception | null, value: Boolean)

Concerns

  • API for initializing GPIO may not be needed because we can initalize gpio when it is required.
  • API for releasing GPIO may not be needed because we can release resources when program down.
  • Setting mode like 'pull-up', 'pull-down', 'open-drain', and etc might not be need if we don't support interrupt based event, I'm not sure about this but my understanding is that this is trivial for most of the use cases, many gpio application could use default mode setting.
  • pin number could be actual hardware pin number or it could be gpio number. I prefer later one, so that pin number could be always 1,2,3,... independent on hardware.

@ILyoan
Copy link
Contributor

ILyoan commented Jul 15, 2015

Binding GPIO in iotjs namespace is also thinkable.
By this applications can get gpio module by var gpio = require('iotjs').gpio.
The advantage of binding is that we can provide 'iotjs' npm fo node.js, so that exactly the same program could be run on both node.js and iot.js without knowing the platform underneath it. Since apps can use 'iotjs' functionality including gpio control independent of hardwares, all that apps have to do will be requiring 'iotjs'.

@seanshpark
Copy link
Contributor Author

Setting mode like 'pull-up', 'pull-down', 'open-drain',

these may need for some devices for addition in/out control. so set() with direction may not be sufficient.

pin number could be actual hardware pin number or it could be gpio number.

please look around 2.2.5 I/O Interface in http://www.element14.com/community/servlet/JiveServlet/previewBody/51124-102-2-267813/STM32F4DIS-BB%20User%20Manual.pdf and http://www.element14.com/community/docs/DOC-73950/l/raspberry-pi-2-model-b-gpio-40-pin-block-pinout file. my opinion is to use pin number and let the application or module develop define and use some named alias.

Binding GPIO in iotjs namespace is also thinkable.

yes, nice. currently in private but please look inside iotjs-app repo.

@ILyoan
Copy link
Contributor

ILyoan commented Jul 15, 2015

Then, what about this?

gpio.set(pin, direction[, mode][, callback])

  • pin: Number - pin number.
  • direction: String - direction of the gpio pin 'in' | 'out'.
  • mode: String - optional.
  • callback: Function(err: Exception | null)

It looks like name aliasing such as GPIO1, GPIO2, GPIO3,... is not proper approach as pin specification are very different from HW to HW. Let's just leave aliasing for application until we find general solution.

@seanshpark
Copy link
Contributor Author

gpio.set(pin, direction[, mode][, callback]) seems nice.
can you describe relation with this API and PR #125 ?

@seanshpark
Copy link
Contributor Author

API for initializing GPIO may not be needed because we can initalize gpio when it is required.
API for releasing GPIO may not be needed because we can release resources when program down.

There may be resource waste. disagree on this.

direction: String - direction of the gpio pin 'in' | 'out'.

why use string when number is used underneath? user module can use this.

API seems nice but for linux system using /sys/class/gpio, I cannot see how to unexport

@ILyoan
Copy link
Contributor

ILyoan commented Jul 16, 2015

@seanshpark
The hardware dependent implementation could be changed according to API.
For example, if we decide to provide gpio.set(pin, direction) the underneath function prototype should be something like SetMode(int pin_number, Direction direction) current implementation assumes pin include mode information including pin number. Also our API to write data to pin was gpio.write(pin, value:bool) then corresponding C++ function prototype will be Write(int pin_number, bool value). So it's relevant to.

I think using string is more intuitive than using enum like number so easy to understand for user. For example filesystem use "r+" instead of O_RDWR.

We can add API for initialiing / releasing / unset pin.

gpio.initialize()

Initialize gpio service. User application should call this function before calling any other gpio functions.

gpio.release()

Release gpio service.

gpio.unset(pin[, callback])

  • pin: Number - pin number to unset.
  • callback: Function(err: Error | null).

@ILyoan
Copy link
Contributor

ILyoan commented Jul 17, 2015

From discussion today morning, we have formed a consensus for GPIO API candidate.

I think this API layout will reflect the idea.

iotjs.gpio

  • pin number is logical number starts from 1. Thus logical pin number k is not necessarily bound to physical pin number k in your board.
  • port number is logical number starts from 1. Thus logical port number k is not necessarily bound to physical port number k in your board.
  • 8 logical pin will be bound to a logical port. For example, pin number 18 will bound to port 1, pin number 916 bound to port 2, and so forth.
  • If you write a byte value to a port, the result is the same as writing each bit to corresponding pin. For example, let's say you write (10101011)2 to port 1. the operation will write up bit to pin 1, up bit to pin 2, down bit to pin 3, ... , up bit to pin 8.

gpio.initialize()

Initialize gpio control.

gpio.release()

Release gpio control.

gpio.setPin(pinNumber, direction[, mode][, callback])

  • pinNumber: Number - pin number to configure
  • direction: 'in' | 'out' - direction of the pin.
  • mode: String - pin mode.
  • callback: Function(err: Error | null).

Configure single pin.

gpio.writePin(pinNumber, value[, callback])

  • pinNumber: Number - pin number to wirte
  • value: Boolean.
  • callback: Function(err: Error | null).

Write a boolean value to a pin.

gpio.readPin(pinNumber, callback)

  • pinNumber: Number - pin number to read.
  • callback: Function(err: Error | null, value: Boolean).

Read value from a pin.

gpio.setPort(portNumber, direction[, mode][, callback])

  • portNumber: Number - port number to configure.
  • direction: 'in' | 'out' - direction of the port.
  • mode: String - pin mode.
  • callback: Function(err: Error | null).

Configure single port. All pins bound to this port will have the configuration.

gpio.writePort(portNumber, value[, callback])

  • portNumber: Number - port number to wirte
  • value: Number(1 Byte).
  • callback: Function(err: Error | null).

Write a byte value to a port.

gpio.readPort(portNumber, callback)

  • portNumber: Number - port number to read.
  • callback: Function(err: Error | null, value: Number(1 byte)).

Read value from a port.

gpio.query(queryOption, callback)

  • queryOption: Object.
  • callback: Function(err: Error | null, result: Object).

@seanshpark
Copy link
Contributor Author

Great. I've coped above descriptions to GPIO-API-candidate page. I've some comments

  1. direction: 'in' | 'out': what do you think using boolean. code will be simple.
  2. is resetPin() api not needed anymore or just forgot?

@ILyoan
Copy link
Contributor

ILyoan commented Jul 17, 2015

@seanshpark

  1. true for what? in or out ? I wonder if it could be a little confusing.
  2. you men unset()? We could provide it. or we can do it with setPin() with direction 'none'.

@seanshpark
Copy link
Contributor Author

  1. something like direction change to out or output and if true, will be set to output mode.
  2. setPin() with direction none can be a choice for unsetPin() but I prefer not to use string as value. simple value compare not string compare.

@seanshpark
Copy link
Contributor Author

I think I got confused. for the JS API, direction with 'out' | 'in' | 'none' seems ok.

@ILyoan
Copy link
Contributor

ILyoan commented Jul 17, 2015

@seanshpark, thanks for your confirmation.

@seanshpark
Copy link
Contributor Author

thank you too, I'll begin the implementation when new HW arrives, for testing.

@seanshpark seanshpark mentioned this issue Jul 20, 2015
7 tasks
@ILyoan
Copy link
Contributor

ILyoan commented Aug 27, 2015

Closing as we reached consensus about the API:
https://github.com/Samsung/iotjs/wiki/IoT.js-API:-GPIO

Feel free to reopen if it needed.

@ILyoan ILyoan closed this as completed Aug 27, 2015
pmarcinkiew referenced this issue in pmarcinkiew/iotjs Aug 29, 2017
Make a build error when CONFIG_MAX_TASKS is not power of 2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants