Jade Perreault
Published © CC BY-NC-SA

MAX32625PICO-WI-FI/BLE/LoRa Board

MAX32625PICO board with Bluetooth/Wi-Fi/LoRa connectivity for smart farming, gas monitoring, remote IoT and environmental applications.

AdvancedFull instructions providedOver 2 days1,204
MAX32625PICO-WI-FI/BLE/LoRa Board

Things used in this project

Hardware components

Maxim Integrated MAX32625PI
×1
PyCom L01
×1

Software apps and online services

Arm Embed
Fritzing
Ultimaker Cura
Visual Studio Code

Hand tools and fabrication machines

Soldering iron (generic)
Soldering iron (generic)
Toaster Oven

Story

Read more

Schematics

Rev 1 Gerber file

Upload to PCb manufacturer

3D Cura Base

3D cura Top

Code

Max32625Pico Serial

C/C++
/* Pmod Interface Library
 *
 */

#include "mbed.h"
#include "SerialInterface.h"

SerialInterface::SerialInterface(I2C *i2c, SPI *spi, DigitalInOut* gpio, AnalogIn* ain): _i2c(i2c), _spi(spi) 
{
    _i2c = i2c;  // save pointer to I2C port
    _spi = spi;  // save pointer to SPI port
    _gpio = gpio;  // save pointer to GPIO pins
    _ain = ain;  // save pointer to AIN pins
}

SerialInterface::~SerialInterface()
{
}

/* Analog In
 * /a              read all
 * /a/[pin]        read from pin
 *   Returns 16bit normalized result
 */
void SerialInterface::fnc_ain(char* resp)
{
    switch (_args[0]) {/0
        case 0:
            sprintf(resp, "[0x%04X,0x%04X,0x%04X,0x%04X,0x%04X,0x%04X,0x%04X,0x%04X]", 
            _ain[0].read_u16(), _ain[1].read_u16(), _ain[2].read_u16(), _ain[3].read_u16(), 
            _ain[4].read_u16(), _ain[5].read_u16(), _ain[6].read_u16(), _ain[7].read_u16() );
            break;
        case 1:
            sprintf(resp, "[0x%04X]", _ain[_args[1]].read_u16());
            break;
        default:
            sprintf(resp, "[-1]");
            break;
    }
}

/* Digital I/O
 * /d              read all
 * /d/[pin]        read from pin
 * /d/[pin]/[cfg]  write configuration to pin
 * [pin] = number (from 0 to 7) of the pin to access
 * [cfg] = pin configuration:
 *     0 - output low
 *     1 - output high
 *     2 - input pull down
 *     3 - input pull up
 *     4 - input pull none
 */
void SerialInterface::fnc_dio(char* resp)
{
    int bdat;
    int bcnt;
    switch (_args[0]) {
        case 0:
            sprintf(resp, "[");
            resp +=1;
            for (bcnt = 0; bcnt < 8 ; bcnt++) {
                bdat = _gpio[bcnt].read();
                sprintf(resp, "%d,", bdat);
                resp +=2;
            }
            sprintf((resp-1), "]");
            break;
        case 1:
            if (_args[1] > 7) {
                sprintf(resp, "[-1]");
            } else {
                sprintf(resp,"[%d]", _gpio[_args[1]].read());
            }
            break;
        case 2:
            if (_args[1] > 7) {
                sprintf(resp, "[-1]");
            } else {
                if (_args[2] < 2) {
                    _gpio[_args[1]].write(_args[2]);
                    _gpio[_args[1]].output();
                } else {
                    if (_args[2] == 2) {
                        _gpio[_args[1]].mode(PullDown);
                    } else if (_args[2] == 3) {
                        _gpio[_args[1]].mode(PullUp);
                    } else {
                        _gpio[_args[1]].mode(PullNone);
                    }
                    _gpio[_args[1]].input();
                }
                sprintf(resp,"[%d]", _args[2]);
            }
            break;
        default:
            sprintf(resp, "[-1]");
            break;
    }
}

/* I2C
 * /i/[even]/[data]...       write
 * /i/[odd]/[cnt]/[data]...  read
 * [even] = even I2C address used for writes
 * [odd]  = odd I2C address used for reads
 * [data] = data to be writen, if data is included with a read, the data
 *     will be written prior to the read to set the register address
 * [cnt]  = number of bytes to read
 * returns data read in JSON array
 */
void SerialInterface::fnc_i2c(char* resp)
{
    int dcnt=0;
    if (_args[IA_CNT] < 2) {
        sprintf(resp, "[-1]");
    } else {
        if (_args[IA_ADD] & 1) {
            sprintf(resp, "[");
            resp +=1;
            if (_args[IA_CNT] > 2) {
                for (dcnt = 0; dcnt < (_args[IA_CNT] -2) ; dcnt++) {
                    _dbuf[dcnt] = _args[(dcnt +3)];
                }
                if ((*_i2c).write(_args[IA_ADD], _dbuf, dcnt, true) != 0) {
                    sprintf(resp, "-1,");
                    resp +=3;
                }
            }
            if ((*_i2c).read(_args[IA_ADD], _dbuf, _args[IA_DATA])!=0) {
                sprintf(resp, "-1]");
            } else {
                for (dcnt = 0; dcnt < _args[IA_DATA]; dcnt++) {
                    sprintf(resp,"0x%02X,", _dbuf[dcnt]);
                    resp +=5;
                }
                sprintf((resp-1), "]");
            }
        } else {
            for (dcnt = 0; dcnt < (_args[IA_CNT] -1) ; dcnt++) {
                _dbuf[dcnt] = _args[(dcnt +2)];
            }
            if ((*_i2c).write(_args[IA_ADD], _dbuf, dcnt) == 0) {
                sprintf(resp,"[%d]", dcnt);
            } else {
                sprintf(resp, "[-1]");
            }
        }
    }
}

/* SPI
 * /s/[cfg]/[data]...      read+write
 * [cfg] = SPI configuration specifies gpio to use for chip
 *   select and other SPI parameters:
 *   0x[Byte3][Byte2][Byte1][Byte0]
 *     Byte3 = SCK frequency in MHz (0 = no change)
 *     Byte2 = Format:
 *       0 = no change
 *       1 = Mode 1
 *       2 = Mode 2
 *       3 = Mode 3
 *       4 = Mode 0
 *     Byte1 = CS polarity 1 = active high, 0 = active low
 *     Byte0 = GPIO to use for CS (0-7)
 *       0 = P5_3
 *       1 = P5_4
 *       2 = P5_5
 *       3 = P5_6
 *       4 = P3_0
 *       5 = P3_1
 *       6 = P3_2
 *       7 = P3_3
 * [data] = data to be writen
 *   this shifts out each data byte provided and
 *   returns each byte read in a JSON array
 */
void SerialInterface::fnc_spi(char* resp)
{
    int dcnt=1;
    int dataIn;
    spiConfig_t spiCfg;
    if (_args[0] < 1) {
        sprintf(resp, "[-1]");
    } else {
        spiCfg.merged = _args[1];
        if (spiCfg.freq) {
            (*_spi).frequency(spiCfg.freq * 1000000);
        }
        if (spiCfg.format) {
            (*_spi).format(8, (spiCfg.format & 3));
        }
        if (_args[0] > 1) {
            sprintf(resp, "[");
            resp++;
            _gpio[spiCfg.csPin] = (spiCfg.csPol);
            while(dcnt < _args[0]) {
                dcnt++;
                dataIn = (*_spi).write(_args[dcnt]);
                sprintf(resp, "0x%02X,", dataIn);
                resp += 5;
            }
            _gpio[spiCfg.csPin] = !(spiCfg.csPol);
            sprintf((resp-1), "]");
        }
    }
}

void SerialInterface::call(char* input, char* output)
{
    char cmd;
    _args[0] = 0;
    if (*input == '/') {
        input++;
        cmd = *input;
        input = strchr(input, '/');
        while (*input == '/') {
            input++;
            _args[(_args[0]+1)] = strtol(input, &input, 0);
            if (input) {
                _args[0]++;
            }
        }
        switch (cmd) {
            case 'a':
            case 'A':
                fnc_ain(output);
                break;
            case 'd':
            case 'D':
                fnc_dio(output);
                break;
            case 'i':
            case 'I':
                fnc_i2c(output);
                break;
            case 's':
            case 'S':
                fnc_spi(output);
                break;
            default:
                sprintf(output, "!commands: ain dio i2c spi");
                break;
        }
    } else {
        sprintf(output, "!format:  /cmd/arg1/arg2...");

    }
}

Credits

Jade Perreault

Jade Perreault

32 projects • 59 followers
27 Years as a Journeyman Electrician , 4 Years as a PCB design engineer for Penteon Corporation Out of New York ..

Comments