├── CMakeLists.txt ├── LICENSE ├── README.md ├── examples ├── examples.c ├── gpio │ ├── README.MD │ ├── gpio_example.c │ ├── gpio_example.h │ ├── gpio_input.fzz │ ├── gpio_input.png │ ├── gpio_input_led.fzz │ ├── gpio_input_led.png │ ├── gpio_led.fzz │ └── gpio_led.png ├── i2c │ ├── README.MD │ ├── adxl345.fzz │ ├── adxl345.png │ ├── i2c_example.c │ ├── i2c_example.h │ ├── led8x8matrix.fzz │ └── led8x8matrix.png ├── leds │ ├── README.md │ ├── onboardleds.c │ └── onboardleds.h ├── pwm │ ├── README.md │ ├── pwm_example.c │ ├── pwm_example.h │ ├── pwm_led.fzz │ └── pwm_led.png ├── spi │ ├── README.MD │ ├── adxl345.fzz │ ├── adxl345.png │ ├── mcp23s08.fzz │ ├── mcp23s08.png │ ├── mcp23s08_mcp4902.fzz │ ├── mcp23s08_mcp4902.png │ ├── mcp4902.fzz │ ├── mcp4902.png │ ├── spi_example.c │ └── spi_example.h └── uart │ ├── README.md │ ├── uart.fzz │ ├── uart.png │ ├── uart_example.c │ └── uart_example.h ├── pbr.sh └── src ├── bbclib.c ├── gpio.c ├── gpio.h ├── i2c-dev.h ├── i2c.c ├── i2c.h ├── log.c ├── log.h ├── pwm.c ├── pwm.h ├── spi.c ├── spi.h ├── uart.c └── uart.h /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.7) 2 | project(BBCLib) 3 | 4 | set(CMAKE_CXX_STANDARD 14) 5 | # To test and compile on Mac mount the arm-willtm-linux-gnueabi.dmg 6 | if( APPLE ) 7 | set(CMAKE_C_COMPILER ../../gcc-arm-none-eabi-8-2018-q4-major/bin/arm-none-eabi-gcc) 8 | set(CMAKE_CXX_COMPILER ../../gcc-arm-none-eabi-8-2018-q4-major/bin/arm-none-eabi-gcc) 9 | endif() 10 | 11 | set(SOURCE_FILES src/bbclib.c src/gpio.c src/gpio.h src/i2c.c src/i2c.h src/i2c-dev.h src/pwm.c src/pwm.h src/spi.c src/spi.h src/uart.c src/uart.h examples/gpio/gpio_example.c examples/gpio/gpio_example.h examples/i2c/i2c_example.c examples/i2c/i2c_example.h examples/leds/onboardleds.c examples/leds/onboardleds.h examples/pwm/pwm_example.c examples/pwm/pwm_example.h examples/spi/spi_example.c examples/spi/spi_example.h examples/uart/uart_example.c examples/uart/uart_example.h examples/examples.c src/log.c src/log.h) 12 | 13 | set(SOURCE_FILES ${SOURCE_FILES}) 14 | 15 | add_executable(BBCLib ${SOURCE_FILES}) 16 | target_link_libraries( BBCLib ) -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | {description} 294 | Copyright (C) {year} {fullname} 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | {signature of Ty Coon}, 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | 341 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # BBCLib 2 | C Library for BeagleBone Black 3 | 4 | Supports: gpio, i2c, pwm, spi and uart. 5 | 6 | Compilation can be done on a none beagblebone system by using the gnu toolchain. Downloads can be found here https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads. 7 | Execution can only be performed on a beaglebone of course. 8 | 9 | -------------------------------------------------------------------------------- /examples/examples.c: -------------------------------------------------------------------------------- 1 | /* 2 | * examples.c 3 | * 4 | * Created on: Jun 7, 2015 5 | * Author: gijs 6 | */ 7 | 8 | #include 9 | #include 10 | #include "./gpio/gpio_example.h" 11 | #include "./i2c/i2c_example.h" 12 | #include "./pwm/pwm_example.h" 13 | #include "./spi/spi_example.h" 14 | #include "./uart/uart_example.h" 15 | #include "./leds/onboardleds.h" 16 | 17 | 18 | int main(int argc, char **argv) { 19 | printf("Choose the example to run:\n"); 20 | printf("1 - onboard leds\n"); 21 | printf("2 - gpio led\n"); 22 | printf("3 - gpio input\n"); 23 | printf("4 - gpio input led\n"); 24 | printf("5 - spi MCP23S08\n"); 25 | printf("6 - spi ADXL345\n"); 26 | printf("7 - spi MCP4902\n"); 27 | printf("8 - i2c 8x8 Led Matrix\n"); 28 | printf("9 - i2c ADXL345\n"); 29 | printf("10 - i2c ADXL345\n"); 30 | printf("11 - i2c ADXL345\n"); 31 | printf("12 - i2c ADXL345\n"); 32 | printf("13 - i2c ADXL345\n"); 33 | printf("14 - i2c ADXL345\n"); 34 | 35 | char c[100]; 36 | scanf("%s" , c) ; 37 | if (strcmp(c,"1") == 0) { 38 | onBoardLedsExample(); 39 | } else if (strcmp(c,"2") == 0) { 40 | gpioLedExample(); 41 | } else if (strcmp(c, "3") == 0) { 42 | gpioInputExample(); 43 | } else if (strcmp(c, "4") == 0) { 44 | gpioInputLedExample(); 45 | } else if (strcmp(c, "5") == 0) { 46 | spiMCP23S08Example(); 47 | } else if (strcmp(c, "6") == 0) { 48 | spiADXL345Example(); 49 | } else if (strcmp(c, "7") == 0) { 50 | spiMCP4902Example(); 51 | } else if (strcmp(c, "8") == 0) { 52 | spiMCP4912Example(); 53 | } else if (strcmp(c, "9") == 0) { 54 | spiMCP4922Example(); 55 | } else if (strcmp(c, "10") == 0) { 56 | i2c8x8LedMatrix(); 57 | } else if (strcmp(c, "11") == 0) { 58 | i2cADXL345(); 59 | } else if (strcmp(c, "12") == 0) { 60 | uartExample(); 61 | } else if (strcmp(c, "13") == 0) { 62 | pwmExample(); 63 | } else if (strcmp(c, "14") == 0) { 64 | spiMC23S08_MCP4902Example(); 65 | } 66 | 67 | return 0; 68 | } 69 | -------------------------------------------------------------------------------- /examples/gpio/README.MD: -------------------------------------------------------------------------------- 1 | The 3 examples are: 2 | * gpio led
3 | Simple example flashing a led for 60 times.
4 |
5 | Youtube 6 | * gpio input
7 | Simple example reading the button state.
8 |
9 | Youtube 10 | * gpio input driving a led
11 |
12 | Simple example of a led showing the button state.
13 | Youtube -------------------------------------------------------------------------------- /examples/gpio/gpio_example.c: -------------------------------------------------------------------------------- 1 | /* 2 | * spi.c 3 | * 4 | * Created on: May 31, 2015 5 | * Author: gijs 6 | */ 7 | 8 | #include "gpio_example.h" 9 | #include "../../src/log.h" 10 | #include 11 | 12 | /* 13 | * This example will open the gpio 60 port and flash the led 20 times. 14 | */ 15 | int gpioLedExample() { 16 | gpio_properties *gpio = malloc(sizeof(gpio_properties)); 17 | gpio->nr = LEDGPIO; 18 | gpio->direction = OUTPUT_PIN; 19 | 20 | int isOpen = gpio_open(gpio); 21 | 22 | if (isOpen == 0) { 23 | int i=0; 24 | for(i=0;i<10;i++) { 25 | gpio_set_value(gpio, 1); 26 | sleep(1); 27 | gpio_set_value(gpio, 0); 28 | sleep(1); 29 | } 30 | gpio_close(gpio); 31 | } 32 | free(gpio); 33 | debug("Finished gpio led example."); 34 | return 0; 35 | } 36 | 37 | /* 38 | * This example will open the gpio 15 port and read the input value for 1 minute. 39 | */ 40 | int gpioInputExample() { 41 | int value, i; 42 | 43 | gpio_properties *gpio = malloc(sizeof(gpio_properties)); 44 | gpio->nr = BUTTONGPIO; 45 | gpio->direction = INPUT_PIN; 46 | 47 | int isOpen = gpio_open(gpio); 48 | 49 | if (isOpen == 0) { 50 | for(i=0;i<600;i++) { 51 | value = gpio_get_value(gpio); 52 | printf("Value: %d\n", value); 53 | sleep(1); 54 | } 55 | gpio_close(gpio); 56 | } 57 | debug("Finished gpio input example."); 58 | return 0; 59 | } 60 | 61 | /* 62 | * This example will open the gpio 15 for input and gpio 60 for output 63 | * A positive read will turn on the led, a negative will turn it off. 64 | * This example will run for 1 minute. 65 | */ 66 | int gpioInputLedExample() { 67 | int value, i; 68 | 69 | gpio_properties *led = malloc(sizeof(gpio_properties)); 70 | led->nr = LEDGPIO; 71 | led->direction = OUTPUT_PIN; 72 | gpio_properties *button = malloc(sizeof(gpio_properties)); 73 | button->nr = BUTTONGPIO; 74 | button->direction = INPUT_PIN; 75 | 76 | int isOpen = gpio_open(led) && gpio_open(button); 77 | 78 | if (isOpen == 0) { 79 | for(i=0;i<600;i++) { 80 | value = gpio_get_value(button); 81 | gpio_set_value(led, value); 82 | sleep(1); 83 | } 84 | gpio_close(led); 85 | gpio_close(button); 86 | } 87 | free(led); 88 | free(button); 89 | debug("Finished gpio input led example."); 90 | return 0; 91 | } 92 | -------------------------------------------------------------------------------- /examples/gpio/gpio_example.h: -------------------------------------------------------------------------------- 1 | /* 2 | * spi.c 3 | * 4 | * Created on: May 31, 2015 5 | * Author: gijs 6 | */ 7 | 8 | #include "../../src/gpio.h" 9 | 10 | #define LEDGPIO 60; 11 | #define BUTTONGPIO 15; 12 | 13 | int gpioLedExample(); 14 | int gpioInputExample(); 15 | int gpioInputLedExample(); 16 | -------------------------------------------------------------------------------- /examples/gpio/gpio_input.fzz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sijpesteijn/BBCLib/7b4ab6acd6969eac9c3109da8e84a4948dfcb498/examples/gpio/gpio_input.fzz -------------------------------------------------------------------------------- /examples/gpio/gpio_input.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sijpesteijn/BBCLib/7b4ab6acd6969eac9c3109da8e84a4948dfcb498/examples/gpio/gpio_input.png -------------------------------------------------------------------------------- /examples/gpio/gpio_input_led.fzz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sijpesteijn/BBCLib/7b4ab6acd6969eac9c3109da8e84a4948dfcb498/examples/gpio/gpio_input_led.fzz -------------------------------------------------------------------------------- /examples/gpio/gpio_input_led.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sijpesteijn/BBCLib/7b4ab6acd6969eac9c3109da8e84a4948dfcb498/examples/gpio/gpio_input_led.png -------------------------------------------------------------------------------- /examples/gpio/gpio_led.fzz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sijpesteijn/BBCLib/7b4ab6acd6969eac9c3109da8e84a4948dfcb498/examples/gpio/gpio_led.fzz -------------------------------------------------------------------------------- /examples/gpio/gpio_led.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sijpesteijn/BBCLib/7b4ab6acd6969eac9c3109da8e84a4948dfcb498/examples/gpio/gpio_led.png -------------------------------------------------------------------------------- /examples/i2c/README.MD: -------------------------------------------------------------------------------- 1 | The beaglebone black has 2 i2c buses. 2 | 3 | The 2 examples are: 4 | * ADXL345 - accelerometer 5 |
6 | Youtube 7 | * LED 8x8 Matrix 8 |
9 | Youtube -------------------------------------------------------------------------------- /examples/i2c/adxl345.fzz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sijpesteijn/BBCLib/7b4ab6acd6969eac9c3109da8e84a4948dfcb498/examples/i2c/adxl345.fzz -------------------------------------------------------------------------------- /examples/i2c/adxl345.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sijpesteijn/BBCLib/7b4ab6acd6969eac9c3109da8e84a4948dfcb498/examples/i2c/adxl345.png -------------------------------------------------------------------------------- /examples/i2c/i2c_example.c: -------------------------------------------------------------------------------- 1 | /* 2 | * spi.c 3 | * 4 | * Created on: May 31, 2015 5 | * Author: gijs 6 | */ 7 | 8 | #include "i2c_example.h" 9 | #include "../../src/log.h" 10 | #include 11 | #include 12 | 13 | const __u8 heart[4][16] = { 14 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 15 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x3c, 0x00, 0x24, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00 }, 16 | { 0x00, 0x00, 0x00, 0x24, 0x00, 0x5a, 0x00, 0x42, 0x00, 0x42, 0x00, 0x24, 0x00, 0x18, 0x00, 0x00 }, 17 | { 0x00, 0x42, 0x00, 0xa5, 0x00, 0x99, 0x00, 0x81, 0x00, 0x81, 0x00, 0x42, 0x00, 0x24, 0x00, 0x18 } 18 | }; 19 | 20 | const __u8 smile[3][16] = { 21 | { 0x00, 0x00, 0x66, 0x00, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x42, 0x00, 0x00, 0x00 }, 22 | { 0x00, 0x00, 0x66, 0x00, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0x3c, 0x00, 0x00, 0x00 }, 23 | { 0x00, 0x00, 0x66, 0x00, 0x66, 0x00, 0x00, 0x00, 0x42, 0x00, 0x42, 0x00, 0x3c, 0x00, 0x00, 0x00 } 24 | }; 25 | 26 | void clearDisplay(i2c_properties *i2c) { 27 | __u8 reg = 0x00; 28 | for (; reg < 0x10; reg++) { 29 | write_data_i2c(i2c, reg, 0x00); 30 | } 31 | } 32 | 33 | void play(i2c_properties *i2c, size_t nrows, const __u8 shape[nrows][16], int delay) { 34 | __u8 reg; 35 | int i, j, loop = 5; 36 | while (loop-- > 0) { 37 | for (j = 0; j < nrows; j++) { 38 | reg = 0x00; 39 | for (i = 0; i < 16; i++) { 40 | write_data_i2c(i2c, reg++, shape[j][i]); 41 | } 42 | usleep(delay * 10000); 43 | } 44 | } 45 | for (i = 0; i < 15; i++) { 46 | clearDisplay(i2c); 47 | usleep(delay * 800); 48 | int g; 49 | reg = 0x00; 50 | for (g = 0; g < 16; g++) 51 | write_data_i2c(i2c, reg++, shape[nrows - 1][g]); 52 | } 53 | 54 | } 55 | 56 | int i2c8x8LedMatrix() { 57 | i2c_properties *i2c = malloc(sizeof(i2c_properties)); 58 | i2c->i2cnr = i2c1; 59 | i2c->deviceAddress = 0x70; 60 | i2c->openMode = O_RDWR; 61 | if (open_i2c(i2c) == -1) { 62 | debug("Could not open i2c bus."); 63 | return 0; 64 | } 65 | 66 | // Setup matrix 67 | write_byte_i2c(i2c,0x21); // Start oscillator 68 | write_byte_i2c(i2c,0x81); // Display on, blinking off 69 | write_byte_i2c(i2c,0xe7); // Full brightness 70 | clearDisplay(i2c); 71 | 72 | play(i2c, 4, heart, 10); 73 | play(i2c, 3, smile, 100); 74 | 75 | free(i2c); 76 | debug("Finished i2c example."); 77 | return 0; 78 | } 79 | 80 | // short is 16-bits in size on the BBB 81 | short combineValues(unsigned char msb, unsigned char lsb) { 82 | //shift the msb right by 8 bits and OR with lsb 83 | return ((short) msb << 8) | (short) lsb; 84 | } 85 | 86 | /* 87 | * ADXL345 is a Digital Accelerometer. It can measure movement on 3 axis. 88 | * This example will probe the axis 20 times every second. 89 | */ 90 | int i2cADXL345() { 91 | i2c_properties *i2c = malloc(sizeof(i2c_properties)); 92 | i2c->i2cnr = i2c1; 93 | i2c->deviceAddress = ADX_DEVID; 94 | i2c->openMode = O_RDWR; 95 | if (open_i2c(i2c) == -1) { 96 | debug("Could not open i2c bus."); 97 | return 0; 98 | } 99 | unsigned char *readBuffer = malloc(sizeof(unsigned char) * BUFFER_SIZE); 100 | 101 | // Setup adxl345 102 | write_data_i2c(i2c, POWER_CTL, 0x08); 103 | write_data_i2c(i2c, DATA_FORMAT, 0x00); 104 | write_data_i2c(i2c, 0x00, 0x00); 105 | 106 | read_i2c(i2c, readBuffer, BUFFER_SIZE); 107 | debug("The Device ID is: 0x%02x", readBuffer[0x00]); 108 | debug("The POWER_CTL mode is: 0x%02x", readBuffer[POWER_CTL]); 109 | debug("The DATA_FORMAT is: 0x%02x", readBuffer[DATA_FORMAT]); 110 | 111 | int i; 112 | for (i = 0; i < 20; i++) { 113 | write_data_i2c(i2c, 0x00, 0x00); 114 | read_i2c(i2c, readBuffer, BUFFER_SIZE); 115 | short x = combineValues(readBuffer[DATAX1], readBuffer[DATAX0]); 116 | short y = combineValues(readBuffer[DATAY1], readBuffer[DATAY0]); 117 | short z = combineValues(readBuffer[DATAZ1], readBuffer[DATAZ0]); 118 | 119 | printf("X = %i Y = %i Z = %i Sample: %i\n", x, y, z, i+1); 120 | usleep(1000000); 121 | } 122 | free(readBuffer); 123 | free(i2c); 124 | 125 | return 0; 126 | } 127 | -------------------------------------------------------------------------------- /examples/i2c/i2c_example.h: -------------------------------------------------------------------------------- 1 | /* 2 | * spi.c 3 | * 4 | * Created on: May 31, 2015 5 | * Author: gijs 6 | */ 7 | 8 | #include 9 | #include "../../src/i2c.h" 10 | 11 | #define ADX_DEVID 0x53 12 | #define POWER_CTL 0x2D 13 | #define DATA_FORMAT 0x31 14 | #define DATAX0 0x32 15 | #define DATAX1 0x33 16 | #define DATAY0 0x34 17 | #define DATAY1 0x35 18 | #define DATAZ0 0x36 19 | #define DATAZ1 0x37 20 | #define BUFFER_SIZE 0x40 21 | 22 | int daddress; 23 | int i2c8x8LedMatrix(); 24 | int i2cADXL345(); 25 | -------------------------------------------------------------------------------- /examples/i2c/led8x8matrix.fzz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sijpesteijn/BBCLib/7b4ab6acd6969eac9c3109da8e84a4948dfcb498/examples/i2c/led8x8matrix.fzz -------------------------------------------------------------------------------- /examples/i2c/led8x8matrix.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sijpesteijn/BBCLib/7b4ab6acd6969eac9c3109da8e84a4948dfcb498/examples/i2c/led8x8matrix.png -------------------------------------------------------------------------------- /examples/leds/README.md: -------------------------------------------------------------------------------- 1 | The BeagleBone has 4 onboard leds we can control. 2 | 3 | The onBoardLedsExample program show some led sequences. 4 | 5 | Youtube: https://youtu.be/ntYn5v-Zb3M -------------------------------------------------------------------------------- /examples/leds/onboardleds.c: -------------------------------------------------------------------------------- 1 | /* 2 | * onboardleds.h 3 | * 4 | * Created on: Jul 28, 2015 5 | * Author: gijs 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include "onboardleds.h" 13 | #include "../../src/log.h" 14 | 15 | void saveOriginalLedTrigger(led_info *led) { 16 | // printf("Get Led trigger %d", led->lednr); 17 | FILE *fd; 18 | int i, j = 0, start = -1, end = -1; 19 | char buf[BUF_SIZE]; 20 | snprintf(buf, sizeof(buf), leddir "trigger", led->lednr); 21 | 22 | fd = fopen(buf, "r"); 23 | if (fd < 0) { 24 | error("On board leds: could not get led trigger"); 25 | } 26 | 27 | char str[1024]; 28 | fgets(str, 1024, fd); 29 | for(i = 0; i < 1024; i++) { 30 | if (str[i] == '[') 31 | start = i + 1; 32 | if (str[i] == ']') 33 | end = i; 34 | } 35 | if (start == -1 || end == -1) { 36 | error("Could not find trigger in values: %s\n", str); 37 | } 38 | led->org_trigger = malloc(sizeof(char)*((end - start) + 1)); 39 | 40 | for( i = start; i < end; i++) { 41 | led->org_trigger[j++] = str[i]; 42 | } 43 | led->org_trigger[end] = '\0'; 44 | fclose(fd); 45 | } 46 | 47 | void setLedTrigger(led_info *led, char *value) { 48 | // printf("Set Led trigger %d", led->lednr); 49 | FILE *fd; 50 | char buf[BUF_SIZE]; 51 | snprintf(buf, sizeof(buf), leddir "trigger", led->lednr); 52 | 53 | fd = fopen(buf, "w"); 54 | fputs(value, fd); 55 | fclose(fd); 56 | } 57 | 58 | void saveOriginalLedBrightness(led_info *led) { 59 | FILE *fd; 60 | char buf[BUF_SIZE]; 61 | snprintf(buf, sizeof(buf), leddir "brightness", led->lednr); 62 | 63 | fd = fopen(buf, "r"); 64 | char str[2]; 65 | fgets(str, 2, fd); 66 | led->org_brightness = atoi(str); 67 | fclose(fd); 68 | } 69 | 70 | void setLedBrightness(led_info *led, int value) { 71 | FILE *fd; 72 | char buf[BUF_SIZE]; 73 | snprintf(buf, sizeof(buf), leddir "brightness", led->lednr); 74 | 75 | fd = fopen(buf, "w"); 76 | char str[2]; 77 | sprintf(str, "%d", value); 78 | fputs(str, fd); 79 | fclose(fd); 80 | } 81 | 82 | void saveState() { 83 | saveOriginalLedTrigger(led0); 84 | saveOriginalLedBrightness(led0); 85 | saveOriginalLedTrigger(led1); 86 | saveOriginalLedBrightness(led1); 87 | saveOriginalLedTrigger(led2); 88 | saveOriginalLedBrightness(led2); 89 | saveOriginalLedTrigger(led3); 90 | saveOriginalLedBrightness(led3); 91 | } 92 | 93 | void resetState() { 94 | setLedTrigger(led0, led0->org_trigger); 95 | setLedBrightness(led0, led0->org_brightness); 96 | setLedTrigger(led1, led1->org_trigger); 97 | setLedBrightness(led1, led1->org_brightness); 98 | setLedTrigger(led2, led2->org_trigger); 99 | setLedBrightness(led2, led2->org_brightness); 100 | setLedTrigger(led3, led3->org_trigger); 101 | setLedBrightness(led3, led3->org_brightness); 102 | } 103 | 104 | void clearLeds() { 105 | setLedTrigger(led0, "none"); 106 | setLedBrightness(led0, 0); 107 | setLedTrigger(led1, "none"); 108 | setLedBrightness(led1, 0); 109 | setLedTrigger(led2, "none"); 110 | setLedBrightness(led2, 0); 111 | setLedTrigger(led3, "none"); 112 | setLedBrightness(led3, 0); 113 | } 114 | 115 | void walker() { 116 | int i; 117 | for(i = 0; i < 5; i++) { 118 | setLedBrightness(led0, 1); 119 | usleep(DELAY/3); 120 | setLedBrightness(led0, 0); 121 | usleep(DELAY/3); 122 | setLedBrightness(led1, 1); 123 | usleep(DELAY/3); 124 | setLedBrightness(led1, 0); 125 | usleep(DELAY/3); 126 | setLedBrightness(led2, 1); 127 | usleep(DELAY/3); 128 | setLedBrightness(led2, 0); 129 | usleep(DELAY/3); 130 | setLedBrightness(led3, 1); 131 | usleep(DELAY/3); 132 | setLedBrightness(led3, 0); 133 | usleep(DELAY/3); 134 | } 135 | } 136 | 137 | void filler() { 138 | int i; 139 | for(i = 0; i < 5; i++) { 140 | setLedBrightness(led0, 1); 141 | usleep(DELAY); 142 | setLedBrightness(led1, 1); 143 | usleep(DELAY); 144 | setLedBrightness(led2, 1); 145 | usleep(DELAY); 146 | setLedBrightness(led3, 1); 147 | usleep(DELAY); 148 | clearLeds(); 149 | usleep(DELAY); 150 | } 151 | } 152 | 153 | void shader() { 154 | int i; 155 | for(i = 0; i < 5; i++) { 156 | setLedBrightness(led0, 1); 157 | setLedBrightness(led1, 1); 158 | setLedBrightness(led2, 1); 159 | setLedBrightness(led3, 1); 160 | usleep(DELAY); 161 | 162 | setLedBrightness(led0, 0); 163 | usleep(DELAY); 164 | setLedBrightness(led0, 1); 165 | setLedBrightness(led1, 0); 166 | usleep(DELAY); 167 | setLedBrightness(led1, 1); 168 | setLedBrightness(led2, 0); 169 | usleep(DELAY); 170 | setLedBrightness(led2, 1); 171 | setLedBrightness(led3, 0); 172 | usleep(DELAY); 173 | } 174 | } 175 | 176 | void flipflop() { 177 | int i; 178 | for(i = 0; i < 5; i++) { 179 | setLedBrightness(led0, 1); 180 | setLedBrightness(led1, 0); 181 | setLedBrightness(led2, 1); 182 | setLedBrightness(led3, 0); 183 | usleep(DELAY); 184 | setLedBrightness(led0, 0); 185 | setLedBrightness(led1, 1); 186 | setLedBrightness(led2, 0); 187 | setLedBrightness(led3, 1); 188 | usleep(DELAY); 189 | } 190 | } 191 | 192 | int onBoardLedsExample() { 193 | led0 = malloc(sizeof(led_info)); 194 | led1 = malloc(sizeof(led_info)); 195 | led2 = malloc(sizeof(led_info)); 196 | led3 = malloc(sizeof(led_info)); 197 | led0->lednr = 0; 198 | led1->lednr = 1; 199 | led2->lednr = 2; 200 | led3->lednr = 3; 201 | 202 | saveState(); 203 | clearLeds(); 204 | walker(); 205 | filler(); 206 | shader(); 207 | flipflop(); 208 | resetState(); 209 | 210 | free(led0); 211 | free(led1); 212 | free(led2); 213 | free(led3); 214 | debug("Finished on board leds example"); 215 | return 0; 216 | } 217 | -------------------------------------------------------------------------------- /examples/leds/onboardleds.h: -------------------------------------------------------------------------------- 1 | /* 2 | * onboardleds.h 3 | * 4 | * Created on: Jul 28, 2015 5 | * Author: gijs 6 | */ 7 | 8 | #ifndef EXAMPLES_LEDS_ONBOARDLEDS_H_ 9 | #define EXAMPLES_LEDS_ONBOARDLEDS_H_ 10 | 11 | #include 12 | #define BUF_SIZE 64 13 | #define leddir "/sys/class/leds/beaglebone:green:usr%d/" 14 | #define DELAY 300000 15 | 16 | typedef struct { 17 | char* org_trigger; 18 | int org_brightness; 19 | int lednr; 20 | } led_info; 21 | 22 | led_info *led0, *led1, *led2, *led3; 23 | int onBoardLedsExample(); 24 | #endif /* EXAMPLES_LEDS_ONBOARDLEDS_H_ */ 25 | -------------------------------------------------------------------------------- /examples/pwm/README.md: -------------------------------------------------------------------------------- 1 | The BeagleBone has eight on-board pwm ports. 2 | 3 | On the BeagleBone Black, we must enable pwm before we can use it. 4 | 5 | To enable the pwm port on the P9 header, gpio 22, we first should disable the on board hdmi port:
6 | Rev A/B: Open the file /media/BEAGLEBONE/uEnv.txt in an editor (vim/nano)
7 | Rev C: Open the file /boot/uEnv.txt in an editor (vim/nano)
8 | Add the key "capemgr.disable_partno="
9 | Add the ports you want to enable, comma separated (BB-UART1, BB-UART2. BB-UART4, BB-UART5)
10 | Reboot
11 | An example line looks like this:
12 |

13 | root@beaglebone:/dev# cat /media/BEAGLEBONE/uEnv.txt
14 | cape_disable=capemgr.disable_partno=BB-BONELT-HDMI,BB-BONELT-HDMIN
15 |
16 | 17 | After reboot, the device tree is no longer loading the HDMI and the pwm port(s) can be loaded. To list the device tree do: 18 | cat /sys/devices/bone_capemgr.9/slots 19 | 20 |

21 | root@arm:/boot# cat /sys/devices/bone_capemgr.9/slots
22 | 0: 54:PF---
23 | 1: 55:PF---
24 | 2: 56:PF---
25 | 3: 57:PF---
26 | 4: ff:P-O-L Bone-LT-eMMC-2G,00A0,Texas Instrument,BB-BONE-EMMC-2G
27 | 5: ff:P-O-- Bone-Black-HDMI,00A0,Texas Instrument,BB-BONELT-HDMI
28 | 6: ff:P-O-- Bone-Black-HDMIN,00A0,Texas Instrument,BB-BONELT-HDMIN
29 |
30 |
-------------------------------------------------------------------------------- /examples/pwm/pwm_example.c: -------------------------------------------------------------------------------- 1 | /* 2 | * spi.c 3 | * 4 | * Created on: May 31, 2015 5 | * Author: gijs 6 | */ 7 | 8 | #include "pwm_example.h" 9 | #include "../../src/log.h" 10 | 11 | int pwmExample() { 12 | 13 | pwm_properties *pwm = malloc(sizeof(pwm_properties)); 14 | pwm->name = "pwm_test_P9_22.12"; 15 | 16 | int isOpen = pwm_open(pwm); 17 | 18 | if (isOpen == 1) { 19 | if (pwm_set_run(pwm, 0) < 0) { 20 | printf("Could not stop pwm port.\n"); 21 | return -1; 22 | } 23 | if (pwm_set_period(pwm, 10000) < 0) { 24 | printf("Could not set period.\n"); 25 | return -1; 26 | } 27 | if (pwm_set_duty(pwm, 1000) < 0) { 28 | printf("Could not set duty.\n"); 29 | return -1; 30 | } 31 | if (pwm_set_run(pwm, 1) < 0) { 32 | printf("Could not start pwm port.\n"); 33 | return -1; 34 | } 35 | 36 | int i=0,j=0; 37 | while(j++ < 10) { 38 | while(i-- > 0) { 39 | if (pwm_set_duty(pwm, i*100) < 0) { 40 | printf("Could not set duty.\n"); 41 | return -1; 42 | } 43 | debug("Wrote %d to pwm (%s)", i, pwm->name); 44 | usleep(100000); 45 | } 46 | i = 10; 47 | } 48 | 49 | pwm_set_run(pwm, 0); 50 | } 51 | debug("Finished pwm example."); 52 | return 0; 53 | } 54 | -------------------------------------------------------------------------------- /examples/pwm/pwm_example.h: -------------------------------------------------------------------------------- 1 | /* 2 | * spi.c 3 | * 4 | * Created on: May 31, 2015 5 | * Author: gijs 6 | */ 7 | 8 | #include 9 | #include "../../src/pwm.h" 10 | 11 | 12 | int pwmExample(); 13 | -------------------------------------------------------------------------------- /examples/pwm/pwm_led.fzz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sijpesteijn/BBCLib/7b4ab6acd6969eac9c3109da8e84a4948dfcb498/examples/pwm/pwm_led.fzz -------------------------------------------------------------------------------- /examples/pwm/pwm_led.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sijpesteijn/BBCLib/7b4ab6acd6969eac9c3109da8e84a4948dfcb498/examples/pwm/pwm_led.png -------------------------------------------------------------------------------- /examples/spi/README.MD: -------------------------------------------------------------------------------- 1 | The beaglebone black has 2 spi buses. 2 | 3 | The 4 examples are: 4 | * ADXL345
5 |
6 | Youtube 7 | * MCP23S08
8 |
9 | Youtube 10 | * MCP4902
11 |
12 | Youtube 13 | * MCP23S08 -> MCP4902 -> TL082
14 |
15 | MCP23S08 driving a MCP4902. The outputs from the MCP4902 are amplified by a TL082
16 | Youtube -------------------------------------------------------------------------------- /examples/spi/adxl345.fzz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sijpesteijn/BBCLib/7b4ab6acd6969eac9c3109da8e84a4948dfcb498/examples/spi/adxl345.fzz -------------------------------------------------------------------------------- /examples/spi/adxl345.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sijpesteijn/BBCLib/7b4ab6acd6969eac9c3109da8e84a4948dfcb498/examples/spi/adxl345.png -------------------------------------------------------------------------------- /examples/spi/mcp23s08.fzz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sijpesteijn/BBCLib/7b4ab6acd6969eac9c3109da8e84a4948dfcb498/examples/spi/mcp23s08.fzz -------------------------------------------------------------------------------- /examples/spi/mcp23s08.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sijpesteijn/BBCLib/7b4ab6acd6969eac9c3109da8e84a4948dfcb498/examples/spi/mcp23s08.png -------------------------------------------------------------------------------- /examples/spi/mcp23s08_mcp4902.fzz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sijpesteijn/BBCLib/7b4ab6acd6969eac9c3109da8e84a4948dfcb498/examples/spi/mcp23s08_mcp4902.fzz -------------------------------------------------------------------------------- /examples/spi/mcp23s08_mcp4902.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sijpesteijn/BBCLib/7b4ab6acd6969eac9c3109da8e84a4948dfcb498/examples/spi/mcp23s08_mcp4902.png -------------------------------------------------------------------------------- /examples/spi/mcp4902.fzz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sijpesteijn/BBCLib/7b4ab6acd6969eac9c3109da8e84a4948dfcb498/examples/spi/mcp4902.fzz -------------------------------------------------------------------------------- /examples/spi/mcp4902.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sijpesteijn/BBCLib/7b4ab6acd6969eac9c3109da8e84a4948dfcb498/examples/spi/mcp4902.png -------------------------------------------------------------------------------- /examples/spi/spi_example.c: -------------------------------------------------------------------------------- 1 | /* 2 | * spi.c 3 | * 4 | * Created on: May 31, 2015 5 | * Author: gijs 6 | */ 7 | 8 | #include "spi_example.h" 9 | #include "../../src/log.h" 10 | 11 | /* 12 | * MCP23S08 is a 8-Bit I/O Expander with Serial Interface. 13 | * This example lights the 8 leds in sequence for 10 times. 14 | */ 15 | int spiMCP23S08Example() { 16 | unsigned char mcp23s08_setup[] = { 0x40, 0x00, 0x00, }; 17 | unsigned char mcp23s08_gpios[] = { 0x40, 0x09, 0x01, }; 18 | 19 | spi_properties *spi = malloc(sizeof(spi_properties)); 20 | spi->spi_id = spi0; 21 | spi->bits_per_word = 8; 22 | spi->mode = 0; 23 | spi->speed = 10000000; 24 | spi->flags = O_RDWR; 25 | 26 | uint8_t isOpen = spi_open(spi); 27 | 28 | if (isOpen == 0) { 29 | spi_send(spi, mcp23s08_setup, sizeof(mcp23s08_setup)); 30 | // Loop from 0 to 255 and light the LED bar as a binary counter 31 | int i = 0, j = 0; 32 | while(j++ < 10) { 33 | for (i = 0; i < 8; i++) { 34 | // This function can send and receive data, just sending here 35 | if (spi_send(spi, mcp23s08_gpios, sizeof(mcp23s08_gpios)) == -1) { 36 | perror("Failed to update the display"); 37 | return -1; 38 | } 39 | usleep(100000); //sleep for 100ms each loop 40 | mcp23s08_gpios[2] = mcp23s08_gpios[2] << 1; 41 | } 42 | mcp23s08_gpios[2] = 0x01; 43 | } 44 | mcp23s08_gpios[2] = 0x00; 45 | if (spi_send(spi, mcp23s08_gpios, sizeof(mcp23s08_gpios)) == -1) { 46 | perror("Failed to update the display"); 47 | return -1; 48 | } 49 | spi_close(spi); 50 | } 51 | debug("Finished spi example."); 52 | return 0; 53 | } 54 | 55 | /* 56 | * ADXL345 is a Digital Accelerometer. It can measure movement on 3 axes. 57 | * This example will probe the axis 20 times every second. 58 | */ 59 | int spiADXL345Example() { 60 | 61 | printf("WORK IN PROGRESS\n"); 62 | unsigned char adxl345_setup[] = {}; 63 | unsigned char receive[6]; 64 | signed short data[3]; 65 | 66 | spi_properties *spi = malloc(sizeof(spi_properties)); 67 | spi->spi_id = spi0; 68 | spi->bits_per_word = 8; 69 | spi->mode = 3; 70 | spi->speed = 2000000; 71 | spi->flags = O_RDWR; 72 | 73 | uint8_t isOpen = spi_open(spi); 74 | 75 | if (isOpen == 0) { 76 | adxl345_setup[0] = 0x31; 77 | adxl345_setup[1] = 0x08; 78 | spi_send(spi, adxl345_setup, 2); 79 | adxl345_setup[0] = 0x2D; 80 | adxl345_setup[1] = 0x08; 81 | spi_send(spi, adxl345_setup, 2); 82 | while(1) { 83 | adxl345_setup[0] = 0x80|0x40|0x32; 84 | adxl345_setup[1] = 0x00; 85 | spi_transfer(spi, adxl345_setup, receive, 6); 86 | data[0] = receive[1]<<8 | receive[0]; // combine MSB and LSB 87 | data[1] = receive[3]<<8 | receive[2]; 88 | data[2] = receive[5]<<8 | receive[4]; 89 | printf("x = %i \ty = %i\t z = %i\n", data[0], data[1], data[2]); 90 | data[0] = 0; 91 | data[1] = 0; 92 | data[2] = 0; 93 | usleep(1000000); 94 | } 95 | } 96 | return 0; 97 | } 98 | 99 | void write8Bits(spi_properties *spi, unsigned char reg, unsigned char value) { 100 | unsigned char data[2] = {}; 101 | data[0] = reg | ((value & 0xf0) >> 4); 102 | data[1] = (value & 0x0f) << 4; 103 | if (spi_send(spi, data, sizeof(data)) == -1) { 104 | perror("Failed to update output."); 105 | } 106 | } 107 | 108 | /* 109 | * MCP4902 is a 8-Bit Dual Voltage Output Digital-to-Analog Converter with SPI Interface. 110 | * This example will increase the output for A untill the maximum and then decrease to the minimum 10 times. 111 | * Output B will reflect the inverse of output A. 112 | * 255 113 | */ 114 | int spiMCP4902Example() { 115 | 116 | spi_properties *spi = malloc(sizeof(spi_properties)); 117 | spi->spi_id = spi0; 118 | spi->bits_per_word = 8; 119 | spi->mode = 3; 120 | spi->speed = 2400000; 121 | spi->flags = O_RDWR; 122 | 123 | int delay = 1000; 124 | 125 | uint8_t isSpiOpen = spi_open(spi); 126 | if (isSpiOpen == 0) { 127 | 128 | int i = 0; 129 | unsigned char value = 0x00; 130 | while(i++ < 10) { 131 | while(value < 0xff) { 132 | write8Bits(spi, 0x70, value); 133 | write8Bits(spi, 0xf0, ~value); 134 | usleep(delay); 135 | value = value + 1; 136 | } 137 | while(value > 0x00) { 138 | value = value - 1; 139 | write8Bits(spi, 0x70, value); 140 | write8Bits(spi, 0xf0, ~value); 141 | usleep(delay); 142 | } 143 | } 144 | write8Bits(spi, 0x70, 0); 145 | write8Bits(spi, 0xf0, 0); 146 | } 147 | free(spi); 148 | debug("Finished spi example."); 149 | return 0; 150 | } 151 | 152 | void write10Bits(spi_properties *spi, unsigned char reg, unsigned short value) { 153 | unsigned char data[2] = {}; 154 | data[0] = reg | ((value & 0xff00) >> 6); 155 | data[1] = (value & 0x00ff); 156 | if (spi_send(spi, data, sizeof(data)) == -1) { 157 | perror("Failed to update output."); 158 | } 159 | } 160 | 161 | /* 162 | * MCP4912 is a 10-Bit Dual Voltage Output Digital-to-Analog Converter with SPI Interface. 163 | * This example will increase the output for A untill the maximum and then decrease to the minimum 10 times. 164 | * Output B will reflect the inverse of output A. 165 | * 1024 166 | */ 167 | int spiMCP4912Example() { 168 | 169 | spi_properties *spi = malloc(sizeof(spi_properties)); 170 | spi->spi_id = spi0; 171 | spi->bits_per_word = 8; 172 | spi->mode = 3; 173 | spi->speed = 2400000; 174 | spi->flags = O_RDWR; 175 | 176 | int delay = 1000; 177 | 178 | uint8_t isSpiOpen = spi_open(spi); 179 | if (isSpiOpen == 0) { 180 | 181 | int i = 0; 182 | while(i++ < 10) { 183 | unsigned short value = 0x0000; 184 | while(value < 0x03ff) { 185 | write10Bits(spi, 0x70, value); 186 | write10Bits(spi, 0xf0, ~value); 187 | usleep(delay); 188 | value = value + 1; 189 | } 190 | while(value > 0x00) { 191 | value = value - 1; 192 | write10Bits(spi, 0x70, value); 193 | write10Bits(spi, 0xf0, ~value); 194 | usleep(delay); 195 | } 196 | } 197 | write10Bits(spi, 0x70, 0); 198 | write10Bits(spi, 0xf0, 0); 199 | } 200 | free(spi); 201 | debug("Finished spi example."); 202 | return 0; 203 | } 204 | 205 | void write12Bits(spi_properties *spi, unsigned char reg, unsigned short value) { 206 | unsigned char data[2] = {}; 207 | data[0] = reg | ((value & 0xff00) >> 8); 208 | data[1] = (value & 0x00ff); 209 | if (spi_send(spi, data, sizeof(data)) == -1) { 210 | perror("Failed to update output."); 211 | } 212 | } 213 | 214 | /* 215 | * MCP4922 is a 12-Bit Dual Voltage Output Digital-to-Analog Converter with SPI Interface. 216 | * This example will increase the output for A untill the maximum and then decrease to the minimum 10 times. 217 | * Output B will reflect the inverse of output A. 218 | * 4096 219 | */ 220 | int spiMCP4922Example() { 221 | 222 | spi_properties *spi = malloc(sizeof(spi_properties)); 223 | spi->spi_id = spi0; 224 | spi->bits_per_word = 8; 225 | spi->mode = 3; 226 | spi->speed = 2400000; 227 | spi->flags = O_RDWR; 228 | 229 | int delay = 1000; 230 | 231 | uint8_t isSpiOpen = spi_open(spi); 232 | if (isSpiOpen == 0) { 233 | 234 | int i = 0; 235 | unsigned short value = 0; 236 | while(i++ < 10) { 237 | while(value < 4096) { 238 | write12Bits(spi, 0x70, value); 239 | write12Bits(spi, 0xf0, ~value); 240 | usleep(delay); 241 | value = value + 1; 242 | } 243 | while(value > 0) { 244 | value = value - 1; 245 | write12Bits(spi, 0x70, value); 246 | write12Bits(spi, 0xf0, ~value); 247 | usleep(delay); 248 | } 249 | } 250 | write12Bits(spi, 0x70, 0); 251 | write12Bits(spi, 0xf0, 0); 252 | } 253 | free(spi); 254 | debug("Finished spi example."); 255 | return 0; 256 | } 257 | 258 | void dprint(unsigned char value) { 259 | debug("0x%02x", value); 260 | } 261 | 262 | int set_MCP23S08_GPIO_values(spi_properties *spi, unsigned char value) { 263 | unsigned char mcp23s08_gpios[] = { 0x40, 0x09, 0x00, }; 264 | mcp23s08_gpios[2] = value; 265 | // dprint(value); 266 | spi_send(spi, mcp23s08_gpios, sizeof(mcp23s08_gpios)); 267 | return 1; 268 | } 269 | 270 | int send_MCP49x2_values(spi_properties *spi, unsigned char value) { 271 | int bit_position = 8; 272 | while(bit_position > 0) { 273 | unsigned char bit_to_send = (value & 0x80) >> 2; 274 | // dprint(bit_to_send); 275 | unsigned char clkdata = bit_to_send; 276 | set_MCP23S08_GPIO_values(spi, clkdata); 277 | clkdata = (MCP23S08_SCK | bit_to_send); 278 | set_MCP23S08_GPIO_values(spi, clkdata); 279 | bit_position--; 280 | value = value << 1; 281 | } 282 | return 1; 283 | } 284 | 285 | void set_MCP49x2(unsigned char data[2], unsigned char chip, spi_properties* spi) { 286 | set_MCP23S08_GPIO_values(spi, chip | MCP23S08_SCK | MCP23S08_SDI); 287 | set_MCP23S08_GPIO_values(spi, MCP23S08_SCK | MCP23S08_SDI); 288 | set_MCP23S08_GPIO_values(spi, MCP23S08_SDI); 289 | set_MCP23S08_GPIO_values(spi, MCP23S08_ALL_DOWN); 290 | send_MCP49x2_values(spi, data[0]); 291 | send_MCP49x2_values(spi, data[1]); 292 | set_MCP23S08_GPIO_values(spi, MCP23S08_SCK | MCP23S08_SDI); 293 | set_MCP23S08_GPIO_values(spi, chip | MCP23S08_SCK | MCP23S08_SDI); 294 | } 295 | 296 | void setData(unsigned char *data, unsigned char reg, unsigned short value) { 297 | data[0] = reg | ((value & 0xf0) >> 4); 298 | data[1] = (value & 0x0f) << 4; 299 | } 300 | 301 | int spiMC23S08_MCP4902Example() { 302 | unsigned char mcp23s08_setup[] = { 0x40, 0x00, 0x00, }; 303 | 304 | spi_properties *spi = malloc(sizeof(spi_properties)); 305 | spi->spi_id = spi0; 306 | spi->bits_per_word = 8; 307 | spi->mode = 0; 308 | spi->speed = 10000000; 309 | spi->flags = O_RDWR; 310 | 311 | uint8_t isOpen = spi_open(spi); 312 | 313 | if (isOpen == 0) { 314 | spi_send(spi, mcp23s08_setup, sizeof(mcp23s08_setup)); 315 | 316 | unsigned char data[2] = {}; 317 | int delay = 1000; 318 | int i = 0; 319 | while(i++ < 10) { 320 | unsigned short value = 0x0000; 321 | while(value < 0xff) { 322 | setData(data, 0x70, value); 323 | set_MCP49x2(data, MCP4902_1_CS, spi); 324 | setData(data, 0xf0, ~value); 325 | set_MCP49x2(data, MCP4902_1_CS, spi); 326 | usleep(delay); 327 | value = value + 1; 328 | } 329 | while(value > 0x00) { 330 | value = value - 1; 331 | setData(data, 0x70, value); 332 | set_MCP49x2(data, MCP4902_1_CS, spi); 333 | setData(data, 0xf0, ~value); 334 | set_MCP49x2(data, MCP4902_1_CS, spi); 335 | usleep(delay); 336 | } 337 | } 338 | data[0] = 0x70; 339 | data[1] = 0x00; 340 | set_MCP49x2(data, MCP4902_1_CS, spi); 341 | data[0] = 0xf0; 342 | data[1] = 0x00; 343 | set_MCP49x2(data, MCP4902_1_CS, spi); 344 | } 345 | 346 | free(spi); 347 | debug("Finished spi example."); 348 | return 0; 349 | } 350 | -------------------------------------------------------------------------------- /examples/spi/spi_example.h: -------------------------------------------------------------------------------- 1 | /* 2 | * spi.c 3 | * 4 | * Created on: May 31, 2015 5 | * Author: gijs 6 | */ 7 | 8 | #include 9 | #include "../../src/spi.h" 10 | #include "../../src/gpio.h" 11 | #include "../gpio/gpio_example.h" 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #define MCP23S08_ALL_DOWN 0x00 23 | #define MCP4902_1_CS 0x01 //GPIO_0 0000 0001 24 | #define MCP4902_2_CS 0x02 //GPIO_1 0000 0010 25 | #define MCP4922_CS 0x04 //GPIO_2 0000 0100 26 | #define MCP23S08_LDAC 0x08 //GPIO_3 0000 1000 27 | #define MCP23S08_SCK 0x10 //GPIO_4 0001 0000 28 | #define MCP23S08_SDI 0x20 //GPIO_5 0010 0000 29 | #define MCP23S08_SHUTTER 0x40 //GPIO_6 0100 0000 30 | #define MCP23S08_SHUTTER_RETURN 0x80 //GPIO_7 1000 0000 31 | 32 | int spiMCP23S08Example(); 33 | int spiADXL345Example(); 34 | int spiMCP4902Example(); 35 | int spiMCP4912Example(); 36 | int spiMCP4922Example(); 37 | int spiMC23S08_MCP4902Example(); 38 | -------------------------------------------------------------------------------- /examples/uart/README.md: -------------------------------------------------------------------------------- 1 | The BeagleBone has six on-board serial ports.
2 |
3 | On the BeagleBone Black, it's only the /dev/ttyO0 that is enabled by default, and it is coupled to the serial console. The other serial ports must be enabled before they can be used.
4 |
5 | To enable the uarts 1,2,4 and/or 5 on the BeagleBone Black, rev A, B and C:
6 | Rev A/B: Open the file /media/BEAGLEBONE/uEnv.txt in an editor (vim/nano)
7 | Rev C: Open the file /boot/uEnv.txt in an editor (vim/nano)
8 | Add the key "cape_enable="
9 | Add the ports you want to enable, comma separated (BB-UART1, BB-UART2. BB-UART4, BB-UART5)
10 | Add the key "cape_disable"
11 | And add the BB-BONELT-HDMI and BB-BONELT-HDMIN
12 | Reboot
13 | An example line looks like this:
14 |

15 | root@beaglebone:/dev# cat /boot/uEnv.txt
16 | cape_enable=capemgr.enable_partno=BB-UART1
17 | cape_disable=capemgr.disable_partno=BB-BONELT-HDMI,BB-BONELT-HDMIN
18 |
19 |
20 |
21 | After reboot, the device is present in the device list:
22 |

23 |  root@beaglebone:/dev# ls -l /dev/ttyO*
24 | crw-rw---- 1 root tty 249, 0 Jan 1 01:18 /dev/ttyO0
25 | crw-rw---- 1 root dialout 249, 4 Jan 1 01:18 /dev/ttyO4
26 |
27 |
28 | The UARTs map to pins and devices like this:
29 |
30 |

31 |  RX  TX  CTS   RTS   Device  Remark
32 | UART0 J1_4 J1_5 /dev/ttyO0 BeagleBone Black only
33 | UART1 P9_26 P9_24 P9_20 P9_19 /dev/ttyO1
34 | UART2 P9_22 P9_21 P8_37 P8_38 /dev/ttyO2
35 | UART3 P9_42 P8_36 P8_34 /dev/ttyO3 TX only
36 | UART4 P9_11 P9_13 P8_35 P8_33 /dev/ttyO4
37 | UART5 P8_38 P8_37 P8_31 P8_32 /dev/ttyO5
38 |
39 | 40 |
-------------------------------------------------------------------------------- /examples/uart/uart.fzz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sijpesteijn/BBCLib/7b4ab6acd6969eac9c3109da8e84a4948dfcb498/examples/uart/uart.fzz -------------------------------------------------------------------------------- /examples/uart/uart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sijpesteijn/BBCLib/7b4ab6acd6969eac9c3109da8e84a4948dfcb498/examples/uart/uart.png -------------------------------------------------------------------------------- /examples/uart/uart_example.c: -------------------------------------------------------------------------------- 1 | /* 2 | * spi.c 3 | * 4 | * Created on: May 31, 2015 5 | * Author: gijs 6 | */ 7 | 8 | #include "uart_example.h" 9 | #include "../../src/log.h" 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | /* 16 | * UART. 17 | * This example will send the text 'foo n' (where is an index) a 10 times to the /dev/ttyO1 uart port. 18 | * The received text is printed on the screen. 19 | */ 20 | int uartExample() { 21 | 22 | printf("!!! Make sure you have enabled UART1 (/dev/ttyO1) see the README.md how to do this. !!!\n"); 23 | 24 | uart_properties *uart = malloc(sizeof(uart_properties)); 25 | uart->uart_id = uart1; 26 | uart->baudrate = B4800; 27 | 28 | uint8_t isOpen = uart_open(uart); 29 | int i = 0; 30 | 31 | if (isOpen == 0) { 32 | unsigned char receive[100]; 33 | while(i++ < 10) 34 | { 35 | char buf[30]; 36 | sprintf(buf, "foo %d", i); 37 | 38 | // Send data to uart1 39 | if (uart_send(uart, buf, strlen(buf) + 1) < 0) { 40 | printf("Could not send data to uart port"); 41 | return -1; 42 | } 43 | 44 | usleep(100000); 45 | 46 | // Read data from uart1 47 | if (uart_read(uart, receive, 100) < 0) { 48 | printf("Could not read data from uart port"); 49 | return -1; 50 | } 51 | 52 | printf("Read: %s\n",receive); 53 | usleep(50000); 54 | } 55 | uart_close(uart); 56 | } 57 | 58 | debug("Finished pwm example."); 59 | return 0; 60 | } 61 | -------------------------------------------------------------------------------- /examples/uart/uart_example.h: -------------------------------------------------------------------------------- 1 | /* 2 | * spi.c 3 | * 4 | * Created on: May 31, 2015 5 | * Author: gijs 6 | */ 7 | 8 | #include "../../src/uart.h" 9 | 10 | int uartExample(); 11 | -------------------------------------------------------------------------------- /pbr.sh: -------------------------------------------------------------------------------- 1 | #/bin/bash 2 | 3 | git pull 4 | make 5 | ./BBCLib -------------------------------------------------------------------------------- /src/bbclib.c: -------------------------------------------------------------------------------- 1 | /* 2 | * bbclib.c 3 | * 4 | * Created on: May 31, 2015 5 | * Author: gijs 6 | */ 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/gpio.c: -------------------------------------------------------------------------------- 1 | /* 2 | * gpio.c 3 | * 4 | * Created on: Jun 7, 2015 5 | * Author: gijs 6 | */ 7 | 8 | #include 9 | #include 10 | #include "gpio.h" 11 | #include "log.h" 12 | 13 | int gpio_open(gpio_properties *gpio) { 14 | // info("gpio_open: export gpio: %d", gpio->nr); 15 | FILE *export; 16 | export = fopen(SYSFS_GPIO_DIR "/export", "w"); 17 | if (export < 0) { 18 | perror("gpio/export"); 19 | return 1; 20 | } 21 | char str[15]; 22 | sprintf(str, "%d", gpio->nr); 23 | fputs(str, export); 24 | fclose(export); 25 | printf("%d\n", (int)gpio->direction); 26 | FILE *fd; 27 | char buf[MAX_BUF]; 28 | 29 | snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/direction", gpio->nr); 30 | fd = fopen(buf, "w"); 31 | if (fd < 0) { 32 | error("Could not set gpio direction: %s", gpio->direction); 33 | return 1; 34 | } 35 | if (gpio->direction == OUTPUT_PIN) 36 | fputs("out", fd); 37 | else 38 | fputs("in", fd); 39 | fclose(fd); 40 | return 0; 41 | } 42 | 43 | int gpio_close(gpio_properties *gpio) { 44 | info("gpio_close: unexport gpio: %d", gpio->nr); 45 | FILE *fd; 46 | fd = fopen(SYSFS_GPIO_DIR "/unexport", "w"); 47 | if (fd < 0) { 48 | perror("gpio/unexport"); 49 | return 1; 50 | } 51 | char str[15]; 52 | sprintf(str, "%d", gpio->nr); 53 | fputs(str, fd); 54 | fclose(fd); 55 | 56 | return 0; 57 | } 58 | 59 | int gpio_set_value(gpio_properties *gpio, int value) { 60 | debug("gpio set value: %d, %d", gpio->nr, value); 61 | FILE *fd; 62 | char buf[MAX_BUF]; 63 | 64 | snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/value", gpio->nr); 65 | 66 | fd = fopen(buf, "w"); 67 | if (fd < 0) { 68 | perror("gpio/set-value"); 69 | return 1; 70 | } 71 | 72 | char str[2]; 73 | sprintf(str, "%d", value); 74 | fputs(str, fd); 75 | 76 | fclose(fd); 77 | return 0; 78 | } 79 | 80 | int gpio_get_value(gpio_properties *gpio) { 81 | debug("gpio get value: %d", gpio->nr); 82 | int value; 83 | FILE *fd; 84 | char buf[MAX_BUF]; 85 | 86 | snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/value", gpio->nr); 87 | fd = fopen(buf, "r"); 88 | if (fd < 0) { 89 | perror("gpio/get-value"); 90 | return 1; 91 | } 92 | 93 | char str[2]; 94 | fgets(str, 2, fd); 95 | 96 | if (strcmp(str, "1") == 0) { 97 | value = 1; 98 | } else { 99 | value = 0; 100 | } 101 | 102 | fclose(fd); 103 | return value; 104 | } 105 | 106 | int gpio_set_edge(gpio_properties *gpio, char *edge) { 107 | debug("gpio set edge: %d, %s", gpio->nr, edge); 108 | FILE *fd; 109 | char buf[MAX_BUF]; 110 | 111 | snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/edge", gpio->nr); 112 | 113 | fd = fopen(buf, "w"); 114 | if (fd < 0) { 115 | perror("gpio/set-edge"); 116 | return 1; 117 | } 118 | 119 | fputs(edge, fd); 120 | fclose(fd); 121 | return 0; 122 | } 123 | -------------------------------------------------------------------------------- /src/gpio.h: -------------------------------------------------------------------------------- 1 | /* 2 | * gpio.h 3 | * 4 | * Created on: Jun 7, 2015 5 | * Author: gijs 6 | */ 7 | 8 | #ifndef GPIO_H_ 9 | #define GPIO_H_ 10 | 11 | #define SYSFS_GPIO_DIR "/sys/class/gpio" 12 | #define MAX_BUF 64 13 | 14 | typedef enum { 15 | INPUT_PIN=0, 16 | OUTPUT_PIN 17 | } PIN_DIRECTION; 18 | 19 | typedef struct { 20 | int nr; 21 | PIN_DIRECTION direction; 22 | } gpio_properties; 23 | 24 | extern int gpio_open(gpio_properties *gpio); 25 | extern int gpio_close(gpio_properties *gpio); 26 | extern int gpio_set_value(gpio_properties *gpio, int value); 27 | extern int gpio_get_value(gpio_properties *gpio); 28 | extern int gpio_set_edge(gpio_properties *gpio, char *edge); 29 | #endif /* GPIO_H_ */ 30 | -------------------------------------------------------------------------------- /src/i2c-dev.h: -------------------------------------------------------------------------------- 1 | /* 2 | i2c-dev.h - i2c-bus driver, char device interface 3 | 4 | Copyright (C) 1995-97 Simon G. Vogl 5 | Copyright (C) 1998-99 Frodo Looijaard 6 | 7 | This program is free software; you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation; either version 2 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program; if not, write to the Free Software 19 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 20 | MA 02110-1301 USA. 21 | */ 22 | 23 | /* $Id: i2c-dev.h 5894 2010-12-12 13:22:29Z khali $ */ 24 | 25 | #ifndef LIB_I2CDEV_H 26 | #define LIB_I2CDEV_H 27 | 28 | #include 29 | #include 30 | 31 | 32 | /* -- i2c.h -- */ 33 | 34 | 35 | /* 36 | * I2C Message - used for pure i2c transaction, also from /dev interface 37 | */ 38 | struct i2c_msg { 39 | __u16 addr; /* slave address */ 40 | unsigned short flags; 41 | #define I2C_M_TEN 0x10 /* we have a ten bit chip address */ 42 | #define I2C_M_RD 0x01 43 | #define I2C_M_NOSTART 0x4000 44 | #define I2C_M_REV_DIR_ADDR 0x2000 45 | #define I2C_M_IGNORE_NAK 0x1000 46 | #define I2C_M_NO_RD_ACK 0x0800 47 | short len; /* msg length */ 48 | char *buf; /* pointer to msg data */ 49 | }; 50 | 51 | /* To determine what functionality is present */ 52 | 53 | #define I2C_FUNC_I2C 0x00000001 54 | #define I2C_FUNC_10BIT_ADDR 0x00000002 55 | #define I2C_FUNC_PROTOCOL_MANGLING 0x00000004 /* I2C_M_{REV_DIR_ADDR,NOSTART,..} */ 56 | #define I2C_FUNC_SMBUS_PEC 0x00000008 57 | #define I2C_FUNC_SMBUS_BLOCK_PROC_CALL 0x00008000 /* SMBus 2.0 */ 58 | #define I2C_FUNC_SMBUS_QUICK 0x00010000 59 | #define I2C_FUNC_SMBUS_READ_BYTE 0x00020000 60 | #define I2C_FUNC_SMBUS_WRITE_BYTE 0x00040000 61 | #define I2C_FUNC_SMBUS_READ_BYTE_DATA 0x00080000 62 | #define I2C_FUNC_SMBUS_WRITE_BYTE_DATA 0x00100000 63 | #define I2C_FUNC_SMBUS_READ_WORD_DATA 0x00200000 64 | #define I2C_FUNC_SMBUS_WRITE_WORD_DATA 0x00400000 65 | #define I2C_FUNC_SMBUS_PROC_CALL 0x00800000 66 | #define I2C_FUNC_SMBUS_READ_BLOCK_DATA 0x01000000 67 | #define I2C_FUNC_SMBUS_WRITE_BLOCK_DATA 0x02000000 68 | #define I2C_FUNC_SMBUS_READ_I2C_BLOCK 0x04000000 /* I2C-like block xfer */ 69 | #define I2C_FUNC_SMBUS_WRITE_I2C_BLOCK 0x08000000 /* w/ 1-byte reg. addr. */ 70 | 71 | #define I2C_FUNC_SMBUS_BYTE (I2C_FUNC_SMBUS_READ_BYTE | \ 72 | I2C_FUNC_SMBUS_WRITE_BYTE) 73 | #define I2C_FUNC_SMBUS_BYTE_DATA (I2C_FUNC_SMBUS_READ_BYTE_DATA | \ 74 | I2C_FUNC_SMBUS_WRITE_BYTE_DATA) 75 | #define I2C_FUNC_SMBUS_WORD_DATA (I2C_FUNC_SMBUS_READ_WORD_DATA | \ 76 | I2C_FUNC_SMBUS_WRITE_WORD_DATA) 77 | #define I2C_FUNC_SMBUS_BLOCK_DATA (I2C_FUNC_SMBUS_READ_BLOCK_DATA | \ 78 | I2C_FUNC_SMBUS_WRITE_BLOCK_DATA) 79 | #define I2C_FUNC_SMBUS_I2C_BLOCK (I2C_FUNC_SMBUS_READ_I2C_BLOCK | \ 80 | I2C_FUNC_SMBUS_WRITE_I2C_BLOCK) 81 | 82 | /* Old name, for compatibility */ 83 | #define I2C_FUNC_SMBUS_HWPEC_CALC I2C_FUNC_SMBUS_PEC 84 | 85 | /* 86 | * Data for SMBus Messages 87 | */ 88 | #define I2C_SMBUS_BLOCK_MAX 32 /* As specified in SMBus standard */ 89 | #define I2C_SMBUS_I2C_BLOCK_MAX 32 /* Not specified but we use same structure */ 90 | union i2c_smbus_data { 91 | __u8 byte; 92 | __u16 word; 93 | __u8 block[I2C_SMBUS_BLOCK_MAX + 2]; /* block[0] is used for length */ 94 | /* and one more for PEC */ 95 | }; 96 | 97 | /* smbus_access read or write markers */ 98 | #define I2C_SMBUS_READ 1 99 | #define I2C_SMBUS_WRITE 0 100 | 101 | /* SMBus transaction types (size parameter in the above functions) 102 | Note: these no longer correspond to the (arbitrary) PIIX4 internal codes! */ 103 | #define I2C_SMBUS_QUICK 0 104 | #define I2C_SMBUS_BYTE 1 105 | #define I2C_SMBUS_BYTE_DATA 2 106 | #define I2C_SMBUS_WORD_DATA 3 107 | #define I2C_SMBUS_PROC_CALL 4 108 | #define I2C_SMBUS_BLOCK_DATA 5 109 | #define I2C_SMBUS_I2C_BLOCK_BROKEN 6 110 | #define I2C_SMBUS_BLOCK_PROC_CALL 7 /* SMBus 2.0 */ 111 | #define I2C_SMBUS_I2C_BLOCK_DATA 8 112 | 113 | 114 | /* ----- commands for the ioctl like i2c_command call: 115 | * note that additional calls are defined in the algorithm and hw 116 | * dependent layers - these can be listed here, or see the 117 | * corresponding header files. 118 | */ 119 | /* -> bit-adapter specific ioctls */ 120 | #define I2C_RETRIES 0x0701 /* number of times a device address */ 121 | /* should be polled when not */ 122 | /* acknowledging */ 123 | #define I2C_TIMEOUT 0x0702 /* set timeout - call with int */ 124 | 125 | 126 | /* this is for i2c-dev.c */ 127 | #define I2C_SLAVE 0x0703 /* Change slave address */ 128 | /* Attn.: Slave address is 7 or 10 bits */ 129 | #define I2C_SLAVE_FORCE 0x0706 /* Change slave address */ 130 | /* Attn.: Slave address is 7 or 10 bits */ 131 | /* This changes the address, even if it */ 132 | /* is already taken! */ 133 | #define I2C_TENBIT 0x0704 /* 0 for 7 bit addrs, != 0 for 10 bit */ 134 | 135 | #define I2C_FUNCS 0x0705 /* Get the adapter functionality */ 136 | #define I2C_RDWR 0x0707 /* Combined R/W transfer (one stop only)*/ 137 | #define I2C_PEC 0x0708 /* != 0 for SMBus PEC */ 138 | 139 | #define I2C_SMBUS 0x0720 /* SMBus-level access */ 140 | 141 | /* -- i2c.h -- */ 142 | 143 | 144 | /* Note: 10-bit addresses are NOT supported! */ 145 | 146 | /* This is the structure as used in the I2C_SMBUS ioctl call */ 147 | struct i2c_smbus_ioctl_data { 148 | char read_write; 149 | __u8 command; 150 | int size; 151 | union i2c_smbus_data *data; 152 | }; 153 | 154 | /* This is the structure as used in the I2C_RDWR ioctl call */ 155 | struct i2c_rdwr_ioctl_data { 156 | struct i2c_msg *msgs; /* pointers to i2c_msgs */ 157 | int nmsgs; /* number of i2c_msgs */ 158 | }; 159 | 160 | 161 | static inline __s32 i2c_smbus_access(int file, char read_write, __u8 command, 162 | int size, union i2c_smbus_data *data) 163 | { 164 | struct i2c_smbus_ioctl_data args; 165 | 166 | args.read_write = read_write; 167 | args.command = command; 168 | args.size = size; 169 | args.data = data; 170 | return ioctl(file,I2C_SMBUS,&args); 171 | } 172 | 173 | 174 | static inline __s32 i2c_smbus_write_quick(int file, __u8 value) 175 | { 176 | return i2c_smbus_access(file,value,0,I2C_SMBUS_QUICK,NULL); 177 | } 178 | 179 | static inline __s32 i2c_smbus_read_byte(int file) 180 | { 181 | union i2c_smbus_data data; 182 | if (i2c_smbus_access(file,I2C_SMBUS_READ,0,I2C_SMBUS_BYTE,&data)) 183 | return -1; 184 | else 185 | return 0x0FF & data.byte; 186 | 187 | } 188 | 189 | static inline __s32 i2c_smbus_write_byte(int file, __u8 value) 190 | { 191 | return i2c_smbus_access(file,I2C_SMBUS_WRITE,value, 192 | I2C_SMBUS_BYTE,NULL); 193 | } 194 | 195 | static inline __s32 i2c_smbus_read_byte_data(int file, __u8 command) 196 | { 197 | union i2c_smbus_data data; 198 | if (i2c_smbus_access(file,I2C_SMBUS_READ,command, 199 | I2C_SMBUS_BYTE_DATA,&data)) 200 | return -1; 201 | else 202 | return 0x0FF & data.byte; 203 | } 204 | 205 | static inline __s32 i2c_smbus_write_byte_data(int file, __u8 command, 206 | __u8 value) 207 | { 208 | union i2c_smbus_data data; 209 | data.byte = value; 210 | return i2c_smbus_access(file,I2C_SMBUS_WRITE,command, 211 | I2C_SMBUS_BYTE_DATA, &data); 212 | } 213 | 214 | static inline __s32 i2c_smbus_read_word_data(int file, __u8 command) 215 | { 216 | union i2c_smbus_data data; 217 | if (i2c_smbus_access(file,I2C_SMBUS_READ,command, 218 | I2C_SMBUS_WORD_DATA,&data)) 219 | return -1; 220 | else 221 | return 0x0FFFF & data.word; 222 | } 223 | 224 | static inline __s32 i2c_smbus_write_word_data(int file, __u8 command, 225 | __u16 value) 226 | { 227 | union i2c_smbus_data data; 228 | data.word = value; 229 | return i2c_smbus_access(file,I2C_SMBUS_WRITE,command, 230 | I2C_SMBUS_WORD_DATA, &data); 231 | } 232 | 233 | static inline __s32 i2c_smbus_process_call(int file, __u8 command, __u16 value) 234 | { 235 | union i2c_smbus_data data; 236 | data.word = value; 237 | if (i2c_smbus_access(file,I2C_SMBUS_WRITE,command, 238 | I2C_SMBUS_PROC_CALL,&data)) 239 | return -1; 240 | else 241 | return 0x0FFFF & data.word; 242 | } 243 | 244 | 245 | /* Returns the number of read bytes */ 246 | static inline __s32 i2c_smbus_read_block_data(int file, __u8 command, 247 | __u8 *values) 248 | { 249 | union i2c_smbus_data data; 250 | int i; 251 | if (i2c_smbus_access(file,I2C_SMBUS_READ,command, 252 | I2C_SMBUS_BLOCK_DATA,&data)) 253 | return -1; 254 | else { 255 | for (i = 1; i <= data.block[0]; i++) 256 | values[i-1] = data.block[i]; 257 | return data.block[0]; 258 | } 259 | } 260 | 261 | static inline __s32 i2c_smbus_write_block_data(int file, __u8 command, 262 | __u8 length, const __u8 *values) 263 | { 264 | union i2c_smbus_data data; 265 | int i; 266 | if (length > 32) 267 | length = 32; 268 | for (i = 1; i <= length; i++) 269 | data.block[i] = values[i-1]; 270 | data.block[0] = length; 271 | return i2c_smbus_access(file,I2C_SMBUS_WRITE,command, 272 | I2C_SMBUS_BLOCK_DATA, &data); 273 | } 274 | 275 | /* Returns the number of read bytes */ 276 | /* Until kernel 2.6.22, the length is hardcoded to 32 bytes. If you 277 | ask for less than 32 bytes, your code will only work with kernels 278 | 2.6.23 and later. */ 279 | static inline __s32 i2c_smbus_read_i2c_block_data(int file, __u8 command, 280 | __u8 length, __u8 *values) 281 | { 282 | union i2c_smbus_data data; 283 | int i; 284 | 285 | if (length > 32) 286 | length = 32; 287 | data.block[0] = length; 288 | if (i2c_smbus_access(file,I2C_SMBUS_READ,command, 289 | length == 32 ? I2C_SMBUS_I2C_BLOCK_BROKEN : 290 | I2C_SMBUS_I2C_BLOCK_DATA,&data)) 291 | return -1; 292 | else { 293 | for (i = 1; i <= data.block[0]; i++) 294 | values[i-1] = data.block[i]; 295 | return data.block[0]; 296 | } 297 | } 298 | 299 | static inline __s32 i2c_smbus_write_i2c_block_data(int file, __u8 command, 300 | __u8 length, 301 | const __u8 *values) 302 | { 303 | union i2c_smbus_data data; 304 | int i; 305 | if (length > 32) 306 | length = 32; 307 | for (i = 1; i <= length; i++) 308 | data.block[i] = values[i-1]; 309 | data.block[0] = length; 310 | return i2c_smbus_access(file,I2C_SMBUS_WRITE,command, 311 | I2C_SMBUS_I2C_BLOCK_BROKEN, &data); 312 | } 313 | 314 | /* Returns the number of read bytes */ 315 | static inline __s32 i2c_smbus_block_process_call(int file, __u8 command, 316 | __u8 length, __u8 *values) 317 | { 318 | union i2c_smbus_data data; 319 | int i; 320 | if (length > 32) 321 | length = 32; 322 | for (i = 1; i <= length; i++) 323 | data.block[i] = values[i-1]; 324 | data.block[0] = length; 325 | if (i2c_smbus_access(file,I2C_SMBUS_WRITE,command, 326 | I2C_SMBUS_BLOCK_PROC_CALL,&data)) 327 | return -1; 328 | else { 329 | for (i = 1; i <= data.block[0]; i++) 330 | values[i-1] = data.block[i]; 331 | return data.block[0]; 332 | } 333 | } 334 | 335 | 336 | #endif /* LIB_I2CDEV_H */ 337 | 338 | 339 | 340 | 341 | 342 | 343 | -------------------------------------------------------------------------------- /src/i2c.c: -------------------------------------------------------------------------------- 1 | /* 2 | * i2c.c 3 | * 4 | * Created on: Jun 7, 2015 5 | * Author: gijs 6 | */ 7 | 8 | #include "i2c.h" 9 | 10 | int res, daddress; 11 | 12 | int open_i2c(i2c_properties *i2c) { 13 | info("i2c open - i2c:%d device address: 0x%x mode:%i", i2c->i2cnr, 14 | i2c->deviceAddress, i2c->openMode); 15 | char filename[20]; 16 | 17 | sprintf(filename, "/dev/i2c-%d", i2c->i2cnr); 18 | i2c->fd = open(filename, i2c->openMode); 19 | if (i2c->fd < 0) { 20 | if (errno == ENOENT) { 21 | error("Error: Could not open file /dev/i2c-%d: %s\n", i2c->i2cnr, strerror(ENOENT)); 22 | } else { 23 | error("Error: Could not open file `%s': %s\n", filename, strerror(errno)); 24 | if (errno == EACCES) 25 | error("Run as root?\n"); 26 | } 27 | return -1; 28 | } 29 | 30 | if (ioctl(i2c->fd, I2C_SLAVE, i2c->deviceAddress) < 0) { 31 | error("Error: Could not set address to 0x%02x: %s\n", 32 | i2c->deviceAddress, strerror(errno)); 33 | return -errno; 34 | } 35 | return 0; 36 | } 37 | 38 | int write_byte_i2c(i2c_properties *i2c, unsigned char reg) { 39 | res = i2c_smbus_write_byte(i2c->fd, reg); 40 | if (res < 0) { 41 | error("Warning - write failed, filename=%i, register=%i\n", 42 | i2c->fd, reg); 43 | return 1; 44 | } 45 | return 0; 46 | } 47 | 48 | int write_data_i2c(i2c_properties *i2c, unsigned char reg, char value) { 49 | unsigned char buf[2]; 50 | buf[0] = reg; 51 | buf[1] = value; 52 | if (write(i2c->fd, buf, 2) != 2) { 53 | error("Warning - write data failed, filename=%i, register=%i\n", i2c->fd, 54 | reg); 55 | return 1; 56 | } 57 | return 0; 58 | } 59 | 60 | int read_i2c(i2c_properties *i2c, unsigned char *readBuffer, int bufferSize) { 61 | if (read(i2c->fd, readBuffer, bufferSize) != bufferSize) { 62 | error("Failed to read in the buffer\n"); 63 | return 1; 64 | } 65 | if(readBuffer[0x00]!=0xE5){ 66 | info("Problem detected! Device ID is wrong"); 67 | } 68 | return 0; 69 | } 70 | 71 | -------------------------------------------------------------------------------- /src/i2c.h: -------------------------------------------------------------------------------- 1 | /* 2 | * i2c.h 3 | * 4 | * Created on: Jun 7, 2015 5 | * Author: gijs 6 | */ 7 | 8 | #ifndef I2C_H_ 9 | #define I2C_H_ 10 | 11 | #include 12 | #include 13 | #include 14 | #include "i2c-dev.h" 15 | #include 16 | //#include 17 | //#include 18 | 19 | typedef enum { 20 | i2c0 = 0, i2c1 = 1 21 | } i2c; 22 | 23 | typedef struct { 24 | int fd; 25 | i2c i2cnr; 26 | int deviceAddress; 27 | int openMode; 28 | } i2c_properties; 29 | 30 | extern int open_i2c(i2c_properties *i2c); 31 | extern int write_byte_i2c(i2c_properties *i2c, unsigned char reg); 32 | extern int write_data_i2c(i2c_properties *i2c, unsigned char reg, char value); 33 | extern int read_i2c(i2c_properties *i2c, unsigned char *readBuffer, int bufferSize); 34 | 35 | #endif /* I2C_H_ */ 36 | -------------------------------------------------------------------------------- /src/log.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Gijs Sijpesteijn on 20/12/2017. 3 | // Until I figure out how to use syslog on apple, I use this. 4 | // 5 | 6 | #include 7 | #include "log.h" 8 | #include 9 | #include 10 | 11 | 12 | void info(const char *message, ...) { 13 | #ifdef __APPLE__ 14 | printf(*message, ...); 15 | #else 16 | syslog (LOG_INFO, message); 17 | #endif 18 | } 19 | 20 | void debug(const char *message, ...) { 21 | #ifdef __APPLE__ 22 | printf(*message, ...); 23 | #else 24 | syslog (LOG_DEBUG, message); 25 | #endif 26 | } 27 | 28 | void error(const char *message, ...) { 29 | #ifdef __APPLE__ 30 | printf(*message, ...); 31 | #else 32 | syslog (LOG_ERR, message); 33 | #endif 34 | } -------------------------------------------------------------------------------- /src/log.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Gijs Sijpesteijn on 20/12/2017. 3 | // 4 | 5 | #ifndef BBLASER_LOG_H 6 | #define BBLASER_LOG_H 7 | 8 | extern void info(const char *message, ...); 9 | extern void debug(const char *message, ...); 10 | extern void error(const char *message, ...); 11 | 12 | 13 | #endif //BBLASER_LOG_H 14 | -------------------------------------------------------------------------------- /src/pwm.c: -------------------------------------------------------------------------------- 1 | /* 2 | * pwm.c 3 | * 4 | * Created on: Jun 7, 2015 5 | * Author: gijs 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include "pwm.h" 12 | #include "log.h" 13 | 14 | int pwm_open(pwm_properties *pwm) { 15 | char filename[60] = PWM_PATH; 16 | strcat(filename, pwm->name); 17 | 18 | if (access(filename, F_OK) == -1) { 19 | error("Could not open file: ", filename); 20 | return 0; 21 | } 22 | return 1; 23 | } 24 | 25 | int pwm_set_run(pwm_properties *pwm, int run) { 26 | char filename[60] = PWM_PATH; 27 | strcat(filename, pwm->name); 28 | strcat(filename, "/"); 29 | 30 | strcat(filename, "run"); 31 | 32 | int file = open(filename, O_RDWR); 33 | char buf[2]; 34 | sprintf(buf, "%d", run); 35 | if (write(file, buf, 2) < 0) { 36 | char* str; 37 | sprintf(str, "Could not execute run. %d", run); 38 | error(str); 39 | return -1; 40 | } 41 | close(file); 42 | return 0; 43 | } 44 | 45 | int pwm_set_period(pwm_properties *pwm, int period) { 46 | char filename[60] = PWM_PATH; 47 | strcat(filename, pwm->name); 48 | strcat(filename, "/"); 49 | 50 | strcat(filename, "period"); 51 | 52 | int file = open(filename, O_RDWR); 53 | char buf[4]; 54 | sprintf(buf, "%d", period); 55 | if (write(file, buf, 4) < 0) { 56 | error("Could not set period. %d", period); 57 | return -1; 58 | } 59 | close(file); 60 | return 0; 61 | } 62 | int pwm_set_duty(pwm_properties *pwm, int duty) { 63 | char filename[60] = PWM_PATH; 64 | strcat(filename, pwm->name); 65 | strcat(filename, "/"); 66 | 67 | strcat(filename, "duty"); 68 | 69 | int file = open(filename, O_RDWR); 70 | char buf[4]; 71 | sprintf(buf, "%d", duty); 72 | if (write(file, buf, 4) < 0) { 73 | error("Could not set duty. %d", duty); 74 | return -1; 75 | } 76 | close(file); 77 | return 0; 78 | } 79 | -------------------------------------------------------------------------------- /src/pwm.h: -------------------------------------------------------------------------------- 1 | /* 2 | * pwm.h 3 | * 4 | * Created on: Jun 7, 2015 5 | * Author: gijs 6 | */ 7 | 8 | #ifndef PWM_H_ 9 | #define PWM_H_ 10 | 11 | #define PWM_PATH "/sys/devices/ocp.3/" 12 | typedef struct { 13 | char *name; 14 | } pwm_properties; 15 | 16 | 17 | extern int pwm_open(pwm_properties *pwm); 18 | extern int pwm_set_run(pwm_properties *pwm, int run); 19 | extern int pwm_set_period(pwm_properties *pwm, int period); 20 | extern int pwm_set_duty(pwm_properties *pwm, int duty); 21 | 22 | #endif /* PWM_H_ */ 23 | -------------------------------------------------------------------------------- /src/spi.c: -------------------------------------------------------------------------------- 1 | /* 2 | * spi.c 3 | * 4 | * Created on: May 31, 2015 5 | * Author: gijs 6 | */ 7 | 8 | #include "spi.h" 9 | #include "log.h" 10 | #include 11 | 12 | uint8_t spi_open(spi_properties *spi) { 13 | // syslog (LOG_INFO, "spi open - spi:%d bits_per_word:%d speed:%d mode:%f", spi, bits_per_word, speed, mode); 14 | char filename[20]; 15 | sprintf(filename, "/dev/spidev1.%d", spi->spi_id); 16 | spi->fd = open(filename, spi->flags); 17 | if (spi->fd < 0) { 18 | perror("could not open spi."); 19 | return -1; 20 | } 21 | info("FD: %i", spi->fd); 22 | if (ioctl(spi->fd, SPI_IOC_WR_MODE, &spi->mode)==-1){ 23 | perror("SPI: Can't set SPI mode."); 24 | return -1; 25 | } 26 | if (ioctl(spi->fd, SPI_IOC_WR_BITS_PER_WORD, &spi->bits_per_word)==-1){ 27 | perror("SPI: Can't set bits per word."); 28 | return -1; 29 | } 30 | if (ioctl(spi->fd, SPI_IOC_WR_MAX_SPEED_HZ, &spi->speed)==-1){ 31 | perror("SPI: Can't set max speed HZ"); 32 | return -1; 33 | } 34 | 35 | // Check that the properties have been set 36 | info("SPI fd is: %d\n", spi->fd); 37 | info("SPI Mode is: %d\n", spi->mode); 38 | info("SPI Bits is: %d\n", spi->bits_per_word); 39 | info("SPI Speed is: %d\n", spi->speed); 40 | return 0; 41 | } 42 | 43 | uint8_t spi_close(spi_properties *spi) { 44 | info("spi close - spi:%d", spi->fd); 45 | close(spi->fd); 46 | return 0; 47 | } 48 | 49 | uint8_t spi_send(spi_properties *spi, unsigned char tx[], int length) { 50 | unsigned char rx[length]; 51 | return spi_transfer(spi, tx, rx, length); 52 | } 53 | 54 | uint8_t spi_transfer(spi_properties *spi, unsigned char tx[], unsigned char rx[], int length) { 55 | struct spi_ioc_transfer transfer = { 56 | .tx_buf = (unsigned long)tx, 57 | .rx_buf = (unsigned long)rx, 58 | .len = length, 59 | .delay_usecs = 0, 60 | .speed_hz = spi->speed, 61 | .bits_per_word = spi->bits_per_word, 62 | }; 63 | // send the SPI message (all of the above fields, inc. buffers) 64 | int status = ioctl(spi->fd, SPI_IOC_MESSAGE(1), &transfer); 65 | if (status < 0) { 66 | perror("SPI: SPI_IOC_MESSAGE Failed"); 67 | return -1; 68 | } 69 | return 0; //status; 70 | } 71 | -------------------------------------------------------------------------------- /src/spi.h: -------------------------------------------------------------------------------- 1 | /* 2 | * spi.h 3 | * 4 | * Created on: May 31, 2015 5 | * Author: gijs 6 | */ 7 | 8 | #ifndef SPI_H_ 9 | #define SPI_H_ 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | typedef enum { 16 | spi0 = 0, spi1 = 1 17 | } spi; 18 | 19 | typedef struct { 20 | int fd; 21 | spi spi_id; 22 | uint8_t bits_per_word; /*!< @brief is used to hold the bits per word size of SPI */ 23 | uint8_t mode; /*!< @brief is used to hold the mode of SPI */ 24 | uint32_t speed; /*!< @brief is used to hold the speed of SPI */ 25 | uint8_t flags; 26 | } spi_properties; 27 | 28 | extern uint8_t spi_open(spi_properties* spi); 29 | extern uint8_t spi_send(spi_properties *spi, unsigned char tx[], int length); 30 | extern uint8_t spi_transfer(spi_properties *spi, unsigned char tx[], unsigned char rx[], int length); 31 | extern uint8_t spi_close(spi_properties *spi); 32 | 33 | #endif /* SPI_H_ */ 34 | -------------------------------------------------------------------------------- /src/uart.c: -------------------------------------------------------------------------------- 1 | /* 2 | * uart.c 3 | * 4 | * Created on: Jun 7, 2015 5 | * Author: gijs 6 | */ 7 | 8 | #include "uart.h" 9 | #include "log.h" 10 | #include 11 | #include 12 | 13 | int uart_open(uart_properties *uart) { 14 | FILE *slots; 15 | char buf[30] = "/dev/ttyO"; 16 | char port_nr[2]; 17 | sprintf(port_nr, "%d", uart->uart_id); 18 | strcat(buf,port_nr); 19 | struct termios uart_port; 20 | 21 | // slots = fopen(SLOTS, "w"); 22 | // if(slots == NULL) printf("slots didn't open\n"); 23 | // fseek(slots,0,SEEK_SET); 24 | // 25 | // fprintf(slots, "BB-UART%i", uart->uart_id+1); 26 | // fflush(slots); 27 | // fclose(slots); 28 | 29 | uart->fd = open(buf, O_RDWR | O_NOCTTY); 30 | if(uart->fd < 0) printf("port failed to open\n"); 31 | 32 | bzero(&uart_port,sizeof(uart_port)); 33 | 34 | uart_port.c_cflag = uart->baudrate | CS8 | CLOCAL | CREAD; 35 | uart_port.c_iflag = IGNPAR | ICRNL; 36 | uart_port.c_oflag = 0; 37 | uart_port.c_lflag = 0; 38 | 39 | uart_port.c_cc[VTIME] = 0; 40 | uart_port.c_cc[VMIN] = 1; 41 | 42 | //clean the line and set the attributes 43 | tcflush(uart->fd,TCIFLUSH); 44 | tcsetattr(uart->fd,TCSANOW,&uart_port); 45 | return 0; 46 | } 47 | 48 | int uart_send(uart_properties *uart, char *tx, int length) { 49 | if (write(uart->fd, tx, length) == -1) { 50 | error("Could not write %s to uart %i", tx, uart->uart_id); 51 | return -1; 52 | } 53 | info("Wrote %s to uart %i", tx, uart->uart_id); 54 | return 0; 55 | } 56 | 57 | int uart_read(uart_properties *uart,unsigned char *rx, int length) { 58 | int count; 59 | if( (count = read(uart->fd,(void*)rx,length)) > 0) { 60 | error("Could not read from uart %i", uart->uart_id); 61 | return count; 62 | } 63 | info("Read %s from uart %i", rx, uart->uart_id); 64 | return 0; 65 | } 66 | 67 | int uart_close(uart_properties *uart) { 68 | close(uart->fd); 69 | return 0; 70 | } 71 | -------------------------------------------------------------------------------- /src/uart.h: -------------------------------------------------------------------------------- 1 | /* 2 | * uart.h 3 | * 4 | * Created on: Jun 7, 2015 5 | * Author: gijs 6 | */ 7 | 8 | #ifndef UART_H_ 9 | #define UART_H_ 10 | 11 | #include 12 | #include 13 | 14 | typedef enum { 15 | uart0 = 0, uart1 = 1, uart2 = 2, uart3 = 3, uart4 = 4, uart5 = 5 16 | } uart; 17 | 18 | 19 | typedef struct { 20 | int fd; 21 | uart uart_id; 22 | int baudrate; 23 | } uart_properties; 24 | 25 | extern int uart_open(uart_properties *uart); 26 | extern int uart_send(uart_properties *uart, char *tx, int length); 27 | extern int uart_read(uart_properties *uart,unsigned char *rx, int length); 28 | extern int uart_close(uart_properties *uart); 29 | 30 | #endif /* UART_H_ */ 31 | --------------------------------------------------------------------------------