├── LICENSE ├── Makefile ├── README.md ├── comm.c ├── interrupt_ex ├── Makefile ├── README.md └── wfi.c ├── megaio.c ├── megaio.h ├── python ├── README.md ├── int_example.py ├── megaio │ ├── .gitignore │ ├── LICENSE │ ├── README.md │ ├── megaio │ │ └── __init__.py │ └── setup.py └── res │ └── sequent.jpg ├── readmeres └── sequent.jpg └── rev_history.txt /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Sequent Microsystems 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | DESTDIR?=/usr 2 | PREFIX?=/local 3 | 4 | ifneq ($V,1) 5 | Q ?= @ 6 | endif 7 | 8 | CC = gcc 9 | CFLAGS = $(DEBUG) -Wall -Wextra $(INCLUDE) -Winline -pipe 10 | 11 | LDFLAGS = -L$(DESTDIR)$(PREFIX)/lib 12 | LIBS = -lwiringPi -lwiringPiDev -lpthread -lrt -lm -lcrypt 13 | 14 | SRC = megaio.c comm.c 15 | 16 | OBJ = $(SRC:.c=.o) 17 | 18 | all: megaio 19 | 20 | megaio: $(OBJ) 21 | $Q echo [Link] 22 | $Q $(CC) -o $@ $(OBJ) $(LDFLAGS) $(LIBS) 23 | 24 | .c.o: 25 | $Q echo [Compile] $< 26 | $Q $(CC) -c $(CFLAGS) $< -o $@ 27 | 28 | .PHONY: clean 29 | clean: 30 | $Q echo "[Clean]" 31 | $Q rm -f $(OBJ) megaio *~ core tags *.bak 32 | 33 | .PHONY: install 34 | install: megaio 35 | $Q echo "[Install]" 36 | $Q cp megaio $(DESTDIR)$(PREFIX)/bin 37 | ifneq ($(WIRINGPI_SUID),0) 38 | $Q chown root.root $(DESTDIR)$(PREFIX)/bin/megaio 39 | $Q chmod 4755 $(DESTDIR)$(PREFIX)/bin/megaio 40 | endif 41 | # $Q mkdir -p $(DESTDIR)$(PREFIX)/man/man1 42 | # $Q cp megaio.1 $(DESTDIR)$(PREFIX)/man/man1 43 | 44 | .PHONY: uninstall 45 | uninstall: 46 | $Q echo "[UnInstall]" 47 | $Q rm -f $(DESTDIR)$(PREFIX)/bin/megaio 48 | $Q rm -f $(DESTDIR)$(PREFIX)/man/man1/megaio.1 49 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | [![megaio-rpi](readmeres/sequent.jpg)](https://sequentmicrosystems.com) 3 | 4 | # megaio-rpi 5 | 6 | This is the command to control Old Raspberry Pi [Mega-IO](https://sequentmicrosystems.com/docs/MEGA-IO-UsersGuide.pdf) Expansion Card 7 | 8 | Before compiling you have to install [Wiring Pi](http://wiringpi.com/download-and-install/), many thanks to Gordon Henderson for the library. 9 | 10 | Since the WiringPi are not longer maintained by his creator, to install it, get the latest .deb version from: 11 | 12 | https://github.com/WiringPi/WiringPi/releases/ 13 | 14 | The -armhf.deb file should be used on 32-bit OS (Raspberry Pi 3 and under) and the -arm64.deb is meant for 64-bit OS (Raspberry Pi 4 and up). Download the appropriate file for your architecture on your Raspberry Pi and install it with the dpkg command: 15 | ```bash 16 | dpkg -i wiringpi-[version]-armhf.deb 17 | 18 | or 19 | 20 | dpkg -i wiringpi-[version]-arm64.deb 21 | ``` 22 | 23 | Test that the WiringPi installation finished successfully with the command: 24 | ```bash 25 | gpio -v 26 | ``` 27 | 28 | ## Usage 29 | 30 | ```bash 31 | ~$ git clone https://github.com/SequentMicrosystems/megaio-rpi.git 32 | ~$ cd megaio-rpi/ 33 | ~/megaio-rpi$ sudo make install 34 | ``` 35 | 36 | Now you can access all the functions of the Mega-IO card through the "megaio" command. 37 | If you clone the repository, any update can be made with the following commands: 38 | 39 | ```bash 40 | ~$ cd megaio-rpi/ 41 | ~/megaio-rpi$ git pull 42 | ~/megaio-rpi$ sudo make install 43 | ``` 44 | 45 | For python library install and usage checkout the "python" subfolder. 46 | -------------------------------------------------------------------------------- /comm.c: -------------------------------------------------------------------------------- 1 | /* 2 | * comm.c: 3 | * Communication routines "platform specific" for Raspberry Pi 4 | * 5 | * Copyright (c) 2016-2018 Sequent Microsystem 6 | * 7 | *********************************************************************** 8 | * Author: Alexandru Burcea 9 | *********************************************************************** 10 | */ 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #include 24 | #include 25 | #include 26 | #include "megaio.h" 27 | 28 | static volatile int globalResponse = 0; 29 | int gLed1HwAdd = 0x20; 30 | int gLed2HwAdd = 0x21; 31 | 32 | PI_THREAD (waitForKey) 33 | { 34 | char resp; 35 | int respI = NO; 36 | 37 | 38 | struct termios info; 39 | tcgetattr(0, &info); /* get current terminal attirbutes; 0 is the file descriptor for stdin */ 40 | info.c_lflag &= ~ICANON; /* disable canonical mode */ 41 | info.c_cc[VMIN] = 1; /* wait until at least one keystroke available */ 42 | info.c_cc[VTIME] = 0; /* no timeout */ 43 | tcsetattr(0, TCSANOW, &info); /* set i */ 44 | 45 | (void)piHiPri (10) ; // Set this thread to be high priority 46 | resp = getchar(); 47 | if((resp == 'y') || (resp == 'Y')) 48 | respI = YES; 49 | 50 | piLock (COUNT_KEY) ; 51 | globalResponse = respI ; 52 | piUnlock (COUNT_KEY) ; 53 | 54 | info.c_lflag |= ICANON; /* disable canonical mode */ 55 | info.c_cc[VMIN] = 0; /* wait until at least one keystroke available */ 56 | info.c_cc[VTIME] = 0; /* no timeout */ 57 | tcsetattr(0, TCSANOW, &info); /* set i */ 58 | printf("\n"); 59 | return &waitForKey; 60 | } 61 | 62 | void startThread(void) 63 | { 64 | wiringPiSetupSys (); 65 | piThreadCreate (waitForKey); 66 | } 67 | 68 | int checkThreadResult(void) 69 | { 70 | int res; 71 | piLock (COUNT_KEY) ; 72 | res = globalResponse; 73 | piUnlock(COUNT_KEY); 74 | return res; 75 | } 76 | 77 | int readReg16(int dev, int add) 78 | { 79 | int val, ret; 80 | 81 | val = wiringPiI2CReadReg16(dev, add); 82 | ret = 0xff & (val >> 8); 83 | ret+= 0xff00 & (val << 8); 84 | return ret; 85 | } 86 | 87 | int writeReg16(int dev, int add, int val) 88 | { 89 | int wVal; 90 | 91 | wVal = 0xff & (val >> 8); 92 | wVal += 0xff00 & (val << 8); 93 | wiringPiI2CWriteReg16(dev,add, wVal); 94 | delay(1); 95 | return 0; 96 | } 97 | 98 | 99 | int writeReg8(int dev, int add, int val) 100 | { 101 | wiringPiI2CWriteReg8(dev, add, val); 102 | 103 | return 0; 104 | } 105 | 106 | int readReg8(int dev, int add) 107 | { 108 | return wiringPiI2CReadReg8(dev, add); 109 | } 110 | 111 | 112 | int readReg24(int dev, int add) 113 | { 114 | int val, aux8; 115 | 116 | aux8 = readReg8(dev, add + 2); 117 | val = aux8; 118 | /*val = 0xffff00 & (val << 8);*/ 119 | aux8 = readReg8(dev, add + 1); 120 | val += 0xff00 & (aux8 << 8); 121 | 122 | aux8 = readReg8(dev, add ); 123 | val += 0xff0000 & (aux8 << 16); 124 | #ifdef DEBUG_I 125 | printbits(val); 126 | printf("\n"); 127 | printf("%#08x\n", val); 128 | #endif 129 | return val; 130 | } 131 | 132 | 133 | 134 | int writeReg24(int dev, int add, int val) 135 | { 136 | int wVal;//, aux8; 137 | 138 | wVal = 0xff & (val >> 8); 139 | writeReg8(dev,add+1, wVal); 140 | 141 | wVal = 0xff & ( val >> 16); 142 | writeReg8(dev,add, wVal); 143 | 144 | wVal = 0xff & val; 145 | writeReg8(dev,add+2, wVal); 146 | 147 | return 0; 148 | } 149 | 150 | 151 | int doBoardInit(int hwAdd) 152 | { 153 | int dev, bV = -1, retry = 10, setupRetry = 10; 154 | 155 | while((bV == -1) && (retry > 0)) 156 | { 157 | dev = -1; 158 | setupRetry = 10; 159 | while((dev < 0) && (setupRetry > 0)) 160 | { 161 | dev = wiringPiI2CSetup (hwAdd); 162 | setupRetry--; 163 | if(setupRetry < 9) 164 | { 165 | delay(250); 166 | } 167 | } 168 | if(dev == -1) 169 | { 170 | return ERROR; 171 | } 172 | bV = wiringPiI2CReadReg8 (dev,REVISION_HW_MAJOR_MEM_ADD); 173 | retry--; 174 | if(retry < 9) 175 | { 176 | delay(250); 177 | } 178 | } 179 | if(bV == -1) 180 | { 181 | printf( "MegaIO id %d not detected\n", hwAdd - MEGAIO_HW_I2C_BASE_ADD); 182 | return ERROR; 183 | } 184 | return dev; 185 | } 186 | 187 | 188 | /* 189 | * getLedVal 190 | * Get the value of leds 191 | * arg: chip 0 - 1 192 | * ret: 0x0000 - 0xffff - success; -1 - fail 193 | */ 194 | int getLedVal(int chip) 195 | { 196 | int dev = -1; 197 | int ret = 0; 198 | u16 rVal = 0; 199 | 200 | if((chip < 0) || (chip > 1)) 201 | { 202 | return -1; 203 | } 204 | dev = wiringPiI2CSetup(gLed1HwAdd + chip); 205 | if(dev <= 0) 206 | { 207 | return -1; 208 | } 209 | ret = wiringPiI2CReadReg16(dev, 0x02); 210 | if(ret < 0) 211 | { 212 | return -1; 213 | } 214 | rVal = 0xff00 & (ret << 4); 215 | rVal += 0x01 & (ret >> 3); 216 | rVal += 0x02 & (ret >> 1); 217 | rVal += 0x04 & (ret << 1); 218 | rVal += 0x08 & (ret << 3); 219 | rVal += 0x10 & (ret >> 11); 220 | rVal += 0x20 & (ret >> 9); 221 | rVal += 0x40 & (ret >> 7); 222 | rVal += 0x80 & (ret >> 5); 223 | 224 | return rVal; 225 | } 226 | 227 | 228 | /* 229 | * setLedVal 230 | * Get the value of leds 231 | * arg: chip 0 - 1 232 | * arg: val 0x0000 - 0xffff 233 | * ret: 0 - success; -1 - fail 234 | */ 235 | int setLedVal(int chip, int val) 236 | { 237 | int dev = -1; 238 | int ret = 0; 239 | u16 wVal = 0; 240 | 241 | if((chip < 0) || (chip > 1)) 242 | { 243 | return -1; 244 | } 245 | if((val < 0) || (val > 0xffff)) 246 | { 247 | return -1; 248 | } 249 | 250 | dev = wiringPiI2CSetup(gLed1HwAdd + chip); 251 | if(dev <= 0) 252 | { 253 | return -1; 254 | } 255 | wVal = 0x0ff0 & ( val >> 4); 256 | wVal += 0x1000 & (val << 5); 257 | wVal += 0x2000 & (val << 7); 258 | wVal += 0x4000 & (val << 9); 259 | wVal += 0x8000 & (val << 11); 260 | wVal += 0x0001 & (val >> 3); 261 | wVal += 0x0002 & (val >> 1); 262 | wVal += 0x0004 & (val << 1); 263 | wVal += 0x0008 & (val << 3); 264 | 265 | //wVal = 0xffff & val; 266 | wiringPiI2CWriteReg16(dev, 0x06, 0x0000); // set all to output 267 | wiringPiI2CWriteReg16(dev, 0x02, wVal); 268 | 269 | return ret; 270 | } 271 | 272 | /* 273 | * wrLeds 274 | * Write leds as a corresponence of relay 275 | */ 276 | #ifdef LED_RELAY_LINK 277 | static int wrLedsR(int stack, int val) 278 | { 279 | int dev, addOut = 0x02; 280 | if(stack < 2) 281 | { 282 | dev = wiringPiI2CSetup(gLed1HwAdd); 283 | } 284 | else if(stack < 4) 285 | { 286 | dev = wiringPiI2CSetup(gLed2HwAdd); 287 | } 288 | else 289 | { 290 | #ifdef DEBUG_LED 291 | printf("Invalid stack level\n"); 292 | #endif 293 | return -1; 294 | } 295 | if(val < 0 || val > 255) 296 | { 297 | #ifdef DEBUG_LED 298 | printf("Led value out of range\n"); 299 | #endif 300 | return -1; 301 | } 302 | if(dev == -1) 303 | { 304 | #ifdef DEBUG_LED 305 | printf("No led board detected\n"); 306 | #endif 307 | return -1; 308 | } 309 | 310 | addOut += (stack & 0x01); 311 | 312 | wiringPiI2CWriteReg16(dev, 0x06, 0x0000); 313 | 314 | wiringPiI2CWriteReg8(dev, addOut, 0xff & (~val)); 315 | // todo: check write succesful 316 | return 1; 317 | } 318 | #endif 319 | void busyWait(int ms) 320 | { 321 | delay(ms); 322 | } 323 | -------------------------------------------------------------------------------- /interrupt_ex/Makefile: -------------------------------------------------------------------------------- 1 | DESTDIR?=/usr 2 | PREFIX?=/local 3 | 4 | ifneq ($V,1) 5 | Q ?= @ 6 | endif 7 | 8 | CC = gcc 9 | CFLAGS = $(DEBUG) -Wall -Wextra $(INCLUDE) -Winline -pipe 10 | 11 | LDFLAGS = -L$(DESTDIR)$(PREFIX)/lib 12 | LIBS = -lwiringPi -lwiringPiDev -lpthread -lrt -lm -lcrypt 13 | 14 | SRC = wfi.c 15 | 16 | OBJ = $(SRC:.c=.o) 17 | 18 | all: wfi 19 | 20 | wfi: $(OBJ) 21 | $Q echo [Link] 22 | $Q $(CC) -o $@ $(OBJ) $(LDFLAGS) $(LIBS) 23 | 24 | .c.o: 25 | $Q echo [Compile] $< 26 | $Q $(CC) -c $(CFLAGS) $< -o $@ 27 | 28 | .PHONY: clean 29 | clean: 30 | $Q echo "[Clean]" 31 | $Q rm -f $(OBJ) wfi *~ core tags *.bak -------------------------------------------------------------------------------- /interrupt_ex/README.md: -------------------------------------------------------------------------------- 1 | # Interrupt Example 2 | 3 | This example show you how to use MegaIO interrupt's. 4 | -------------------------------------------------------------------------------- /interrupt_ex/wfi.c: -------------------------------------------------------------------------------- 1 | /* 2 | * wfi.c: 3 | * Wait for Interrupt test program 4 | * 5 | * This program demonstrates the use of the megaio interrupt usage 6 | * 7 | * BCM_GPIO pin 4 used for interrupt the raspberry 8 | * 9 | * The biggest issue with this method is that it really only works 10 | * well in Sys mode. 11 | * 12 | *********************************************************************** 13 | */ 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | // A 'key' which we can lock and unlock - values are 0 through 3 21 | // This is interpreted internally as a pthread_mutex by wiringPi 22 | // which is hiding some of that to make life simple. 23 | 24 | #define COUNT_KEY 0 25 | 26 | // What BCM_GPIO input are we using? 27 | 28 | #define BUTTON_PIN 4 29 | 30 | // Debounce time in mS 31 | 32 | #define DEBOUNCE_TIME 100 33 | 34 | 35 | // globalCounter: 36 | // Global variable to count interrupts 37 | // Should be declared volatile to make sure the compiler doesn't cache it. 38 | 39 | static volatile int globalCounter = 0 ; 40 | 41 | 42 | /* 43 | * waitForIt: 44 | * This is a thread created using the wiringPi simplified threading 45 | * mechanism. It will wait on an interrupt on the button and increment 46 | * a counter. 47 | ********************************************************************************* 48 | */ 49 | 50 | PI_THREAD (waitForIt) 51 | { 52 | 53 | 54 | (void)piHiPri (10) ; // Set this thread to be high priority 55 | 56 | for (;;) 57 | { 58 | if (waitForInterrupt (BUTTON_PIN, -1) > 0) // Got it 59 | { 60 | // state ^= 1 ; 61 | digitalRead (BUTTON_PIN); 62 | piLock (COUNT_KEY) ; 63 | ++globalCounter ; 64 | piUnlock (COUNT_KEY) ; 65 | 66 | } 67 | } 68 | } 69 | 70 | 71 | /* 72 | * setup: 73 | * Demo a crude but effective way to initialise the hardware 74 | ********************************************************************************* 75 | */ 76 | 77 | void setup (void) 78 | { 79 | int i; 80 | char str[250]; 81 | 82 | // Use the gpio program to initialise the hardware 83 | // (This is the crude, but effective) 84 | 85 | system ("gpio edge 4 both") ; 86 | /*for (i = 1; i< 19; i++) 87 | { 88 | sprintf(str,"megaio 0 ioirqset %d none", i); 89 | printf("%s\n", str); 90 | system (str); 91 | 92 | delay(300); 93 | 94 | }*/ 95 | 96 | for (i = 1; i< 9; i++) 97 | { 98 | sprintf(str,"megaio 0 optirqset %d change", i); 99 | printf("%s\n", str); 100 | system (str); 101 | delay(40); 102 | } 103 | 104 | //*/ 105 | // Setup wiringPi 106 | 107 | wiringPiSetupSys () ; 108 | 109 | // Fire off our interrupt handler 110 | 111 | piThreadCreate (waitForIt) ; 112 | 113 | } 114 | 115 | 116 | 117 | /* 118 | * main 119 | ********************************************************************************* 120 | */ 121 | 122 | int main (void) 123 | { 124 | int lastCounter = 0 ; 125 | int myCounter = 0 ; 126 | 127 | setup () ; 128 | 129 | for (;;) 130 | { 131 | printf ("Waiting ... ") ; fflush (stdout) ; 132 | 133 | while (myCounter == lastCounter) 134 | { 135 | piLock (COUNT_KEY) ; 136 | myCounter = globalCounter ; 137 | piUnlock (COUNT_KEY) ; 138 | delay (10) ; 139 | } 140 | 141 | //printf (" Done. myCounter: %5d\n", myCounter) ; 142 | 143 | /* printf ("IO interrupts flags "); 144 | fflush (stdout) ; 145 | system("megaio 0 ioitread");*/ 146 | 147 | //delay(100); 148 | printf ("OPTO IN interrupts flags "); 149 | fflush (stdout) ; 150 | system("megaio 0 optitread"); 151 | 152 | lastCounter = myCounter ; 153 | } 154 | 155 | return 0 ; 156 | } 157 | -------------------------------------------------------------------------------- /megaio.c: -------------------------------------------------------------------------------- 1 | /* 2 | * megaio.c: 3 | * Command-line interface to the Raspberry 4 | * Pi's MegaIO board. 5 | * Copyright (c) 2016-2017 Sequent Microsystem 6 | * 7 | *********************************************************************** 8 | * Author: Alexandru Burcea 9 | *********************************************************************** 10 | */ 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include "megaio.h" 21 | 22 | #define ADC_TEST_VAL_LOW 2850 23 | #define ADC_TEST_VAL_HIGH 3300 24 | 25 | #define ADC_TEST_SAMPLES_NR 500 26 | 27 | #define DEBUG_LED 28 | //#define DEBUG_TEST 1 29 | //#define TEST_RESET 1 30 | 31 | #define VERSION_BASE (int)2 32 | #define VERSION_MAJOR (int)2 33 | #define VERSION_MINOR (int)4 34 | 35 | int gHwAdd = MEGAIO_HW_I2C_BASE_ADD; 36 | 37 | 38 | 39 | char *usage = "Usage: megaio -h \n" 40 | " megaio -v\n" 41 | " megaio -lt\n" 42 | " megaio -lw \n" 43 | " megaio -lw \n" 44 | " megaio -warranty\n" 45 | " megaio -connector\n" 46 | " megaio board\n" 47 | " megaio rwrite \n" 48 | " megaio rread \n" 49 | " megaio rread\n" 50 | " megaio aread \n" 51 | " megaio awrite \n" 52 | " megaio optread \n" 53 | " megaio optread\n" 54 | " megaio ocread\n" 55 | " megaio ocwrite \n" 56 | " megaio ocwrite \n" 57 | " megaio optirqset \n" 58 | " megaio optitRead\n" 59 | " megaio iodwrite \n" 60 | " megaio iodread \n" 61 | " megaio iodread\n" 62 | " megaio iowrite \n" 63 | " megaio ioread \n" 64 | " megaio ioread\n" 65 | " megaio ioirqset \n" 66 | " megaio ioitread\n" 67 | " megaio test\n" 68 | " megaio atest \n" 69 | " megaio test-opto-oc \n" 70 | " megaio test-io \n" 71 | " megaio test-dac-adc \n" 72 | "Where: = Board level id = 0..3\n" 73 | "Type megaio -h for more help";// No trailing newline needed here. 74 | 75 | char *warranty =" Copyright (c) 2016-2018 Sequent Microsystems\n" 76 | " \n" 77 | " This program is free software; you can redistribute it and/or modify\n" 78 | " it under the terms of the GNU Leser General Public License as published\n" 79 | " by the Free Software Foundation, either version 3 of the License, or\n" 80 | " (at your option) any later version.\n" 81 | " \n" 82 | " This program is distributed in the hope that it will be useful,\n" 83 | " but WITHOUT ANY WARRANTY; without even the implied warranty of\n" 84 | " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" 85 | " GNU Lesser General Public License for more details.\n" 86 | " \n" 87 | " You should have received a copy of the GNU Lesser General Public License\n" 88 | " along with this program. If not, see ."; 89 | 90 | 91 | char *cnv2 = " SIGNAL CONNECTOR SIGNAL\n" 92 | " |---|\n" 93 | " 3.3V -- 1|O O| 2-- +5V\n" 94 | " OPTO1 -- 3|O O| 4-- 5VEXT1\n" 95 | " OPTO2 -- 5|O O| 6-- GND\n" 96 | " DAC -- 7|O O| 8-- OPTO3\n" 97 | " GND -- 9|O O|10-- OPTO4\n" 98 | " ADC7 --11|O O|12-- ADC8\n" 99 | " ADC6 --13|O O|14-- GND\n" 100 | " ADC4 --15|O O|16-- ADC5\n" 101 | " 3.3V --17|O O|18-- ADC3\n" 102 | " ADC2 --19|O O|20-- GND\n" 103 | " ADC1 --21|O O|22-- IO6\n" 104 | " IO5 --23|O O|24-- IO4\n" 105 | " GND --25|O O|26-- IO3\n" 106 | " IO2 --27|O O|28-- IO1\n" 107 | " OC4 --29|O O|30-- 5VEXT2\n" 108 | " OC3 --31|O O|32-- OC2\n" 109 | " OC1 --33|O O|34-- GND\n" 110 | " N/C --35|O O|36-- OPTO5\n" 111 | " OPTO6 --37|O O|38-- OPTO7\n" 112 | " GND --39|O O|40-- OPTO8\n" 113 | " |---|\n"; 114 | 115 | 116 | char *failStr = " ######## ### #### ## #### \n" 117 | " ## ## ## ## ## #### \n" 118 | " ## ## ## ## ## #### \n" 119 | " ###### ## ## ## ## ## \n" 120 | " ## ######### ## ## \n" 121 | " ## ## ## ## ## #### \n" 122 | " ## ## ## #### ######## #### \n"; 123 | 124 | char *passStr = " ######## ### ###### ###### \n" 125 | " ## ## ## ## ## ## ## ## \n" 126 | " ## ## ## ## ## ## \n" 127 | " ######## ## ## ###### ###### \n" 128 | " ## ######### ## ## \n" 129 | " ## ## ## ## ## ## ## \n" 130 | " ## ## ## ###### ###### \n"; 131 | 132 | void printbits(int v) 133 | { 134 | int i; // for C89 compatibility 135 | 136 | for(i = 17; i >= 0; i--) putchar('0' + ((v >> i) & 1)); 137 | } 138 | 139 | 140 | // set ON/OFF specify relay channel 141 | int relayChSet(int dev, u8 channel, OutStateEnumType state) 142 | { 143 | int resp; 144 | 145 | if((channel < CHANNEL_NR_MIN) || (channel > RELAY_CH_NR_MAX)) 146 | { 147 | printf("Invalid relay nr!\n"); 148 | return ERROR; 149 | } 150 | switch(state) 151 | { 152 | case OFF: 153 | resp = writeReg8(dev,RELAY_OFF_MEM_ADD, channel); 154 | break; 155 | case ON: 156 | resp = writeReg8(dev,RELAY_ON_MEM_ADD, channel); 157 | break; 158 | 159 | default: 160 | printf("Invalid relay state!\n"); 161 | return ERROR; 162 | break; 163 | } 164 | if(0 < resp) 165 | { 166 | return OK; 167 | } 168 | return FAIL; 169 | } 170 | 171 | 172 | int adcGet(int dev, int ch) 173 | { 174 | int resp, add; 175 | 176 | add = ADC_VAL_MEM_ADD + 2* (ch-1); 177 | resp = readReg16(dev, add); 178 | return resp; 179 | } 180 | 181 | int dacSet(int dev, int val) 182 | { 183 | int retry, inVal; 184 | 185 | retry = RETRY_TIMES; 186 | inVal = val +1; 187 | while((retry > 0) && (inVal != val)) 188 | { 189 | writeReg16(dev, DAC_VAL_H_MEM_ADD, val); 190 | inVal = readReg16(dev, DAC_VAL_H_MEM_ADD); 191 | retry --; 192 | } 193 | if(retry == 0) 194 | { 195 | return FAIL; 196 | } 197 | return OK; 198 | } 199 | 200 | static int doLed(int argc, char *argv[]) 201 | { 202 | unsigned int val; 203 | u16 setVal, getVal; 204 | int ledNr; 205 | int ledVal; 206 | int ret = 0; 207 | int ledChip = 0; 208 | 209 | if(argc == 3) // call by value 210 | { 211 | ret = sscanf(argv[2], "%x", &val); 212 | if(ret <= 0) 213 | { 214 | printf("Invalid LED value\n"); 215 | exit(1); 216 | } 217 | val = ~val; // active low 218 | ret = 0; 219 | setVal = 0xffff & val; 220 | ret += setLedVal(1, setVal); 221 | setVal = 0xffff & (val >> 16); 222 | ret += setLedVal(0, setVal); 223 | if(ret < 0) 224 | { 225 | printf("Fail to write leds\n"); 226 | return -1; 227 | } 228 | else 229 | { 230 | return 0; 231 | } 232 | } 233 | else if(argc == 4) 234 | { 235 | ledNr = atoi(argv[2]); 236 | if((ledNr < 0) || (ledNr > 32)) 237 | { 238 | printf("Invalid LED number\n"); 239 | return -1; 240 | } 241 | ledVal = -1; 242 | if((strcasecmp(argv[3], "on") == 0) || (strcasecmp(argv[3], "high") == 0)|| (strcasecmp(argv[3], "1") == 0)) 243 | { 244 | ledVal = 0; 245 | } 246 | if((strcasecmp(argv[3], "off") == 0) || (strcasecmp(argv[3], "low") == 0)|| (strcasecmp(argv[3], "0") == 0)) 247 | { 248 | ledVal = 1; 249 | } 250 | if(ledVal == -1) 251 | { 252 | printf("Invalid LED value\n"); 253 | return -1; 254 | } 255 | if(ledNr < 17) 256 | { 257 | ledChip = 1; 258 | } 259 | else 260 | { 261 | ledChip = 0; 262 | ledNr -= 16; 263 | } 264 | ret = getLedVal(ledChip); 265 | if(ret < 0) 266 | { 267 | printf("Fail to comm with LED's\n"); 268 | return -1; 269 | } 270 | getVal = 0xffff & ret; 271 | setVal = (u16)1 << (ledNr -1); 272 | if(ledVal == 1) 273 | { 274 | setVal = getVal | setVal; 275 | } 276 | else 277 | { 278 | setVal = getVal & (~setVal); 279 | } 280 | ret = setLedVal(ledChip, setVal); 281 | if( ret < 0) 282 | { 283 | printf("Fail to write LED's\n"); 284 | return -1; 285 | } 286 | } 287 | else 288 | { 289 | printf("Invalid parameter number\n"); 290 | } 291 | return -1; 292 | } 293 | 294 | 295 | /* 296 | * doLedTest 297 | * Testing the led board 298 | */ 299 | static void doLedTest(void) 300 | { 301 | int led, val; 302 | 303 | val = 0; 304 | for(led = 0; led < 32; led++) 305 | { 306 | val += 1 << led; 307 | setLedVal(1, 0xffff & ~val); 308 | setLedVal(0, 0xffff & ~(val >> 16)); 309 | busyWait(100); 310 | } 311 | busyWait(250); 312 | val = 0; 313 | for(led = 0; led < 32; led++) 314 | { 315 | val += 1 << led; 316 | setLedVal(1, 0xffff & val); 317 | setLedVal(0, 0xffff & (val >> 16)); 318 | busyWait(100); 319 | } 320 | } 321 | 322 | /* 323 | * doRelayWrite: 324 | * Write coresponding relay channel 325 | ************************************************************************************** 326 | */ 327 | static void doRelayWrite(int argc, char *argv[]) 328 | { 329 | int pin, val, dev, valR, valRmask, retry; 330 | 331 | if ((argc != 5) && (argc != 4)) 332 | { 333 | printf( "Usage: megaio rwrite \n") ; 334 | printf( "Usage: megaio rwrite \n") ; 335 | exit (1) ; 336 | } 337 | 338 | dev = doBoardInit (gHwAdd); 339 | if(dev <= 0) 340 | { 341 | exit(1); 342 | } 343 | if(argc == 5) 344 | { 345 | pin = atoi (argv [3]) ; 346 | if((pin < 1) || (pin > 8)) 347 | { 348 | printf( "Relay number value out of range\n"); 349 | exit(1); 350 | } 351 | 352 | /**/ if ((strcasecmp (argv [4], "up") == 0) || (strcasecmp (argv [4], "on") == 0)) 353 | val = ON ; 354 | else if ((strcasecmp (argv [4], "down") == 0) || (strcasecmp (argv [4], "off") == 0)) 355 | val = OFF ; 356 | else 357 | { 358 | val = atoi (argv [4]) ; 359 | } 360 | relayChSet(dev, pin, val); 361 | valR = readReg8(dev, RELAY_MEM_ADD); 362 | 363 | valRmask = 0x01 & (valR >> (pin - 1)); 364 | retry = RETRY_TIMES; 365 | 366 | while((retry > 0) && (valRmask != val)) 367 | { 368 | relayChSet(dev, pin, val); 369 | valR = readReg8(dev, RELAY_MEM_ADD); 370 | valRmask = 0x01 & (valR >> (pin - 1)); 371 | retry--; 372 | } 373 | #ifdef DEBUG_I 374 | if(retry < RETRY_TIMES) 375 | { 376 | printf("retry %d times\n", 3-retry); 377 | } 378 | #endif 379 | if(retry == 0) 380 | { 381 | printf( "Fail to write relay\n"); 382 | exit(1); 383 | } 384 | } 385 | else 386 | { 387 | val = atoi (argv [3]) ; 388 | if(val < 0 || val > 255) 389 | { 390 | printf( "Invalid relay value\n"); 391 | exit(1); 392 | } 393 | retry = RETRY_TIMES; 394 | valR = -1; 395 | while((retry > 0) && (valR != val)) 396 | { 397 | writeReg8(dev, RELAY_MEM_ADD, val); 398 | valR = readReg8(dev, RELAY_MEM_ADD); 399 | } 400 | if(retry == 0) 401 | { 402 | printf( "Fail to write relay\n"); 403 | exit(1); 404 | } 405 | } 406 | #ifdef LED_RELAY_LINK 407 | wrLedsR(gHwAdd-0x31, valR); 408 | #endif 409 | } 410 | 411 | 412 | /* 413 | * doRelayRead: 414 | * Read relay state 415 | ****************************************************************************************** 416 | */ 417 | static void doRelayRead(int argc, char *argv[]) 418 | { 419 | int pin, val, dev; 420 | 421 | dev = doBoardInit (gHwAdd); 422 | if(dev <= 0) 423 | { 424 | exit(1); 425 | } 426 | 427 | if (argc == 4) 428 | { 429 | pin = atoi (argv [3]) ; 430 | if((pin < 1) || (pin > 8)) 431 | { 432 | printf( "Relay number value out of range\n"); 433 | exit(1); 434 | } 435 | val = readReg8(dev, RELAY_MEM_ADD); 436 | if(val < 0) 437 | { 438 | printf("Fail to read\n"); 439 | exit(1); 440 | } 441 | 442 | val = val & (1 << (pin-1)); 443 | if(val != 0) 444 | { 445 | printf("1\n"); 446 | } 447 | else 448 | { 449 | printf("0\n"); 450 | } 451 | } 452 | else if(argc == 3) 453 | { 454 | val = readReg8(dev, RELAY_MEM_ADD); 455 | if(val < 0) 456 | { 457 | printf("Fail to read\n"); 458 | exit(1); 459 | } 460 | printf("%d\n", val); 461 | } 462 | else 463 | { 464 | printf( "Usage: %s read relay value\n", argv [0]) ; 465 | exit (1) ; 466 | } 467 | } 468 | 469 | 470 | /* 471 | * doAnalogRead: 472 | * Read analog channel 473 | *********************************************************************************** 474 | */ 475 | static void doAnalogRead(int argc, char *argv[]) 476 | { 477 | int pin, dev, rd; 478 | 479 | dev = doBoardInit (gHwAdd); 480 | if(dev <= 0) 481 | { 482 | exit(1); 483 | } 484 | if (argc == 4) 485 | { 486 | pin = atoi (argv [3]) ; 487 | if((pin < 1) || (pin > 8)) 488 | { 489 | printf( "Analog channel number %d out of range\n", pin); 490 | exit(1); 491 | } 492 | rd = adcGet(dev, pin); 493 | printf("%d\n", rd); 494 | } 495 | else 496 | { 497 | printf( "Usage: %s analog read \n", argv [0]) ; 498 | exit (1) ; 499 | } 500 | } 501 | 502 | 503 | /* 504 | * doAnalogWrite: 505 | * Write the DAC value 506 | *********************************************************************************************** 507 | */ 508 | 509 | static void doAnalogWrite(int argc, char *argv[]) 510 | { 511 | int dev, val; 512 | 513 | dev = doBoardInit (gHwAdd); 514 | if(dev <= 0) 515 | { 516 | exit(1); 517 | } 518 | if (argc != 4) 519 | { 520 | printf( "Usage: %s analog write\n", argv [0]) ; 521 | exit (1) ; 522 | } 523 | val = atoi(argv[3]); 524 | if((val < ANALOG_VAL_MIN) || (val > ANALOG_VAL_MAX)) 525 | { 526 | printf( "analog write value out of range\n"); 527 | exit(1); 528 | } 529 | 530 | if(dacSet(dev, val) != OK) 531 | { 532 | printf("Fail to write DAC!\n"); 533 | exit(1); 534 | } 535 | } 536 | 537 | 538 | /* 539 | * doOptoInRead: 540 | * Read the optocupled input pins 541 | ************************************************************************************************ 542 | */ 543 | 544 | static void doOptoInRead(int argc, char *argv[]) 545 | { 546 | int pin, val, dev; 547 | 548 | dev = doBoardInit(gHwAdd); 549 | if(dev <= 0) 550 | { 551 | exit(1); 552 | } 553 | 554 | if (argc == 4) 555 | { 556 | pin = atoi (argv [3]) ; 557 | if((pin < 1) || (pin > 8)) 558 | { 559 | printf( "Opto In channel out of range\n"); 560 | exit(1); 561 | } 562 | 563 | val = readReg8(dev, OPTO_IN_MEM_ADD); 564 | val = val & (1 << (pin-1)); 565 | if(val != 0) 566 | { 567 | printf("1\n"); 568 | } 569 | else 570 | { 571 | printf("0\n"); 572 | } 573 | } 574 | else if(argc == 3) 575 | { 576 | val = readReg8(dev, OPTO_IN_MEM_ADD); 577 | printf("%d\n", val); 578 | } 579 | else 580 | { 581 | printf( "Usage: %s read opto pins \n", argv [0]) ; 582 | exit (1) ; 583 | } 584 | } 585 | 586 | /* 587 | * doOptoInIrq: 588 | * Set the optocupled input interrupt 589 | ************************************************************************************************ 590 | */ 591 | 592 | static void doOptoInIrq(int argc, char *argv[]) 593 | { 594 | int pin, val, rRising, rFalling; 595 | int dev; 596 | 597 | dev = doBoardInit (gHwAdd); 598 | if(dev <= 0) 599 | { 600 | exit(1); 601 | } 602 | if (argc == 5) 603 | { 604 | pin = atoi (argv [3]) ; 605 | if((pin < 1) || (pin > 8)) 606 | { 607 | printf( "Opto in pin number value out of range\n"); 608 | exit(1); 609 | } 610 | 611 | /**/ if ((strcasecmp (argv [4], "rising") == 0) || (strcasecmp (argv [4], "high") == 0)) 612 | { 613 | val = INT_RISING ; 614 | } 615 | else if ((strcasecmp (argv [4], "falling") == 0) || (strcasecmp (argv [4], "low") == 0)) 616 | { 617 | val = INT_FALLING ; 618 | } 619 | else if ((strcasecmp (argv [4], "both") == 0) || (strcasecmp (argv [4], "change") == 0)) 620 | { 621 | val = INT_BOTH ; 622 | } 623 | else if ((strcasecmp (argv [4], "disable") == 0) || (strcasecmp (argv [4], "none") == 0)) 624 | { 625 | val = INT_DISABLE; 626 | } 627 | else 628 | { 629 | val = atoi (argv [4]); 630 | } 631 | 632 | rRising = readReg8(dev,OPTO_IT_RISING_MEM_ADD ); 633 | busyWait(10); 634 | rFalling = readReg8(dev, OPTO_IT_FALLING_MEM_ADD); 635 | busyWait(10); 636 | switch(val) 637 | { 638 | case 0: 639 | rRising &= ~( 1 << (pin-1)); 640 | rFalling &= ~( 1 << (pin-1)); 641 | break; 642 | 643 | case 1: 644 | rRising |= (1 << (pin-1)); 645 | rFalling &= ~( 1 << (pin-1)); 646 | break; 647 | 648 | case 2: 649 | rRising &= ~( 1 << (pin-1)); 650 | rFalling |= ( 1 << (pin-1)); 651 | break; 652 | 653 | case 3: 654 | rRising |= ( 1 << (pin-1)); 655 | rFalling |= ( 1 << (pin-1)); 656 | break; 657 | 658 | default: 659 | printf( "Invalid interrupt type %s\n", argv[4]); 660 | exit(1); 661 | break; 662 | } 663 | val = (0xff00 & (rFalling << 8)) + (0xff & rRising); 664 | 665 | writeReg8(dev,OPTO_IT_RISING_MEM_ADD, rRising); 666 | busyWait(10); 667 | writeReg8(dev,OPTO_IT_FALLING_MEM_ADD, rFalling); 668 | 669 | } 670 | else 671 | { 672 | printf( "megaio optirq \n") ; 673 | exit (1) ; 674 | } 675 | } 676 | 677 | /* 678 | * doOptoInIt 679 | * Read the rise event by opto in pins.. 680 | ****************************************************************************************** 681 | */ 682 | static void doOptoInIt(int argc) 683 | { 684 | int dev, val; 685 | 686 | dev = doBoardInit (gHwAdd); 687 | if(dev <= 0) 688 | { 689 | exit(1); 690 | } 691 | if (argc == 3) 692 | { 693 | val = readReg8(dev,OPTO_IT_FLAGS_MEM_ADD ); 694 | printf("%d\n", val); 695 | } 696 | else 697 | { 698 | printf( "Invalid command\n"); 699 | exit(1); 700 | } 701 | } 702 | /* 703 | * doIoModeSet: 704 | * Set the coresponding io pin direction 705 | * ******************************************************************************************* 706 | */ 707 | static void doIoModeSet(int argc, char *argv[]) 708 | { 709 | int dev, pin, val, rVal; 710 | 711 | dev = doBoardInit (gHwAdd); 712 | if(dev <= 0) 713 | { 714 | 715 | exit(1); 716 | } 717 | if (argc == 5) 718 | { 719 | pin = atoi (argv [3]) ; 720 | if((pin < 1) || (pin > GPIO_PIN_NUMBER)) 721 | { 722 | printf( "IO pin number value out of range\n"); 723 | exit(1); 724 | } 725 | 726 | /**/ if ((strcasecmp (argv [4], "in") == 0) || (strcasecmp (argv [4], "high") == 0)) 727 | { 728 | val = 1 ; 729 | } 730 | else if ((strcasecmp (argv [4], "out") == 0) || (strcasecmp (argv [4], "low") == 0)) 731 | { 732 | val = 0 ; 733 | } 734 | else 735 | { 736 | val = atoi (argv [4]); 737 | } 738 | 739 | rVal = readReg8(dev, GPIO_DIR_MEM_ADD); 740 | 741 | /**/ if (val == 0) 742 | { 743 | rVal &= ~( 1 << (pin-1)); 744 | } 745 | else 746 | { 747 | rVal |= (1 << (pin - 1)); 748 | } 749 | 750 | writeReg8(dev,GPIO_DIR_MEM_ADD, 0xff & rVal); 751 | } 752 | else if(argc == 4) 753 | { 754 | printf( "Not available on this version\n"); 755 | /* 756 | val = atoi(argv[3]); 757 | if((val < 0) || (val > 0x3ffff)) 758 | { 759 | printf( "Usage: %s invalid io mode\n", argv[3]); 760 | exit(1); 761 | } 762 | rVal = val; 763 | writeReg24(dev, GPIO_DIR_MEM_ADD, rVal); */ 764 | } 765 | else 766 | { 767 | printf( "Usage: %s write io mode usage\n", argv [0]) ; 768 | exit (1) ; 769 | } 770 | } 771 | 772 | 773 | /* 774 | * doIoModeGet: 775 | * Get the coresponding io pin direction 776 | * ******************************************************************************************* 777 | */ 778 | static void doIoModeGet(int argc, char *argv[]) 779 | { 780 | int dev, pin, val, rVal; 781 | 782 | dev = doBoardInit(gHwAdd); 783 | if(dev <= 0) 784 | { 785 | exit(1); 786 | } 787 | rVal = 0x3f; 788 | 789 | if (argc == 4) 790 | { 791 | pin = atoi (argv [3]) ; 792 | if((pin < 1) || (pin > GPIO_PIN_NUMBER)) 793 | { 794 | printf( "IO pin number value out of range\n"); 795 | exit(1); 796 | } 797 | 798 | rVal = readReg8(dev, GPIO_DIR_MEM_ADD); 799 | val = 1 << (pin -1); 800 | val = val & rVal; 801 | /**/ if (val == 0) 802 | { 803 | printf("0\n"); 804 | } 805 | else 806 | { 807 | printf("1\n"); 808 | } 809 | } 810 | else if(argc == 3) 811 | { 812 | rVal = readReg8(dev, GPIO_DIR_MEM_ADD); 813 | printf("%d\n", rVal); 814 | } 815 | else 816 | { 817 | printf( "Usage: %s read io mode usage\n", argv [0]) ; 818 | exit (1) ; 819 | } 820 | } 821 | 822 | 823 | /* 824 | * doIoSet: 825 | * Set the coresponding io pin 826 | * ******************************************************************************************* 827 | */ 828 | static void doIoSet(int argc, char *argv[]) 829 | { 830 | int dev, pin, val; 831 | 832 | dev = doBoardInit(gHwAdd); 833 | if(dev <= 0) 834 | { 835 | exit(1); 836 | } 837 | 838 | 839 | if (argc == 5) 840 | { 841 | pin = atoi (argv [3]) ; 842 | if((pin < 1) || (pin > GPIO_PIN_NUMBER)) 843 | { 844 | printf( "IO pin number value out of range\n"); 845 | exit(1); 846 | } 847 | 848 | /**/ if ((strcasecmp (argv [4], "on") == 0) || (strcasecmp (argv [4], "high") == 0)) 849 | { 850 | val = 1 ; 851 | } 852 | else if ((strcasecmp (argv [4], "off") == 0) || (strcasecmp (argv [4], "low") == 0)) 853 | { 854 | val = 0 ; 855 | } 856 | else 857 | { 858 | val = atoi (argv [4]); 859 | } 860 | 861 | /**/ if (val == 0) 862 | { 863 | writeReg8(dev, GPIO_CLR_MEM_ADD, pin); 864 | } 865 | else 866 | { 867 | writeReg8(dev, GPIO_SET_MEM_ADD, pin); 868 | } 869 | 870 | } 871 | else if(argc == 4) 872 | { 873 | printf( "Not available on this version\n"); 874 | /*val = atoi(argv[3]); 875 | 876 | if((val < 0) || (val > 0x3ffff)) 877 | { 878 | printf( "Usage: %s invalid io mode\n", argv[3]); 879 | exit(1); 880 | } 881 | rVal = val; 882 | writeReg24(dev, GPIO_VAL_MEM_ADD, rVal); */ 883 | } 884 | else 885 | { 886 | printf( "Usage: %s write io mode usage\n", argv [0]) ; 887 | exit (1) ; 888 | } 889 | 890 | } 891 | 892 | 893 | 894 | /* 895 | * doIoGet: 896 | * Get the coresponding io pin value 897 | * ******************************************************************************************* 898 | */ 899 | static void doIoGet(int argc, char *argv[]) 900 | { 901 | int dev, pin, val, rVal; 902 | 903 | dev = doBoardInit(gHwAdd); 904 | if(dev <= 0) 905 | { 906 | 907 | exit(1); 908 | } 909 | rVal = 0x3f; 910 | 911 | if (argc == 4) 912 | { 913 | pin = atoi (argv [3]) ; 914 | if((pin < 1) || (pin > GPIO_PIN_NUMBER)) 915 | { 916 | printf( "IO pin number value out of range\n"); 917 | exit(1); 918 | } 919 | 920 | rVal = readReg8(dev, GPIO_VAL_MEM_ADD); 921 | val = 1 << (pin -1); 922 | val = val & rVal; 923 | /**/ if (val == 0) 924 | { 925 | printf("0\n"); 926 | } 927 | else 928 | { 929 | printf("1\n"); 930 | } 931 | } 932 | else if(argc == 3) 933 | { 934 | rVal = readReg8(dev, GPIO_VAL_MEM_ADD); 935 | printf("%d\n", rVal); 936 | } 937 | else 938 | { 939 | printf( "Usage: %s write io mode usage\n", argv [0]) ; 940 | exit (1) ; 941 | } 942 | } 943 | 944 | /* 945 | * doIoIrqSet: 946 | * Set the coresponding io pin direction 947 | * ******************************************************************************************* 948 | */ 949 | static void doIoIrqSet(int argc, char *argv[]) 950 | { 951 | int dev, pin, val, rValRising, rValFalling; 952 | 953 | dev = doBoardInit (gHwAdd); 954 | if(dev <= 0) 955 | { 956 | 957 | exit(1); 958 | } 959 | if (argc == 5) 960 | { 961 | pin = atoi (argv [3]) ; 962 | if((pin < 1) || (pin > GPIO_PIN_NUMBER)) 963 | { 964 | printf( "IO pin number value out of range\n"); 965 | exit(1); 966 | } 967 | 968 | /**/ if ((strcasecmp (argv [4], "rising") == 0) || (strcasecmp (argv [4], "high") == 0)) 969 | { 970 | val = 1 ; 971 | } 972 | else if ((strcasecmp (argv [4], "falling") == 0) || (strcasecmp (argv [4], "low") == 0)) 973 | { 974 | val = 2 ; 975 | } 976 | else if ((strcasecmp (argv [4], "bowth") == 0) || (strcasecmp (argv [4], "change") == 0)) 977 | { 978 | val = 3 ; 979 | } 980 | else if ((strcasecmp (argv [4], "disable") == 0) || (strcasecmp (argv [4], "none") == 0)) 981 | { 982 | val = 0; 983 | } 984 | else 985 | { 986 | val = atoi (argv [4]); 987 | } 988 | 989 | rValRising = readReg8(dev, GPIO_EXT_IT_RISING_MEM_ADD); 990 | busyWait(10); 991 | rValFalling = readReg8(dev, GPIO_EXT_IT_FALLING_MEM_ADD); 992 | switch(val) 993 | { 994 | case 0: // disable 995 | rValRising &= ~( (u8)1 << (pin-1)); 996 | rValFalling &= ~( (u8)1 << (pin-1)); 997 | break; 998 | 999 | case 1: //rising 1000 | rValRising |= (u8)1 << (pin-1); 1001 | rValFalling &= ~( (u8)1 << (pin-1)); 1002 | break; 1003 | 1004 | case 2: // falling 1005 | rValFalling |= (u8)1 << (pin-1); 1006 | rValRising &= ~( (u8)1 << (pin-1)); 1007 | break; 1008 | 1009 | case 3: //both 1010 | rValFalling |= (u8)1 << (pin-1); 1011 | rValRising |= (u8)1 << (pin-1); 1012 | break; 1013 | 1014 | default: 1015 | printf( "Invalid io irq type %s\n", argv[4] ); 1016 | exit(1); 1017 | break; 1018 | } 1019 | busyWait(10); 1020 | 1021 | writeReg8(dev,GPIO_EXT_IT_RISING_MEM_ADD, 0xff & rValRising ); 1022 | busyWait(10); 1023 | writeReg8(dev,GPIO_EXT_IT_FALLING_MEM_ADD, 0xff & rValFalling ); 1024 | 1025 | 1026 | 1027 | } 1028 | else if(argc == 4) 1029 | { 1030 | printf( "Not available on this version\n"); 1031 | /* 1032 | val = atoi(argv[3]); 1033 | if((val < 0) || (val > 0x3ffff)) 1034 | { 1035 | printf( "Usage: %s invalid io mode\n", argv[3]); 1036 | exit(1); 1037 | } 1038 | rVal = val; 1039 | writeReg24(dev, GPIO_DIR_MEM_ADD, rVal); */ 1040 | } 1041 | else 1042 | { 1043 | printf( "Usage: %s write io mode usage\n", argv [0]) ; 1044 | exit (1) ; 1045 | } 1046 | } 1047 | 1048 | 1049 | /* 1050 | * doIoIt 1051 | * Read the rise event by XPIO pins.. 1052 | ****************************************************************************************** 1053 | */ 1054 | static void doIoIt(int argc) 1055 | { 1056 | int dev, val; 1057 | 1058 | dev = doBoardInit (gHwAdd); 1059 | if(dev <= 0) 1060 | { 1061 | exit(1); 1062 | } 1063 | if (argc == 3) 1064 | { 1065 | val = readReg8(dev,GPIO_IT_FLAGS_MEM_ADD ); 1066 | printf("%d\n", val); 1067 | } 1068 | else 1069 | { 1070 | printf( "Invalid command\n"); 1071 | exit(1); 1072 | } 1073 | } 1074 | 1075 | /* 1076 | * doOcOutWrite: 1077 | * Write coresponding Open collector output channel 1078 | ************************************************************************************** 1079 | */ 1080 | 1081 | static void doOcOutWrite(int argc, char *argv[]) 1082 | { 1083 | int pin, val, dev, valR, valRmask, retry; 1084 | 1085 | if ((argc != 5) && (argc != 4)) 1086 | { 1087 | printf( "Usage: megaio ocwrite \n") ; 1088 | printf( "Usage: megaio ocwrite \n") ; 1089 | 1090 | exit (1) ; 1091 | } 1092 | 1093 | dev = doBoardInit (gHwAdd); 1094 | if(dev <= 0) 1095 | { 1096 | exit(1); 1097 | } 1098 | if(argc == 5) 1099 | { 1100 | pin = atoi (argv [3]) ; 1101 | if((pin < CHANNEL_NR_MIN) || (pin > OC_CH_NR_MAX)) 1102 | { 1103 | printf( "Open collector output number value out of range\n"); 1104 | exit(1); 1105 | } 1106 | 1107 | if ((strcasecmp (argv [4], "up") == 0) || (strcasecmp (argv [4], "on") == 0)) 1108 | val = 1 ; 1109 | else if ((strcasecmp (argv [4], "down") == 0) || (strcasecmp (argv [4], "off") == 0)) 1110 | val = 0 ; 1111 | else 1112 | { 1113 | val = atoi (argv [4]) ; 1114 | } 1115 | if (val == 0) 1116 | { 1117 | writeReg8 (dev,OC_OUT_CLR_MEM_ADD, pin); 1118 | } 1119 | else 1120 | { 1121 | writeReg8 (dev,OC_OUT_SET_MEM_ADD, pin); 1122 | } 1123 | valR = readReg8(dev, OC_OUT_VAL_MEM_ADD); 1124 | valRmask = 0x01 & (valR >> (pin - 1)); 1125 | retry = RETRY_TIMES; 1126 | 1127 | while((retry > 0) && (valRmask != val)) 1128 | { 1129 | if (val == 0) 1130 | { 1131 | writeReg8 (dev,OC_OUT_CLR_MEM_ADD, pin); 1132 | } 1133 | else 1134 | { 1135 | writeReg8 (dev,OC_OUT_SET_MEM_ADD, pin); 1136 | } 1137 | valR = readReg8(dev, OC_OUT_VAL_MEM_ADD); 1138 | valRmask = 0x01 & (valR >> (pin - 1)); 1139 | retry--; 1140 | } 1141 | #ifdef DEBUG_I 1142 | if(retry < RETRY_TIMES) 1143 | { 1144 | printf("retry %d times\n", 3-retry); 1145 | } 1146 | #endif 1147 | if(retry == 0) 1148 | { 1149 | printf( "Fail to write open collector output\n"); 1150 | exit(1); 1151 | } 1152 | } 1153 | else 1154 | { 1155 | val = atoi (argv [3]) ; 1156 | if(val < 0 || val > 0x0f) 1157 | { 1158 | printf( "Invalid open collector output value\n"); 1159 | exit(1); 1160 | } 1161 | retry = RETRY_TIMES; 1162 | while((retry > 0) && (valR != val)) 1163 | { 1164 | writeReg8 (dev,OC_OUT_VAL_MEM_ADD, val); 1165 | 1166 | valR = readReg8(dev, OC_OUT_VAL_MEM_ADD); 1167 | } 1168 | if(retry == 0) 1169 | { 1170 | printf( "Fail to write open collector output out\n"); 1171 | exit(1); 1172 | } 1173 | } 1174 | //wrLeds(gHwAdd-0x31, valR); 1175 | } 1176 | 1177 | 1178 | /* 1179 | * doOcOutRead: 1180 | * Read Open collector output state 1181 | ****************************************************************************************** 1182 | */ 1183 | static void doOcOutRead(int argc, char *argv[]) 1184 | { 1185 | int pin, val, dev; 1186 | 1187 | dev = doBoardInit (gHwAdd); 1188 | if(dev <= 0) 1189 | { 1190 | 1191 | exit(1); 1192 | } 1193 | 1194 | if (argc == 4) 1195 | { 1196 | pin = atoi (argv [3]) ; 1197 | if((pin < 1) || (pin > 4)) 1198 | { 1199 | printf( "Open collector output number value out of range\n"); 1200 | exit(1); 1201 | } 1202 | 1203 | val = readReg8(dev, OC_OUT_VAL_MEM_ADD); 1204 | val = val & (1 << (pin-1)); 1205 | if(val != 0) 1206 | { 1207 | printf("1\n"); 1208 | } 1209 | else 1210 | { 1211 | printf("0\n"); 1212 | } 1213 | } 1214 | else if(argc == 3) 1215 | { 1216 | val = readReg8(dev, OC_OUT_VAL_MEM_ADD); 1217 | printf("%d\n", val); 1218 | } 1219 | else 1220 | { 1221 | printf( "Usage: %s read Open collector output value\n", argv [0]) ; 1222 | exit (1) ; 1223 | } 1224 | 1225 | } 1226 | 1227 | 1228 | void doHelp(int argc, char *argv[]) 1229 | { 1230 | if(argc == 3) 1231 | { 1232 | /**/ if (strcasecmp (argv [2], "rwrite" ) == 0) 1233 | { 1234 | printf("\trwrite: Set Relay On/Off\n"); 1235 | printf("\tUsage: megaio rwrite \n"); 1236 | printf("\tExample: megaio 0 rwrite 2 On; Set Relay #2 on Board #0 On\n"); 1237 | } 1238 | else if (strcasecmp (argv [2], "board" ) == 0) 1239 | { 1240 | printf("\tboard: Check MegaIO Board Hardware and Software Version\n"); 1241 | printf("\tUsage: megaio board\n"); 1242 | printf("\tExample: megaio 0 board\n"); 1243 | } 1244 | else if (strcasecmp (argv [2], "rread" ) == 0) 1245 | { 1246 | printf("\trread: Read Relay Status\n"); 1247 | printf("\tUsage: megaio rread \n"); 1248 | printf("\tUsage: megaio rread\n"); 1249 | printf("\tExample: megaio 0 rread 2; Read Status of Relay #2 on Board #0\n"); 1250 | } 1251 | else if (strcasecmp (argv [2], "aread" ) == 0) 1252 | { 1253 | printf("\taread: Read Analog Input\n"); 1254 | printf("\tUsage: megaio aread \n"); 1255 | printf("\tExample: megaio 0 aread 2; Read Value of ADC Port #3\n"); 1256 | } 1257 | else if (strcasecmp (argv [2], "awrite" ) == 0) 1258 | { 1259 | printf("\tawrite: Write Analog Output\n"); 1260 | printf("\tUsage: megaio awrite \n"); 1261 | printf("\tExample: megaio 0 awrite 1024; Set DAC output to (1024/4095) of full scale\n"); 1262 | } 1263 | else if (strcasecmp (argv [2], "optread" ) == 0) 1264 | { 1265 | printf("\toptread: Read Optically Isolated Input bit or port\n"); 1266 | printf("\tUsage: megaio optread ()\n"); 1267 | printf("\tExample: megaio 0 optread; Read all optically isolated inputs\n"); 1268 | printf("\tExample: megaio 0 optread 3; Read optically isolated input #3\n"); 1269 | } 1270 | else if (strcasecmp (argv [2], "optirqset" ) == 0) 1271 | { 1272 | printf("\toptirqset: Set Interrupt on Optically Isolated Input\n"); 1273 | printf("\tUsage: megaio optirqset \n"); 1274 | printf("\tExample: megaio 0 optirqset 5 rising; Interrupt on optoisolated channel 5 rising edge\n"); 1275 | } 1276 | else if (strcasecmp (argv [2], "optitread" ) == 0) 1277 | { 1278 | printf("\toptitread: Read the pending interrupt(s) on Opto Isolated Input\n"); 1279 | printf("\tUsage: megaio optitread\n"); 1280 | printf("\tExample: megaio 0 optitread\n"); 1281 | } 1282 | else if (strcasecmp (argv [2], "iodread" ) == 0) 1283 | { 1284 | printf("\tiodread: Read direction of IO Port(s)\n"); 1285 | printf("\tUsage: megaio iodread ; Channel = 1..18\n"); 1286 | printf("\tExample: megaio 0 iodread 7; Read direction of XPIO #7\n"); 1287 | printf("\tUsage: megaio iodread; Read direction of all XPIO ports\n"); 1288 | printf("\tExample: megaio 0 iodread\n"); 1289 | } 1290 | else if (strcasecmp (argv [2], "iodwrite" ) == 0) 1291 | { 1292 | printf("\tiodwrite: Set direction of IO Port(s)\n"); 1293 | printf("\tUsage: megaio iodwrite \n"); 1294 | printf("\tExample: megaio 0 iodwrite 2 out; Set IO Port #2 Output\n"); 1295 | } 1296 | else if (strcasecmp (argv [2], "iowrite" ) == 0) 1297 | { 1298 | printf("\tiowrite: Set state of IO Port(s)\n"); 1299 | printf("\tUsage: megaio iowrite <0/1 or low/high>\n"); 1300 | printf("\tExample: megaio 0 iowrite 3 1; Set XPIO 3 to high state\n"); 1301 | } 1302 | else if (strcasecmp (argv [2], "ioread" ) == 0) 1303 | { 1304 | printf("\tioread: Read state of IO Port(s)\n"); 1305 | printf("\tUsage: megaio ioread \n"); 1306 | printf("\tExample: megaio 0 ioread 4 : Read the XPIO pin 4 State\n"); 1307 | printf("\tUsage: megaio ioread\n"); 1308 | printf("\tExample: megaio 0 ioread; Read the entire XPIO port value\n"); 1309 | } 1310 | else if (strcasecmp (argv [2], "ioirqset" ) == 0) 1311 | { 1312 | printf("\tioirqset: Set Interrupt on XPIO Pin\n"); 1313 | printf("\tUsage: megaio ioirqset \n"); 1314 | printf("\tExample: megaio 0 ioirqset 5 change ; set on change interrupt on XPIO Pin 5\n"); 1315 | } 1316 | else if (strcasecmp (argv [2], "ioitread" ) == 0) 1317 | { 1318 | printf("\tioitread: Read the pending interrupt(s) on XPIO Pin(s)\n"); 1319 | printf("\tUsage: megaio ioitread\n"); 1320 | printf("\tExample: megaio 0 ioitread\n"); 1321 | } 1322 | else if (strcasecmp(argv[2], "-lt") == 0) 1323 | { 1324 | printf("\t-lt: Test all the LED's \n"); 1325 | printf("\tUsage: megaio -lt\n"); 1326 | printf("\tExample: megaio -lt\n"); 1327 | } 1328 | else if(strcasecmp(argv[2], "-lw") == 0) 1329 | { 1330 | printf("\t-lw: Turn on/off LED's\n"); 1331 | printf("\tUsage: megaio -lw : turn on/off the 'led_nr' LED\n"); 1332 | printf("\tExample: megaio -lw 10 on\n"); 1333 | printf("\tUsage: megaio -lw : hex value of all 32 LED's\n"); 1334 | printf("\tExample: megaio -lw 55555555 : turn on all odd number LED's\n"); 1335 | } 1336 | else if(strcasecmp(argv[2], "atest") == 0) 1337 | { 1338 | printf("\tatest: Test a adc channel, compute mean, peak to peak and stdDev\n"); 1339 | printf("\tUsage: megaio atest \n"); 1340 | printf("\tExample: megaio 0 atest 2 : test ADC channel 2\n"); 1341 | } 1342 | else if(strcasecmp(argv[2], "test") == 0) 1343 | { 1344 | printf("\ttest: \tTest the board, it pass only with test card connected\n"); 1345 | printf("\tWARNING:\tThis option should not be run with your board connected to external devices!\n"); 1346 | printf("\tUsage: \tmegaio test\n"); 1347 | printf("\tExample:\tmegaio 0 test\n"); 1348 | } 1349 | else if(strcasecmp(argv[2], "test-dac-adc") == 0) 1350 | { 1351 | printf("\ttest-dac-adc:\tTest one analog in channel connected with the analog output channel\n"); 1352 | printf("\tWARNING: \tThis option should not be run with your board connected to external devices!\n"); 1353 | printf("\tUsage: \tmegaio test-dac-adc \n"); 1354 | printf("\tExample: \tmegaio 0 test-dac-adc 1\n"); 1355 | } 1356 | else if(strcasecmp(argv[2], "test-io") == 0) 1357 | { 1358 | printf("\ttest-io:\tTest two digital GPIO connected together\n"); 1359 | printf("\tWARNING:\tThis option should not be run with your board connected to external devices!\n"); 1360 | printf("\tUsage: \tmegaio test-io \n"); 1361 | printf("\tExample:\tmegaio 0 test-io 1 2\n"); 1362 | } 1363 | else if(strcasecmp(argv[2], "test-opto-oc") == 0) 1364 | { 1365 | printf("\ttest-opto-oc:\tTest one opto-isolated in channel connected with one open-collector output channel\n"); 1366 | printf("\tWARNING: \tThis option should not be run with your board connected to external devices!\n"); 1367 | printf("\tUsage: \tmegaio test-opto-oc \n"); 1368 | printf("\tExample: \tmegaio 0 test-opto-o 1 1\n"); 1369 | } 1370 | else if(strcasecmp(argv[2], "ocread") == 0) 1371 | { 1372 | printf("\tocread: Read the open-collector output's\n"); 1373 | printf("\tUsage: megaio ocread\n"); 1374 | printf("\tExample: megaio 0 ocread\n"); 1375 | } 1376 | else if(strcasecmp(argv[2], "ocwrite") == 0) 1377 | { 1378 | printf("\tocwrite: Write the open-collectot output's\n"); 1379 | printf("\tUsage: megaio ocwrite \n"); 1380 | printf("\tExample: megaio 0 ocwrite 5\n"); 1381 | printf("\tUsage: megaio ocwrite \n"); 1382 | printf("\tExample: megaio 0 ocwrite 2 on\n"); 1383 | } 1384 | else 1385 | { 1386 | printf("Invalid command!\n"); 1387 | printf("%s: %s\n", argv [0], usage); 1388 | } 1389 | } 1390 | else 1391 | { 1392 | printf("%s: %s\n", argv [0], usage); 1393 | } 1394 | } 1395 | 1396 | void doBoard(int argc) 1397 | { 1398 | int dev, hwMajor, hwMinor, minor , major; 1399 | 1400 | if(argc == 3) 1401 | { 1402 | dev = doBoardInit(gHwAdd); 1403 | if(dev <= 0) 1404 | { 1405 | exit(1); 1406 | } 1407 | hwMajor = readReg8(dev, REVISION_HW_MAJOR_MEM_ADD); 1408 | hwMinor = readReg8(dev, REVISION_HW_MINOR_MEM_ADD); 1409 | major = readReg8(dev, REVISION_MAJOR_MEM_ADD); 1410 | minor = readReg8(dev, REVISION_MINOR_MEM_ADD); 1411 | printf("MegaIO Hardware version %d.%d Firmware version %d.%d\n", hwMajor, hwMinor, major, minor); 1412 | } 1413 | else 1414 | { 1415 | printf( "Usage: megaio board\n"); 1416 | } 1417 | } 1418 | 1419 | static void doVersion(void) 1420 | { 1421 | printf("MegaIO v%d.%d.%d Copyright (c) 2016 - 2018 Sequent Microsystems\n", VERSION_BASE, VERSION_MAJOR, VERSION_MINOR); 1422 | printf("\nThis is free software with ABSOLUTELY NO WARRANTY.\n"); 1423 | printf("For details type: megaio -warranty\n"); 1424 | 1425 | } 1426 | 1427 | static void doAdcTest(int argc, char* argv[]) 1428 | { 1429 | int dev = -1; 1430 | u16 adcVal[ADC_TEST_SAMPLES_NR] = {0}; 1431 | u16 minVal = 4096; 1432 | u16 maxVal = 0; 1433 | int chNr = 0; 1434 | u16 addr; 1435 | float mean = 0; 1436 | float sigma = 0; 1437 | int i; 1438 | 1439 | dev = doBoardInit (gHwAdd); 1440 | if(dev <= 0) 1441 | { 1442 | exit(1); 1443 | } 1444 | if(argc != 4) 1445 | { 1446 | printf("Invalid parameters number\n"); 1447 | exit(1); 1448 | } 1449 | chNr = atoi(argv[3]); 1450 | if((chNr < 1) || (chNr > 8)) 1451 | { 1452 | printf("Invalid channel number\n"); 1453 | exit(1); 1454 | } 1455 | addr = ADC_VAL_MEM_ADD + 2* (chNr-1); 1456 | printf("\n"); 1457 | for(i = 0; i < ADC_TEST_SAMPLES_NR; i++) 1458 | { 1459 | adcVal[i] = readReg16(dev, addr); 1460 | if(adcVal[i] > maxVal) 1461 | maxVal = adcVal[i]; 1462 | if(adcVal[i] < minVal) 1463 | minVal = adcVal[i]; 1464 | mean += adcVal[i]; 1465 | 1466 | printf("\b\b\b%d\%%",(int)(i/(ADC_TEST_SAMPLES_NR/100))); 1467 | fflush(stdout); 1468 | busyWait(10); 1469 | } 1470 | printf("\n"); 1471 | mean = mean/ADC_TEST_SAMPLES_NR; 1472 | for(i = 0; i< ADC_TEST_SAMPLES_NR; i++) 1473 | { 1474 | sigma += (adcVal[i] - mean) * (adcVal[i] - mean); 1475 | } 1476 | sigma = sqrt(sigma / ADC_TEST_SAMPLES_NR); 1477 | printf("Statistics on ch %d : \n", chNr); 1478 | printf("Standard deviation: %f\n", sigma); 1479 | printf("Mean %d\n", (int)mean); 1480 | printf("Peak to peak : %d\n", maxVal - minVal); 1481 | } 1482 | 1483 | /* 1484 | * Self test for production 1485 | */ 1486 | static void doTest(int argc, char* argv[]) 1487 | { 1488 | int dev, i, retry; 1489 | u8 relVal, valR, addr; 1490 | int relayResult = 0; 1491 | u16 adcVal; 1492 | u16 dacVal = 0; 1493 | u8 dacFault = 0; 1494 | FILE* file = NULL; 1495 | const u8 relayOrder[8] = {1, 2, 5, 6, 7, 8, 4, 3}; 1496 | char* optTest[4] = { 1497 | "Open collector ch 1, opto ch 6 & 3 test", 1498 | "Open collector ch 2, opto ch 5 & 4 test", 1499 | "Open collector ch 3, opto ch 7 & 1 test", 1500 | "Open collector ch 4, opto ch 8 & 2 test" 1501 | }; 1502 | 1503 | u8 optoTab[4] = {0x24, 0x18, 0x41, 0x82}; 1504 | u8 pass = 1; 1505 | u8 ocCh, opto; 1506 | int ioRead = 0; 1507 | 1508 | dev = doBoardInit (gHwAdd); 1509 | if(dev <= 0) 1510 | { 1511 | exit(1); 1512 | } 1513 | if(argc == 4) 1514 | { 1515 | file = fopen( argv[3], "w"); 1516 | if(!file) 1517 | { 1518 | printf( "Fail to open result file\n"); 1519 | //return -1; 1520 | } 1521 | } 1522 | 1523 | //relay test**************************** 1524 | if (strcasecmp( argv[2], "test") == 0) 1525 | { 1526 | relVal = 0; 1527 | printf("Are all relays and LEDs turning on and off in sequence?\nPress y for Yes or any key for No...."); 1528 | startThread(); 1529 | while(relayResult == 0) 1530 | { 1531 | for (i = 0; i < 8; i++) 1532 | { 1533 | relayResult = checkThreadResult(); 1534 | if(relayResult != 0) 1535 | { 1536 | break; 1537 | } 1538 | valR = 0; 1539 | relVal = (u8)1<< (relayOrder[i] -1); 1540 | 1541 | retry = RETRY_TIMES; 1542 | while((retry > 0) && ((valR & relVal) == 0)) 1543 | { 1544 | writeReg8 (dev,RELAY_ON_MEM_ADD, relayOrder[i]); 1545 | valR = readReg8(dev, RELAY_MEM_ADD); 1546 | } 1547 | if(retry == 0) 1548 | { 1549 | printf( "Fail to write relay\n"); 1550 | if(file) 1551 | fclose(file); 1552 | exit(1); 1553 | } 1554 | busyWait(150); 1555 | } 1556 | 1557 | 1558 | for (i = 0; i < 8; i++) 1559 | { 1560 | relayResult = checkThreadResult(); 1561 | if(relayResult != 0) 1562 | { 1563 | break; 1564 | } 1565 | 1566 | valR = 0xff; 1567 | relVal = (u8)1<< (relayOrder[i] -1); 1568 | retry = RETRY_TIMES; 1569 | while((retry > 0) && ((valR & relVal) != 0)) 1570 | { 1571 | writeReg8 (dev,RELAY_OFF_MEM_ADD, relayOrder[i]); 1572 | valR = readReg8(dev, RELAY_MEM_ADD); 1573 | } 1574 | if(retry == 0) 1575 | { 1576 | printf( "Fail to write relay!\n"); 1577 | if(file) 1578 | fclose(file); 1579 | exit(1); 1580 | } 1581 | 1582 | busyWait(150); 1583 | } 1584 | } 1585 | 1586 | writeReg8 (dev,RELAY_MEM_ADD, 0x00); 1587 | busyWait(150); 1588 | if(relayResult == YES) 1589 | { 1590 | if(file) 1591 | { 1592 | fprintf(file, "Relay Test ............................ PASS\n"); 1593 | } 1594 | else 1595 | { 1596 | printf("Relay Test ............................ PASS\n"); 1597 | } 1598 | } 1599 | else 1600 | { 1601 | if(file) 1602 | { 1603 | fprintf(file, "Relay Test ............................ FAIL!\n"); 1604 | } 1605 | else 1606 | { 1607 | printf("Relay Test ............................ FAIL!\n"); 1608 | pass = 0; 1609 | } 1610 | } 1611 | 1612 | // end relay test 1613 | } 1614 | 1615 | // adc test ******************************************** 1616 | for(i = 1; i< 9;i++) 1617 | { 1618 | if(i == 7) 1619 | { 1620 | retry = 0; 1621 | dacVal = 1; 1622 | adcVal = 200; 1623 | while (((dacVal != 0)|| (adcVal > 150)) && (retry < 100)) 1624 | { 1625 | writeReg16(dev, DAC_VAL_H_MEM_ADD, 0x0000); 1626 | busyWait(2); 1627 | dacVal = readReg16(dev,DAC_VAL_H_MEM_ADD); 1628 | busyWait(2); 1629 | retry ++; 1630 | addr = ADC_VAL_MEM_ADD + 2* (i-1); 1631 | adcVal = readReg16(dev, addr); 1632 | busyWait(2); 1633 | } 1634 | addr = ADC_VAL_MEM_ADD + 2* (i-1); 1635 | adcVal = readReg16(dev, addr); 1636 | if(adcVal > 150) 1637 | { 1638 | if(file) 1639 | { 1640 | fprintf(file, "ADC ch 7 / DAC test ................... FAIL!: %d\n", adcVal); 1641 | } 1642 | else 1643 | { 1644 | printf("ADC ch 7 / DAC test ................... FAIL! val = %d", adcVal); 1645 | printf(" DAC Retry %d\n", retry); 1646 | pass = 0; 1647 | } 1648 | dacFault++; 1649 | continue; 1650 | } 1651 | retry = 0; 1652 | while (((dacVal != 3000)|| (adcVal < ADC_TEST_VAL_LOW)) && (retry < 100)) 1653 | { 1654 | writeReg16(dev, DAC_VAL_H_MEM_ADD, 3000); 1655 | busyWait(2); 1656 | dacVal = readReg16(dev,DAC_VAL_H_MEM_ADD); 1657 | busyWait(2); 1658 | retry ++; 1659 | addr = ADC_VAL_MEM_ADD + 2* (i-1); 1660 | adcVal = readReg16(dev, addr); 1661 | } 1662 | } 1663 | addr = ADC_VAL_MEM_ADD + 2* (i-1); 1664 | busyWait(1); 1665 | adcVal = readReg16(dev, addr); 1666 | retry = 0; 1667 | while(((ADC_TEST_VAL_LOW > adcVal) || (adcVal > ADC_TEST_VAL_HIGH)) && (retry < 100)) 1668 | { 1669 | busyWait(2); 1670 | adcVal = readReg16(dev, addr); 1671 | retry ++; 1672 | } 1673 | 1674 | if((ADC_TEST_VAL_LOW < adcVal) && (adcVal < ADC_TEST_VAL_HIGH)) 1675 | { 1676 | if(file) 1677 | { 1678 | fprintf(file, "ADC ch %d test ......................... PASS\n", (int)i); 1679 | } 1680 | else 1681 | { 1682 | printf("ADC ch %d test ......................... PASS\n", (int)i); 1683 | } 1684 | 1685 | } 1686 | else 1687 | { 1688 | if(i == 7) 1689 | { 1690 | dacFault++; 1691 | printf(" DAC Retry %d\n", retry); 1692 | } 1693 | 1694 | if(file) 1695 | { 1696 | fprintf(file, "ADC ch %d test ......................... FAIL!\n", (int)i); 1697 | } 1698 | else 1699 | { 1700 | printf("ADC ch %d test ......................... FAIL! val= %d\n", (int)i, (int)adcVal); 1701 | pass = 0; 1702 | } 1703 | } 1704 | } 1705 | if(dacFault == 0) 1706 | { 1707 | if(file) 1708 | { 1709 | fprintf(file, "DAC test .............................. PASS\n"); 1710 | } 1711 | else 1712 | { 1713 | printf( "DAC test .............................. PASS\n"); 1714 | } 1715 | } 1716 | else 1717 | { 1718 | if(file) 1719 | { 1720 | fprintf(file, "DAC test .............................. FAIL!\n"); 1721 | } 1722 | else 1723 | { 1724 | printf( "DAC test .............................. FAIL Check U4!\n"); 1725 | pass = 0; 1726 | } 1727 | } 1728 | //*****************Open collector out/ Optocupled in test****************************/ 1729 | u8 Q = 2; 1730 | 1731 | for(ocCh = CHANNEL_NR_MIN; ocCh <= OC_CH_NR_MAX; ocCh++) 1732 | { 1733 | writeReg8 (dev,OC_OUT_CLR_MEM_ADD, ocCh); 1734 | #ifdef TEST_RESET 1735 | printf("hit a key\n"); 1736 | getchar(); 1737 | #endif 1738 | if(ocCh > 2) 1739 | { 1740 | Q = 1; 1741 | } 1742 | else 1743 | { 1744 | Q = 2; 1745 | } 1746 | retry = 0; 1747 | opto = optoTab[ocCh - 1] + 1; 1748 | while((opto != optoTab[ocCh - 1]) && (retry < 10)) 1749 | { 1750 | //busyWait(1); 1751 | writeReg8 (dev,OC_OUT_SET_MEM_ADD, ocCh); 1752 | //busyWait(1); 1753 | opto = readReg8(dev, OPTO_IN_MEM_ADD); 1754 | retry ++; 1755 | } 1756 | if(opto == optoTab[ocCh - 1]) 1757 | { 1758 | //sprintf(outTest, "%s PASS\n", optTest[ocCh -1]); 1759 | if(file) 1760 | { 1761 | fprintf(file, "%s PASS\n", optTest[ocCh -1]); 1762 | } 1763 | else 1764 | { 1765 | printf("%s PASS\n", optTest[ocCh -1]); 1766 | } 1767 | } 1768 | else 1769 | { 1770 | //sprintf(outTest, "%s FAIL\n", optTest[ocCh -1]); 1771 | if(file) 1772 | { 1773 | fprintf(file, "%s FAIL!\n", optTest[ocCh -1]); 1774 | } 1775 | else 1776 | { 1777 | printf("%s FAIL ", optTest[ocCh -1]); 1778 | pass = 0; 1779 | 1780 | if(opto == 0) 1781 | { 1782 | printf("Check D10, D11, Q%d!\n", Q); 1783 | } 1784 | else if(opto < 0x10) 1785 | { 1786 | printf("Check D11!\n"); 1787 | } 1788 | else if(opto > 0x0f) 1789 | { 1790 | printf("Check D10!\n"); 1791 | } 1792 | } 1793 | } 1794 | busyWait(1); 1795 | writeReg8 (dev,OC_OUT_CLR_MEM_ADD, ocCh); 1796 | } 1797 | // ********************** I/O test********************************************* 1798 | //setup io1/2/4 as output. 1799 | #ifdef TEST_RESET 1800 | printf("hit a key\n"); 1801 | getchar(); 1802 | #endif 1803 | retry = 0; 1804 | ioRead = 1; 1805 | while((ioRead != 0) && (retry < 10)) 1806 | { 1807 | writeReg8 (dev,GPIO_DIR_MEM_ADD, 0x34); 1808 | busyWait(1); 1809 | writeReg8 (dev,GPIO_VAL_MEM_ADD, 0); 1810 | busyWait(1); 1811 | 1812 | ioRead = readReg8(dev, GPIO_VAL_MEM_ADD); 1813 | busyWait(1); 1814 | retry ++; 1815 | } 1816 | dacFault = 0; 1817 | 1818 | if(ioRead != 0) 1819 | { 1820 | if(file) 1821 | { 1822 | fprintf(file, "IO test ............................... FAIL!: %d\n", ioRead); 1823 | } 1824 | else 1825 | { 1826 | printf("IO test ............................... FAIL!: %d\n", ioRead); 1827 | pass = 0; 1828 | } 1829 | } 1830 | else 1831 | { 1832 | #ifdef TEST_RESET 1833 | printf("hit a key\n"); 1834 | getchar(); 1835 | #endif 1836 | retry = 0; 1837 | while((ioRead != 5) && (retry < RETRY_TIMES)) 1838 | { 1839 | busyWait(1); 1840 | writeReg8 (dev,GPIO_SET_MEM_ADD, 1); 1841 | busyWait(1); 1842 | ioRead =readReg8(dev, GPIO_VAL_MEM_ADD); 1843 | retry ++; 1844 | } 1845 | if(ioRead != 5) 1846 | { 1847 | if(file) 1848 | { 1849 | fprintf(file, "IO ch 1/3 test ........................ FAIL!: %d\n", ioRead); 1850 | } 1851 | else 1852 | { 1853 | printf("IO ch 1/3 test ........................ FAIL: %d. Check R46, R44!\n", ioRead); 1854 | pass = 0; 1855 | } 1856 | } 1857 | else 1858 | { 1859 | if(file) 1860 | { 1861 | fprintf(file, "IO ch 1/3 test ........................ PASS\n"); 1862 | } 1863 | else 1864 | { 1865 | printf("IO ch 1/3 test ........................ PASS\n"); 1866 | } 1867 | } 1868 | #ifdef TEST_RESET 1869 | printf("hit a key\n"); 1870 | getchar(); 1871 | #endif 1872 | retry = 0; 1873 | while((ioRead != 18) && (retry < RETRY_TIMES)) 1874 | { 1875 | busyWait(1); 1876 | writeReg8 (dev,GPIO_CLR_MEM_ADD, 1); 1877 | busyWait(1); 1878 | writeReg8 (dev,GPIO_SET_MEM_ADD, 2); 1879 | busyWait(1); 1880 | ioRead = readReg8(dev, GPIO_VAL_MEM_ADD); 1881 | retry ++; 1882 | } 1883 | 1884 | if(ioRead != 18) 1885 | { 1886 | if(file) 1887 | { 1888 | fprintf(file, "IO ch 2/5 test ........................ FAIL!: %d\n", ioRead); 1889 | } 1890 | else 1891 | { 1892 | printf("IO ch 2/5 test ........................ FAIL: %d. Check R45, R42!\n", ioRead); 1893 | pass = 0; 1894 | } 1895 | } 1896 | else 1897 | { 1898 | if(file) 1899 | { 1900 | fprintf(file, "IO ch 2/5 test ........................ PASS\n"); 1901 | } 1902 | else 1903 | { 1904 | printf("IO ch 2/5 test ........................ PASS\n"); 1905 | } 1906 | } 1907 | #ifdef TEST_RESET 1908 | printf("hit a key\n"); 1909 | getchar(); 1910 | #endif 1911 | retry = 0; 1912 | while((ioRead != 40) && (retry < RETRY_TIMES)) 1913 | { 1914 | busyWait(1); 1915 | writeReg8 (dev,GPIO_CLR_MEM_ADD, 2); 1916 | busyWait(1); 1917 | writeReg8 (dev,GPIO_SET_MEM_ADD, 4); 1918 | busyWait(1); 1919 | ioRead = readReg8(dev, GPIO_VAL_MEM_ADD); 1920 | busyWait(1); 1921 | retry ++; 1922 | } 1923 | 1924 | if(ioRead != 40) 1925 | { 1926 | if(file) 1927 | { 1928 | fprintf(file, "IO ch 4/6 test ........................ FAIL!: %d\n", ioRead); 1929 | } 1930 | else 1931 | { 1932 | printf("IO ch 4/6 test ........................ FAIL: %d. Check R43, R41!\n", ioRead); 1933 | pass = 0; 1934 | } 1935 | } 1936 | else 1937 | { 1938 | if(file) 1939 | { 1940 | fprintf(file, "IO ch 4/6 test ........................ PASS\n"); 1941 | } 1942 | else 1943 | { 1944 | printf("IO ch 4/6 test ........................ PASS\n"); 1945 | } 1946 | } 1947 | #ifdef TEST_RESET 1948 | printf("hit a key\n"); 1949 | getchar(); 1950 | #endif 1951 | writeReg8 (dev,GPIO_CLR_MEM_ADD, 4); 1952 | } 1953 | busyWait(1); 1954 | writeReg8 (dev,GPIO_DIR_MEM_ADD, 0x3f); 1955 | if(file) 1956 | { 1957 | fclose(file); 1958 | } 1959 | if(pass == 0) 1960 | { 1961 | printf("%s", failStr); 1962 | } 1963 | else 1964 | { 1965 | printf("%s", passStr); 1966 | } 1967 | } 1968 | // megaio test-io 1969 | static void doIoTest(int argc, char* argv[]) 1970 | { 1971 | int dev = -1; 1972 | int ch1, ch2; 1973 | int val; 1974 | 1975 | dev = doBoardInit (gHwAdd); 1976 | if(dev <= 0) 1977 | { 1978 | exit(1); 1979 | } 1980 | if(argc != 5) 1981 | { 1982 | printf("Invalid parameters number!\n"); 1983 | exit(1); 1984 | } 1985 | ch1 = atoi(argv[3]); 1986 | if((ch1 < CHANNEL_NR_MIN) || (ch1 > GPIO_CH_NR_MAX)) 1987 | { 1988 | printf("Invalid I/O channel number!\n"); 1989 | exit(1); 1990 | } 1991 | 1992 | ch2 = atoi(argv[4]); 1993 | if((ch2 < CHANNEL_NR_MIN) || (ch2 > GPIO_CH_NR_MAX)) 1994 | { 1995 | printf("Invalid I/O channel number!\n"); 1996 | exit(1); 1997 | } 1998 | if(ch1 == ch2) 1999 | { 2000 | printf("The two channels must be different!\n"); 2001 | exit(1); 2002 | } 2003 | //set ch1 as output 2004 | val = ~(1 << (ch1 - 1)); 2005 | writeReg8(dev,GPIO_DIR_MEM_ADD, val); 2006 | writeReg8(dev, GPIO_CLR_MEM_ADD, ch1); 2007 | val = readReg8(dev, GPIO_VAL_MEM_ADD); 2008 | if( (val & (1 << (ch2 - 1))) != 0) 2009 | { 2010 | writeReg8(dev,GPIO_DIR_MEM_ADD, 0xff); 2011 | printf("Test FAIL!\n"); 2012 | exit(1); 2013 | } 2014 | writeReg8(dev, GPIO_SET_MEM_ADD, ch1); 2015 | val = readReg8(dev, GPIO_VAL_MEM_ADD); 2016 | if( (val & (1 << (ch2 - 1))) == 0) 2017 | { 2018 | writeReg8(dev,GPIO_DIR_MEM_ADD, 0xff); 2019 | printf("Test FAIL!\n"); 2020 | exit(1); 2021 | } 2022 | 2023 | printf("Test PASS\n"); 2024 | 2025 | } 2026 | //megaio test-opto-oc 2027 | static void doOptoOcTest(int argc, char* argv[]) 2028 | { 2029 | int dev = -1; 2030 | int optCh, ocCh; 2031 | int opto; 2032 | 2033 | dev = doBoardInit (gHwAdd); 2034 | if(dev <= 0) 2035 | { 2036 | exit(1); 2037 | } 2038 | if(argc != 5) 2039 | { 2040 | printf("Invalid parameters number!\n"); 2041 | exit(1); 2042 | } 2043 | 2044 | optCh = atoi(argv[3]); 2045 | if((optCh < CHANNEL_NR_MIN) || (optCh > OPTO_CH_NR_MAX)) 2046 | { 2047 | printf("Invalid Opto channel number!\n"); 2048 | exit(1); 2049 | } 2050 | 2051 | ocCh = atoi(argv[4]); 2052 | if((ocCh < CHANNEL_NR_MIN) || (ocCh > OC_CH_NR_MAX)) 2053 | { 2054 | printf("Invalid Open-collector channel number!\n"); 2055 | exit(1); 2056 | } 2057 | // set oc channel to floating 2058 | writeReg8(dev,OC_OUT_CLR_MEM_ADD, ocCh); 2059 | 2060 | opto = readReg8(dev,OPTO_IN_MEM_ADD); 2061 | if( (opto & (1 << (optCh - 1))) != 0) 2062 | { 2063 | printf("Test FAIL!\n"); 2064 | exit(1); 2065 | } 2066 | // set oc channel to GND 2067 | writeReg8(dev,OC_OUT_SET_MEM_ADD, ocCh); 2068 | 2069 | opto = readReg8(dev,OPTO_IN_MEM_ADD); 2070 | if( (opto & (1 << (optCh - 1))) == 0) 2071 | { 2072 | printf("Test FAIL!\n"); 2073 | writeReg8(dev,OC_OUT_CLR_MEM_ADD, ocCh); 2074 | exit(1); 2075 | } 2076 | 2077 | writeReg8(dev,OC_OUT_CLR_MEM_ADD, ocCh); 2078 | printf("Test PASS\n"); 2079 | } 2080 | 2081 | 2082 | //megaio test-dac-adc 2083 | static void doDacAdcTest(int argc, char* argv[]) 2084 | { 2085 | int dev = -1; 2086 | int chNr = 0; 2087 | int val = 0; 2088 | int err, retry; 2089 | 2090 | dev = doBoardInit (gHwAdd); 2091 | if(dev <= 0) 2092 | { 2093 | exit(1); 2094 | } 2095 | if(argc != 4) 2096 | { 2097 | printf("Invalid parameters number\n"); 2098 | exit(1); 2099 | } 2100 | chNr = atoi(argv[3]); 2101 | if((chNr < CHANNEL_NR_MIN) || (chNr > ADC_CH_NR_MAX)) 2102 | { 2103 | printf("Invalid channel number!\n"); 2104 | exit(1); 2105 | } 2106 | // minim 2107 | val = ANALOG_VAL_MIN; 2108 | if(dacSet(dev, val) != OK) 2109 | { 2110 | printf("Fail to write DAC!\n"); 2111 | exit(1); 2112 | } 2113 | err = val - adcGet(dev, chNr); 2114 | retry = RETRY_TIMES; 2115 | while(((err < -ANALOG_ERR_THRESHOLD) || (err > ANALOG_ERR_THRESHOLD)) && (retry > 0)) 2116 | { 2117 | err = val - adcGet(dev, chNr); 2118 | retry--; 2119 | } 2120 | if(0 == retry) 2121 | { 2122 | printf("Test FAIL!\n"); 2123 | exit(1); 2124 | } 2125 | // half 2126 | val = (ANALOG_VAL_MAX - ANALOG_VAL_MIN)/2; 2127 | if(dacSet(dev, val) != OK) 2128 | { 2129 | printf("Fail to write DAC!\n"); 2130 | exit(1); 2131 | } 2132 | err = val - adcGet(dev, chNr); 2133 | retry = RETRY_TIMES; 2134 | while(((err < -ANALOG_ERR_THRESHOLD) || (err > ANALOG_ERR_THRESHOLD)) && (retry > 0)) 2135 | { 2136 | err = val - adcGet(dev, chNr); 2137 | retry--; 2138 | } 2139 | if(0 == retry) 2140 | { 2141 | printf("Test FAIL!\n"); 2142 | exit(1); 2143 | } 2144 | // max 2145 | val = ANALOG_VAL_MAX; 2146 | if(dacSet(dev, val) != OK) 2147 | { 2148 | printf("Fail to write DAC!\n"); 2149 | exit(1); 2150 | } 2151 | err = val - adcGet(dev, chNr); 2152 | retry = RETRY_TIMES; 2153 | while(((err < -ANALOG_ERR_THRESHOLD) || (err > ANALOG_ERR_THRESHOLD)) && (retry > 0)) 2154 | { 2155 | err = val - adcGet(dev, chNr); 2156 | retry--; 2157 | } 2158 | if(0 == retry) 2159 | { 2160 | printf("Test FAIL!\n"); 2161 | exit(1); 2162 | } 2163 | printf("Test PASS\n"); 2164 | } 2165 | 2166 | /* 2167 | * Main loop 2168 | ************************************************************************************************ 2169 | */ 2170 | int main(int argc, char *argv []) 2171 | { 2172 | int id; 2173 | 2174 | if (argc == 1) 2175 | { 2176 | printf( "%s\n", usage) ; 2177 | return 1 ; 2178 | } 2179 | 2180 | 2181 | // Help 2182 | 2183 | if (strcasecmp (argv [1], "-h") == 0) 2184 | { 2185 | doHelp(argc, argv); 2186 | return 0; 2187 | } 2188 | 2189 | // Warranty 2190 | 2191 | if (strcasecmp (argv [1], "-warranty") == 0) 2192 | { 2193 | printf("%s\n", warranty); 2194 | return 0; 2195 | } 2196 | 2197 | // Connector 2198 | 2199 | if (strcasecmp (argv [1], "-connector") == 0) 2200 | { 2201 | printf("%s\n", cnv2); 2202 | return 0; 2203 | } 2204 | // Version 2205 | 2206 | if (strcasecmp (argv [1], "-v") == 0) 2207 | { 2208 | doVersion(); 2209 | return 0; 2210 | } 2211 | 2212 | 2213 | if (strcasecmp (argv [1], "-lt") == 0) 2214 | { 2215 | doLedTest(); 2216 | return 0; 2217 | } 2218 | 2219 | if (strcasecmp (argv [1], "-lw") == 0) 2220 | { 2221 | doLed(argc, argv); 2222 | return 0; 2223 | } 2224 | 2225 | if(argc < 3) 2226 | { 2227 | printf( "%s\n", usage) ; 2228 | return 1 ; 2229 | } 2230 | id = atoi(argv[1]); 2231 | if((id < 0) || (id > 3)) 2232 | { 2233 | printf( "invalid boartd id\n"); 2234 | return 1; 2235 | } 2236 | gHwAdd = 0x31 + id; 2237 | 2238 | 2239 | /**/ if (strcasecmp (argv [2], "rwrite" ) == 0) { doRelayWrite (argc, argv) ; return 0 ; } 2240 | else if (strcasecmp (argv [2], "rread" ) == 0) { doRelayRead (argc, argv) ; return 0 ; } 2241 | else if (strcasecmp (argv [2], "aread" ) == 0) { doAnalogRead (argc, argv) ; return 0 ; } 2242 | else if (strcasecmp (argv [2], "awrite" ) == 0) { doAnalogWrite (argc, argv) ; return 0 ; } 2243 | else if (strcasecmp (argv [2], "optread" ) == 0) { doOptoInRead (argc, argv) ; return 0 ; } 2244 | else if (strcasecmp (argv [2], "optirqset" ) == 0) { doOptoInIrq (argc, argv) ; return 0 ; } 2245 | else if (strcasecmp (argv [2], "optitread" ) == 0) { doOptoInIt (argc) ; return 0 ; } 2246 | else if (strcasecmp (argv [2], "iodwrite" ) == 0) { doIoModeSet (argc, argv) ; return 0 ; } 2247 | else if (strcasecmp (argv [2], "iodread" ) == 0) { doIoModeGet (argc, argv) ; return 0 ; } 2248 | else if (strcasecmp (argv [2], "iowrite" ) == 0) { doIoSet (argc, argv) ; return 0 ; } 2249 | else if (strcasecmp (argv [2], "ioread" ) == 0) { doIoGet (argc, argv) ; return 0 ; } 2250 | else if (strcasecmp (argv [2], "ioirqset" ) == 0) { doIoIrqSet (argc, argv) ; return 0 ; } 2251 | else if (strcasecmp (argv [2], "ioitread" ) == 0) { doIoIt (argc) ; return 0 ; } 2252 | else if (strcasecmp (argv [2], "board" ) == 0) { doBoard (argc) ; return 0 ; } 2253 | else if (strcasecmp (argv [2], "ocwrite" ) == 0) { doOcOutWrite (argc, argv) ; return 0 ; } 2254 | else if (strcasecmp (argv [2], "ocread" ) == 0) { doOcOutRead (argc, argv) ; return 0 ; } 2255 | else if (strcasecmp (argv [2], "test" ) == 0) { doTest (argc, argv) ; return 0 ; } 2256 | else if (strcasecmp (argv [2], "testc" ) == 0) { doTest (argc, argv) ; return 0 ; } 2257 | else if (strcasecmp (argv [2], "atest" ) == 0) { doAdcTest (argc, argv) ; return 0 ; } 2258 | else if (strcasecmp (argv [2], "test-dac-adc") == 0) { doDacAdcTest (argc, argv) ; return 0 ; } 2259 | else if (strcasecmp (argv [2], "test-opto-oc") == 0) { doOptoOcTest (argc, argv) ; return 0 ; } 2260 | else if (strcasecmp (argv [2], "test-io" ) == 0) { doIoTest (argc, argv) ; return 0 ; } 2261 | else { printf( "%s\n", usage) ; return 1;} 2262 | return 0; 2263 | } 2264 | -------------------------------------------------------------------------------- /megaio.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef MEGAIO_H_ 3 | #define MEGAIO_H_ 4 | 5 | 6 | 7 | #define RETRY_TIMES 10 8 | 9 | 10 | #define RELAY_MEM_ADD (u8)0x00 11 | #define RELAY_ON_MEM_ADD (u8)0x01 12 | #define RELAY_OFF_MEM_ADD (u8)0x02 13 | #define OPTO_IN_MEM_ADD (u8)0x03 14 | #define OC_OUT_VAL_MEM_ADD (u8)0x04 15 | #define OC_OUT_SET_MEM_ADD (u8)0x05 16 | #define OC_OUT_CLR_MEM_ADD (u8)0x06 17 | 18 | #define ADC_VAL_MEM_ADD (u8)0x07 19 | #define DAC_VAL_H_MEM_ADD (u8)0x17 20 | #define DAC_VAL_L_MEM_ADD (u8)0x18 21 | #define GPIO_VAL_MEM_ADD (u8)0x19 22 | #define GPIO_SET_MEM_ADD (u8)0x1a 23 | #define GPIO_CLR_MEM_ADD (u8)0x1b 24 | #define GPIO_DIR_MEM_ADD (u8)0x1c 25 | #define OPTO_IT_RISING_MEM_ADD (u8)0x1d // 1B 26 | #define OPTO_IT_FALLING_MEM_ADD (u8)0x1e // 1B 27 | #define GPIO_EXT_IT_RISING_MEM_ADD (u8)0x1f // 1B 28 | #define GPIO_EXT_IT_FALLING_MEM_ADD (u8)0x20 // 1B 29 | #define OPTO_IT_FLAGS_MEM_ADD (u8)0x21 // 1B 30 | #define GPIO_IT_FLAGS_MEM_ADD (u8)0x22 // 1B 31 | 32 | #define REVISION_HW_MAJOR_MEM_ADD (u8)0x3c 33 | #define REVISION_HW_MINOR_MEM_ADD (u8)0x3d 34 | #define REVISION_MAJOR_MEM_ADD (u8)0x3e 35 | #define REVISION_MINOR_MEM_ADD (u8)0x3f 36 | 37 | #define GPIO_PIN_NUMBER (u8)6 38 | 39 | 40 | #define ERROR -1 41 | #define FAIL 0 42 | #define OK 1 43 | 44 | #define CHANNEL_NR_MIN 1 45 | #define RELAY_CH_NR_MAX 8 46 | #define ADC_CH_NR_MAX 8 47 | #define OPTO_CH_NR_MAX 8 48 | #define OC_CH_NR_MAX 4 49 | #define GPIO_CH_NR_MAX 6 50 | 51 | #define ANALOG_VAL_MIN 0 52 | #define ANALOG_VAL_MAX 4095 53 | #define ANALOG_ERR_THRESHOLD 100 54 | 55 | #define COUNT_KEY 0 56 | #define YES 1 57 | #define NO 2 58 | 59 | #define MEGAIO_HW_I2C_BASE_ADD 0x31 60 | 61 | 62 | typedef uint8_t u8; 63 | typedef uint16_t u16; 64 | 65 | typedef enum 66 | { 67 | OFF = 0, 68 | ON 69 | } OutStateEnumType; 70 | 71 | enum 72 | { 73 | INT_DISABLE = 0, 74 | INT_RISING, 75 | INT_FALLING, 76 | INT_BOTH 77 | }; 78 | 79 | 80 | void startThread(void); 81 | int checkThreadResult(void); 82 | int readReg16(int dev, int add); 83 | int readReg24(int dev, int add); 84 | int writeReg16(int dev, int add, int val); 85 | int writeReg24(int dev, int add, int val); 86 | void printbits(int v); 87 | int writeReg8(int dev, int add, int val); 88 | int readReg8(int dev, int add); 89 | int doBoardInit(int hwAdd); 90 | int getLedVal(int chip); 91 | int setLedVal(int chip, int val); 92 | void busyWait(int ms); 93 | 94 | #endif //MEGAIO_H_ 95 | -------------------------------------------------------------------------------- /python/README.md: -------------------------------------------------------------------------------- 1 | 2 | [![megaio-rpi](res/sequent.jpg)](https://www.sequentmicrosystems.com) 3 | 4 | # megaio 5 | 6 | This is the python library to control Old Raspberry Pi Mega-IO Expansion Card 7 | 8 | ## Install 9 | 10 | ```bash 11 | ~$ sudo apt-get update 12 | ~$ sudo apt-get install build-essential python-pip python-dev python-smbus git 13 | ~$ git clone https://github.com/SequentMicrosystems/megaio-rpi.git 14 | ~$ cd megaio-rpi/python/megaio/ 15 | ~/megaio-rpi/python/megaio$ sudo python setup.py install 16 | ``` 17 | ## Update 18 | 19 | ```bash 20 | ~$ cd megaio-rpi/ 21 | ~/megaio-rpi$ git pull 22 | ~$ cd megaio-rpi/python/megaio/ 23 | ~/megaio-rpi/python/megaio$ sudo python setup.py install 24 | ``` 25 | 26 | ## Usage 27 | 28 | Before using the library make sure you disable 1-wire interface (raspi-config), because the board use the pin7 (GPIO4 / 1-wire bus pin) for interrupt. 29 | Now you can import the megaio library and use its functions. To test, read relays status from the MegaIO board with stack level 0: 30 | 31 | ```bash 32 | ~$ python 33 | Python 2.7.9 (default, Sep 17 2016, 20:26:04) 34 | [GCC 4.9.2] on linux2 35 | Type "help", "copyright", "credits" or "license" for more information. 36 | >>> import megaio 37 | >>> megaio.get_relays(0) 38 | 0 39 | >>> 40 | ``` 41 | Prototypes for all functions can be found in README.md file locate under megaio-rpi/python/megaio/ directory. 42 | 43 | This library works with both Python2.x and Python3 44 | 45 | For interrupt driven usage please check int_example.py file 46 | -------------------------------------------------------------------------------- /python/int_example.py: -------------------------------------------------------------------------------- 1 | import megaio as m 2 | import time 3 | 4 | total_event = 10; 5 | 6 | def opto_callback(ch): 7 | global total_event 8 | s = 'Event rise on opto channel no. ' + repr(ch) 9 | print (s) 10 | total_event-= 1 11 | s = repr(total_event) + ' events remaining' 12 | print (s) 13 | if total_event == 0: 14 | m.remove_all_opto_events(); 15 | print ("Remove all events, exiting..") 16 | exit() 17 | 18 | m.add_opto_event(0, 1, m.RISING, opto_callback) 19 | m.add_opto_event(0, 2, m.RISING, opto_callback) 20 | 21 | try: 22 | print ("This example show you how to use external interrupt on megaio board") 23 | 24 | print ("Connect pin 2 and 4 for optocuplers power(+5V and 5VEXT)") 25 | print ("Momentary connect opto channel 1 and 2 (pin 3 and 5) to GND") 26 | print ("for generating the interrupts") 27 | print ("Waith for opto events..") 28 | while 1: 29 | time.sleep(.02) 30 | print ("end wait") 31 | 32 | except KeyboardInterrupt: 33 | print ("Interrupted") 34 | -------------------------------------------------------------------------------- /python/megaio/.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | dist/ 3 | *.egg-info 4 | *.pyc 5 | setuptools* 6 | 7 | .idea 8 | -------------------------------------------------------------------------------- /python/megaio/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2018 Sequent Microsystems 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /python/megaio/README.md: -------------------------------------------------------------------------------- 1 | # megaio 2 | 3 | This is the python library to control [Raspberry Pi Mega-IO Expansion Card](https://www.sequentmicrosystems.com/megaio.html). 4 | Below you find the functions prototypes. 5 | 6 | ## Functions 7 | ### set_relay(stack, relay, value) 8 | Set one relay state. 9 | 10 | stack - stack level of the megaio card (selectable from address jumpers [0..3]) 11 | 12 | relay - relay number (id) [1..8] 13 | 14 | value - relay state 1: turn ON, 0: turn OFF[0..1] 15 | 16 | ### set_relays(stack, value) 17 | Set all relays state. 18 | 19 | stack - stack level of the megaio card (selectable from address jumpers [0..3]) 20 | 21 | value - 8 bit value of all relays (ex: 255: turn on all relays, 0: turn off all relays, 1:turn on relay #1 and off the rest) 22 | 23 | ### get_relay(stack, relay) 24 | Return the state of one relay. 25 | 26 | stack - stack level of the megaio card (selectable from address jumpers [0..3]) 27 | 28 | relay - relay number (id) [1..8] 29 | 30 | return - [0..1] 31 | 32 | ### get_relays(stack) 33 | Return the state of all relays. 34 | 35 | stack - stack level of the megaio card (selectable from address jumpers [0..3]) 36 | 37 | return - [0..255] 38 | 39 | ### get_adc(stack, channel) 40 | Return the raw value of ADC conversion on specific channel 41 | 42 | stack - stack level of the megaio card (selectable from address jumpers [0..3]) 43 | 44 | channel - analog input channel number [1..8] 45 | 46 | return raw value (0 for 0V, 4095 for 3.3V) 47 | 48 | ### get_adc_volt(stack, channel) 49 | Return the ADC measured voltage on a specific channel 50 | 51 | stack - stack level of the megaio card (selectable from address jumpers [0..3]) 52 | 53 | channel - analog input channel number [1..8] 54 | 55 | return voltage [0..3.3] 56 | 57 | ### set_dac(stack, value) 58 | Set a voltage on the analog output channel (raw version) 59 | 60 | stack - stack level of the megaio card (selectable from address jumpers [0..3]) 61 | 62 | value - raw value (0 for 0V, 4095 for 3.3V) [0...4095] 63 | 64 | ### set_dac_volt(stack, value) 65 | Set a voltage on the analog out channel 66 | 67 | stack - stack level of the megaio card (selectable from address jumpers [0..3]) 68 | 69 | value - value in volts [0..3.3] 70 | 71 | ### get_dac(stack) 72 | Get the raw value previously set to the DAC. 73 | 74 | stack - stack level of the megaio card (selectable from address jumpers [0..3]) 75 | 76 | return - raw value (0 for 0V, 4095 for 3.3V) [0...4095] 77 | 78 | ### get_opto_in(stack) 79 | Get the state of the opto-coupled inputs 80 | 81 | stack - stack level of the megaio card (selectable from address jumpers [0..3]) 82 | 83 | return - value of the inputs [0..255] 84 | 85 | ### get_opto_in_ch(stack, ch) 86 | Get the state of the one opto-coupled input channel 87 | 88 | stack - stack level of the megaio card (selectable from address jumpers [0..3]) 89 | 90 | ch - Channel to be read [1..8] 91 | 92 | return - value of the selected channel 0/1 93 | 94 | ### set_io_pin_dir(stack, pin, dir) 95 | Set the corresponding digital I/O pin direction 96 | 97 | stack - stack level of the megaio card (selectable from address jumpers [0..3]) 98 | 99 | pin - I/O pin number [1..6] 100 | 101 | dir - I/O pin direction 0: output; 1: input[0..1] 102 | 103 | ### get_io_val(stack) 104 | Get the state of digital I/O pins 105 | 106 | stack - stack level of the megaio card (selectable from address jumpers [0..3]) 107 | 108 | return - the state of I/O pins (ex 0 - all pins are LOW; 63 - all pins are HIGH; 1 - pin 1 HIGH rest LOW) 109 | 110 | ### get_io_pin_val(stack, pin) 111 | Get the state of one digital I/O pin 112 | 113 | stack - stack level of the megaio card (selectable from address jumpers [0..3]) 114 | 115 | pin - pin number [1..6] 116 | 117 | return - the state of I/O pin (0/1) 118 | 119 | ### set_io_pin(stack, pin, val) 120 | Set the state of corresponding I/O pins set as outputs; ignore pins set as inputs 121 | 122 | stack - stack level of the megaio card (selectable from address jumpers [0..3]) 123 | 124 | pin - I/O pin number [1..6] 125 | 126 | val - state of I/O pin 0: LOW, 1: HIGH [0..1] 127 | 128 | ### set_oc_pin(stack, pin, val) 129 | Set the state of the corresponding open-collector output pin 130 | 131 | stack - stack level of the megaio card (selectable from address jumpers [0..3]) 132 | 133 | pin - open-collector pin # [1..4] 134 | 135 | val - state 0: ON, 1: OFF [0..1] 136 | 137 | ### get_oc_val(stack) 138 | Get the previously set state of all open-collector output pins 139 | 140 | stack - stack level of the megaio card (selectable from address jumpers [0..3]) 141 | 142 | return - state of pins ( ex: 0: all pins OFF, 15: all pins ON, 1: pin #1 ON, all the rest: OFF) 143 | 144 | ### add_opto_event(stack, ch, edge, callback) 145 | Add a function to be called when a change of a optocupled input pin status occur ( also enable the interrupt on selected edge and channel); 146 | 147 | stack - stack level of the megaio card (selectable from address jumpers [0..3]) 148 | 149 | ch - optocupled channel number [1..8] 150 | 151 | edge - RISING or FALLING 152 | 153 | callback - the name of the function to be called. 154 | 155 | ### remove_opto_event(stack, ch, edge) 156 | Remove previus added callback and disable interrupt on selected channel and edge. 157 | 158 | stack - stack level of the megaio card (selectable from address jumpers [0..3]) 159 | 160 | ch - optocupled channel number [1..8] 161 | 162 | edge - RISING or FALLING 163 | 164 | ### remove_all_opto_events() 165 | Remove all callbacks and disable all interrupts on every megaio card connected 166 | 167 | ### add_gpio_event(stack, ch, edge, callback) 168 | Add a function to be called when a change of a gpio input pin status occur ( also enable the interrupt on selected edge and channel); 169 | 170 | stack - stack level of the megaio card (selectable from address jumpers [0..3]) 171 | 172 | ch - gpio channel number [1..6] 173 | 174 | edge - RISING or FALLING 175 | 176 | callback - the name of the function to be called. 177 | 178 | ### remove_gpio_event(stack, ch, edge) 179 | Remove previus added callback and disable interrupt on selected channel and edge. 180 | 181 | stack - stack level of the megaio card (selectable from address jumpers [0..3]) 182 | 183 | ch - gpio channel number [1..6] 184 | 185 | edge - RISING or FALLING 186 | 187 | ### remove_all_gpio_events() 188 | Remove all callbacks and disable all gpio interrupts on every megaio card connected 189 | -------------------------------------------------------------------------------- /python/megaio/megaio/__init__.py: -------------------------------------------------------------------------------- 1 | import smbus 2 | import RPi.GPIO as GPIO 3 | 4 | # bus = smbus.SMBus(1) # 0 = /dev/i2c-0 (port I2C0), 1 = /dev/i2c-1 (port I2C1) 5 | 6 | DEVICE_ADDRESS = 0x31 # 7 bit address (will be left shifted to add the read write bit) 7 | RETRY_TIMES = 10 8 | 9 | RELAY_MEM_ADD = 0x00 10 | RELAY_ON_MEM_ADD = 0x01 11 | RELAY_OFF_MEM_ADD = 0x02 12 | OPTO_IN_MEM_ADD = 0x03 13 | OC_OUT_VAL_MEM_ADD = 0x04 14 | OC_OUT_SET_MEM_ADD = 0x05 15 | OC_OUT_CLR_MEM_ADD = 0x06 16 | 17 | ADC_VAL_MEM_ADD = 0x07 18 | DAC_VAL_H_MEM_ADD = 0x17 19 | DAC_VAL_L_MEM_ADD = 0x18 20 | GPIO_VAL_MEM_ADD = 0x19 21 | GPIO_SET_MEM_ADD = 0x1a 22 | GPIO_CLR_MEM_ADD = 0x1b 23 | GPIO_DIR_MEM_ADD = 0x1c 24 | OPTO_IT_RISING_MEM_ADD = 0x1d # 1B 25 | OPTO_IT_FALLING_MEM_ADD = 0x1e # 1B 26 | GPIO_EXT_IT_RISING_MEM_ADD = 0x1f # 1B 27 | GPIO_EXT_IT_FALLING_MEM_ADD = 0x20 # 1B 28 | OPTO_IT_FLAGS_MEM_ADD = 0x21 # 1B 29 | GPIO_IT_FLAGS_MEM_ADD = 0x22 # 1B 30 | 31 | REVISION_HW_MAJOR_MEM_ADD = 0x3c 32 | REVISION_HW_MINOR_MEM_ADD = 0x3d 33 | REVISION_MAJOR_MEM_ADD = 0x3e 34 | REVISION_MINOR_MEM_ADD = 0x3f 35 | 36 | RISING = 1 37 | FALLING = 0 38 | 39 | opto_callbacks = {} 40 | gpio_callbacks = {} 41 | 42 | GPIO.setmode(GPIO.BCM) 43 | GPIO.setup(4, GPIO.IN, pull_up_down=GPIO.PUD_UP) 44 | 45 | 46 | def version(): 47 | print("megaio python library v1.3.1 Sequent Microsystems") 48 | 49 | 50 | def set_relay(stack, relay, value): 51 | if stack < 0 or stack > 3: 52 | raise ValueError('Invalid stack level') 53 | if relay < 1 or relay > 8: 54 | raise ValueError('Invalid relay number') 55 | bus = smbus.SMBus(1) 56 | try: 57 | if value == 0: 58 | bus.write_byte_data(DEVICE_ADDRESS + stack, RELAY_OFF_MEM_ADD, relay) 59 | else: 60 | bus.write_byte_data(DEVICE_ADDRESS + stack, RELAY_ON_MEM_ADD, relay) 61 | except Exception as e: 62 | bus.close() 63 | raise Exception(e) 64 | bus.close() 65 | 66 | 67 | def set_relays(stack, value): 68 | if stack < 0 or stack > 3: 69 | raise ValueError('Invalid stack level') 70 | if value > 255: 71 | raise ValueError('Invalid relay value') 72 | if value < 0: 73 | raise ValueError('Invalid relay value') 74 | bus = smbus.SMBus(1) 75 | try: 76 | bus.write_byte_data(DEVICE_ADDRESS + stack, RELAY_MEM_ADD, value) 77 | except Exception as e: 78 | bus.close() 79 | raise Exception(e) 80 | bus.close() 81 | 82 | 83 | def get_relay(stack, relay): 84 | if stack < 0 or stack > 3: 85 | raise ValueError('Invalid stack level') 86 | if relay < 1 or relay > 8: 87 | raise ValueError('Invalid relay number') 88 | bus = smbus.SMBus(1) 89 | try: 90 | outVal = (bus.read_byte_data(DEVICE_ADDRESS + stack, RELAY_MEM_ADD) >> (relay - 1)) & 0x01 91 | except Exception as e: 92 | bus.close() 93 | raise Exception(e) 94 | bus.close() 95 | return outVal 96 | 97 | 98 | def get_relays(stack): 99 | bus = smbus.SMBus(1) 100 | if stack < 0 or stack > 3: 101 | raise ValueError('Invalid stack level') 102 | bus = smbus.SMBus(1) 103 | try: 104 | outVal = bus.read_byte_data(DEVICE_ADDRESS + stack, RELAY_MEM_ADD) 105 | except Exception as e: 106 | bus.close() 107 | raise Exception(e) 108 | bus.close() 109 | return outVal 110 | 111 | 112 | def get_adc(stack, channel): 113 | if stack < 0 or stack > 3: 114 | raise ValueError('Invalid stack level') 115 | if channel < 1 or channel > 8: 116 | raise ValueError('Invalid channel number') 117 | bus = smbus.SMBus(1) 118 | try: 119 | aux = bus.read_word_data(DEVICE_ADDRESS + stack, ADC_VAL_MEM_ADD + 2 * (channel - 1)) 120 | outData = (0xff00 & (aux << 8)) + (0xff & (aux >> 8)) 121 | except Exception as e: 122 | bus.close() 123 | raise Exception(e) 124 | bus.close() 125 | return outData 126 | 127 | 128 | def get_adc_volt(stack, channel): 129 | if stack < 0 or stack > 3: 130 | raise ValueError('Invalid stack level') 131 | if channel < 1 or channel > 8: 132 | raise ValueError('Invalid channel number') 133 | bus = smbus.SMBus(1) 134 | try: 135 | aux = bus.read_word_data(DEVICE_ADDRESS + stack, ADC_VAL_MEM_ADD + 2 * (channel - 1)) 136 | outData = (0xff00 & (aux << 8)) + (0xff & (aux >> 8)) 137 | outData = 3.3 * outData / 4096 138 | except Exception as e: 139 | bus.close() 140 | raise Exception(e) 141 | bus.close() 142 | return outData 143 | 144 | 145 | def set_dac(stack, value): 146 | if stack < 0 or stack > 3: 147 | raise ValueError('Invalid stack level') 148 | if value < 0 or value > 4095: 149 | raise ValueError('Invalid DAC value') 150 | bus = smbus.SMBus(1) 151 | try: 152 | outData = (0xff00 & (value << 8)) + (0xff & (value >> 8)) 153 | bus.write_word_data(DEVICE_ADDRESS + stack, DAC_VAL_H_MEM_ADD, outData) 154 | except Exception as e: 155 | bus.close() 156 | raise Exception(e) 157 | bus.close() 158 | 159 | 160 | def set_dac_volt(stack, value): 161 | if stack < 0 or stack > 3: 162 | raise ValueError('Invalid stack level') 163 | if value < 0 or value > 3.3: 164 | raise ValueError('Invalid DAC value') 165 | bus = smbus.SMBus(1) 166 | try: 167 | ival = int(4095 * value / 3.3); 168 | outData = (0xff00 & (ival << 8)) + (0xff & (ival >> 8)) 169 | bus.write_word_data(DEVICE_ADDRESS + stack, DAC_VAL_H_MEM_ADD, outData) 170 | except Exception as e: 171 | bus.close() 172 | raise Exception(e) 173 | bus.close() 174 | 175 | 176 | def get_dac(stack): 177 | if stack < 0 or stack > 3: 178 | raise ValueError('Invalid stack level') 179 | bus = smbus.SMBus(1) 180 | try: 181 | aux = bus.read_word_data(DEVICE_ADDRESS + stack, DAC_VAL_H_MEM_ADD) 182 | except Exceptions as e: 183 | bus.close() 184 | raise Exception(e) 185 | bus.close() 186 | outData = (0xff00 & (aux << 8)) + (0xff & (aux >> 8)) 187 | return outData 188 | 189 | 190 | def get_opto_in(stack): 191 | if stack < 0 or stack > 3: 192 | raise ValueError('Invalid stack level') 193 | try: 194 | bus = smbus.SMBus(1) 195 | outData = bus.read_byte_data(DEVICE_ADDRESS + stack, OPTO_IN_MEM_ADD) 196 | except Exceptions as e: 197 | bus.close() 198 | raise Exception(e) 199 | bus.close() 200 | return outData 201 | 202 | 203 | def get_opto_in_ch(stack, ch): 204 | if stack < 0 or stack > 3: 205 | raise ValueError('Invalid stack level') 206 | if ch < 1 or ch > 8: 207 | raise ValueError('Invalid opto channel') 208 | 209 | bus = smbus.SMBus(1) 210 | try: 211 | outData = bus.read_byte_data(DEVICE_ADDRESS + stack, OPTO_IN_MEM_ADD) 212 | except Exceptions as e: 213 | bus.close() 214 | raise Exception(e) 215 | bus.close() 216 | if (1 << (ch - 1)) & outData != 0: 217 | return 1 218 | return 0 219 | 220 | 221 | def set_io_pin_dir(stack, pin, dir): 222 | if stack < 0 or stack > 3: 223 | raise ValueError('Invalid stack level') 224 | if pin < 1 or pin > 6: 225 | raise ValueError('Invalid IO pin number') 226 | if dir != 0 and dir != 1: 227 | raise ValueError('Invalid IO direction') 228 | bus = smbus.SMBus(1) 229 | try: 230 | inData = bus.read_byte_data(DEVICE_ADDRESS + stack, GPIO_DIR_MEM_ADD) 231 | aux = 1 << (pin - 1) 232 | if dir == 1: 233 | inData = inData | aux 234 | else: 235 | inData = inData & (~aux) 236 | bus.write_byte_data(DEVICE_ADDRESS + stack, GPIO_DIR_MEM_ADD, inData) 237 | except Exceptions as e: 238 | bus.close() 239 | raise Exception(e) 240 | bus.close() 241 | 242 | 243 | def get_io_val(stack): 244 | if stack < 0 or stack > 3: 245 | raise ValueError('Invalid stack level') 246 | bus = smbus.SMBus(1) 247 | try: 248 | outVal = bus.read_byte_data(DEVICE_ADDRESS + stack, GPIO_VAL_MEM_ADD) 249 | except Exceptions as e: 250 | bus.close() 251 | raise Exception(e) 252 | bus.close() 253 | return outVal 254 | 255 | 256 | def get_io_pin_val(stack, pin): 257 | if stack < 0 or stack > 3: 258 | raise ValueError('Invalid stack level') 259 | if pin < 1 or pin > 6: 260 | raise ValueError('Invalid GPIO pin') 261 | bus = smbus.SMBus(1) 262 | try: 263 | outVal = (bus.read_byte_data(DEVICE_ADDRESS + stack, GPIO_VAL_MEM_ADD) >> (pin - 1)) & 0x01 264 | except Exceptions as e: 265 | bus.close() 266 | raise Exception(e) 267 | bus.close() 268 | return outVal 269 | 270 | 271 | def set_io_pin(stack, pin, val): 272 | if stack < 0 or stack > 3: 273 | raise ValueError('Invalid stack level') 274 | if pin < 1 or pin > 6: 275 | raise ValueError('Invalid IO pin number') 276 | if val != 0 and val != 1: 277 | raise ValueError('Invalid IO output level') 278 | bus = smbus.SMBus(1) 279 | try: 280 | if val == 1: 281 | bus.write_byte_data(DEVICE_ADDRESS + stack, GPIO_SET_MEM_ADD, pin) 282 | else: 283 | bus.write_byte_data(DEVICE_ADDRESS + stack, GPIO_CLR_MEM_ADD, pin) 284 | except Exceptions as e: 285 | bus.close() 286 | raise Exception(e) 287 | bus.close() 288 | 289 | 290 | def set_oc_pin(stack, pin, val): 291 | if stack < 0 or stack > 3: 292 | raise ValueError('Invalid stack level') 293 | if pin < 1 or pin > 4: 294 | raise ValueError('Invalid OC channel number') 295 | if val != 0 and val != 1: 296 | raise ValueError('Invalid OC value') 297 | bus = smbus.SMBus(1) 298 | try: 299 | if val == 1: 300 | bus.write_byte_data(DEVICE_ADDRESS + stack, OC_OUT_SET_MEM_ADD, pin) 301 | else: 302 | bus.write_byte_data(DEVICE_ADDRESS + stack, OC_OUT_CLR_MEM_ADD, pin) 303 | except Exceptions as e: 304 | bus.close() 305 | raise Exception(e) 306 | bus.close() 307 | 308 | 309 | def get_oc_val(stack): 310 | if stack < 0 or stack > 3: 311 | raise ValueError('Invalid stack level') 312 | bus = smbus.SMBus(1) 313 | try: 314 | outVal = bus.read_byte_data(DEVICE_ADDRESS + stack, OC_OUT_VAL_MEM_ADD) 315 | except Exceptions as e: 316 | bus.close() 317 | raise Exception(e) 318 | bus.close() 319 | return outVal 320 | 321 | 322 | # External interrupt setup functions ########################################### 323 | 324 | # add optocupled input event 325 | def add_opto_event(stack, ch, edge, callback): 326 | global opto_callbacks 327 | if stack < 0 or stack > 3: 328 | raise ValueError('Invalid stack level') 329 | if edge != RISING and edge != FALLING or ch < 1 or ch > 8: 330 | raise ValueError('Invalid edge or channel') 331 | if stack not in opto_callbacks: 332 | opto_callbacks[stack] = {} 333 | if ch not in opto_callbacks[stack]: 334 | opto_callbacks[stack][ch] = {} 335 | opto_callbacks[stack][ch][edge] = callback 336 | bus = smbus.SMBus(1) 337 | aux = 1 << (ch - 1) 338 | try: 339 | if edge == RISING: 340 | inData = bus.read_byte_data(DEVICE_ADDRESS + stack, OPTO_IT_RISING_MEM_ADD) 341 | inData = inData | aux; 342 | bus.write_byte_data(DEVICE_ADDRESS + stack, OPTO_IT_RISING_MEM_ADD, inData) 343 | else: 344 | inData = bus.read_byte_data(DEVICE_ADDRESS + stack, OPTO_IT_FALLING_MEM_ADD) 345 | inData = inData | aux; 346 | bus.write_byte_data(DEVICE_ADDRESS + stack, OPTO_IT_FALLING_MEM_ADD, inData) 347 | except Exceptions as e: 348 | bus.close() 349 | raise Exception(e) 350 | bus.close() 351 | 352 | 353 | 354 | def remove_opto_event(stack, ch, edge):# remove optocupled input event 355 | global opto_callbacks 356 | if stack < 0 or stack > 3: 357 | raise ValueError('Invalid stack level') 358 | if edge != RISING and edge != FALLING or ch < 1 or ch > 8: 359 | raise ValueError('Invalid edge or channel') 360 | if stack in opto_callbacks: 361 | if ch in opto_callbacks[stack]: 362 | if edge in opto_callbacks[stack][ch]: 363 | del opto_callbacks[stack][ch][edge] 364 | bus = smbus.SMBus(1) 365 | aux = ~(1 << (ch - 1)) 366 | try: 367 | if edge == RISING: 368 | inData = bus.read_byte_data(DEVICE_ADDRESS + stack, OPTO_IT_RISING_MEM_ADD) 369 | inData = inData & aux; 370 | bus.write_byte_data(DEVICE_ADDRESS + stack, OPTO_IT_RISING_MEM_ADD, inData) 371 | else: 372 | inData = bus.read_byte_data(DEVICE_ADDRESS + stack, OPTO_IT_FALLING_MEM_ADD) 373 | inData = inData & aux; 374 | bus.write_byte_data(DEVICE_ADDRESS + stack, OPTO_IT_FALLING_MEM_ADD, inData) 375 | except Exceptions as e: 376 | bus.close() 377 | raise Exception(e) 378 | bus.close() 379 | 380 | 381 | 382 | def remove_all_opto_events(): # remove all optocupled input events 383 | global opto_callbacks 384 | for stack in opto_callbacks: 385 | for ch in opto_callbacks[stack]: 386 | remove_opto_event(stack, ch, RISING) 387 | remove_opto_event(stack, ch, FALLING) 388 | del opto_callbacks 389 | 390 | 391 | 392 | def add_gpio_event(stack, ch, edge, callback):# add gpio input event 393 | global gpio_callbacks 394 | if stack < 0 or stack > 3: 395 | raise ValueError('Invalid stack level') 396 | if edge != RISING and edge != FALLING or ch < 1 or ch > 6: 397 | raise ValueError('Invalid edge or channel') 398 | if stack not in gpio_callbacks: 399 | gpio_callbacks[stack] = {} 400 | if ch not in gpio_callbacks[stack]: 401 | gpio_callbacks[stack][ch] = {} 402 | gpio_callbacks[stack][ch][edge] = callback 403 | bus = smbus.SMBus(1) 404 | aux = 1 << (ch - 1); 405 | try: 406 | if edge == RISING: 407 | inData = bus.read_byte_data(DEVICE_ADDRESS + stack, GPIO_EXT_IT_RISING_MEM_ADD) 408 | inData = inData | aux; 409 | bus.write_byte_data(DEVICE_ADDRESS + stack, GPIO_EXT_IT_RISING_MEM_ADD, inData) 410 | else: 411 | inData = bus.read_byte_data(DEVICE_ADDRESS + stack, GPIO_EXT_IT_FALLING_MEM_ADD) 412 | inData = inData | aux; 413 | bus.write_byte_data(DEVICE_ADDRESS + stack, GPIO_EXT_IT_FALLING_MEM_ADD, inData) 414 | except Exceptions as e: 415 | bus.close() 416 | raise Exception(e) 417 | bus.close() 418 | 419 | 420 | 421 | def remove_gpio_event(stack, ch, edge): # remove gpio input event 422 | global gpio_callbacks 423 | if stack < 0 or stack > 3: 424 | raise ValueError('Invalid stack level') 425 | if edge != RISING and edge != FALLING or ch < 1 or ch > 6: 426 | raise ValueError('Invalid edge or channel') 427 | if stack in gpio_callbacks: 428 | if ch in gpio_callbacks[stack]: 429 | if edge in gpio_callbacks[stack][ch]: 430 | del gpio_callbacks[stack][ch][edge] 431 | bus = smbus.SMBus(1) 432 | aux = ~(1 << (ch - 1)); 433 | try: 434 | if edge == RISING: 435 | inData = bus.read_byte_data(DEVICE_ADDRESS + stack, GPIO_EXT_IT_RISING_MEM_ADD) 436 | inData = inData & aux; 437 | bus.write_byte_data(DEVICE_ADDRESS + stack, GPIO_EXT_IT_RISING_MEM_ADD, inData) 438 | else: 439 | inData = bus.read_byte_data(DEVICE_ADDRESS + stack, GPIO_EXT_IT_FALLING_MEM_ADD) 440 | inData = inData & aux; 441 | bus.write_byte_data(DEVICE_ADDRESS + stack, GPIO_EXT_IT_FALLING_MEM_ADD, inData) 442 | except Exceptions as e: 443 | bus.close() 444 | raise Exception(e) 445 | bus.close() 446 | 447 | 448 | def remove_all_gpio_events():# remove all gpio input events 449 | global gpio_callbacks 450 | for stack in gpio_callbacks: 451 | for ch in gpio_callbacks[stack]: 452 | remove_gpio_event(stack, ch, RISING) 453 | remove_gpio_event(stack, ch, FALLING) 454 | del gpio_callbacks 455 | 456 | 457 | 458 | def process_isr(channel):# Process the interrupt 459 | bus = smbus.SMBus(1) 460 | try: 461 | for stack in opto_callbacks: 462 | opto_it_flags = bus.read_byte_data(DEVICE_ADDRESS + stack, OPTO_IT_FLAGS_MEM_ADD) 463 | opto_val = bus.read_byte_data(DEVICE_ADDRESS + stack, OPTO_IN_MEM_ADD) 464 | for ch in opto_callbacks[stack]: 465 | if ((opto_it_flags >> (ch - 1)) & 1) == 1: 466 | if ((opto_val >> (ch - 1)) & 1) == 1: 467 | if RISING in opto_callbacks[stack][ch]: # rising edge 468 | opto_callbacks[stack][ch][RISING](ch) 469 | else: 470 | if FALLING in opto_callbacks[stack][ch]: 471 | opto_callbacks[stack][ch][FALLING](ch) 472 | 473 | for stack in gpio_callbacks: 474 | gpio_it_flags = bus.read_byte_data(DEVICE_ADDRESS + stack, GPIO_IT_FLAGS_MEM_ADD) 475 | gpio_val = bus.read_byte_data(DEVICE_ADDRESS + stack, GPIO_VAL_MEM_ADD) 476 | for ch in gpio_callbacks[stack]: 477 | if ((gpio_it_flags >> (ch - 1)) & 1) == 1: 478 | if ((gpio_val >> (ch - 1)) & 1) == 1: 479 | if RISING in gpio_callbacks[stack][ch]: # rising edge 480 | gpio_callbacks[stack][ch][RISING](ch) 481 | else: 482 | if FALLING in gpio_callbacks[stack][ch]: 483 | gpio_callbacks[stack][ch][FALLING](ch) 484 | except Exceptions as e: 485 | bus.close() 486 | raise Exception(e) 487 | bus.close() 488 | 489 | GPIO.add_event_detect(4, GPIO.FALLING, callback=process_isr, bouncetime=200) 490 | -------------------------------------------------------------------------------- /python/megaio/setup.py: -------------------------------------------------------------------------------- 1 | import setuptools 2 | 3 | with open("README.md", "r") as fh: 4 | long_description = fh.read() 5 | 6 | setuptools.setup( 7 | name="megaio", 8 | version="1.3.3", 9 | author="Alexandru Burcea", 10 | author_email="olcit@gmail.com", 11 | description="A set of functions to control Sequent Microsystems MegaIO board", 12 | license='MIT', 13 | url="https://github.com/SequentMicrosystems/megaio-rpi", 14 | packages=setuptools.find_packages(), 15 | classifiers=[ 16 | "Programming Language :: Python :: 2/3", 17 | "License :: OSI Approved :: MIT License", 18 | "Operating System :: OS Independent", 19 | ], 20 | ) -------------------------------------------------------------------------------- /python/res/sequent.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SequentMicrosystems/megaio-rpi/1fdca6ec160bd8f4225ea68560c7980c4034f1af/python/res/sequent.jpg -------------------------------------------------------------------------------- /readmeres/sequent.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SequentMicrosystems/megaio-rpi/1fdca6ec160bd8f4225ea68560c7980c4034f1af/readmeres/sequent.jpg -------------------------------------------------------------------------------- /rev_history.txt: -------------------------------------------------------------------------------- 1 | .... 2 | Version 1.1.5: 3 | 1) Implement option "-v" - display the megaio version 4 | 2) Implement option "board" - display the board version and firmware version 5 | 3) Implement retry mechanism for relay write command 6 | 7 | Version 1.1.6: 8 | 1) Board detection mechanism 9 | 2) DEBUG defines 10 | 3) Retry report in debug mode 11 | 12 | Version 1.1.7: 13 | 1)Update board option 14 | 2) Add interrupt functionality for optoio and XPIO 15 | 3) Update help command(s) 16 | 17 | Version 1.1.7: 18 | 1) Add rwrite command with retry 19 | 20 | Version 1.1.9 21 | 1) Add led board suport. 22 | 23 | Version 2.0.1: 24 | 1) Change for hardware version 3.1 (no back compatibility!!!!!!!!!!) 25 | 2) Add "megaio test" - self test (you shuld plug the test card in order to PASS) Warning!! This test will change relay state 26 | 3) Add "megaio test - self test and save all result in text format in file 27 | 4) Add "megaio atest - Test the analog channel, compute "peack to peack" "median" "standard deviation" values. 28 | 5) Add "megaio -warranty" 29 | 30 | Version 2.1.0: 31 | 1)Treat LED board independet (no led change with relay change) 32 | 2) Add "megaio -lw " : Write 32bits hex value to led card 33 | 3) Add "megaio -lw " : Turn on/off corespondent led 34 | 4) Add "megaio -lt" :fash the led's... 35 | 36 | Version 2.1.2: 37 | 1) Reduce delay in test command 38 | 2) Introduce retry mechanism in test commands 39 | 3) Add testc command similar to test without relays (used to test "test cards") 40 | ...... 41 | Version 2.2.0: 42 | 1) Split function in two .c files: comm.c (platform specific communication functions); megaio.c (platfom independent MegaIO control functions) This is made for easy mantain UP-Board repository 43 | 2) Rewrite some functions in order to support new communications routines 44 | 3) Eliminate some "magic numbers" 45 | 46 | Version 2.2.1: 47 | 1) Add "-connector" option to display MegaIO connector pinout 48 | 2) Add " test-opto-oc " option for easy testing a opto/opencollector pair 49 | 3) Add " test-io " option for easy test two I/O pair 50 | 4) Add " test-dac-adc " option for easy test a adc channel 51 | 52 | Version 2.2.2: 53 | 1) Minor code reorganizations 54 | 55 | Version 2.2.4: 56 | 1) "-connector" option update 57 | 2) Retry mechanism for I2C connect to the board 58 | --------------------------------------------------------------------------------