mirror of
				https://github.com/eclipse/upm.git
				synced 2025-10-31 07:04:14 +03:00 
			
		
		
		
	nunchuck: C port; FTI; C++ wraps C
Some API changes were made as well, see docs/apichanges.md. Signed-off-by: Jon Trulson <jtrulson@ics.com>
This commit is contained in:
		| @@ -4,6 +4,14 @@ API Changes                       {#apichanges} | |||||||
| Here's a list of other API changes made to the library that break source/binary | Here's a list of other API changes made to the library that break source/binary | ||||||
| compatibility between releases: | compatibility between releases: | ||||||
|  |  | ||||||
|  |  * **nunchuck** This driver no longer supports the init() function. | ||||||
|  |    All initialization is now done in the C nunchuck_init() function, | ||||||
|  |    or the C++ constructor.  In addition, the *NUNCHUCK_I2C_ADDR* | ||||||
|  |    define is no longer exposed, as it is not possible to use any other | ||||||
|  |    I2C address than *0x52*.  The readBytes() and writeByte() functions | ||||||
|  |    are also no longer exposed, since aside from what the driver does | ||||||
|  |    to initialize and read data, there are no other options available. | ||||||
|  |  | ||||||
|  * **enc03r** This driver no longer supports the value() function.  In |  * **enc03r** This driver no longer supports the value() function.  In | ||||||
|  addition, an update() function has been added.  This function must be |  addition, an update() function has been added.  This function must be | ||||||
|  called prior to calling angularVelocity().  angularVelocity() no |  called prior to calling angularVelocity().  angularVelocity() no | ||||||
|   | |||||||
| @@ -43,37 +43,29 @@ int main(int argc, char **argv) | |||||||
|   signal(SIGINT, sig_handler); |   signal(SIGINT, sig_handler); | ||||||
|  |  | ||||||
| //! [Interesting] | //! [Interesting] | ||||||
|   // Instantiate a nunchuck controller bus 0 |   // Instantiate a nunchuck controller bus 3 | ||||||
|   upm::NUNCHUCK *nunchuck = new upm::NUNCHUCK(0); |   upm::NUNCHUCK *nunchuck = new upm::NUNCHUCK(3); | ||||||
|    |  | ||||||
|   // always do this first |  | ||||||
|   cout << "Initializing... " << endl; |  | ||||||
|   if (!nunchuck->init()) |  | ||||||
|     { |  | ||||||
|       cerr << "nunchuck->init() failed." << endl; |  | ||||||
|       return 0; |  | ||||||
|     } |  | ||||||
|    |  | ||||||
|   while (shouldRun) |   while (shouldRun) | ||||||
|     { |     { | ||||||
|       nunchuck->update(); |       nunchuck->update(); | ||||||
|  |  | ||||||
|       cout << "stickX: " << nunchuck->stickX  |       cout << "stickX: " << nunchuck->stickX | ||||||
|            << ", stickY: " << nunchuck->stickY << endl; |            << ", stickY: " << nunchuck->stickY << endl; | ||||||
|       cout << "accelX: " << nunchuck->accelX  |       cout << "accelX: " << nunchuck->accelX | ||||||
|            << ", accelY: " << nunchuck->accelY  |            << ", accelY: " << nunchuck->accelY | ||||||
|            << ", accelZ: " << nunchuck->accelZ << endl; |            << ", accelZ: " << nunchuck->accelZ << endl; | ||||||
|        |  | ||||||
|       cout << "button C: "  |       cout << "button C: " | ||||||
|            << ((nunchuck->buttonC) ? "pressed" : "not pressed") << endl; |            << ((nunchuck->buttonC) ? "pressed" : "not pressed") << endl; | ||||||
|       cout << "button Z: "  |       cout << "button Z: " | ||||||
|            << ((nunchuck->buttonZ) ? "pressed" : "not pressed") << endl; |            << ((nunchuck->buttonZ) ? "pressed" : "not pressed") << endl; | ||||||
|       cout << endl; |       cout << endl; | ||||||
|  |  | ||||||
|       usleep(100000); |       usleep(100000); | ||||||
|     } |     } | ||||||
|   //! [Interesting] |   //! [Interesting] | ||||||
|    |  | ||||||
|   delete nunchuck; |   delete nunchuck; | ||||||
|   return 0; |   return 0; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -148,6 +148,7 @@ add_example (cjq4435) | |||||||
| add_example (hmc5883l) | add_example (hmc5883l) | ||||||
| add_example (wfs) | add_example (wfs) | ||||||
| add_example (enc03r) | add_example (enc03r) | ||||||
|  | add_example (nunchuck) | ||||||
|  |  | ||||||
| # Custom examples | # Custom examples | ||||||
| add_custom_example (nmea_gps_i2c-example-c nmea_gps_i2c.c nmea_gps) | add_custom_example (nmea_gps_i2c-example-c nmea_gps_i2c.c nmea_gps) | ||||||
|   | |||||||
							
								
								
									
										84
									
								
								examples/c/nunchuck.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								examples/c/nunchuck.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,84 @@ | |||||||
|  | /* | ||||||
|  |  * Author: Jon Trulson <jtrulson@ics.com> | ||||||
|  |  * Copyright (c) 2015 Intel Corporation. | ||||||
|  |  * | ||||||
|  |  * Permission is hereby granted, free of charge, to any person obtaining | ||||||
|  |  * a copy of this software and associated documentation files (the | ||||||
|  |  * "Software"), to deal in the Software without restriction, including | ||||||
|  |  * without limitation the rights to use, copy, modify, merge, publish, | ||||||
|  |  * distribute, sublicense, and/or sell copies of the Software, and to | ||||||
|  |  * permit persons to whom the Software is furnished to do so, subject to | ||||||
|  |  * the following conditions: | ||||||
|  |  * | ||||||
|  |  * The above copyright notice and this permission notice shall be | ||||||
|  |  * included in all copies or substantial portions of the Software. | ||||||
|  |  * | ||||||
|  |  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||||||
|  |  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||||||
|  |  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||||||
|  |  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | ||||||
|  |  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||||||
|  |  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||||||
|  |  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #include <unistd.h> | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <signal.h> | ||||||
|  |  | ||||||
|  | #include <upm_utilities.h> | ||||||
|  | #include "nunchuck.h" | ||||||
|  |  | ||||||
|  | bool shouldRun = true; | ||||||
|  |  | ||||||
|  | void sig_handler(int signo) | ||||||
|  | { | ||||||
|  |     if (signo == SIGINT) | ||||||
|  |         shouldRun = false; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int main(int argc, char **argv) | ||||||
|  | { | ||||||
|  |     signal(SIGINT, sig_handler); | ||||||
|  |  | ||||||
|  | //! [Interesting] | ||||||
|  |     // Instantiate a nunchuck controller bus 3 | ||||||
|  |     nunchuck_context sensor = nunchuck_init(3); | ||||||
|  |  | ||||||
|  |     if (!sensor) | ||||||
|  |     { | ||||||
|  |         printf("%s: nunchuck_init() failed\n", __FUNCTION__); | ||||||
|  |         return 1; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     while (shouldRun) | ||||||
|  |     { | ||||||
|  |         if (nunchuck_update(sensor)) | ||||||
|  |         { | ||||||
|  |             printf("%s: nunchuck_update() failed\n", __FUNCTION__); | ||||||
|  |             nunchuck_close(sensor); | ||||||
|  |             return 1; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         int x, y, z; | ||||||
|  |         nunchuck_get_stick(sensor, &x, &y); | ||||||
|  |         printf("stickX: %d stickY: %d\n", x, y); | ||||||
|  |  | ||||||
|  |         nunchuck_get_acceleration(sensor, &x, &y, &z); | ||||||
|  |         printf("accelX: %d accelY: %d accelZ: %d\n", x, y, z); | ||||||
|  |  | ||||||
|  |         bool bc, bz; | ||||||
|  |         nunchuck_get_buttons(sensor, &bc, &bz); | ||||||
|  |         printf("button C: %s\n", | ||||||
|  |                ((bc) ? "pressed" : "not pressed")); | ||||||
|  |         printf("button Z: %s\n\n", | ||||||
|  |                ((bz) ? "pressed" : "not pressed")); | ||||||
|  |  | ||||||
|  |         upm_delay_ms(100); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     nunchuck_close(sensor); | ||||||
|  |  | ||||||
|  |     //! [Interesting] | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
| @@ -24,38 +24,38 @@ | |||||||
|  |  | ||||||
| public class NUNCHUCKSample { | public class NUNCHUCKSample { | ||||||
|  |  | ||||||
| 	public static void main(String[] args) throws InterruptedException { |     public static void main(String[] args) throws InterruptedException { | ||||||
| 		// ! [Interesting] |         // ! [Interesting] | ||||||
| 		// Instantiate a nunchuck controller bus 0 |         // Instantiate a nunchuck controller bus 0 | ||||||
| 		upm_nunchuck.NUNCHUCK nunchuck = new upm_nunchuck.NUNCHUCK(0); |         upm_nunchuck.NUNCHUCK nunchuck = new upm_nunchuck.NUNCHUCK(3); | ||||||
|  |  | ||||||
| 		// always do this first |         while (true) | ||||||
| 		System.out.println("Initializing... "); |         { | ||||||
| 		if (!nunchuck.init()) { |             nunchuck.update(); | ||||||
| 			System.err.println("nunchuck->init() failed."); |             System.out.println("stickX: " | ||||||
| 			return; |                                + nunchuck.getStickX() | ||||||
| 		} |                                + ", stickY: " | ||||||
|  |                                + nunchuck.getStickY()); | ||||||
|  |             System.out.println("accelX: " | ||||||
|  |                                + nunchuck.getAccelX() | ||||||
|  |                                + ", accelY: " | ||||||
|  |                                + nunchuck.getAccelY() | ||||||
|  |                                + ", accelZ: " | ||||||
|  |                                + nunchuck.getAccelZ()); | ||||||
|  |  | ||||||
| 		while (true) { |             if (nunchuck.getButtonC()) | ||||||
| 			nunchuck.update(); |                 System.out.println("Button C pressed"); | ||||||
| 			System.out.println("stickX: " + nunchuck.getStickX() + ", stickY: " |             else | ||||||
| 					+ nunchuck.getStickY()); |                 System.out.println("Button C not pressed"); | ||||||
| 			System.out.println("accelX: " + nunchuck.getAccelX() + ", accelY: " |  | ||||||
| 					+ nunchuck.getAccelY() + ", accelZ: " + nunchuck.getAccelZ()); |  | ||||||
|  |  | ||||||
| 			if (nunchuck.getButtonC()) |             if (nunchuck.getButtonZ()) | ||||||
| 				System.out.println("Button C pressed"); |                 System.out.println("Button Z pressed"); | ||||||
| 			else |             else | ||||||
| 				System.out.println("Button C not pressed"); |                 System.out.println("Button Z not pressed"); | ||||||
|  |  | ||||||
| 			if (nunchuck.getButtonZ()) |             Thread.sleep(100); | ||||||
| 				System.out.println("Button Z pressed"); |         } | ||||||
| 			else |         // ! [Interesting] | ||||||
| 				System.out.println("Button Z not pressed"); |     } | ||||||
|  |  | ||||||
| 			Thread.sleep(1000); | } | ||||||
| 		} |  | ||||||
| 		// ! [Interesting] |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| } |  | ||||||
|   | |||||||
| @@ -24,16 +24,8 @@ | |||||||
|  |  | ||||||
| var nunchuck_lib = require('jsupm_nunchuck'); | var nunchuck_lib = require('jsupm_nunchuck'); | ||||||
|  |  | ||||||
| // Instantiate a nunchuck controller bus 0 | // Instantiate a nunchuck controller bus 3 | ||||||
| var nunchuck_obj = new nunchuck_lib.NUNCHUCK(0); | var nunchuck_obj = new nunchuck_lib.NUNCHUCK(3); | ||||||
|  |  | ||||||
| // always do this first |  | ||||||
| console.log("Initializing... "); |  | ||||||
| if (!nunchuck_obj.init()) |  | ||||||
| { |  | ||||||
| 	console.log("nunchuck->init() failed."); |  | ||||||
| 	process.exit(0); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| setInterval(function() | setInterval(function() | ||||||
| { | { | ||||||
|   | |||||||
| @@ -26,8 +26,8 @@ import time, sys, signal, atexit | |||||||
| from upm import pyupm_nunchuck as upmNunchuck | from upm import pyupm_nunchuck as upmNunchuck | ||||||
|  |  | ||||||
| def main(): | def main(): | ||||||
|     # Instantiate a nunchuck controller bus 0 on I2C |     # Instantiate a nunchuck controller bus 3 on I2C | ||||||
|     myNunchuck = upmNunchuck.NUNCHUCK(0) |     myNunchuck = upmNunchuck.NUNCHUCK(3) | ||||||
|  |  | ||||||
|     ## Exit handlers ## |     ## Exit handlers ## | ||||||
|     # This function stops python from printing a stacktrace when you hit control-C |     # This function stops python from printing a stacktrace when you hit control-C | ||||||
| @@ -43,12 +43,6 @@ def main(): | |||||||
|     atexit.register(exitHandler) |     atexit.register(exitHandler) | ||||||
|     signal.signal(signal.SIGINT, SIGINTHandler) |     signal.signal(signal.SIGINT, SIGINTHandler) | ||||||
|  |  | ||||||
|     # always do this first |  | ||||||
|     print("Initializing... ") |  | ||||||
|     if (not myNunchuck.init()): |  | ||||||
|         print("nunchuck->init() failed.") |  | ||||||
|         sys.exit(0); |  | ||||||
|  |  | ||||||
|     def buttonStateStr(buttonState): |     def buttonStateStr(buttonState): | ||||||
|         return "pressed" if buttonState else "not pressed" |         return "pressed" if buttonState else "not pressed" | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										46
									
								
								include/fti/upm_buttons.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								include/fti/upm_buttons.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,46 @@ | |||||||
|  | /* | ||||||
|  |  * Author: Jon Trulson <jtrulson@ics.com> | ||||||
|  |  * Copyright (c) 2017 Intel Corporation. | ||||||
|  |  * | ||||||
|  |  * Permission is hereby granted, free of charge, to any person obtaining | ||||||
|  |  * a copy of this software and associated documentation files (the | ||||||
|  |  * "Software"), to deal in the Software without restriction, including | ||||||
|  |  * without limitation the rights to use, copy, modify, merge, publish, | ||||||
|  |  * distribute, sublicense, and/or sell copies of the Software, and to | ||||||
|  |  * permit persons to whom the Software is furnished to do so, subject to | ||||||
|  |  * the following conditions: | ||||||
|  |  * | ||||||
|  |  * The above copyright notice and this permission notice shall be | ||||||
|  |  * included in all copies or substantial portions of the Software. | ||||||
|  |  * | ||||||
|  |  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||||||
|  |  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||||||
|  |  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||||||
|  |  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | ||||||
|  |  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||||||
|  |  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||||||
|  |  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||||||
|  |  */ | ||||||
|  | #ifndef UPM_BUTTONS_H_ | ||||||
|  | #define UPM_BUTTONS_H_ | ||||||
|  |  | ||||||
|  | #ifdef __cplusplus | ||||||
|  | extern "C" { | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | // Buttons function table | ||||||
|  | typedef struct _upm_buttons_ft { | ||||||
|  |     // This function is used to query button state.  The num_button | ||||||
|  |     // specifies the total number of buttons present, and the values | ||||||
|  |     // indicates each button's current value as an array of bools. | ||||||
|  |     upm_result_t (*upm_buttons_get_num_buttons) (const void *dev, | ||||||
|  |                                                  unsigned int *num_buttons); | ||||||
|  |     upm_result_t (*upm_buttons_get_values) (const void *dev, | ||||||
|  |                                             bool *values); | ||||||
|  | } upm_buttons_ft; | ||||||
|  |  | ||||||
|  | #ifdef __cplusplus | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #endif /* UPM_BUTTONS_H_ */ | ||||||
| @@ -75,7 +75,8 @@ typedef enum { | |||||||
|     UPM_STREAM, |     UPM_STREAM, | ||||||
|     UPM_ORP, |     UPM_ORP, | ||||||
|     UPM_BINARY, |     UPM_BINARY, | ||||||
|     UPM_ROTARYENCODER |     UPM_ROTARYENCODER, | ||||||
|  |     UPM_BUTTONS | ||||||
| } upm_sensor_t; | } upm_sensor_t; | ||||||
|  |  | ||||||
| /* Supported IO protocols via MRAA */ | /* Supported IO protocols via MRAA */ | ||||||
| @@ -127,6 +128,8 @@ typedef struct _upm_sensor_ft* (*func_get_upm_sensor_ft)(upm_sensor_t sensor_typ | |||||||
| #include <fti/upm_pressure.h> | #include <fti/upm_pressure.h> | ||||||
| #include <fti/upm_compass.h> | #include <fti/upm_compass.h> | ||||||
| #include <fti/upm_gyroscope.h> | #include <fti/upm_gyroscope.h> | ||||||
|  | #include <fti/upm_buttons.h> | ||||||
|  | #include <fti/upm_joystick.h> | ||||||
|  |  | ||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,5 +1,9 @@ | |||||||
| set (libname "nunchuck") | upm_mixed_module_init (NAME nunchuck | ||||||
| set (libdescription "Wii nunchuck module") |     DESCRIPTION "I2C nunchuck driver" | ||||||
| set (module_src ${libname}.cxx) |     C_HDR nunchuck.h | ||||||
| set (module_hpp ${libname}.hpp) |     C_SRC nunchuck.c | ||||||
| upm_module_init() |     CPP_HDR nunchuck.hpp | ||||||
|  |     CPP_SRC nunchuck.cxx | ||||||
|  |     FTI_SRC nunchuck_fti.c | ||||||
|  |     CPP_WRAPS_C | ||||||
|  |     REQUIRES mraa) | ||||||
|   | |||||||
							
								
								
									
										206
									
								
								src/nunchuck/nunchuck.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										206
									
								
								src/nunchuck/nunchuck.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,206 @@ | |||||||
|  | /* | ||||||
|  |  * Author: Jon Trulson <jtrulson@ics.com> | ||||||
|  |  * Copyright (c) 2017 Intel Corporation. | ||||||
|  |  * | ||||||
|  |  * Permission is hereby granted, free of charge, to any person obtaining | ||||||
|  |  * a copy of this software and associated documentation files (the | ||||||
|  |  * "Software"), to deal in the Software without restriction, including | ||||||
|  |  * without limitation the rights to use, copy, modify, merge, publish, | ||||||
|  |  * distribute, sublicense, and/or sell copies of the Software, and to | ||||||
|  |  * permit persons to whom the Software is furnished to do so, subject to | ||||||
|  |  * the following conditions: | ||||||
|  |  * | ||||||
|  |  * The above copyright notice and this permission notice shall be | ||||||
|  |  * included in all copies or substantial portions of the Software. | ||||||
|  |  * | ||||||
|  |  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||||||
|  |  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||||||
|  |  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||||||
|  |  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | ||||||
|  |  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||||||
|  |  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||||||
|  |  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <string.h> | ||||||
|  | #include <unistd.h> | ||||||
|  | #include <assert.h> | ||||||
|  |  | ||||||
|  | #include "nunchuck.h" | ||||||
|  |  | ||||||
|  | // This is not changeable | ||||||
|  | #define NUNCHUCK_I2C_ADDR    0x52 | ||||||
|  |  | ||||||
|  | // static functions for r/w the device.  No user-serviceable parts | ||||||
|  | // inside. | ||||||
|  |  | ||||||
|  | static upm_result_t nunchuck_write_byte(const nunchuck_context dev, | ||||||
|  |                                         uint8_t reg, uint8_t byte) | ||||||
|  | { | ||||||
|  |     assert(dev != NULL); | ||||||
|  |  | ||||||
|  |     if (mraa_i2c_write_byte_data(dev->i2c, byte, reg)) | ||||||
|  |     { | ||||||
|  |         printf("%s: mraa_i2c_write_byte_data() failed\n", __FUNCTION__); | ||||||
|  |         return UPM_ERROR_OPERATION_FAILED; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     return UPM_SUCCESS; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static int nunchuck_read_bytes(const nunchuck_context dev, uint8_t reg, | ||||||
|  |                                uint8_t *buffer, int len) | ||||||
|  | { | ||||||
|  |     assert(dev != NULL); | ||||||
|  |  | ||||||
|  |     if (!len || !buffer) | ||||||
|  |         return 0; | ||||||
|  |  | ||||||
|  |     if (mraa_i2c_write_byte(dev->i2c, reg)) | ||||||
|  |     { | ||||||
|  |         printf("%s: mraa_i2c_write_byte() failed\n", __FUNCTION__); | ||||||
|  |         return -1; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     return mraa_i2c_read(dev->i2c, buffer, len); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // init | ||||||
|  | nunchuck_context nunchuck_init(int bus) | ||||||
|  | { | ||||||
|  |     // make sure MRAA is initialized | ||||||
|  |     int mraa_rv; | ||||||
|  |     if ((mraa_rv = mraa_init()) != MRAA_SUCCESS) | ||||||
|  |     { | ||||||
|  |         printf("%s: mraa_init() failed (%d).\n", __FUNCTION__, mraa_rv); | ||||||
|  |         return NULL; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     nunchuck_context dev = | ||||||
|  |         (nunchuck_context)malloc(sizeof(struct _nunchuck_context)); | ||||||
|  |  | ||||||
|  |     if (!dev) | ||||||
|  |         return NULL; | ||||||
|  |  | ||||||
|  |     memset((void *)dev, 0, sizeof(struct _nunchuck_context)); | ||||||
|  |  | ||||||
|  |     // setup our i2c link | ||||||
|  |     if ( !(dev->i2c = mraa_i2c_init(bus)) ) | ||||||
|  |     { | ||||||
|  |         printf("%s: mraa_i2c_init() failed\n", __FUNCTION__); | ||||||
|  |         nunchuck_close(dev); | ||||||
|  |         return NULL; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (mraa_i2c_address(dev->i2c, NUNCHUCK_I2C_ADDR)) | ||||||
|  |     { | ||||||
|  |         printf("%s: mraa_i2c_address() failed\n", __FUNCTION__); | ||||||
|  |         nunchuck_close(dev); | ||||||
|  |         return NULL; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // sleep for a second to let things settle | ||||||
|  |     upm_delay(1); | ||||||
|  |  | ||||||
|  |     // disable encryption | ||||||
|  |     if (nunchuck_write_byte(dev, 0xf0, 0x55) | ||||||
|  |         || nunchuck_write_byte(dev, 0xfb, 0x00)) | ||||||
|  |     { | ||||||
|  |         printf("%s: nunchuck_write_byte() failed\n", __FUNCTION__); | ||||||
|  |         nunchuck_close(dev); | ||||||
|  |         return NULL; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     return dev; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void nunchuck_close(nunchuck_context dev) | ||||||
|  | { | ||||||
|  |     assert(dev != NULL); | ||||||
|  |  | ||||||
|  |     if (dev->i2c) | ||||||
|  |         mraa_i2c_stop(dev->i2c); | ||||||
|  |  | ||||||
|  |     free(dev); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | upm_result_t nunchuck_update(const nunchuck_context dev) | ||||||
|  | { | ||||||
|  |     assert(dev != NULL); | ||||||
|  |  | ||||||
|  |     const int bufsize = 6; | ||||||
|  |     uint8_t buf[bufsize]; | ||||||
|  |     int rv; | ||||||
|  |  | ||||||
|  |     rv = nunchuck_read_bytes(dev, 0x00, buf, bufsize); | ||||||
|  |  | ||||||
|  |     if (rv != bufsize) | ||||||
|  |     { | ||||||
|  |         printf("%s: nunchuck_read_bytes() failed.  Expected %d, got %d.\n", | ||||||
|  |                __FUNCTION__, bufsize, rv); | ||||||
|  |         return UPM_ERROR_OPERATION_FAILED; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // analog stick X | ||||||
|  |     dev->stickX = buf[0]; | ||||||
|  |  | ||||||
|  |     // analog stick Y | ||||||
|  |     dev->stickY = buf[1]; | ||||||
|  |  | ||||||
|  |     // accelerometer X | ||||||
|  |     dev->accelX = ( (buf[2] << 2) | ((buf[5] & 0x0c) >> 2) ); | ||||||
|  |  | ||||||
|  |     // accelerometer Y | ||||||
|  |     dev->accelY = ( (buf[3] << 2) | ((buf[5] & 0x30) >> 4) ); | ||||||
|  |  | ||||||
|  |     // accelerometer Z | ||||||
|  |     dev->accelZ = ( (buf[4] << 2) | ((buf[5] & 0xc0) >> 6) ); | ||||||
|  |  | ||||||
|  |     // buttonC | ||||||
|  |     if (buf[5] & 0x02) | ||||||
|  |         dev->buttonC = false; | ||||||
|  |     else | ||||||
|  |         dev->buttonC = true; | ||||||
|  |  | ||||||
|  |     // buttonZ | ||||||
|  |     if (buf[5] & 0x01) | ||||||
|  |         dev->buttonZ = false; | ||||||
|  |     else | ||||||
|  |         dev->buttonZ = true; | ||||||
|  |  | ||||||
|  |     return UPM_SUCCESS; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void nunchuck_get_stick(const nunchuck_context dev, int *x, int *y) | ||||||
|  | { | ||||||
|  |     assert(dev != NULL); | ||||||
|  |  | ||||||
|  |     if (x) | ||||||
|  |         *x = dev->stickX; | ||||||
|  |     if (y) | ||||||
|  |         *y = dev->stickY; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void nunchuck_get_acceleration(const nunchuck_context dev, | ||||||
|  |                                int *x, int *y, int *z) | ||||||
|  | { | ||||||
|  |     assert(dev != NULL); | ||||||
|  |  | ||||||
|  |     if (x) | ||||||
|  |         *x = dev->accelX; | ||||||
|  |     if (y) | ||||||
|  |         *y = dev->accelY; | ||||||
|  |     if (z) | ||||||
|  |         *z = dev->accelZ; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void nunchuck_get_buttons(const nunchuck_context dev, bool *c, bool *z) | ||||||
|  | { | ||||||
|  |     assert(dev != NULL); | ||||||
|  |  | ||||||
|  |     if (c) | ||||||
|  |         *c = dev->buttonC; | ||||||
|  |     if (z) | ||||||
|  |         *z = dev->buttonZ; | ||||||
|  | } | ||||||
| @@ -1,6 +1,6 @@ | |||||||
| /* | /* | ||||||
|  * Author: Jon Trulson <jtrulson@ics.com> |  * Author: Jon Trulson <jtrulson@ics.com> | ||||||
|  * Copyright (c) 2015 Intel Corporation. |  * Copyright (c) 2015-2017 Intel Corporation. | ||||||
|  * |  * | ||||||
|  * Permission is hereby granted, free of charge, to any person obtaining |  * Permission is hereby granted, free of charge, to any person obtaining | ||||||
|  * a copy of this software and associated documentation files (the |  * a copy of this software and associated documentation files (the | ||||||
| @@ -33,117 +33,27 @@ using namespace upm; | |||||||
| using namespace std; | using namespace std; | ||||||
|  |  | ||||||
|  |  | ||||||
| NUNCHUCK::NUNCHUCK(int bus, uint8_t addr) | NUNCHUCK::NUNCHUCK(int bus) : | ||||||
|  |     m_nunchuck(nunchuck_init(bus)) | ||||||
| { | { | ||||||
|   stickX = 0; |     if (!m_nunchuck) | ||||||
|   stickY = 0; |         throw std::runtime_error(string(__FUNCTION__) | ||||||
|   accelX = 0; |                                  + ": nunchuck_init() failed"); | ||||||
|   accelY = 0; |  | ||||||
|   accelZ = 0; |  | ||||||
|   buttonC = false; |  | ||||||
|   buttonZ = false; |  | ||||||
|  |  | ||||||
|   // setup our i2c link |  | ||||||
|   if ( !(m_i2c = mraa_i2c_init(bus)) )  |  | ||||||
|     { |  | ||||||
|       throw std::invalid_argument(std::string(__FUNCTION__) + |  | ||||||
|                                   ": mraa_i2c_init() failed"); |  | ||||||
|       return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|   mraa_result_t rv; |  | ||||||
|  |  | ||||||
|   if ( (rv = mraa_i2c_address(m_i2c, addr)) != MRAA_SUCCESS ) |  | ||||||
|     { |  | ||||||
|       throw std::invalid_argument(std::string(__FUNCTION__) + |  | ||||||
|                                   ": mraa_i2c_address() failed"); |  | ||||||
|     } |  | ||||||
| } | } | ||||||
|  |  | ||||||
| NUNCHUCK::~NUNCHUCK() | NUNCHUCK::~NUNCHUCK() | ||||||
| { | { | ||||||
|   mraa_i2c_stop(m_i2c); |     nunchuck_close(m_nunchuck); | ||||||
| } |  | ||||||
|  |  | ||||||
| bool NUNCHUCK::writeByte(uint8_t reg, uint8_t byte) |  | ||||||
| { |  | ||||||
|   mraa_result_t rv; |  | ||||||
|  |  | ||||||
|   if ( (rv = mraa_i2c_write_byte_data(m_i2c, byte, reg)) != MRAA_SUCCESS ) |  | ||||||
|     { |  | ||||||
|       throw std::runtime_error(std::string(__FUNCTION__) + |  | ||||||
|                                ": mraa_i2c_write_byte_data() failed"); |  | ||||||
|       return false; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|   return true; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| int NUNCHUCK::readBytes(uint8_t reg, uint8_t *buffer, int len) |  | ||||||
| { |  | ||||||
|   if (!len || !buffer) |  | ||||||
|     return 0; |  | ||||||
|  |  | ||||||
|   mraa_i2c_address(m_i2c, NUNCHUCK_I2C_ADDR); |  | ||||||
|   mraa_i2c_write_byte(m_i2c, reg); |  | ||||||
|  |  | ||||||
|   return mraa_i2c_read(m_i2c, buffer, len); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| bool NUNCHUCK::init() |  | ||||||
| { |  | ||||||
|   usleep(1000000); |  | ||||||
|  |  | ||||||
|   // disable encryption |  | ||||||
|   if (!writeByte(0xf0, 0x55)) |  | ||||||
|     return false; |  | ||||||
|  |  | ||||||
|   if (!writeByte(0xfb, 0x00)) |  | ||||||
|     return false; |  | ||||||
|  |  | ||||||
|   return true; |  | ||||||
| } | } | ||||||
|  |  | ||||||
| void NUNCHUCK::update() | void NUNCHUCK::update() | ||||||
| { | { | ||||||
|   const int bufsize = 6; |     if (nunchuck_update(m_nunchuck)) | ||||||
|   uint8_t buf[bufsize]; |         throw std::runtime_error(string(__FUNCTION__) | ||||||
|   int rv; |                                  + ": nunchuck_update() failed"); | ||||||
|  |  | ||||||
|   rv = readBytes(0x00, buf, bufsize); |     nunchuck_get_stick(m_nunchuck, &stickX, &stickY); | ||||||
|  |     nunchuck_get_acceleration(m_nunchuck, &accelX, &accelY, &accelZ); | ||||||
|   if (rv != bufsize) |     nunchuck_get_buttons(m_nunchuck, &buttonC, &buttonZ); | ||||||
|     { |  | ||||||
|       throw std::runtime_error(std::string(__FUNCTION__) + |  | ||||||
|                                ": readBytes() failed"); |  | ||||||
|       return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|   // analog stick X |  | ||||||
|   stickX = buf[0]; |  | ||||||
|  |  | ||||||
|   // analog stick Y |  | ||||||
|   stickY = buf[1]; |  | ||||||
|  |  | ||||||
|   // accelerometer X |  | ||||||
|   accelX = ( (buf[2] << 2) | ((buf[5] & 0x0c) >> 2) ); |  | ||||||
|  |  | ||||||
|   // accelerometer Y |  | ||||||
|   accelY = ( (buf[3] << 2) | ((buf[5] & 0x30) >> 4) ); |  | ||||||
|  |  | ||||||
|   // accelerometer Z |  | ||||||
|   accelZ = ( (buf[4] << 2) | ((buf[5] & 0xc0) >> 6) ); |  | ||||||
|  |  | ||||||
|   // buttonC |  | ||||||
|   if (buf[5] & 0x02) |  | ||||||
|     buttonC = false; |  | ||||||
|   else |  | ||||||
|     buttonC = true; |  | ||||||
|  |  | ||||||
|   // buttonZ |  | ||||||
|   if (buf[5] & 0x01) |  | ||||||
|     buttonZ = false; |  | ||||||
|   else |  | ||||||
|     buttonZ = true; |  | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										123
									
								
								src/nunchuck/nunchuck.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										123
									
								
								src/nunchuck/nunchuck.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,123 @@ | |||||||
|  | /* | ||||||
|  |  * Author: Jon Trulson <jtrulson@ics.com> | ||||||
|  |  * Copyright (c) 2017 Intel Corporation. | ||||||
|  |  * | ||||||
|  |  * Permission is hereby granted, free of charge, to any person obtaining | ||||||
|  |  * a copy of this software and associated documentation files (the | ||||||
|  |  * "Software"), to deal in the Software without restriction, including | ||||||
|  |  * without limitation the rights to use, copy, modify, merge, publish, | ||||||
|  |  * distribute, sublicense, and/or sell copies of the Software, and to | ||||||
|  |  * permit persons to whom the Software is furnished to do so, subject to | ||||||
|  |  * the following conditions: | ||||||
|  |  * | ||||||
|  |  * The above copyright notice and this permission notice shall be | ||||||
|  |  * included in all copies or substantial portions of the Software. | ||||||
|  |  * | ||||||
|  |  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||||||
|  |  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||||||
|  |  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||||||
|  |  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | ||||||
|  |  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||||||
|  |  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||||||
|  |  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||||||
|  |  */ | ||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <upm.h> | ||||||
|  |  | ||||||
|  | #include <mraa/i2c.h> | ||||||
|  |  | ||||||
|  | #ifdef __cplusplus | ||||||
|  | extern "C" { | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @file nunchuck.h | ||||||
|  |      * @library nunchuck | ||||||
|  |      * @brief C API for the nunchuck driver | ||||||
|  |      * | ||||||
|  |      * @include nunchuck.c | ||||||
|  |      */ | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Device context | ||||||
|  |      */ | ||||||
|  |     typedef struct _nunchuck_context { | ||||||
|  |         mraa_i2c_context  i2c; | ||||||
|  |  | ||||||
|  |         // sticks - x, y | ||||||
|  |         int stickX; | ||||||
|  |         int stickY; | ||||||
|  |  | ||||||
|  |         // accel | ||||||
|  |         int accelX; | ||||||
|  |         int accelY; | ||||||
|  |         int accelZ; | ||||||
|  |  | ||||||
|  |         // buttons | ||||||
|  |         bool buttonC; | ||||||
|  |         bool buttonZ; | ||||||
|  |  | ||||||
|  |     } *nunchuck_context; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * NUNCHUCK constructor | ||||||
|  |      * | ||||||
|  |      * @param bus I2C bus to use | ||||||
|  |      * @return A Device context, or NULL on error | ||||||
|  |      */ | ||||||
|  |     nunchuck_context nunchuck_init(int bus); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Close the device and deallocate all resources. | ||||||
|  |      * | ||||||
|  |      * @param dev Device context | ||||||
|  |      */ | ||||||
|  |     void nunchuck_close(nunchuck_context dev); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Reads and updates the current state of the controller. | ||||||
|  |      * | ||||||
|  |      * @param dev Device context | ||||||
|  |      * @return UPM result | ||||||
|  |      */ | ||||||
|  |     upm_result_t nunchuck_update(const nunchuck_context dev); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Returns the current analog stick X and Y positions. | ||||||
|  |      * nunchuck_update() must have been called prior to calling this | ||||||
|  |      * function. | ||||||
|  |      * | ||||||
|  |      * @param dev Device context | ||||||
|  |      * @param x Pointer in which the X value will be stored | ||||||
|  |      * @param y Pointer in which the Y value will be stored | ||||||
|  |      */ | ||||||
|  |     void nunchuck_get_stick(const nunchuck_context dev, int *x, int *y); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Returns the current accelerometer values.  nunchuck_update() | ||||||
|  |      * must have been called prior to calling this function. | ||||||
|  |      * | ||||||
|  |      * @param dev Device context | ||||||
|  |      * @param x Pointer in which the X value will be stored | ||||||
|  |      * @param y Pointer in which the Y value will be stored | ||||||
|  |      * @param z Pointer in which the Z value will be stored | ||||||
|  |      */ | ||||||
|  |     void nunchuck_get_acceleration(const nunchuck_context dev, | ||||||
|  |                                    int *x, int *y, int *z); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Returns the current button values values.  nunchuck_update() | ||||||
|  |      * must have been called prior to calling this function. | ||||||
|  |      * | ||||||
|  |      * @param dev Device context | ||||||
|  |      * @param c Pointer in which the C button value will be stored | ||||||
|  |      * @param z Pointer in which the Z button value will be stored | ||||||
|  |      */ | ||||||
|  |     void nunchuck_get_buttons(const nunchuck_context dev, bool *c, bool *z); | ||||||
|  |  | ||||||
|  | #ifdef __cplusplus | ||||||
|  | } | ||||||
|  | #endif | ||||||
| @@ -1,6 +1,6 @@ | |||||||
| /* | /* | ||||||
|  * Author: Jon Trulson <jtrulson@ics.com> |  * Author: Jon Trulson <jtrulson@ics.com> | ||||||
|  * Copyright (c) 2015 Intel Corporation. |  * Copyright (c) 2015-2017 Intel Corporation. | ||||||
|  * |  * | ||||||
|  * Permission is hereby granted, free of charge, to any person obtaining |  * Permission is hereby granted, free of charge, to any person obtaining | ||||||
|  * a copy of this software and associated documentation files (the |  * a copy of this software and associated documentation files (the | ||||||
| @@ -24,9 +24,8 @@ | |||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #include <string> | #include <string> | ||||||
| #include <mraa/i2c.h> | #include "nunchuck.h" | ||||||
|  |  | ||||||
| #define NUNCHUCK_I2C_ADDR    0x52 |  | ||||||
|  |  | ||||||
| namespace upm { | namespace upm { | ||||||
|  |  | ||||||
| @@ -48,17 +47,16 @@ namespace upm { | |||||||
|    * @brief API for the Wii* Nunchuk controller |    * @brief API for the Wii* Nunchuk controller | ||||||
|    * |    * | ||||||
|    * UPM module for the Wii Nunchuk controller. This module was tested with |    * UPM module for the Wii Nunchuk controller. This module was tested with | ||||||
|    * Wii Nunchuk connected to I2C via a Grove Wii Nunchuk adapter. |    * Wii Nunchuck connected to I2C via a Grove Wii Nunchuck adapter. | ||||||
|    * |    * | ||||||
|    * See http://wiibrew.org/wiki/Wiimote/Extension_Controllers and |    * See http://wiibrew.org/wiki/Wiimote/Extension_Controllers and | ||||||
|    * http://wiibrew.org/wiki/Wiimote/Extension_Controllers/Nunchuck |    * http://wiibrew.org/wiki/Wiimote/Extension_Controllers/Nunchuck | ||||||
|    * for more details on the controller and its protocol. |    * for more details on the controller and its protocol. | ||||||
|    * |    * | ||||||
|    * A warning for the Grove Wii Nunchuk adapter: it has 2 traces on one |    * A warning for the Grove Wii Nunchuk adapter: it has 2 traces on | ||||||
|    * side, and 3 traces on the other.  Do not match these up with the |    * one side, and 3 traces on the other.  Do not match these up with | ||||||
|    * Nunchuk connector's traces. The connector's 'Grove' |    * the Nunchuk connector's traces. The connector's 'groove' should | ||||||
|    * should be on the same side as the Grove interface socket on the |    * be on the same side as the Grove interface socket on the adapter. | ||||||
|    * adapter. |  | ||||||
|    * |    * | ||||||
|    * @image html nunchuck.jpg |    * @image html nunchuck.jpg | ||||||
|    * @snippet nunchuck.cxx Interesting |    * @snippet nunchuck.cxx Interesting | ||||||
| @@ -71,39 +69,12 @@ namespace upm { | |||||||
|      * @param bus I2C bus to use |      * @param bus I2C bus to use | ||||||
|      * @param addr I2C address to use |      * @param addr I2C address to use | ||||||
|      */ |      */ | ||||||
|     NUNCHUCK(int bus, uint8_t addr=NUNCHUCK_I2C_ADDR); |     NUNCHUCK(int bus); | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * NUNCHUCK destructor |      * NUNCHUCK destructor | ||||||
|      */ |      */ | ||||||
|     ~NUNCHUCK(); |     virtual ~NUNCHUCK(); | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Writes value(s) into registers |  | ||||||
|      * |  | ||||||
|      * @param reg Register location to start writing into |  | ||||||
|      * @param byte Byte to write |  | ||||||
|      * @return True if successful |  | ||||||
|      */ |  | ||||||
|     bool writeByte(uint8_t reg, uint8_t byte); |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Reads value(s) from registers |  | ||||||
|      * |  | ||||||
|      * @param reg Register location to start reading from |  | ||||||
|      * @param buffer Buffer for data storage |  | ||||||
|      * @param len Number of bytes to read |  | ||||||
|      * @return Number of bytes read |  | ||||||
|      */ |  | ||||||
|     int readBytes(uint8_t reg, uint8_t *buffer, int len); |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Initializes the controller. Here, we disable encryption after |  | ||||||
|      * delaying for a time to ensure the controller is ready. |  | ||||||
|      * |  | ||||||
|      * @return True if initialization is successful |  | ||||||
|      */ |  | ||||||
|     bool init(); |  | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Reads and updates the current state of the controller. |      * Reads and updates the current state of the controller. | ||||||
| @@ -153,8 +124,10 @@ namespace upm { | |||||||
|      */ |      */ | ||||||
|     bool buttonZ; |     bool buttonZ; | ||||||
|  |  | ||||||
|  |   protected: | ||||||
|  |       nunchuck_context m_nunchuck; | ||||||
|  |  | ||||||
|   private: |   private: | ||||||
|     mraa_i2c_context m_i2c; |  | ||||||
|   }; |   }; | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										190
									
								
								src/nunchuck/nunchuck_fti.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										190
									
								
								src/nunchuck/nunchuck_fti.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,190 @@ | |||||||
|  | /* | ||||||
|  |  * Author: Jon Trulson <jtrulson@ics.com> | ||||||
|  |  * Copyright (c) 2017 Intel Corporation. | ||||||
|  |  * | ||||||
|  |  * Permission is hereby granted, free of charge, to any person obtaining | ||||||
|  |  * a copy of this software and associated documentation files (the | ||||||
|  |  * "Software"), to deal in the Software without restriction, including | ||||||
|  |  * without limitation the rights to use, copy, modify, merge, publish, | ||||||
|  |  * distribute, sublicense, and/or sell copies of the Software, and to | ||||||
|  |  * permit persons to whom the Software is furnished to do so, subject to | ||||||
|  |  * the following conditions: | ||||||
|  |  * | ||||||
|  |  * The above copyright notice and this permission notice shall be | ||||||
|  |  * included in all copies or substantial portions of the Software. | ||||||
|  |  * | ||||||
|  |  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||||||
|  |  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||||||
|  |  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||||||
|  |  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | ||||||
|  |  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||||||
|  |  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||||||
|  |  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #include "nunchuck.h" | ||||||
|  |  | ||||||
|  | #include "upm_fti.h" | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * This file implements the Function Table Interface (FTI) for this sensor | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | const char upm_nunchuck_name[] = "NUNCHUCK"; | ||||||
|  | const char upm_nunchuck_description[] = "Nunchuck controller"; | ||||||
|  | const upm_protocol_t upm_nunchuck_protocol[] = {UPM_I2C}; | ||||||
|  | const upm_sensor_t upm_nunchuck_category[] = | ||||||
|  | { UPM_ACCELEROMETER, UPM_JOYSTICK, UPM_BUTTONS}; | ||||||
|  |  | ||||||
|  | // forward declarations | ||||||
|  | const void* upm_nunchuck_get_ft(upm_sensor_t sensor_type); | ||||||
|  | void* upm_nunchuck_init_name(); | ||||||
|  | void upm_nunchuck_close(void *dev); | ||||||
|  | upm_result_t upm_nunchuck_get_accel_values(void *dev, float *value, upm_acceleration_u unit); | ||||||
|  | upm_result_t upm_nunchuck_get_joystick_value_x(const void *dev, float *value); | ||||||
|  | upm_result_t upm_nunchuck_get_joystick_value_y(const void *dev, float *value); | ||||||
|  | upm_result_t upm_nunchuck_get_num_buttons(const void *dev, | ||||||
|  |                                           unsigned int *num_buttons); | ||||||
|  | upm_result_t upm_nunchuck_get_button_values(const void *dev, | ||||||
|  |                                             bool *values); | ||||||
|  |  | ||||||
|  | const upm_sensor_descriptor_t upm_nunchuck_get_descriptor() | ||||||
|  | { | ||||||
|  |     upm_sensor_descriptor_t usd; | ||||||
|  |     usd.name = upm_nunchuck_name; | ||||||
|  |     usd.description = upm_nunchuck_description; | ||||||
|  |     usd.protocol_size = 1; | ||||||
|  |     usd.protocol = upm_nunchuck_protocol; | ||||||
|  |     usd.category_size = 3; | ||||||
|  |     usd.category = upm_nunchuck_category; | ||||||
|  |     return usd; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static const upm_sensor_ft ft = | ||||||
|  | { | ||||||
|  |     .upm_sensor_init_name = upm_nunchuck_init_name, | ||||||
|  |     .upm_sensor_close = upm_nunchuck_close, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | static const upm_acceleration_ft aft = | ||||||
|  | { | ||||||
|  |     .upm_acceleration_get_value = upm_nunchuck_get_accel_values | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | static const upm_joystick_ft jft = | ||||||
|  | { | ||||||
|  |     .upm_joystick_get_value_x = upm_nunchuck_get_joystick_value_x, | ||||||
|  |     .upm_joystick_get_value_y = upm_nunchuck_get_joystick_value_y | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | static const upm_buttons_ft bft = | ||||||
|  | { | ||||||
|  |     .upm_buttons_get_num_buttons = upm_nunchuck_get_num_buttons, | ||||||
|  |     .upm_buttons_get_values = upm_nunchuck_get_button_values | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | const void* upm_nunchuck_get_ft(upm_sensor_t sensor_type) | ||||||
|  | { | ||||||
|  |   switch(sensor_type) | ||||||
|  |     { | ||||||
|  |     case UPM_SENSOR: | ||||||
|  |       return &ft; | ||||||
|  |  | ||||||
|  |     case UPM_ACCELEROMETER: | ||||||
|  |       return &aft; | ||||||
|  |  | ||||||
|  |     case UPM_JOYSTICK: | ||||||
|  |       return &jft; | ||||||
|  |  | ||||||
|  |     case UPM_BUTTONS: | ||||||
|  |       return &bft; | ||||||
|  |  | ||||||
|  |     default: | ||||||
|  |       return NULL; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void* upm_nunchuck_init_name() | ||||||
|  | { | ||||||
|  |     return NULL; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void upm_nunchuck_close(void *dev) | ||||||
|  | { | ||||||
|  |     nunchuck_close((nunchuck_context)dev); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | upm_result_t upm_nunchuck_get_accel_values(void *dev, | ||||||
|  |                                            float *value, | ||||||
|  |                                            upm_acceleration_u unit) | ||||||
|  | { | ||||||
|  |     if (nunchuck_update((nunchuck_context)dev)) | ||||||
|  |         return UPM_ERROR_OPERATION_FAILED; | ||||||
|  |  | ||||||
|  |     int x, y, z; | ||||||
|  |     nunchuck_get_acceleration((nunchuck_context)dev, &x, &y, &z); | ||||||
|  |     value[0] = (float)x; | ||||||
|  |     value[1] = (float)y; | ||||||
|  |     value[2] = (float)z; | ||||||
|  |  | ||||||
|  |     return UPM_SUCCESS; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | upm_result_t upm_nunchuck_get_joystick_value_x(const void *dev, float *value) | ||||||
|  | { | ||||||
|  |     // This is bad - separating getting X and Y stick values... You | ||||||
|  |     // can't be sure when updating for one axis whether the other | ||||||
|  |     // changed... Should be fixed by having a single function return | ||||||
|  |     // both values from the same sampletime.  Same goes for the rest | ||||||
|  |     // of the values reported. | ||||||
|  |     if (nunchuck_update((nunchuck_context)dev)) | ||||||
|  |         return UPM_ERROR_OPERATION_FAILED; | ||||||
|  |  | ||||||
|  |     int x; | ||||||
|  |     nunchuck_get_stick((nunchuck_context)dev, &x, NULL); | ||||||
|  |     *value = (float)x; | ||||||
|  |  | ||||||
|  |     return UPM_SUCCESS; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | upm_result_t upm_nunchuck_get_joystick_value_y(const void *dev, float *value) | ||||||
|  | { | ||||||
|  |     // This is bad - separating getting X and Y stick values... You | ||||||
|  |     // can't be sure when updating for one axis whether the other | ||||||
|  |     // changed... Should be fixed by having a single function return | ||||||
|  |     // both values from the same sampletime.  Same goes for the rest | ||||||
|  |     // of the values reported. | ||||||
|  |     if (nunchuck_update((nunchuck_context)dev)) | ||||||
|  |         return UPM_ERROR_OPERATION_FAILED; | ||||||
|  |  | ||||||
|  |     int y; | ||||||
|  |     nunchuck_get_stick((nunchuck_context)dev, NULL, &y); | ||||||
|  |     *value = (float)y; | ||||||
|  |  | ||||||
|  |     return UPM_SUCCESS; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | upm_result_t upm_nunchuck_get_num_buttons(const void *dev, | ||||||
|  |                                           unsigned int *num_buttons) | ||||||
|  | { | ||||||
|  |     // always 2 buttons (C and Z) | ||||||
|  |  | ||||||
|  |     *num_buttons = 2; | ||||||
|  |  | ||||||
|  |     return UPM_SUCCESS; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | upm_result_t upm_nunchuck_get_button_values(const void *dev, | ||||||
|  |                                             bool *values) | ||||||
|  | { | ||||||
|  |     if (nunchuck_update((nunchuck_context)dev)) | ||||||
|  |         return UPM_ERROR_OPERATION_FAILED; | ||||||
|  |  | ||||||
|  |     bool bc, bz; | ||||||
|  |     nunchuck_get_buttons((nunchuck_context)dev, &bc, &bz); | ||||||
|  |     // hope they passed a bool[2].... | ||||||
|  |     values[0] = bc; | ||||||
|  |     values[1] = bz; | ||||||
|  |  | ||||||
|  |     return UPM_SUCCESS; | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user
	 Jon Trulson
					Jon Trulson