aboutsummaryrefslogtreecommitdiff
path: root/busdevice.c
blob: 7c422024de9812ed513238cf1c066b1eaee93bde (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
#include "busdevice.h"

#include "drivers/serial/pcserialport.h"
#include "drivers/tcpip/tcpclient.h"
#include "drivers/ftdi_d2xx/sm_d2xx.h"

#include <string.h>
#include <errno.h>
#include <stdlib.h>

#define BD_NONE 0
#define BD_RS 1
#define BD_FTDI 2
#define BD_TCP 3

//how much bytes available in transmit buffer
#define TANSMIT_BUFFER_LENGTH 128

unsigned long SMBusBaudrate=SM_BAUDRATE; //the next opened port (with smOpenBus) will be opened with the PBS defined here (default 460800 BPS)

typedef struct _SMBusDevice
{
	//common
    smint8 bdType;//bus device type (such as rs232 or ftdi lib or mcu UART etc). 1=rs232 lib
	smbool opened;

    SM_STATUS cumulativeSmStatus;

	//used for rs232 lib only
	int comPort;

    smuint8 txBuffer[TANSMIT_BUFFER_LENGTH];
    smint32 txBufferUsed;//how many bytes in buffer currently

	//used for FTDI lib only
} SMBusDevice;

//init on first open
smbool bdInitialized=smfalse;
SMBusDevice BusDevice[SM_MAX_BUSES];

//init device struct table
void smBDinit()
{
	int i;
	for(i=0;i<SM_MAX_BUSES;i++)
	{
		BusDevice[i].bdType=BD_NONE;
		BusDevice[i].opened=smfalse;
        BusDevice[i].txBufferUsed=0;
	}
	bdInitialized=smtrue;
}


//ie "COM1" "VSD2USB"
//return -1 if fails, otherwise handle number
smbusdevicehandle smBDOpen( const char *devicename )
{
	int handle;

	//true on first call
	if(bdInitialized==smfalse)
		smBDinit();

	//find free handle
	for(handle=0;handle<SM_MAX_BUSES;handle++)
	{
		if(BusDevice[handle].opened==smfalse) break;//choose this
	}

	//all handles in use
	if(handle>=SM_MAX_BUSES) return -1;

        if(strncmp(devicename,"COM",3) == 0 || strncmp(devicename,"/dev/tty",8) == 0 || strncmp(devicename,"/dev/cu.",8) == 0) //use rs232 lib
	{
            BusDevice[handle].comPort=serialPortOpen( devicename, SMBusBaudrate );
                if( BusDevice[handle].comPort == -1 )
		{
			return -1; //failed to open
		}
		BusDevice[handle].bdType=BD_RS;
        BusDevice[handle].txBufferUsed=0;
	}
    else if (validateIpAddress(devicename, NULL, NULL) == 0)
    {
        char ip[128];
        short port = 4001;
        if (parseIpAddress(devicename, ip, sizeof(ip), &port) < 0)
            return -1;
        BusDevice[handle].comPort=OpenTCPPort( ip, port );
        if( BusDevice[handle].comPort == -1 )
        {
            return -1; //failed to open
        }
        BusDevice[handle].bdType=BD_TCP;
        BusDevice[handle].txBufferUsed=0;
    }
#ifdef FTDI_D2XX_SUPPORT
    else if (strncmp(devicename,"FTDI",4) == 0)//starts with FTDI. Full name is FTDIn where n=index starting from 0.
    {
        BusDevice[handle].comPort=d2xxPortOpen( devicename, SMBusBaudrate );
            if( BusDevice[handle].comPort == -1 )
        {
            return -1; //failed to open
        }
        BusDevice[handle].bdType=BD_FTDI;
        BusDevice[handle].txBufferUsed=0;
    }
#endif
    else//no other bus types supproted yet
    {
        smDebug( -1, Low, "smBDOpen device name argument syntax didn't match any supported driver port name");
        return -1;
    }

	//success
    BusDevice[handle].cumulativeSmStatus=0;
	BusDevice[handle].opened=smtrue;
	return handle;
}

smbool smIsBDHandleOpen( const smbusdevicehandle handle )
{
	if(handle<0) return smfalse;
	if(handle>=SM_MAX_BUSES) return smfalse;
	return BusDevice[handle].opened;
}

//return true if ok
smbool smBDClose( const smbusdevicehandle handle )
{
	//check if handle valid & open
	if( smIsBDHandleOpen(handle)==smfalse ) return smfalse;

	if( BusDevice[handle].bdType==BD_RS )
	{
        serialPortClose( BusDevice[handle].comPort );
		BusDevice[handle].opened=smfalse;
		return smtrue;
	}
    else if( BusDevice[handle].bdType==BD_TCP )
    {
        CloseTCPport( BusDevice[handle].comPort );
        BusDevice[handle].opened=smfalse;
        return smtrue;
    }
#ifdef FTDI_D2XX_SUPPORT
    else if( BusDevice[handle].bdType==BD_FTDI )
    {
        d2xxPortClose( BusDevice[handle].comPort );
        BusDevice[handle].opened=smfalse;
        return smtrue;
    }
#endif

    return smfalse;
}




//write one byte to buffer and send later with smBDTransmit()
//returns true on success
smbool smBDWrite(const smbusdevicehandle handle, const smuint8 byte )
{
	//check if handle valid & open
	if( smIsBDHandleOpen(handle)==smfalse ) return smfalse;

    if(BusDevice[handle].txBufferUsed<TANSMIT_BUFFER_LENGTH)
    {
        //append to buffer
        BusDevice[handle].txBuffer[BusDevice[handle].txBufferUsed]=byte;
        BusDevice[handle].txBufferUsed++;
        return smtrue;
    }

    return smfalse;
}

smbool smBDTransmit(const smbusdevicehandle handle)
{
    //check if handle valid & open
    if( smIsBDHandleOpen(handle)==smfalse ) return smfalse;

    if( BusDevice[handle].bdType==BD_RS )
    {
        if(serialPortWriteBuffer(BusDevice[handle].comPort,BusDevice[handle].txBuffer, BusDevice[handle].txBufferUsed)==BusDevice[handle].txBufferUsed)
        {
            BusDevice[handle].txBufferUsed=0;
            return smtrue;
        }
        else
        {
            BusDevice[handle].txBufferUsed=0;
            return smfalse;
        }
    }
    else if( BusDevice[handle].bdType==BD_TCP )
    {
        if(SendTCPBuf(BusDevice[handle].comPort,BusDevice[handle].txBuffer, BusDevice[handle].txBufferUsed)==BusDevice[handle].txBufferUsed)
        {
            BusDevice[handle].txBufferUsed=0;
            return smtrue;
        }
        else
        {
            BusDevice[handle].txBufferUsed=0;
            return smfalse;
        }
    }
#ifdef FTDI_D2XX_SUPPORT
    else if( BusDevice[handle].bdType==BD_FTDI )
    {
        if(d2xxPortWriteBuffer(BusDevice[handle].comPort,BusDevice[handle].txBuffer, BusDevice[handle].txBufferUsed)==BusDevice[handle].txBufferUsed)
        {
            BusDevice[handle].txBufferUsed=0;
            return smtrue;
        }
        else
        {
            BusDevice[handle].txBufferUsed=0;
            return smfalse;
        }
    }
#endif

    return smfalse;
}

//read one byte from bus. if byte not immediately available, block return up to SM_READ_TIMEOUT millisecs to wait data
//returns true if byte read sucessfully
smbool smBDRead( const smbusdevicehandle handle, smuint8 *byte )
{
	//check if handle valid & open
	if( smIsBDHandleOpen(handle)==smfalse ) return smfalse;

	if( BusDevice[handle].bdType==BD_RS )
	{
		int n;
        n=serialPortRead(BusDevice[handle].comPort, byte, 1);
		if( n!=1 ) return smfalse;
		else return smtrue;
	}
    else if( BusDevice[handle].bdType==BD_TCP )
    {
        int n;
        n=PollTCPPort(BusDevice[handle].comPort, byte, 1);
        if( n!=1 ) return smfalse;
        else return smtrue;
    }
#ifdef FTDI_D2XX_SUPPORT
    else if( BusDevice[handle].bdType==BD_FTDI )
    {
        int n;
        n=d2xxPortRead(BusDevice[handle].comPort, byte, 1);
        if( n!=1 ) return smfalse;
        else return smtrue;
    }
#endif

	return smfalse;
}

//BUS DEVICE INFO FETCH FUNCTIONS:

//Return number of bus devices found. details of each device may be consequently fetched by smGetBusDeviceDetails()
smint smBDGetNumberOfDetectedBuses()
{
    //only supports FTDI D2XX at the moment
#ifdef FTDI_D2XX_SUPPORT
    return d2xxGetNumberOfDetectedBuses();
#endif
    return 0;
}

smbool smBDGetBusDeviceDetails( smint index, SM_BUS_DEVICE_INFO *info )
{
    //only supports FTDI D2XX at the moment
#ifdef FTDI_D2XX_SUPPORT
    return d2xxGetBusDeviceDetails(index,info);
#endif
    return smfalse;

}