## SPI

The module support SPI communications with following features (_mode 3_):

- module is slave 
- SS signal is not used
- clock signal at __1 MHz maximum__
- clock __polarity is HIGH__
- clock __phase is HIGH__
- byte codification is __8 bits__ MSB

It exchanges bytes with two shifted registers: from master via MOSI and to master via MISO (circular buffer).

Lua example:

    -- configure SPI bus
    spi.setup(1, spi.MASTER, spi.CPOL_HIGH, spi.CPHA_HIGH, 8, 22, spi.FULLDUPLEX)
    
    -- send byte by byte
    function spiSend(data)
        -- send one byte and receive another (to/from module)
        r = { spi.send(1, data) }
        return r[2]
    end
    
    -- useful conversion of values longer than 1 byte
    function int32Net(val)
        local b = {}                                                                     
        b[4] = val % 256                                                               
        val = val / 256                                                              
        b[3] = val % 256                                                               
        val = val / 256                                                              
        b[2] = val % 256                                                               
        b[1] = val / 256                                                               
        return b                                                                         
    end
                                                                                     

## Protocol

Master sends commands and, optionally, some parameter. Commands are 1 byte constant (specified below). Parameters are 0-N bytes sequence and length depends on each command.

When the command is processed, the module sends the response starting with a SM (Start of Message) constant followed by a 0-N bytes sequence and the OK constant. While command response is not available, requesting answer is NC (No Command) in result.

Lua example:

    NC = 0x00
    OK = 0x01
    KO = 0x02
    SM = 0xFF
    
    function sendCommand(cmd, params, retCount)
        spiSend(cmd)        
        for p=1,#params do spiSend(params[p]) end
        result = {}
        n = 0
        while spiSend(NC) ~= SM do 
            tmr.delay(10000)
            n = n + 1
            if n > 100 then return false end 
        end
        for r=1,retCount do table.insert(result, spiSend(NC)) end
        return (spiSend(NC) == OK and result or false)
    end
    

## Commands


### 0x10 hello()

- command (1 byte, unsigned): 0x10

Returns:

- SM (1 byte, unsigned): 0xFF
- firmVersion (1 byte, unsigned): 0 .. 255
- serialNumber (2 bytes, unsigned): 0 .. 65535
- OK (1 byte, unsigned): 0x01

Lua example:

    function hello()
        r = sendCommand(0x10, {}, 3)
        if not r then return false end
        version = r[1]
        serial = (r[2]*0x100)+r[3]
        return { version, serial }
    end
    
    h = hello()
    print("version " .. h[1] .. ", serial " .. h[2])


### 0x22 setPower(left, right)

- command (1 byte unsigned): 0x22
- left (1 byte signed): -128 .. 127
- right (1 byte signed): -128 .. 127

Returns:

- SM (1 byte, unsigned): 0xFF
- OK (1 byte, unsigned): 0x01

Lua example:

    function setPower(left, right)
        r = sendCommand(0x22, {left, right}, 0)
        return (r and true or false)
    end
    
    =setPower(127, -20)
    

### 0x30 getSteps()

- command (1 byte, unsigned): 0x40

Returns:

- SM (1 byte, unsigned): 0xFF
- leftSteps (4 bytes, signed): −2147483648 .. 2147483647
- rightSteps (4 bytes, signed): −2147483648 .. 2147483647
- OK (1 byte, unsigned): 0x01

Lua example:

    function getSteps()
        r = sendCommand(0x30, {}, 8)
        if r then
            left = (r[1]*0x1000000)+(r[2]*0x10000)+(r[3]*0x100)+r[4]
            right = (r[5]*0x1000000)+(r[6]*0x10000)+(r[7]*0x100)+r[8]
            return { left, right }
        else 
            return false
        end        
    end


### 0x40 resetSteps()

- command (1 byte, unsigned): 0x50

Returns:

- SM (1 byte, unsigned): 0xFF
- OK (1 byte, unsigned): 0x01

Lua example:

    function resetSteps()
        r = sendCommand(0x40, {}, 0)
        return (r and true or false)
    end
    
    =resetSteps()


### 0x54 alarmStepsLeft(steps)

- command (1 byte, unsigned): 0x54
- steps (4 bytes, signed): −2147483648 .. 2147483647

Returns:

- SM (1 byte, unsigned): 0xFF
- OK (1 byte, unsigned): 0x01

Note: see "Alarm steps" below.

Lua example:

    function alarmStepsLeft(steps)
        r = sendCommand(0x54, int32Net(steps), 0)                                        
        return (r and true or false)                                                     
    end
    
    =alarmStepsLeft(400)


### 0x64 alarmStepsRight(steps)

- command (1 byte, unsigned): 0x64
- steps (4 bytes, signed): −2147483648 .. 2147483647

Returns:

- SM (1 byte, unsigned): 0xFF
- OK (1 byte, unsigned): 0x01

Note: see "Alarm steps" below.

Lua example:

    function alarmStepsRight(steps)
        r = sendCommand(0x64, int32Net(steps), 0)
        return (r and true or false)
    end
    
    =alarmStepsRight(-300)


## Alarm steps

Commands _alarmStepsLeft_ and _alarmStepsRight_ set an absolute value of steps to alarm when the left or right encoder reachs the steps. When it ocurrs, the MMI pin is set HIGH and the main controller should read the steps with _getSteps_ command. MMI pin is set LOW again by the motor module when _getSteps_ command is executed.

Even though the steps value is absolute (32 bits integer), motor module can only set the alarm to a value not greater or lower than 32767 steps (16 bits integer) from current steps value. This is an internal memory optimization and it should be enough to manage almost use cases. If you want to be alarmed in longer steps, set intermediate alarm values within the working range.

### Lua examples

-ToDo-