1 | /** @file wl_user.c |
---|
2 | * @brief WARPLab Framework (User Extensions) |
---|
3 | * |
---|
4 | * This contains the code for WARPLab Framework user extensions. |
---|
5 | * |
---|
6 | * @copyright Copyright 2013-2015, Mango Communications. All rights reserved. |
---|
7 | * Distributed under the WARP license (http://warpproject.org/license) |
---|
8 | * |
---|
9 | * @author Chris Hunter (chunter [at] mangocomm.com) |
---|
10 | * @author Patrick Murphy (murphpo [at] mangocomm.com) |
---|
11 | * @author Erik Welsh (welsh [at] mangocomm.com) |
---|
12 | */ |
---|
13 | |
---|
14 | /***************************** Include Files *********************************/ |
---|
15 | |
---|
16 | // Xilinx / Standard library includes |
---|
17 | #include <xparameters.h> |
---|
18 | #include <xil_types.h> |
---|
19 | #include <xstatus.h> |
---|
20 | #include <stdlib.h> |
---|
21 | #include <stdio.h> |
---|
22 | |
---|
23 | // WARPLab includes |
---|
24 | #include "wl_common.h" |
---|
25 | #include "wl_user.h" |
---|
26 | |
---|
27 | |
---|
28 | // Peripheral includes |
---|
29 | #ifdef WARP_HW_VER_v3 |
---|
30 | #include <w3_iic_eeprom.h> |
---|
31 | #endif |
---|
32 | |
---|
33 | /*************************** Constant Definitions ****************************/ |
---|
34 | |
---|
35 | #define EEPROM_EXAMPLE_BUFFER_SIZE 10 |
---|
36 | |
---|
37 | |
---|
38 | /*********************** Global Variable Definitions *************************/ |
---|
39 | |
---|
40 | |
---|
41 | /*************************** Variable Definitions ****************************/ |
---|
42 | |
---|
43 | |
---|
44 | /*************************** Function Prototypes *****************************/ |
---|
45 | |
---|
46 | |
---|
47 | /******************************** Functions **********************************/ |
---|
48 | |
---|
49 | |
---|
50 | /*****************************************************************************/ |
---|
51 | /** |
---|
52 | * Process User Defined Commands |
---|
53 | * |
---|
54 | * This function is part of the Ethernet processing system and will process the |
---|
55 | * various user defined commands. |
---|
56 | * |
---|
57 | * @param socket_index - Index of the socket on which to send message |
---|
58 | * @param from - Pointer to socket address structure (struct sockaddr *) where command is from |
---|
59 | * @param command - Pointer to WARPLab Command |
---|
60 | * @param response - Pointer to WARPLab Response |
---|
61 | * |
---|
62 | * @return int - Status of the command: |
---|
63 | * NO_RESP_SENT - No response has been sent |
---|
64 | * RESP_SENT - A response has been sent |
---|
65 | * |
---|
66 | * @note See on-line documentation for more information about the ethernet |
---|
67 | * packet structure for WARPLab: www.warpproject.org |
---|
68 | * |
---|
69 | ******************************************************************************/ |
---|
70 | |
---|
71 | int user_process_cmd(int socket_index, void * from, wl_cmd_resp * command, wl_cmd_resp * response) { |
---|
72 | |
---|
73 | // |
---|
74 | // IMPORTANT ENDIAN NOTES: |
---|
75 | // - command |
---|
76 | // - header - Already endian swapped by the framework (safe to access directly) |
---|
77 | // - args - Must be endian swapped as necessary by code (framework does not know the contents of the command) |
---|
78 | // - response |
---|
79 | // - header - Will be endian swapped by the framework (safe to write directly) |
---|
80 | // - args - Must be endian swapped as necessary by code (framework does not know the contents of the response) |
---|
81 | // |
---|
82 | |
---|
83 | // Standard variables |
---|
84 | u32 resp_sent = NO_RESP_SENT; |
---|
85 | |
---|
86 | wl_cmd_resp_hdr * cmd_hdr = command->header; |
---|
87 | u32 * cmd_args_32 = command->args; |
---|
88 | u32 cmd_id = WL_CMD_TO_CMDID(cmd_hdr->cmd); |
---|
89 | |
---|
90 | wl_cmd_resp_hdr * resp_hdr = response->header; |
---|
91 | u32 * resp_args_32 = response->args; |
---|
92 | u32 resp_index = 0; |
---|
93 | |
---|
94 | // Specific command variables |
---|
95 | |
---|
96 | #ifdef WARP_HW_VER_v3 |
---|
97 | // Arguments for EEPROM Read/Write example |
---|
98 | u32 k; |
---|
99 | u32 buffer_32[EEPROM_EXAMPLE_BUFFER_SIZE + 1]; // Extra entry for Null termination of strings |
---|
100 | u8 * buffer_8 = (u8 *) buffer_32; |
---|
101 | u32 length; |
---|
102 | u32 eeprom_addr_offset; |
---|
103 | #endif |
---|
104 | |
---|
105 | // Set up the response header |
---|
106 | resp_hdr->cmd = cmd_hdr->cmd; |
---|
107 | resp_hdr->length = 0; |
---|
108 | resp_hdr->num_args = 0; |
---|
109 | |
---|
110 | // Process the command |
---|
111 | switch(cmd_id) { |
---|
112 | |
---|
113 | #ifdef WARP_HW_VER_v3 |
---|
114 | |
---|
115 | // Write string to EEPROM |
---|
116 | case CMDID_USER_EEPROM_WRITE_STRING: |
---|
117 | // Process command arguments |
---|
118 | eeprom_addr_offset = Xil_Ntohl(cmd_args_32[0]); |
---|
119 | length = ((cmd_hdr->length) / sizeof(u32)); |
---|
120 | |
---|
121 | // Check that we have allocated enough space for the write |
---|
122 | if (length <= (EEPROM_EXAMPLE_BUFFER_SIZE << 2)) { |
---|
123 | |
---|
124 | // Initialize buffer to zero (also serves to null terminate all strings) |
---|
125 | for (k = 0; k < (EEPROM_EXAMPLE_BUFFER_SIZE + 1); k++ ) { buffer_32[k] = 0; } |
---|
126 | |
---|
127 | // Endian swap all of the characters to write |
---|
128 | for(k = 0; k < length; k++) { |
---|
129 | buffer_32[k] = Xil_Ntohl(cmd_args_32[k+1]); |
---|
130 | } |
---|
131 | |
---|
132 | // Write the string to the EEPROM |
---|
133 | for(k = 0; k < (cmd_hdr->length); k++){ |
---|
134 | iic_eeprom_writeByte(EEPROM_BASEADDR, (k + eeprom_addr_offset), buffer_8[k]); |
---|
135 | } |
---|
136 | |
---|
137 | wl_printf(WL_PRINT_NONE, print_type_user, "Wrote '%s' to EEPROM\n", buffer_8); |
---|
138 | } else { |
---|
139 | wl_printf(WL_PRINT_ERROR, print_type_user, "Message too long (%d characters). Only %d characters supported.\n", |
---|
140 | cmd_hdr->length, (EEPROM_EXAMPLE_BUFFER_SIZE << 2)); |
---|
141 | } |
---|
142 | break; |
---|
143 | |
---|
144 | // Read string from EERPOM |
---|
145 | case CMDID_USER_EEPROM_READ_STRING: |
---|
146 | // Process command arguments |
---|
147 | eeprom_addr_offset = Xil_Ntohl(cmd_args_32[0]); |
---|
148 | length = Xil_Ntohl(cmd_args_32[1]); // Length of the read (in bytes) |
---|
149 | |
---|
150 | // Check that we have allocated enough space for the read |
---|
151 | if ( length <= (EEPROM_EXAMPLE_BUFFER_SIZE << 2)) { |
---|
152 | |
---|
153 | // Initialize buffer to zero (also serves to null terminate all strings) |
---|
154 | for (k = 0; k < (EEPROM_EXAMPLE_BUFFER_SIZE + 1); k++ ) { buffer_32[k] = 0; } |
---|
155 | |
---|
156 | // Read the string from the EEPROM |
---|
157 | for(k = 0; k < length; k++){ |
---|
158 | buffer_8[k] = iic_eeprom_readByte(EEPROM_BASEADDR, (k + eeprom_addr_offset)); |
---|
159 | } |
---|
160 | |
---|
161 | wl_printf(WL_PRINT_NONE, print_type_user, "Read '%s' from EEPROM\n", buffer_8); |
---|
162 | |
---|
163 | // Endian swap all the characters to read |
---|
164 | for(resp_index = 0; resp_index < ((length)/sizeof(u32)); resp_index++) { |
---|
165 | resp_args_32[resp_index] = Xil_Htonl(buffer_32[resp_index]); |
---|
166 | } |
---|
167 | |
---|
168 | resp_hdr->length += (resp_index * sizeof(resp_args_32)); |
---|
169 | resp_hdr->num_args = resp_index; |
---|
170 | } else { |
---|
171 | wl_printf(WL_PRINT_ERROR, print_type_user, "Requested message too long (%d characters). Only %d characters supported.\n", |
---|
172 | length, (EEPROM_EXAMPLE_BUFFER_SIZE << 2)); |
---|
173 | } |
---|
174 | break; |
---|
175 | |
---|
176 | #endif |
---|
177 | |
---|
178 | /* Example Additional User Command |
---|
179 | case SOME_CMD_ID: <-- Needs to be defined as same number in both Matlab and C |
---|
180 | arg0 = Xil_Ntohl(cmd_args[0]); |
---|
181 | arg1 = Xil_Ntohl(cmd_args[1]); |
---|
182 | result = do_something_with_args(arg0, arg1); |
---|
183 | |
---|
184 | resp_args_32[resp_index++] = Xil_Htonl(result); |
---|
185 | resp_hdr->length += (resp_index * sizeof(resp_args_32)); |
---|
186 | resp_hdr->numArgs = resp_index; |
---|
187 | break; |
---|
188 | */ |
---|
189 | |
---|
190 | default: |
---|
191 | wl_printf(WL_PRINT_ERROR, print_type_user, "Unknown user command ID: %d\n", cmd_id); |
---|
192 | break; |
---|
193 | } |
---|
194 | |
---|
195 | return resp_sent; |
---|
196 | } |
---|
197 | |
---|
198 | |
---|
199 | |
---|
200 | /*****************************************************************************/ |
---|
201 | /** |
---|
202 | * @brief User extension subsystem initialization |
---|
203 | * |
---|
204 | * Initializes the user extension subsystem |
---|
205 | * |
---|
206 | * @param None |
---|
207 | * |
---|
208 | * @return int - Status of the command: |
---|
209 | * XST_SUCCESS - Command completed successfully |
---|
210 | * XST_FAILURE - There was an error in the command |
---|
211 | * |
---|
212 | ******************************************************************************/ |
---|
213 | int user_init(){ |
---|
214 | int status = XST_SUCCESS; |
---|
215 | |
---|
216 | // User initialization goes here |
---|
217 | // Framework calls user_init when node is initialized |
---|
218 | // (on boot and when node 'initialize' command is received) |
---|
219 | |
---|
220 | return status; |
---|
221 | } |
---|
222 | |
---|
223 | |
---|
224 | |
---|
225 | |
---|