Command processor to access I2C and SPI Takes URI coded commands and returns JSON array

Fork of SerialInterface by Greg Steiert

Committer:
switches
Date:
Thu Dec 15 17:42:33 2016 +0000
Revision:
7:06a2eb2483f6
Parent:
6:c9b7256c8261
Child:
9:f52181496512
Moved the GPIO and AIN pointer assignment to the declaration to eliminate the need for the init function.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
gsteiert 0:828bfd94972b 1 /* Pmod Interface Library
gsteiert 0:828bfd94972b 2 *
gsteiert 0:828bfd94972b 3 */
gsteiert 0:828bfd94972b 4
gsteiert 0:828bfd94972b 5 #include "mbed.h"
switches 2:3f6a8ac111a9 6 #include "SerialInterface.h"
gsteiert 0:828bfd94972b 7
switches 7:06a2eb2483f6 8 SerialInterface::SerialInterface(I2C &i2c, SPI &spi, DigitalInOut* gpio, AnalogIn* ain): _i2c(i2c), _spi(spi)
gsteiert 0:828bfd94972b 9 {
switches 7:06a2eb2483f6 10 _gpio = gpio; // save pointer to GPIO pins
switches 7:06a2eb2483f6 11 _ain = ain; // save pointer to GPIO pins
gsteiert 0:828bfd94972b 12 }
gsteiert 0:828bfd94972b 13
switches 2:3f6a8ac111a9 14 SerialInterface::~SerialInterface()
gsteiert 0:828bfd94972b 15 {
gsteiert 0:828bfd94972b 16 }
gsteiert 0:828bfd94972b 17
switches 6:c9b7256c8261 18 /* Analog In
switches 6:c9b7256c8261 19 * /a read all
switches 6:c9b7256c8261 20 * /a/[pin] read from pin
switches 6:c9b7256c8261 21 * Returns 16bit normalized result
switches 6:c9b7256c8261 22 */
switches 6:c9b7256c8261 23 void SerialInterface::fnc_ain(char* resp)
gsteiert 0:828bfd94972b 24 {
switches 6:c9b7256c8261 25 switch (_args[0]) {
switches 6:c9b7256c8261 26 case 0:
switches 6:c9b7256c8261 27 sprintf(resp, "[0x%04X,0x%04X,0x%04X,0x%04X,0x%04X,0x%04X,0x%04X,0x%04X]",
switches 6:c9b7256c8261 28 _ain[0].read_u16(), _ain[1].read_u16(), _ain[2].read_u16(), _ain[3].read_u16(),
switches 6:c9b7256c8261 29 _ain[4].read_u16(), _ain[5].read_u16(), _ain[6].read_u16(), _ain[7].read_u16() );
switches 6:c9b7256c8261 30 break;
switches 6:c9b7256c8261 31 case 1:
switches 6:c9b7256c8261 32 sprintf(resp, "[0x%04X]", _ain[_args[1]].read_u16());
switches 6:c9b7256c8261 33 break;
switches 6:c9b7256c8261 34 default:
switches 6:c9b7256c8261 35 sprintf(resp, "[-1]");
switches 6:c9b7256c8261 36 break;
switches 6:c9b7256c8261 37 }
switches 5:9e27e2a46fa6 38 }
switches 5:9e27e2a46fa6 39
switches 5:9e27e2a46fa6 40 /* Digital I/O
switches 5:9e27e2a46fa6 41 * /d read all
switches 5:9e27e2a46fa6 42 * /d/[pin] read from pin
switches 5:9e27e2a46fa6 43 * /d/[pin]/[cfg] write configuration to pin
switches 5:9e27e2a46fa6 44 * [pin] = number (from 0 to 7) of the pin to access
switches 5:9e27e2a46fa6 45 * [cfg] = pin configuration:
switches 5:9e27e2a46fa6 46 * 0 - output low
switches 5:9e27e2a46fa6 47 * 1 - output high
switches 5:9e27e2a46fa6 48 * 2 - input pull down
switches 5:9e27e2a46fa6 49 * 3 - input pull up
switches 5:9e27e2a46fa6 50 * 4 - input pull none
switches 5:9e27e2a46fa6 51 */
switches 5:9e27e2a46fa6 52 void SerialInterface::fnc_dio(char* resp)
switches 5:9e27e2a46fa6 53 {
switches 5:9e27e2a46fa6 54 int bdat;
switches 5:9e27e2a46fa6 55 int bcnt;
switches 5:9e27e2a46fa6 56 switch (_args[0]) {
switches 5:9e27e2a46fa6 57 case 0:
switches 5:9e27e2a46fa6 58 sprintf(resp, "[");
switches 5:9e27e2a46fa6 59 resp +=1;
switches 5:9e27e2a46fa6 60 for (bcnt = 0; bcnt < 8 ; bcnt++) {
switches 5:9e27e2a46fa6 61 bdat = _gpio[bcnt].read();
switches 5:9e27e2a46fa6 62 sprintf(resp, "%d,", bdat);
switches 5:9e27e2a46fa6 63 resp +=2;
switches 5:9e27e2a46fa6 64 }
switches 5:9e27e2a46fa6 65 sprintf((resp-1), "]");
switches 5:9e27e2a46fa6 66 break;
switches 5:9e27e2a46fa6 67 case 1:
switches 5:9e27e2a46fa6 68 if (_args[1] > 7) {
switches 5:9e27e2a46fa6 69 sprintf(resp, "[-1]");
switches 5:9e27e2a46fa6 70 } else {
switches 5:9e27e2a46fa6 71 sprintf(resp,"[%d]", _gpio[_args[1]].read());
switches 5:9e27e2a46fa6 72 }
switches 5:9e27e2a46fa6 73 break;
switches 5:9e27e2a46fa6 74 case 2:
switches 5:9e27e2a46fa6 75 if (_args[1] > 7) {
switches 5:9e27e2a46fa6 76 sprintf(resp, "[-1]");
switches 5:9e27e2a46fa6 77 } else {
switches 5:9e27e2a46fa6 78 if (_args[2] < 2) {
switches 5:9e27e2a46fa6 79 _gpio[_args[1]].write(_args[2]);
switches 5:9e27e2a46fa6 80 _gpio[_args[1]].output();
switches 5:9e27e2a46fa6 81 } else {
switches 5:9e27e2a46fa6 82 if (_args[2] == 2) {
switches 5:9e27e2a46fa6 83 _gpio[_args[1]].mode(PullDown);
switches 5:9e27e2a46fa6 84 } else if (_args[2] == 3) {
switches 5:9e27e2a46fa6 85 _gpio[_args[1]].mode(PullUp);
switches 5:9e27e2a46fa6 86 } else {
switches 5:9e27e2a46fa6 87 _gpio[_args[1]].mode(PullNone);
switches 5:9e27e2a46fa6 88 }
switches 5:9e27e2a46fa6 89 _gpio[_args[1]].input();
switches 5:9e27e2a46fa6 90 }
switches 5:9e27e2a46fa6 91 sprintf(resp,"[%d]", _args[2]);
switches 5:9e27e2a46fa6 92 }
switches 5:9e27e2a46fa6 93 break;
switches 5:9e27e2a46fa6 94 default:
switches 5:9e27e2a46fa6 95 sprintf(resp, "[-1]");
switches 5:9e27e2a46fa6 96 break;
switches 5:9e27e2a46fa6 97 }
gsteiert 0:828bfd94972b 98 }
gsteiert 0:828bfd94972b 99
gsteiert 0:828bfd94972b 100 /* I2C
gsteiert 0:828bfd94972b 101 * /i/[even]/[data]... write
gsteiert 0:828bfd94972b 102 * /i/[odd]/[cnt]/[data]... read
gsteiert 0:828bfd94972b 103 * [even] = even I2C address used for writes
gsteiert 0:828bfd94972b 104 * [odd] = odd I2C address used for reads
gsteiert 0:828bfd94972b 105 * [data] = data to be writen, if data is included with a read, the data
gsteiert 0:828bfd94972b 106 * will be written prior to the read to set the register address
gsteiert 0:828bfd94972b 107 * [cnt] = number of bytes to read
switches 3:601b78524967 108 * returns data read in JSON array
gsteiert 0:828bfd94972b 109 */
switches 2:3f6a8ac111a9 110 void SerialInterface::fnc_i2c(char* resp)
gsteiert 0:828bfd94972b 111 {
gsteiert 0:828bfd94972b 112 int dcnt=0;
gsteiert 0:828bfd94972b 113 if (_args[IA_CNT] < 2) {
switches 2:3f6a8ac111a9 114 sprintf(resp, "[-1]");
gsteiert 0:828bfd94972b 115 } else {
gsteiert 0:828bfd94972b 116 if (_args[IA_ADD] & 1) {
switches 2:3f6a8ac111a9 117 sprintf(resp, "[");
switches 2:3f6a8ac111a9 118 resp +=1;
gsteiert 0:828bfd94972b 119 if (_args[IA_CNT] > 2) {
gsteiert 0:828bfd94972b 120 for (dcnt = 0; dcnt < (_args[IA_CNT] -2) ; dcnt++) {
gsteiert 0:828bfd94972b 121 _dbuf[dcnt] = _args[(dcnt +3)];
gsteiert 0:828bfd94972b 122 }
switches 6:c9b7256c8261 123 if (_i2c.write(_args[IA_ADD], _dbuf, dcnt, true) != 0) {
switches 2:3f6a8ac111a9 124 sprintf(resp, "-1,");
switches 2:3f6a8ac111a9 125 resp +=3;
gsteiert 0:828bfd94972b 126 }
gsteiert 0:828bfd94972b 127 }
switches 6:c9b7256c8261 128 if (_i2c.read(_args[IA_ADD], _dbuf, _args[IA_DATA])!=0) {
switches 2:3f6a8ac111a9 129 sprintf(resp, "-1]");
gsteiert 0:828bfd94972b 130 } else {
gsteiert 0:828bfd94972b 131 for (dcnt = 0; dcnt < _args[IA_DATA]; dcnt++) {
switches 2:3f6a8ac111a9 132 sprintf(resp,"0x%02X,", _dbuf[dcnt]);
gsteiert 0:828bfd94972b 133 resp +=5;
gsteiert 0:828bfd94972b 134 }
switches 2:3f6a8ac111a9 135 sprintf((resp-1), "]");
gsteiert 0:828bfd94972b 136 }
gsteiert 0:828bfd94972b 137 } else {
gsteiert 0:828bfd94972b 138 for (dcnt = 0; dcnt < (_args[IA_CNT] -1) ; dcnt++) {
gsteiert 0:828bfd94972b 139 _dbuf[dcnt] = _args[(dcnt +2)];
gsteiert 0:828bfd94972b 140 }
switches 6:c9b7256c8261 141 if (_i2c.write(_args[IA_ADD], _dbuf, dcnt) == 0) {
switches 2:3f6a8ac111a9 142 sprintf(resp,"[%d]", dcnt);
gsteiert 0:828bfd94972b 143 } else {
switches 2:3f6a8ac111a9 144 sprintf(resp, "[-1]");
gsteiert 0:828bfd94972b 145 }
gsteiert 0:828bfd94972b 146 }
gsteiert 0:828bfd94972b 147 }
gsteiert 0:828bfd94972b 148 }
gsteiert 0:828bfd94972b 149
switches 2:3f6a8ac111a9 150 /* SPI
switches 5:9e27e2a46fa6 151 * /s/[cfg]/[data]... read+write
switches 5:9e27e2a46fa6 152 * [cfg] = SPI configuration specifies gpio to use for chip
switches 5:9e27e2a46fa6 153 * select and other SPI parameters:
switches 5:9e27e2a46fa6 154 * 0x[Byte3][Byte2][Byte1][Byte0]
switches 5:9e27e2a46fa6 155 * Byte3 = SCK frequency in MHz (0 = no change)
switches 5:9e27e2a46fa6 156 * Byte2 = Format:
switches 5:9e27e2a46fa6 157 * 0 = no change
switches 5:9e27e2a46fa6 158 * 1 = Mode 1
switches 5:9e27e2a46fa6 159 * 2 = Mode 2
switches 5:9e27e2a46fa6 160 * 3 = Mode 3
switches 5:9e27e2a46fa6 161 * 4 = Mode 0
switches 5:9e27e2a46fa6 162 * Byte1 = CS polarity 1 = active high, 0 = active low
switches 5:9e27e2a46fa6 163 * Byte0 = GPIO to use for CS (0-7)
switches 5:9e27e2a46fa6 164 * 0 = P5_3
switches 5:9e27e2a46fa6 165 * 1 = P5_4
switches 5:9e27e2a46fa6 166 * 2 = P5_5
switches 5:9e27e2a46fa6 167 * 3 = P5_6
switches 5:9e27e2a46fa6 168 * 4 = P3_0
switches 5:9e27e2a46fa6 169 * 5 = P3_1
switches 5:9e27e2a46fa6 170 * 6 = P3_2
switches 5:9e27e2a46fa6 171 * 7 = P3_3
switches 2:3f6a8ac111a9 172 * [data] = data to be writen
switches 3:601b78524967 173 * this shifts out each data byte provided and
switches 3:601b78524967 174 * returns each byte read in a JSON array
gsteiert 0:828bfd94972b 175 */
switches 2:3f6a8ac111a9 176 void SerialInterface::fnc_spi(char* resp)
gsteiert 0:828bfd94972b 177 {
switches 5:9e27e2a46fa6 178 int dcnt=1;
switches 2:3f6a8ac111a9 179 int dataIn;
switches 5:9e27e2a46fa6 180 spiConfig_t spiCfg;
switches 2:3f6a8ac111a9 181 if (_args[0] < 1) {
switches 2:3f6a8ac111a9 182 sprintf(resp, "[-1]");
gsteiert 0:828bfd94972b 183 } else {
switches 5:9e27e2a46fa6 184 spiCfg.merged = _args[1];
switches 5:9e27e2a46fa6 185 if (spiCfg.freq) {
switches 6:c9b7256c8261 186 _spi.frequency(spiCfg.freq * 1000000);
switches 5:9e27e2a46fa6 187 }
switches 5:9e27e2a46fa6 188 if (spiCfg.format) {
switches 6:c9b7256c8261 189 _spi.format(8, (spiCfg.format & 3));
gsteiert 0:828bfd94972b 190 }
switches 5:9e27e2a46fa6 191 if (_args[0] > 1) {
switches 5:9e27e2a46fa6 192 sprintf(resp, "[");
switches 5:9e27e2a46fa6 193 resp++;
switches 5:9e27e2a46fa6 194 _gpio[spiCfg.csPin] = (spiCfg.csPol);
switches 5:9e27e2a46fa6 195 while(dcnt < _args[0]) {
switches 5:9e27e2a46fa6 196 dcnt++;
switches 6:c9b7256c8261 197 dataIn = _spi.write(_args[dcnt]);
switches 5:9e27e2a46fa6 198 sprintf(resp, "0x%02X,", dataIn);
switches 5:9e27e2a46fa6 199 resp += 5;
switches 5:9e27e2a46fa6 200 }
switches 5:9e27e2a46fa6 201 _gpio[spiCfg.csPin] = !(spiCfg.csPol);
switches 5:9e27e2a46fa6 202 sprintf((resp-1), "]");
switches 5:9e27e2a46fa6 203 }
gsteiert 0:828bfd94972b 204 }
gsteiert 0:828bfd94972b 205 }
gsteiert 0:828bfd94972b 206
switches 2:3f6a8ac111a9 207 void SerialInterface::call(char* input, char* output)
gsteiert 0:828bfd94972b 208 {
gsteiert 0:828bfd94972b 209 char cmd;
gsteiert 0:828bfd94972b 210 _args[0] = 0;
gsteiert 0:828bfd94972b 211 if (*input == '/') {
gsteiert 0:828bfd94972b 212 input++;
gsteiert 0:828bfd94972b 213 cmd = *input;
gsteiert 0:828bfd94972b 214 input = strchr(input, '/');
gsteiert 0:828bfd94972b 215 while (*input == '/') {
gsteiert 0:828bfd94972b 216 input++;
gsteiert 0:828bfd94972b 217 _args[(_args[0]+1)] = strtol(input, &input, 0);
gsteiert 0:828bfd94972b 218 if (input) {
gsteiert 0:828bfd94972b 219 _args[0]++;
gsteiert 0:828bfd94972b 220 }
gsteiert 0:828bfd94972b 221 }
gsteiert 0:828bfd94972b 222 switch (cmd) {
switches 6:c9b7256c8261 223 case 'a':
switches 6:c9b7256c8261 224 case 'A':
switches 6:c9b7256c8261 225 fnc_ain(output);
switches 6:c9b7256c8261 226 break;
switches 5:9e27e2a46fa6 227 case 'd':
switches 5:9e27e2a46fa6 228 case 'D':
switches 5:9e27e2a46fa6 229 fnc_dio(output);
switches 5:9e27e2a46fa6 230 break;
gsteiert 0:828bfd94972b 231 case 'i':
gsteiert 0:828bfd94972b 232 case 'I':
gsteiert 0:828bfd94972b 233 fnc_i2c(output);
gsteiert 0:828bfd94972b 234 break;
gsteiert 0:828bfd94972b 235 case 's':
gsteiert 0:828bfd94972b 236 case 'S':
gsteiert 0:828bfd94972b 237 fnc_spi(output);
gsteiert 0:828bfd94972b 238 break;
gsteiert 0:828bfd94972b 239 default:
switches 6:c9b7256c8261 240 sprintf(output, "!commands: ain dio i2c spi");
gsteiert 0:828bfd94972b 241 break;
gsteiert 0:828bfd94972b 242 }
gsteiert 0:828bfd94972b 243 } else {
gsteiert 0:828bfd94972b 244 sprintf(output, "!format: /cmd/arg1/arg2...");
gsteiert 0:828bfd94972b 245
gsteiert 0:828bfd94972b 246 }
gsteiert 0:828bfd94972b 247 }