2017-07-02 18:22:19 +00:00
|
|
|
/*
|
|
|
|
* This file is part of the stmbl project.
|
|
|
|
*
|
|
|
|
* Copyright (C) 2013 Rene Hopf <renehopf@mac.com>
|
|
|
|
* Copyright (C) 2015 Ian McMahon <facetious.ian@gmail.com>
|
|
|
|
* Copyright (C) 2013 Nico Stute <crinq@crinq.de>
|
|
|
|
*
|
|
|
|
* This program is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
//dump:
|
|
|
|
//sigrok-cli --driver fx2lafw --config samplerate=24m --time 1s --channels 3=rx,2=tx -t rx=f -o sserial.sr
|
|
|
|
//decode:
|
|
|
|
//sigrok-cli -i sserial.sr -P uart:baudrate=2500000:tx=tx:rx=rx:format=hex -A uart=tx-data:rx-data
|
|
|
|
//decode more:
|
|
|
|
//sigrok-cli -i sserial.sr -P uart:baudrate=2500000:tx=tx:rx=rx,sserial
|
|
|
|
//sudo mesaflash --device 5i25 --sserial --verbose
|
|
|
|
|
|
|
|
#define UnitNumberRPC 0xbc
|
|
|
|
#define DiscoveryRPC 0xbb
|
|
|
|
#define ProcessDataRPC 0xbd
|
|
|
|
|
|
|
|
//local commands
|
|
|
|
#define LBPCookieCMD 0xdf
|
|
|
|
#define LBPCookie 0x5a
|
|
|
|
|
|
|
|
#define LBPStatusCMD 0xc1
|
|
|
|
|
|
|
|
#define LBPCardName "stbl"
|
|
|
|
#define LBPCardName0Cmd 0xd0
|
|
|
|
#define LBPCardName1Cmd 0xd1
|
|
|
|
#define LBPCardName2Cmd 0xd2
|
|
|
|
#define LBPCardName3Cmd 0xd3
|
|
|
|
|
2017-09-06 02:20:06 +00:00
|
|
|
#define CT_RW 1 // 01b
|
|
|
|
#define CT_RPC 2 // 10b
|
|
|
|
#define CT_LOCAL 3 // 11b
|
2017-07-02 18:22:19 +00:00
|
|
|
|
|
|
|
#define MEM_SIZE 2048
|
|
|
|
|
|
|
|
#define RECORD_TYPE_PROCESS_DATA_RECORD 0xA0
|
|
|
|
#define RECORD_TYPE_MODE_DATA_RECORD 0xB0
|
|
|
|
|
|
|
|
//process data
|
2017-09-06 02:20:06 +00:00
|
|
|
#define DATA_TYPE_PAD 0x00 //padding, done automaticly at the end
|
|
|
|
#define DATA_TYPE_BITS 0x01
|
|
|
|
#define DATA_TYPE_UNSIGNED 0x02
|
|
|
|
#define DATA_TYPE_SIGNED 0x03
|
|
|
|
#define DATA_TYPE_NONVOL_UNSIGNED 0x04
|
|
|
|
#define DATA_TYPE_NONVOL_SIGNED 0x05
|
|
|
|
#define DATA_TYPE_STREAM 0x06
|
|
|
|
#define DATA_TYPE_BOOLEAN 0x07
|
|
|
|
#define DATA_TYPE_ENCODER 0x08
|
|
|
|
#define DATA_TYPE_FLOAT 0x10 // New for STMBL
|
|
|
|
#define DATA_TYPE_ENCODER_H 0x18
|
|
|
|
#define DATA_TYPE_ENCODER_L 0x28
|
2017-07-02 18:22:19 +00:00
|
|
|
|
|
|
|
#define DATA_DIRECTION_INPUT 0x00
|
|
|
|
#define DATA_DIRECTION_BI_DIRECTIONAL 0x40
|
|
|
|
#define DATA_DIRECTION_OUTPUT 0x80
|
|
|
|
|
2017-09-06 02:20:06 +00:00
|
|
|
#define MEMPTR(p) ((uint32_t)&p - (uint32_t)&memory)
|
2017-07-02 18:22:19 +00:00
|
|
|
|
|
|
|
#define MEMU8(ptr) (memory.bytes[ptr])
|
2017-09-06 02:20:06 +00:00
|
|
|
#define MEMU16(ptr) (memory.bytes[ptr] | memory.bytes[ptr + 1] << 8)
|
|
|
|
#define MEMU32(ptr) (memory.bytes[ptr] | memory.bytes[ptr + 1] << 8 | memory.bytes[ptr + 2] << 16 | memory.bytes[ptr + 3] << 24)
|
|
|
|
#define MEMFLOAT(ptr) ((float)({uint32_t tmp = MEMU32(ptr);*((float*)&tmp); }))
|
2017-07-02 18:22:19 +00:00
|
|
|
|
|
|
|
#define NUM_BYTES(bits) (bits / 8 + (bits % 8 > 0 ? 1 : 0))
|
|
|
|
|
|
|
|
#define IS_INPUT(pdr) (pdr->data_direction != 0x80)
|
|
|
|
#define IS_OUTPUT(pdr) (pdr->data_direction != 0x00)
|
|
|
|
|
|
|
|
#define SIGNED(pdr) (pdr->data_type == DATA_TYPE_SIGNED || pdr->data_type == DATA_TYPE_NONVOL_SIGNED)
|
|
|
|
#define UNSIGNED(pdr) (pdr->data_type == DATA_TYPE_UNSIGNED || pdr->data_type == DATA_TYPE_NONVOL_UNSIGNED)
|
|
|
|
|
|
|
|
#define INDIRECT_PD(pd_ptr) ((process_data_descriptor_t *)(memory.bytes + *pd_ptr))
|
|
|
|
#define DATA_DIR(pd_ptr) INDIRECT_PD(pd_ptr)->data_direction
|
|
|
|
#define DATA_SIZE(pd_ptr) INDIRECT_PD(pd_ptr)->data_size
|
|
|
|
|
2017-09-06 02:20:06 +00:00
|
|
|
#define ADD_PROCESS_VAR(args) \
|
|
|
|
*ptocp = add_pd args; \
|
|
|
|
input_bits += IS_INPUT(INDIRECT_PD(ptocp)) ? DATA_SIZE(ptocp) : 0; \
|
|
|
|
output_bits += IS_OUTPUT(INDIRECT_PD(ptocp)) ? DATA_SIZE(ptocp) : 0; \
|
|
|
|
last_pd = INDIRECT_PD(ptocp++)
|
2017-07-02 18:22:19 +00:00
|
|
|
#define ADD_GLOBAL_VAR(args) *gtocp++ = add_pd args
|
|
|
|
#define ADD_MODE(args) *gtocp++ = add_mode args
|
|
|
|
|
2017-09-06 02:20:06 +00:00
|
|
|
#define BITSLEFT(ptr) (8 - ptr)
|
2017-07-02 18:22:19 +00:00
|
|
|
|
|
|
|
#define BOOLPIN(pin) (uint8_t)(PIN(pin) > 0.0)
|
|
|
|
|
2017-09-06 02:20:06 +00:00
|
|
|
typedef union {
|
|
|
|
struct {
|
|
|
|
uint8_t ds : 2; //DataSize: Specifies data size, 00b = 1 bytes, 01b = 2 bytes, 10 b= 4 bytes, 11b = 8 bytes.
|
|
|
|
uint8_t as : 1; //AddressSize: 0 to specify current address, 1 to specify 2 byte address.
|
|
|
|
uint8_t ai : 1; //AutoInc: 0 leaves address unchanged, 1 specifies that address is post incremented by data size in bytes.
|
|
|
|
uint8_t rid : 1; //RPCIncludesData: 0 specifies that data is from stream, 1, that data is from RPC (RPC only, ignored for non RPC commands)
|
|
|
|
uint8_t wr : 1; //Write: 1 to specify write, 0 to specify read
|
|
|
|
uint8_t ct : 2; //CommandType: Must be 01b to specify data read/write command
|
|
|
|
// 01:rw 11:local command 10:rpc
|
|
|
|
};
|
|
|
|
struct {
|
|
|
|
uint8_t rpc : 6;
|
|
|
|
uint8_t dummy : 2;
|
|
|
|
//01:rw 11: local command 10:rpc
|
|
|
|
};
|
|
|
|
uint8_t byte;
|
2017-07-02 18:22:19 +00:00
|
|
|
} lbp_t;
|
|
|
|
|
|
|
|
#pragma pack(1)
|
|
|
|
typedef union {
|
|
|
|
uint8_t byte[4];
|
|
|
|
uint32_t unit;
|
|
|
|
} unit_no_t;
|
|
|
|
|
2017-09-06 02:20:06 +00:00
|
|
|
typedef struct {
|
|
|
|
uint8_t record_type; //0xa0
|
|
|
|
uint8_t data_size;
|
|
|
|
uint8_t data_type;
|
|
|
|
uint8_t data_direction;
|
|
|
|
float param_min;
|
|
|
|
float param_max;
|
|
|
|
uint16_t data_addr;
|
|
|
|
char names;
|
2017-07-02 18:22:19 +00:00
|
|
|
} process_data_descriptor_t;
|
|
|
|
|
2017-09-06 02:20:06 +00:00
|
|
|
typedef struct {
|
|
|
|
uint8_t record_type; //0xb0
|
|
|
|
uint8_t index;
|
|
|
|
uint8_t type;
|
|
|
|
uint8_t unused;
|
|
|
|
char names;
|
2017-07-02 18:22:19 +00:00
|
|
|
} mode_descriptor_t;
|
|
|
|
|
2017-09-06 02:20:06 +00:00
|
|
|
typedef struct {
|
|
|
|
uint8_t input; //process data input bytes
|
|
|
|
uint8_t output; //process data output bytes
|
|
|
|
uint16_t ptocp; //pointer to process data table start
|
|
|
|
uint16_t gtocp; //pointer to mode data table start
|
2017-07-02 18:22:19 +00:00
|
|
|
} discovery_rpc_t;
|
|
|
|
|
|
|
|
typedef union {
|
|
|
|
struct {
|
2017-09-06 02:20:06 +00:00
|
|
|
discovery_rpc_t discovery; //6 bytes
|
|
|
|
uint16_t foo; //padding, so heap is word aligned
|
2017-07-02 18:22:19 +00:00
|
|
|
uint8_t heap[MEM_SIZE - sizeof(discovery_rpc_t)];
|
|
|
|
};
|
|
|
|
|
|
|
|
uint8_t bytes[MEM_SIZE];
|
|
|
|
} memory_t;
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
process_data_descriptor_t *ptr;
|
|
|
|
float range;
|
|
|
|
uint32_t bitmax;
|
|
|
|
} pd_metadata_t;
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
pd_metadata_t pos_cmd;
|
|
|
|
pd_metadata_t pos_fb;
|
2017-11-23 00:25:11 +00:00
|
|
|
pd_metadata_t vel_cmd;
|
|
|
|
pd_metadata_t vel_fb;
|
2017-07-02 18:22:19 +00:00
|
|
|
pd_metadata_t input_pins;
|
|
|
|
pd_metadata_t output_pins;
|
|
|
|
pd_metadata_t fault;
|
|
|
|
pd_metadata_t enable;
|
2017-10-29 21:43:48 +00:00
|
|
|
pd_metadata_t index_enable;
|
2017-12-04 15:48:44 +00:00
|
|
|
pd_metadata_t current;
|
2017-07-02 18:22:19 +00:00
|
|
|
} pd_table_t;
|