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