aboutsummaryrefslogtreecommitdiffstats
path: root/src/hal/components/mesa_pktgyro_test.comp
blob: 33ad83791dbfc380be026a86932a7607a3069c39 (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
286
component mesa_pktgyro_test "PktUART simple test with Microstrain 3DM-GX3-15 gyro";

description """This component is written in order to test
the PktUART driver for Mesa. It resembles partly Andy Pugh's mesa_uart.comp .

This module uses the names= mode of loadrt declaration to specify which PktUART
instances to enable. A check is included to ensure that the count= option is
not used instead.
For simplicity we test only one PktUART instance, therefore load the component
like this:

\\fB loadrt mesa_uart names=hm2_5i25.0.pktuart.0\\fR

The PktUART instance names are printed to the dmesg buffer during the Hostmot2
setup sequence, one for each PktUART instance included in the bitfile loaded to
each installed card during the Hostmot2 setup sequence. Type "dmesg" at the
terminal prompt to view the output.
If you want to work with more than one PktUART instance, consult Andy Pugh's
mesa_uart.comp

In order to compile and install do:
\\fB halcompile --install src/hal/drivers/mesa_pktgyro_test.comp\\fR

The component exports only one function, namely receive, which needs to be added
to a realtime thread.
To test this component  set DEBUG=5 before and execute this HAL script:
\\fB loadrt hostmot2\\fR
\\fB loadrt hm2_pci\\fR
\\fB loadrt mesa_pktgyro_test names=hm2_5i25.0.pktuart.0\\fR
\\fB loadrt threads name1=test1 period1=10000000\\fR
\\fB addf hm2_5i25.0.pktuart.0.receive test1\\fR
\\fB start\\fR

Check linuxcnc.log for debug output.

""";


author "Boris Skegin";
license "GPL";

include "hal/drivers/mesa-hostmot2/hostmot2.h";


pin out s32 rxbytes  "Number of Bytes received or negative Error code";

variable char *name; // PktUART name

option extra_setup yes;

function receive;

;;



#define BAUDRATE (115200)



/* This uses the RTAPI_MP_ARRAY_STRING macro to load the list of PktUART channels
into an array. This is copied into the *name string of each */

char *pktuart_chans[4] = {0,};
RTAPI_MP_ARRAY_STRING(pktuart_chans, 2, "PktUART Channel names");

static hostmot2_t* hm2=NULL;



FUNCTION(receive){
	rtapi_u16 max_frame_length = 20;
	rtapi_u8 num_frames = 20;
	unsigned char Replyd3[num_frames*max_frame_length];
	rtapi_u16 frame_sizes3[20];
	rxbytes=hm2_pktuart_read(name, Replyd3, &num_frames, &max_frame_length, frame_sizes3);
	rtapi_print_msg(RTAPI_MSG_INFO, "PktUART receive: got %d bytes, %d frames\n", rxbytes, num_frames);

	//Print out the actual frame sizes
	int i;
	for(i=0;i<num_frames; i++) {
	    rtapi_print_msg(RTAPI_MSG_INFO, "Rec frame %d: size %d bytes\n", i+1 , frame_sizes3[i]);
		}
	rtapi_print_msg(RTAPI_MSG_INFO, "\n");

	// Print out ACK replies for the frames sent out
	// from EXTRA_SETUP function
	int k=0;
	int bytes_total = 0;
	while(k <num_frames) {
		        int j=0;
	            while(j<=frame_sizes3[k]-1) {
				   rtapi_print_msg(RTAPI_MSG_INFO, "Rec frame %d, byte %d 0x%.2x", k+1 , bytes_total+j , Replyd3[bytes_total+j]);
				   j++;
				}
		   bytes_total = bytes_total + frame_sizes3[k];
		   rtapi_print_msg(RTAPI_MSG_INFO, "\n");
		   k++;
	}



}

EXTRA_SETUP(){ // the names parameters are passed in 'prefix'.
	if (prefix[0] == 'm'){ // should be the 'm' of hm2_....
		rtapi_print_msg(0, "mesa_pktuart_test can not be loaded using the 'count' "
						"parameter, see man mesa_uart for details\n");
		return -1;
	}
	name = prefix;


	/* 115200bps - default value from MIP Monitor Systems Settings */


	 rtapi_print_msg(RTAPI_MSG_INFO, "Set up PktUART now\n");

	/* Check buff = (u32)((bitrate * 1048576.0)/inst->clock_freq);
	   Bitrate is (RXBitrate_Register_Value/1048576)*ClockLow */
	/*  http://freeby.mesanet.com/regmap
	  The PktUARTxMode register is used for setting and checking the
	  PktUARTx's operation mode, timing and status:
	  Bit  21	       FrameBuffer Has Data
	  Bits 20..16      Frames to send
	  Bits 15..8       InterFrame delay in bit times
	  Bit  7	       Tr Logic active (not an error)
	  Bit  6	       Drive Enable bit (enables external RS-422/485 Driver when set)
	  Bit  5	       Drive enable Auto (Automatic external drive enable)
	  Bit  4	       unused
	  Bits 3..0        Drive enable delay (delay from asserting drive enable
					   to start of data transmit. In CLock Low periods
	*/

	 /* http://freeby.mesanet.com/regmap
	  The PktUARTrMode register is used for setting and checking the PktUARTr's
	  operation mode, timing, and status
	  Bit  21	       FrameBuffer has data
	  Bits 20..16      Frames received
	  Bits 15..8       InterFrame delay in bit times
	  Bit  7	       Rx Logic active ( not an error)
	  Bit  6	       RXMask
	  Bit  5	       Unused
	  Bit  4	       RCFIFO Error
	  Bit  3	       RXEnable (must be set to receive packets)
	  Bit  2	       RXMask Enable (enables input data masking when transmitting)
	  Bit  1	       Overrun error (no stop bit when expected) (sticky)
	  Bit  0	       False Start bit error (sticky)
	*/


	/*
	   In case our device is streaming data from the very beginning,
	   at first we do not set RXEnable but clear Rx and Tx registers.
	   Then we read out whatever is in the buffer, send the DISABLE STREAM
	   datagram and only then set RXEnable bit.
	*/
	int retval=hm2_pktuart_setup(name, BAUDRATE , 0x0ff20,  0x007f00,1,1);
	if (retval<0)
	{
	    rtapi_print_msg(1, "PktUART for gyro setup problem: %d\n", retval);
	    return -1;
	}

	/*
	  We expect the max frame length to be 58 byte if the gyro is
	  streaming data from the beginning,
	  but in case the InterFrame delay is not appropriate,
	  the frame size can be longer.
	  Anyway as long as the array size we pass to hm2_pktuart_read
	  is big enough, we can read everything which is in the Rx buffer.
	*/
	rtapi_u16 max_frame_length = 58*2;
	rtapi_u8 num_frames = 20;

	// If Rx buffer <= 1024 bytes, than 2*58*20 bytes of read1 array are enough
	unsigned char read1[num_frames*max_frame_length];
	rtapi_u16 read1_sizes[num_frames];

	// read out as many frames as possible
	retval=hm2_pktuart_read(name, read1, &num_frames, &max_frame_length, read1_sizes);

	rtapi_print_msg(RTAPI_MSG_INFO, "PktUART after first read: got %d bytes\n", retval);



	//Print out the actual frame sizes
	int i;
	for(i=0;i<num_frames; i++) {
	    rtapi_print_msg(RTAPI_MSG_INFO, "Reply frame %d: size %d bytes\n", i+1 , read1_sizes[i]);
	}

	int k=0;
	int bytes_total=0;
	while(k < num_frames) {
		  int j=0;
	      while(j<read1_sizes[k]) {
				rtapi_print_msg(RTAPI_MSG_INFO, "Reply frame %d, byte %d 0x%.2x", k+1 , bytes_total+j , read1[bytes_total+j]);
				j++;
		  }
		  bytes_total = bytes_total + read1_sizes[k];
		  rtapi_print_msg(RTAPI_MSG_INFO, "\n");
		  k++;
	}
	// We have read out everything we could
	rtapi_print_msg(RTAPI_MSG_INFO, "%s: read all of the buffer\n", name);


	// Test the exported hm2_get_pktuart function
	retval = hm2_get_pktuart(&hm2, name);
	if (retval < 0)
	{
	   rtapi_print_msg(RTAPI_MSG_ERR, "%s hm2_get_pktuart: smth. is wrong. \n", name);
	   return -1;
	}

	// Now we set RxEnable bit and clear Rx/Tx registers
	retval=hm2_pktuart_setup(name, BAUDRATE , 0x0ff20,  0x007f08,1,1);
	if (retval<0)
	{
	 rtapi_print_msg(1, "PktUART for gyro setup problem: %d\n", retval);
	 return -1;
	}

	/*
	Disable the IMU/AHRS data-stream "7565 0C05 0511 0101 0003 19"
	In order to test the hm2_pktuart_send function
	we want to send out 16 DISABLE STREAM datagrams
	and receive 16 ACK datagrams as replies.
	*/

	unsigned char disable16[11*16] ={
	0x75, 0x65, 0x0C,0x05,  0x05,0x11, 0x01,0x01, 0x00, 0x03, 0x19,
	0x75, 0x65, 0x0C,0x05,  0x05,0x11, 0x01,0x01, 0x00, 0x03, 0x19,
	0x75, 0x65, 0x0C,0x05,  0x05,0x11, 0x01,0x01, 0x00, 0x03, 0x19,
	0x75, 0x65, 0x0C,0x05,  0x05,0x11, 0x01,0x01, 0x00, 0x03, 0x19,

	0x75, 0x65, 0x0C,0x05,  0x05,0x11, 0x01,0x01, 0x00, 0x03, 0x19,
	0x75, 0x65, 0x0C,0x05,  0x05,0x11, 0x01,0x01, 0x00, 0x03, 0x19,
	0x75, 0x65, 0x0C,0x05,  0x05,0x11, 0x01,0x01, 0x00, 0x03, 0x19,
	0x75, 0x65, 0x0C,0x05,  0x05,0x11, 0x01,0x01, 0x00, 0x03, 0x19,

	0x75, 0x65, 0x0C,0x05,  0x05,0x11, 0x01,0x01, 0x00, 0x03, 0x19,
	0x75, 0x65, 0x0C,0x05,  0x05,0x11, 0x01,0x01, 0x00, 0x03, 0x19,
	0x75, 0x65, 0x0C,0x05,  0x05,0x11, 0x01,0x01, 0x00, 0x03, 0x19,
	0x75, 0x65, 0x0C,0x05,  0x05,0x11, 0x01,0x01, 0x00, 0x03, 0x19,

	0x75, 0x65, 0x0C,0x05,  0x05,0x11, 0x01,0x01, 0x00, 0x03, 0x19,
	0x75, 0x65, 0x0C,0x05,  0x05,0x11, 0x01,0x01, 0x00, 0x03, 0x19,
	0x75, 0x65, 0x0C,0x05,  0x05,0x11, 0x01,0x01, 0x00, 0x03, 0x19,
	0x75, 0x65, 0x0C,0x05,  0x05,0x11, 0x01,0x01, 0x00, 0x03, 0x19
	};
	rtapi_u16 disable_size16[16]={11,11,11,11, 11,11,11,11, 11,11,11,11, 11,11,11,11};
	num_frames = 16;
	retval=hm2_pktuart_send(name, disable16, &num_frames, disable_size16);
	rtapi_print_msg(RTAPI_MSG_INFO, "%s sent: bytes %d, frames %u\n", name, retval, num_frames);



	/*
	We assume a bit time to be 10 us/bit at 115200 bit/s baud rate for simplicity.
	Try to estimate the total time for sending out 16 frames and receiving
	16 reply frames:

	16 Frames * 10 bits/byte * 10 us/bit*11 bytes + 15*255*10 us/bit (Tx Interfame delay) +
	+ 16 Frames * 10 bits/byte * 10 us/bit*10 bytes + 15*255*10 us/bit (Rx Interfame delay) =
	= 17600 + 38250 + 16000 + 38250 = 110100 us at least as the gyro needs to process
	each DISABLE STREAM datagram and "compute" an ACK reply.

	This wait time might be too long for  EXTRA_SETUP function,
	that's why we read  out the ACK reply frames in the receive function
	attached to a thread cycle of 10000 us , as we need about
	10 bits/byte * 10 us/bit*10 bytes + 255*10 us/bit = 1000 + 2550 = 3550 us
	for receiving an ACK frame of 10 bytes at 115200 bit/s baud rate .
	*/


	return 0;
}


int get_count(void){
	int i;
	for (i= 0; pktuart_chans[i] != NULL && i < 2 ; i++){}
	return i;
}
bues.ch cgit interface