[4284] | 1 | /** @file wl_user.c |
---|
| 2 | * @brief WARPLab Framework (User Extensions) |
---|
| 3 | * |
---|
| 4 | * This contains the code for WARPLab Framework user extensions. |
---|
| 5 | * |
---|
[4668] | 6 | * @copyright Copyright 2013-2015, Mango Communications. All rights reserved. |
---|
[4284] | 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 | */ |
---|
[1915] | 13 | |
---|
[2070] | 14 | /***************************** Include Files *********************************/ |
---|
| 15 | |
---|
[4284] | 16 | // Xilinx / Standard library includes |
---|
[1957] | 17 | #include <xparameters.h> |
---|
[4284] | 18 | #include <xil_types.h> |
---|
| 19 | #include <xstatus.h> |
---|
[1957] | 20 | #include <stdlib.h> |
---|
| 21 | #include <stdio.h> |
---|
[2013] | 22 | |
---|
[4284] | 23 | // WARPLab includes |
---|
| 24 | #include "wl_common.h" |
---|
| 25 | #include "wl_user.h" |
---|
| 26 | |
---|
| 27 | |
---|
| 28 | // Peripheral includes |
---|
[2013] | 29 | #ifdef WARP_HW_VER_v3 |
---|
[1957] | 30 | #include <w3_iic_eeprom.h> |
---|
[2013] | 31 | #endif |
---|
[1915] | 32 | |
---|
[2070] | 33 | /*************************** Constant Definitions ****************************/ |
---|
[1915] | 34 | |
---|
[4284] | 35 | #define EEPROM_EXAMPLE_BUFFER_SIZE 10 |
---|
[2070] | 36 | |
---|
| 37 | |
---|
| 38 | /*********************** Global Variable Definitions *************************/ |
---|
| 39 | |
---|
| 40 | |
---|
| 41 | /*************************** Variable Definitions ****************************/ |
---|
| 42 | |
---|
| 43 | |
---|
| 44 | /*************************** Function Prototypes *****************************/ |
---|
| 45 | |
---|
| 46 | |
---|
| 47 | /******************************** Functions **********************************/ |
---|
| 48 | |
---|
| 49 | |
---|
| 50 | /*****************************************************************************/ |
---|
| 51 | /** |
---|
[4514] | 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 | * |
---|
[4668] | 62 | * @return int - Status of the command: |
---|
| 63 | * NO_RESP_SENT - No response has been sent |
---|
| 64 | * RESP_SENT - A response has been sent |
---|
[4514] | 65 | * |
---|
| 66 | * @note See on-line documentation for more information about the ethernet |
---|
| 67 | * packet structure for WARPLab: www.warpproject.org |
---|
| 68 | * |
---|
| 69 | ******************************************************************************/ |
---|
[2070] | 70 | |
---|
[4514] | 71 | int user_process_cmd(int socket_index, void * from, wl_cmd_resp * command, wl_cmd_resp * response) { |
---|
[1915] | 72 | |
---|
[4668] | 73 | // |
---|
[4514] | 74 | // IMPORTANT ENDIAN NOTES: |
---|
[4668] | 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 | // |
---|
[1915] | 82 | |
---|
[4668] | 83 | // Standard variables |
---|
[4514] | 84 | u32 resp_sent = NO_RESP_SENT; |
---|
[1915] | 85 | |
---|
[4514] | 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 | |
---|
[2013] | 96 | #ifdef WARP_HW_VER_v3 |
---|
[4668] | 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; |
---|
[2013] | 103 | #endif |
---|
[1957] | 104 | |
---|
[4668] | 105 | // Set up the response header |
---|
| 106 | resp_hdr->cmd = cmd_hdr->cmd; |
---|
| 107 | resp_hdr->length = 0; |
---|
| 108 | resp_hdr->num_args = 0; |
---|
[1915] | 109 | |
---|
[4668] | 110 | // Process the command |
---|
| 111 | switch(cmd_id) { |
---|
[4284] | 112 | |
---|
[2070] | 113 | #ifdef WARP_HW_VER_v3 |
---|
[1915] | 114 | |
---|
[4668] | 115 | // Write string to EEPROM |
---|
[4783] | 116 | case CMDID_USER_EEPROM_WRITE_STRING: |
---|
[4668] | 117 | // Process command arguments |
---|
| 118 | eeprom_addr_offset = Xil_Ntohl(cmd_args_32[0]); |
---|
| 119 | length = ((cmd_hdr->length) / sizeof(u32)); |
---|
[1915] | 120 | |
---|
[4668] | 121 | // Check that we have allocated enough space for the write |
---|
| 122 | if (length <= (EEPROM_EXAMPLE_BUFFER_SIZE << 2)) { |
---|
[1957] | 123 | |
---|
[4668] | 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; } |
---|
[1957] | 126 | |
---|
[4668] | 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 | } |
---|
[2070] | 131 | |
---|
[4284] | 132 | // Write the string to the EEPROM |
---|
[4668] | 133 | for(k = 0; k < (cmd_hdr->length); k++){ |
---|
| 134 | iic_eeprom_writeByte(EEPROM_BASEADDR, (k + eeprom_addr_offset), buffer_8[k]); |
---|
| 135 | } |
---|
[1957] | 136 | |
---|
[4668] | 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; |
---|
[1957] | 143 | |
---|
[4668] | 144 | // Read string from EERPOM |
---|
[4783] | 145 | case CMDID_USER_EEPROM_READ_STRING: |
---|
[4668] | 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) |
---|
[1957] | 149 | |
---|
[4668] | 150 | // Check that we have allocated enough space for the read |
---|
| 151 | if ( length <= (EEPROM_EXAMPLE_BUFFER_SIZE << 2)) { |
---|
[4284] | 152 | |
---|
[4668] | 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; } |
---|
[4284] | 155 | |
---|
[4668] | 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 | } |
---|
[4284] | 160 | |
---|
[4668] | 161 | wl_printf(WL_PRINT_NONE, print_type_user, "Read '%s' from EEPROM\n", buffer_8); |
---|
[4284] | 162 | |
---|
[4668] | 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 | } |
---|
[4284] | 167 | |
---|
[4668] | 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; |
---|
[2070] | 175 | |
---|
[2013] | 176 | #endif |
---|
[1957] | 177 | |
---|
[2070] | 178 | /* Example Additional User Command |
---|
[4668] | 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); |
---|
[2070] | 183 | |
---|
[4668] | 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; |
---|
[2070] | 188 | */ |
---|
| 189 | |
---|
[4668] | 190 | default: |
---|
| 191 | wl_printf(WL_PRINT_ERROR, print_type_user, "Unknown user command ID: %d\n", cmd_id); |
---|
| 192 | break; |
---|
| 193 | } |
---|
[4284] | 194 | |
---|
[4668] | 195 | return resp_sent; |
---|
[1915] | 196 | } |
---|
| 197 | |
---|
| 198 | |
---|
[2070] | 199 | |
---|
| 200 | /*****************************************************************************/ |
---|
| 201 | /** |
---|
[4284] | 202 | * @brief User extension subsystem initialization |
---|
| 203 | * |
---|
| 204 | * Initializes the user extension subsystem |
---|
| 205 | * |
---|
[4668] | 206 | * @param None |
---|
[4284] | 207 | * |
---|
[4668] | 208 | * @return int - Status of the command: |
---|
| 209 | * XST_SUCCESS - Command completed successfully |
---|
| 210 | * XST_FAILURE - There was an error in the command |
---|
| 211 | * |
---|
[4284] | 212 | ******************************************************************************/ |
---|
[1915] | 213 | int user_init(){ |
---|
[4668] | 214 | int status = XST_SUCCESS; |
---|
[1915] | 215 | |
---|
[4668] | 216 | // User initialization goes here |
---|
| 217 | // Framework calls user_init when node is initialized |
---|
| 218 | // (on boot and when node 'initialize' command is received) |
---|
[1915] | 219 | |
---|
[4668] | 220 | return status; |
---|
[1915] | 221 | } |
---|
[2070] | 222 | |
---|
| 223 | |
---|
| 224 | |
---|
| 225 | |
---|