1 /**
2     @file LMS64CProtocol.h
3     @author Lime Microsystems
4     @brief Implementation of LMS64C protocol.
5 */
6 
7 #pragma once
8 #include <IConnection.h>
9 #include <mutex>
10 #include <LMS64CCommands.h>
11 #include <LMSBoards.h>
12 #include <thread>
13 
14 namespace lime{
15 
16 /*!
17  * Implement the LMS64CProtocol.
18  * The LMS64CProtocol is an IConnection that implements
19  * configuration and spi access over the LMS64C Protocol.
20  * Connections using LMS64C may inherit from LMS64C.
21  */
22 class LIME_API LMS64CProtocol : public virtual IConnection
23 {
24 public:
25     LMS64CProtocol(void);
26 
27     ~LMS64CProtocol(void) override;
28 
29     DeviceInfo GetDeviceInfo(void) override;
30 
31     //! DeviceReset implemented by LMS64C
32     int DeviceReset(int ind=0);
33 
34     //! TransactSPI implemented by LMS64C
35     int TransactSPI(const int addr, const uint32_t *writeData, uint32_t *readData, const size_t size) override;
36 
37     //! WriteI2C implemented by LMS64C
38     int WriteI2C(const int addr, const std::string &data) override;
39 
40     //! ReadI2C implemented by LMS64C
41     int ReadI2C(const int addr, const size_t numBytes, std::string &data) override;
42 
43     //! WriteRegisters (BRDSPI) implemented by LMS64C
44     int WriteRegisters(const uint32_t *addrs, const uint32_t *data, const size_t size) override;
45 
46     //! ReadRegisters (BRDSPI) implemented by LMS64C
47     int ReadRegisters(const uint32_t *addrs, uint32_t *data, const size_t size) override;
48 
49     /// Supported connection types.
50     enum eConnectionType
51     {
52         CONNECTION_UNDEFINED = -1,
53         COM_PORT = 0,
54         USB_PORT = 1,
55         SPI_PORT = 2,
56         PCIE_PORT = 3,
57         //insert new types here
58         CONNECTION_TYPES_COUNT //used only for memory allocation
59     };
60 
61     struct GenericPacket
62     {
GenericPacketGenericPacket63         GenericPacket()
64         {
65             cmd = CMD_GET_INFO;
66             status = STATUS_UNDEFINED;
67             periphID = 0;
68         }
69 
70         eCMD_LMS cmd;
71         eCMD_STATUS status;
72         unsigned periphID;
73         std::vector<unsigned char> outBuffer;
74         std::vector<unsigned char> inBuffer;
75     };
76 
77     struct ProtocolLMS64C
78     {
79         static const int pktLength = 64;
80         static const int maxDataLength = 56;
ProtocolLMS64CProtocolLMS64C81         ProtocolLMS64C() :cmd(0),status(STATUS_UNDEFINED),blockCount(0)
82         {
83              memset(reserved, 0, 4);
84         };
85         unsigned char cmd;
86         unsigned char status;
87         unsigned char blockCount;
88         unsigned char periphID;
89         unsigned char reserved[4];
90         unsigned char data[maxDataLength];
91     };
92 
93     /*!
94      * Transfer a packet over the underlying transport layer.
95      * TransferPacket performs a request/response
96      * using the GenericPacket data structure.
97      * Some implementations will cast to LMS64CProtocol
98      * and directly use the TransferPacket() API call.
99      */
100     virtual int TransferPacket(GenericPacket &pkt);
101 
102     struct LMSinfo
103     {
104         eLMS_DEV device;
105         eEXP_BOARD expansion;
106         int firmware;
107         int hardware;
108         int protocol;
109         uint64_t boardSerialNumber;
110     };
111 
112     LMSinfo GetInfo();
113 
114     struct FPGAinfo
115     {
116         int boardID;
117         int gatewareVersion;
118         int gatewareRevision;
119         int hwVersion;
120     };
121 
122     FPGAinfo GetFPGAInfo();
123     void VersionCheck();
124     int ProgramUpdate(const bool download, const bool force, IConnection::ProgrammingCallback callback) override;
125 
126     //! implement in base class
127     virtual eConnectionType GetType(void) = 0;
128 
129     //! virtual write function to be implemented by the base class
130     virtual int Write(const unsigned char *buffer, int length, int timeout_ms = 100) = 0;
131 
132     //! virtual read function to be implemented by the base class
133     virtual int Read(unsigned char *buffer, int length, int timeout_ms = 100) = 0;
134 
135     enum ProgramWriteTarget
136     {
137         HPM,
138         FX3, //
139         FPGA, // prog_modes: 0-bitstream to FPGA, 1-to FLASH, 2-bitstream from FLASH
140 
141         PROGRAM_WRITE_TARGET_COUNT
142     };
143 
144     int ProgramWrite(const char *buffer, const size_t length, const int programmingMode, const int device, ProgrammingCallback callback = nullptr) override;
145 
146     int CustomParameterRead(const uint8_t *ids, double *values, const size_t count, std::string* units) override;
147     int CustomParameterWrite(const uint8_t *ids, const double *values, const size_t count, const std::string& units) override;
148 
149     int GPIOWrite(const uint8_t *buffer, const size_t bufLength) override;
150     int GPIORead(uint8_t *buffer, const size_t bufLength) override;
151     int GPIODirWrite(const uint8_t *buffer, const size_t bufLength) override;
152     int GPIODirRead(uint8_t *buffer, const size_t bufLength) override;
153 
154     int ProgramMCU(const uint8_t *buffer, const size_t length, const MCU_PROG_MODE mode, ProgrammingCallback callback) override;
155     int WriteLMS7002MSPI(const uint32_t *writeData, size_t size,unsigned periphID = 0) override;
156     int ReadLMS7002MSPI(const uint32_t *writeData, uint32_t *readData, size_t size, unsigned periphID = 0) override;
157 protected:
158 #ifdef REMOTE_CONTROL
159     void InitRemote();
160     void CloseRemote();
161     void ProcessConnections();
162     bool remoteOpen;
163     int socketFd;
164     std::thread remoteThread;
165 #endif
166 private:
167     int WriteSi5351I2C(const std::string &data);
168     int ReadSi5351I2C(const size_t numBytes, std::string &data);
169 
170     int WriteADF4002SPI(const uint32_t *writeData, const size_t size);
171     int ReadADF4002SPI(const uint32_t *writeData, uint32_t *readData, const size_t size);
172 
173     unsigned char* PreparePacket(const GenericPacket &pkt, int &length);
174     int ParsePacket(GenericPacket &pkt, const unsigned char* buffer, const int length);
175     std::mutex mControlPortLock;
176     double _cachedRefClockRate;
177 };
178 }
179