From ac4fd8e8340886f455add8cf92ee1c8458b8ae19 Mon Sep 17 00:00:00 2001 From: Yuval Adam Date: Sun, 16 Mar 2014 14:31:22 +0200 Subject: Add ek-tm4c1294xl example projects --- boards/ek-tm4c1294xl/drivers/buttons.c | 187 ++++ boards/ek-tm4c1294xl/drivers/buttons.h | 110 +++ boards/ek-tm4c1294xl/drivers/eth_client_lwip.c | 1046 ++++++++++++++++++++++ boards/ek-tm4c1294xl/drivers/eth_client_lwip.h | 88 ++ boards/ek-tm4c1294xl/drivers/exosite_hal_lwip.c | 1081 +++++++++++++++++++++++ boards/ek-tm4c1294xl/drivers/exosite_hal_lwip.h | 138 +++ boards/ek-tm4c1294xl/drivers/http.c | 587 ++++++++++++ boards/ek-tm4c1294xl/drivers/http.h | 75 ++ boards/ek-tm4c1294xl/drivers/pinout.c | 301 +++++++ boards/ek-tm4c1294xl/drivers/pinout.h | 80 ++ 10 files changed, 3693 insertions(+) create mode 100644 boards/ek-tm4c1294xl/drivers/buttons.c create mode 100644 boards/ek-tm4c1294xl/drivers/buttons.h create mode 100644 boards/ek-tm4c1294xl/drivers/eth_client_lwip.c create mode 100644 boards/ek-tm4c1294xl/drivers/eth_client_lwip.h create mode 100644 boards/ek-tm4c1294xl/drivers/exosite_hal_lwip.c create mode 100644 boards/ek-tm4c1294xl/drivers/exosite_hal_lwip.h create mode 100644 boards/ek-tm4c1294xl/drivers/http.c create mode 100644 boards/ek-tm4c1294xl/drivers/http.h create mode 100644 boards/ek-tm4c1294xl/drivers/pinout.c create mode 100644 boards/ek-tm4c1294xl/drivers/pinout.h (limited to 'boards/ek-tm4c1294xl/drivers') diff --git a/boards/ek-tm4c1294xl/drivers/buttons.c b/boards/ek-tm4c1294xl/drivers/buttons.c new file mode 100644 index 0000000..5d243a0 --- /dev/null +++ b/boards/ek-tm4c1294xl/drivers/buttons.c @@ -0,0 +1,187 @@ +//***************************************************************************** +// +// buttons.c - Evaluation board driver for push buttons. +// +// Copyright (c) 2013-2014 Texas Instruments Incorporated. All rights reserved. +// Software License Agreement +// +// Texas Instruments (TI) is supplying this software for use solely and +// exclusively on TI's microcontroller products. The software is owned by +// TI and/or its suppliers, and is protected under applicable copyright +// laws. You may not combine this software with "viral" open-source +// software in order to form a larger program. +// +// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. +// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT +// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY +// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +// DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 2.1.0.12573 of the EK-TM4C1294XL Firmware Package. +// +//***************************************************************************** + +#include +#include +#include "inc/hw_types.h" +#include "inc/hw_memmap.h" +#include "inc/hw_gpio.h" +#include "driverlib/sysctl.h" +#include "driverlib/rom.h" +#include "driverlib/rom_map.h" +#include "driverlib/pin_map.h" +#include "driverlib/gpio.h" +#include "drivers/buttons.h" + +//***************************************************************************** +// +//! \addtogroup buttons_api +//! @{ +// +//***************************************************************************** + +//***************************************************************************** +// +// Holds the current, debounced state of each button. A 0 in a bit indicates +// that that button is currently pressed, otherwise it is released. +// We assume that we start with all the buttons released (though if one is +// pressed when the application starts, this will be detected). +// +//***************************************************************************** +static uint8_t g_ui8ButtonStates = ALL_BUTTONS; + +//***************************************************************************** +// +//! Polls the current state of the buttons and determines which have changed. +//! +//! \param pui8Delta points to a character that will be written to indicate +//! which button states changed since the last time this function was called. +//! This value is derived from the debounced state of the buttons. +//! \param pui8RawState points to a location where the raw button state will +//! be stored. +//! +//! This function should be called periodically by the application to poll the +//! pushbuttons. It determines both the current debounced state of the buttons +//! and also which buttons have changed state since the last time the function +//! was called. +//! +//! In order for button debouncing to work properly, this function should be +//! caled at a regular interval, even if the state of the buttons is not needed +//! that often. +//! +//! If button debouncing is not required, the the caller can pass a pointer +//! for the \e pui8RawState parameter in order to get the raw state of the +//! buttons. The value returned in \e pui8RawState will be a bit mask where +//! a 1 indicates the buttons is pressed. +//! +//! \return Returns the current debounced state of the buttons where a 1 in the +//! button ID's position indicates that the button is pressed and a 0 +//! indicates that it is released. +// +//***************************************************************************** +uint8_t +ButtonsPoll(uint8_t *pui8Delta, uint8_t *pui8RawState) +{ + uint32_t ui32Delta; + uint32_t ui32Data; + static uint8_t ui8SwitchClockA = 0; + static uint8_t ui8SwitchClockB = 0; + + // + // Read the raw state of the push buttons. Save the raw state + // (inverting the bit sense) if the caller supplied storage for the + // raw value. + // + ui32Data = (ROM_GPIOPinRead(BUTTONS_GPIO_BASE, ALL_BUTTONS)); + if(pui8RawState) + { + *pui8RawState = (uint8_t)~ui32Data; + } + + // + // Determine the switches that are at a different state than the debounced + // state. + // + ui32Delta = ui32Data ^ g_ui8ButtonStates; + + // + // Increment the clocks by one. + // + ui8SwitchClockA ^= ui8SwitchClockB; + ui8SwitchClockB = ~ui8SwitchClockB; + + // + // Reset the clocks corresponding to switches that have not changed state. + // + ui8SwitchClockA &= ui32Delta; + ui8SwitchClockB &= ui32Delta; + + // + // Get the new debounced switch state. + // + g_ui8ButtonStates &= ui8SwitchClockA | ui8SwitchClockB; + g_ui8ButtonStates |= (~(ui8SwitchClockA | ui8SwitchClockB)) & ui32Data; + + // + // Determine the switches that just changed debounced state. + // + ui32Delta ^= (ui8SwitchClockA | ui8SwitchClockB); + + // + // Store the bit mask for the buttons that have changed for return to + // caller. + // + if(pui8Delta) + { + *pui8Delta = (uint8_t)ui32Delta; + } + + // + // Return the debounced buttons states to the caller. Invert the bit + // sense so that a '1' indicates the button is pressed, which is a + // sensible way to interpret the return value. + // + return(~g_ui8ButtonStates); +} + +//***************************************************************************** +// +//! Initializes the GPIO pins used by the board pushbuttons. +//! +//! This function must be called during application initialization to +//! configure the GPIO pins to which the pushbuttons are attached. It enables +//! the port used by the buttons and configures each button GPIO as an input +//! with a weak pull-up. +//! +//! \return None. +// +//***************************************************************************** +void +ButtonsInit(void) +{ + // + // Enable the GPIO port to which the pushbuttons are connected. + // + ROM_SysCtlPeripheralEnable(BUTTONS_GPIO_PERIPH); + + // + // Set each of the button GPIO pins as an input with a pull-up. + // + ROM_GPIODirModeSet(BUTTONS_GPIO_BASE, ALL_BUTTONS, GPIO_DIR_MODE_IN); + MAP_GPIOPadConfigSet(BUTTONS_GPIO_BASE, ALL_BUTTONS, + GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU); + + // + // Initialize the debounced button state with the current state read from + // the GPIO bank. + // + g_ui8ButtonStates = ROM_GPIOPinRead(BUTTONS_GPIO_BASE, ALL_BUTTONS); +} + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/boards/ek-tm4c1294xl/drivers/buttons.h b/boards/ek-tm4c1294xl/drivers/buttons.h new file mode 100644 index 0000000..38d01e1 --- /dev/null +++ b/boards/ek-tm4c1294xl/drivers/buttons.h @@ -0,0 +1,110 @@ +//***************************************************************************** +// +// buttons.h - Prototypes for the evaluation board buttons driver. +// +// Copyright (c) 2013-2014 Texas Instruments Incorporated. All rights reserved. +// Software License Agreement +// +// Texas Instruments (TI) is supplying this software for use solely and +// exclusively on TI's microcontroller products. The software is owned by +// TI and/or its suppliers, and is protected under applicable copyright +// laws. You may not combine this software with "viral" open-source +// software in order to form a larger program. +// +// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. +// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT +// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY +// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +// DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 2.1.0.12573 of the EK-TM4C1294XL Firmware Package. +// +//***************************************************************************** + +#ifndef __BUTTONS_H__ +#define __BUTTONS_H__ + +//***************************************************************************** +// +// If building with a C++ compiler, make all of the definitions in this header +// have a C binding. +// +//***************************************************************************** +#ifdef __cplusplus +extern "C" +{ +#endif + +//***************************************************************************** +// +// Defines for the hardware resources used by the pushbuttons. +// +// The switches are on the following ports/pins: +// +// PJ0 - Left Button +// PJ1 - Right Button +// +// The switches tie the GPIO to ground, so the GPIOs need to be configured +// with pull-ups, and a value of 0 means the switch is pressed. +// +//***************************************************************************** +#define BUTTONS_GPIO_PERIPH SYSCTL_PERIPH_GPIOJ +#define BUTTONS_GPIO_BASE GPIO_PORTJ_BASE + +#define NUM_BUTTONS 2 +#define USR_SW1 GPIO_PIN_0 +#define USR_SW2 GPIO_PIN_1 +#define LEFT_BUTTON USR_SW1 +#define RIGHT_BUTTON USR_SW2 + + +#define ALL_BUTTONS (USR_SW1 | USR_SW2) + +//***************************************************************************** +// +// Useful macros for detecting button events. +// +//***************************************************************************** +#define BUTTON_PRESSED(button, buttons, changed) \ + (((button) & (changed)) && ((button) & (buttons))) + +#define BUTTON_RELEASED(button, buttons, changed) \ + (((button) & (changed)) && !((button) & (buttons))) + +//***************************************************************************** +// +// If building with a C++ compiler, make all of the definitions in this header +// have a C binding. +// +//***************************************************************************** +#ifdef __cplusplus +extern "C" +{ +#endif + +//***************************************************************************** +// +// Functions exported from buttons.c +// +//***************************************************************************** +extern void ButtonsInit(void); +extern uint8_t ButtonsPoll(uint8_t *pui8Delta, + uint8_t *pui8Raw); + +//***************************************************************************** +// +// Mark the end of the C bindings section for C++ compilers. +// +//***************************************************************************** +#ifdef __cplusplus +} +#endif + +//***************************************************************************** +// +// Prototypes for the globals exported by this driver. +// +//***************************************************************************** + +#endif // __BUTTONS_H__ diff --git a/boards/ek-tm4c1294xl/drivers/eth_client_lwip.c b/boards/ek-tm4c1294xl/drivers/eth_client_lwip.c new file mode 100644 index 0000000..ff4f1e3 --- /dev/null +++ b/boards/ek-tm4c1294xl/drivers/eth_client_lwip.c @@ -0,0 +1,1046 @@ +//***************************************************************************** +// +// eth_client.c - This is the portion of the ethernet client. +// +// Copyright (c) 2013-2014 Texas Instruments Incorporated. All rights reserved. +// Software License Agreement +// +// Texas Instruments (TI) is supplying this software for use solely and +// exclusively on TI's microcontroller products. The software is owned by +// TI and/or its suppliers, and is protected under applicable copyright +// laws. You may not combine this software with "viral" open-source +// software in order to form a larger program. +// +// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. +// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT +// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY +// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +// DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 2.1.0.12573 of the EK-TM4C1294XL Firmware Package. +// +//***************************************************************************** +#include +#include +#include "inc/hw_memmap.h" +#include "inc/hw_types.h" +#include "driverlib/flash.h" +#include "driverlib/gpio.h" +#include "driverlib/interrupt.h" +#include "driverlib/sysctl.h" +#include "driverlib/systick.h" +#include "eth_client_lwip.h" +#include "utils/lwiplib.h" +#include "lwip/dns.h" +#include "lwipopts.h" + +#if RTOS_FREERTOS +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "semphr.h" +#endif + + +//***************************************************************************** +// +// Flag indexes for g_sEnet.ui32Flags +// +//***************************************************************************** +#define FLAG_TIMER_DHCP_EN 0 +#define FLAG_TIMER_DNS_EN 1 +#define FLAG_TIMER_TCP_EN 2 +#define FLAG_DHCP_STARTED 3 +#define FLAG_DNS_ADDRFOUND 4 + +//***************************************************************************** +// +// The current state of the Ethernet connection. +// +//***************************************************************************** +struct +{ + volatile uint32_t ui32Flags; + + // + // Array to hold the MAC addresses. + // + uint8_t pui8MACAddr[8]; + + // + // Global define of the TCP structure used. + // + struct tcp_pcb *psTCP; + + // + // Global IP structure to hold a copy of the IP address. + // + struct ip_addr sIPAddr; + + // + // Global IP structure to hold a copy of the DNS resolved address. + // + struct ip_addr sResolvedIP; + + // + // The saved proxy name as a text string. + // + const char *pcProxyName; + + // + // The port number for the proxy server. + // + uint16_t ui16ProxyPort; + + // + // The saved host name as a text string. + // + const char *pcHostName; + + // + // The port number on the host. + // + uint16_t ui16HostPort; + + // + // The number of bytes to be sent. + // + uint32_t ui32SendSize; + + // + // The index into the send buffer. + // + uint32_t ui32SendIndex; + + // + // Event handler. + // + tEventFunction pfnEvent; + + // + // States. + // + volatile enum + { + iEthNoConnection, + iEthDHCPWait, + iEthDNSWait, + iEthTCPOpen, + iEthTCPWait, + iEthSend, + iEthIdle + } eState; +} +g_sEnet; + +//***************************************************************************** +// +// Maximum size of a request. +// +//***************************************************************************** +#define MAX_REQUEST 256 + +//***************************************************************************** +// +// Send buffer config. +// +//***************************************************************************** +uint8_t g_pui8SendBuff[SEND_BUFFER_SIZE]; + +//***************************************************************************** +// +// Reset the state to a non-connected state to restart dhcp and dns. +// +//***************************************************************************** +static void +ResetConnection(void) +{ + // + // Nothing to do if already not connected. + // + if(g_sEnet.eState != iEthNoConnection) + { + // + // No longer have a link. + // + g_sEnet.eState = iEthNoConnection; + + // + // Reset the flags to just enable the lwIP timer. + // + g_sEnet.ui32Flags = (1 << FLAG_TIMER_DHCP_EN); + } + + // + // Deallocate the TCP structure if it was already allocated. + // + if(g_sEnet.psTCP) + { + // + // Clear out all of the TCP callbacks. + // + tcp_sent(g_sEnet.psTCP, NULL); + tcp_recv(g_sEnet.psTCP, NULL); + tcp_err(g_sEnet.psTCP, NULL); + + // + // Close the TCP connection. + // + tcp_close(g_sEnet.psTCP); + g_sEnet.psTCP = 0; + } +} + +//***************************************************************************** +// +// Handler function when the DNS server gets a response or times out. +// +// \param pcName is DNS server name. +// \param psIPAddr is the DNS server's IP address. +// \param vpArg is the configurable argument. +// +// This function is called when the DNS server resolves an IP or times out. +// If the DNS server returns an IP structure that is not NULL, add the IP to +// to the g_sEnet.sResolvedIP IP structure. +// +// \return None. +// +//***************************************************************************** +static void +DNSServerFound(const char *pcName, struct ip_addr *psIPAddr, void *vpArg) +{ + // + // Check if a valid DNS server address was found. + // + if((psIPAddr) && (psIPAddr->addr)) + { + // + // Copy the returned IP address into a global IP address. + // + g_sEnet.sResolvedIP = *psIPAddr; + + // + // Tell the main program that a DNS address was found. + // + HWREGBITW(&g_sEnet.ui32Flags, FLAG_DNS_ADDRFOUND) = 1; + } + else + { + // + // Disable the DNS timer. + // + HWREGBITW(&g_sEnet.ui32Flags, FLAG_TIMER_DNS_EN) = 0; + } +} + +//***************************************************************************** +// +//! Handles lwIP TCP/IP errors. +//! +//! \param vPArg is the state data for this connection. +//! \param iErr is the error that was detected. +//! +//! This function is called when the lwIP TCP/IP stack has detected an error. +//! The connection is no longer valid. +//! +//! \return None. +// +//***************************************************************************** +void +TCPError(void *vPArg, err_t iErr) +{ + // + // Signal event handler that there was an error. + // + g_sEnet.pfnEvent(ETH_CLIENT_EVENT_ERROR, 0, (uint32_t)iErr); +} + +//***************************************************************************** +// +//! Finalizes the TCP connection in client mode. +//! +//! \param pvArg is the state data for this connection. +//! \param psPcb is the pointer to the TCP control structure. +//! \param psBuf +//! \param iErr is not used in this implementation. +//! +//! This function is called when the lwIP TCP/IP stack has completed a TCP +//! connection. +//! +//! \return This function will return an lwIP defined error code. +// +//***************************************************************************** +err_t +TCPReceived(void *pvArg, struct tcp_pcb *psPcb, struct pbuf *psBuf, err_t iErr) +{ + struct pbuf *psBufCur; + + // + // Signal event handler that data is available. + // + g_sEnet.pfnEvent(ETH_CLIENT_EVENT_RECEIVE, (void *)psBuf->payload, + (uint32_t)psBuf->len); + + // + // Indicate that you have received and processed this set of TCP data. + // + tcp_recved(psPcb, psBuf->len); + + // + // Initialize the linked list pointer to parse. + // + psBufCur = psBuf; + + // + // Free the buffers used since they have been processed. + // + while(psBufCur->len != 0) + { + // + // Indicate that you have received and processed this set of TCP data. + // + tcp_recved(psPcb, psBufCur->len); + + // + // Go to the next buffer. + // + psBufCur = psBufCur->next; + + // + // Terminate if there are no more buffers. + // + if(psBufCur == 0) + { + break; + } + } + + // + // Free the memory space allocated for this receive. + // + pbuf_free(psBuf); + + // + // Return. + // + return(ERR_OK); +} + +//***************************************************************************** +// +//! Handles acknowledgment of data transmitted via Ethernet. +//! +//! \param pvArg is the state data for this connection. +//! \param psPcb is the pointer to the TCP control structure. +//! \param ui16Len is the length of the data transmitted. +//! +//! This function is called when the lwIP TCP/IP stack has received an +//! acknowledgment for data that has been transmitted. +//! +//! \return This function will return an lwIP defined error code. +// +//***************************************************************************** +err_t +TCPSent(void *pvArg, struct tcp_pcb *psPcb, u16_t ui16Len) +{ + // + // Signal the event handler that data was sent. + // + g_sEnet.pfnEvent(ETH_CLIENT_EVENT_SEND, 0, (uint32_t)ui16Len); + + // + // Return OK. + // + return (ERR_OK); +} + +//***************************************************************************** +// +//! Finalizes the TCP connection in client mode. +//! +//! \param pvArg is the state data for this connection. +//! \param psPcb is the pointer to the TCP control structure. +//! \param iErr is not used in this implementation. +//! +//! This function is called when the lwIP TCP/IP stack has completed a TCP +//! connection. +//! +//! \return This function will return an lwIP defined error code. +// +//***************************************************************************** +err_t +TCPConnected(void *pvArg, struct tcp_pcb *psPcb, err_t iErr) +{ + // + // Check if there was a TCP error. + // + if(iErr != ERR_OK) + { + // + // Clear out all of the TCP callbacks. + // + tcp_sent(psPcb, NULL); + tcp_recv(psPcb, NULL); + tcp_err(psPcb, NULL); + + // + // Close the TCP connection. + // + tcp_close(psPcb); + + if(psPcb == g_sEnet.psTCP) + { + g_sEnet.psTCP = 0; + } + + // + // And return. + // + return(ERR_CONN); + } + + // + // Setup the TCP receive function. + // + tcp_recv(psPcb, TCPReceived); + + // + // Setup the TCP error function. + // + tcp_err(psPcb, TCPError); + + // + // Setup the TCP sent callback function. + // + tcp_sent(psPcb, TCPSent); + + // + // Signal event handler that connection is established. + // + g_sEnet.pfnEvent(ETH_CLIENT_EVENT_CONNECT, 0, 0); + + // + // Return a success code. + // + return(ERR_OK); +} + +//***************************************************************************** +// +//! TCP connect +//! +//! This function attempts to connect to a TCP endpoint. +//! +//! \return None. +// +//***************************************************************************** +int32_t +EthClientTCPConnect(void) +{ + err_t eTCPReturnCode; + + // + // Enable the TCP timer function calls. + // + HWREGBITW(&g_sEnet.ui32Flags, FLAG_TIMER_TCP_EN) = 1; + + if(g_sEnet.psTCP) + { + // + // Initially clear out all of the TCP callbacks. + // + tcp_sent(g_sEnet.psTCP, NULL); + tcp_recv(g_sEnet.psTCP, NULL); + tcp_err(g_sEnet.psTCP, NULL); + + // + // Make sure there is no lingering TCP connection. + // + tcp_close(g_sEnet.psTCP); + } + + // + // Create a new TCP socket. + // + g_sEnet.psTCP = tcp_new(); + + // + // Check if you need to go through a proxy. + // + if(g_sEnet.pcProxyName != 0) + { + // + // Attempt to connect through the proxy server. + // + eTCPReturnCode = tcp_connect(g_sEnet.psTCP, &g_sEnet.sResolvedIP, + g_sEnet.ui16ProxyPort, TCPConnected); + } + else + { + // + // Attempt to connect to the server directly. + // + eTCPReturnCode = tcp_connect(g_sEnet.psTCP, &g_sEnet.sResolvedIP, + g_sEnet.ui16HostPort, TCPConnected); + } + + if((eTCPReturnCode == ERR_OK) || (eTCPReturnCode == ERR_INPROGRESS)) + { + return(0); + } + else + { + return(1); + } +} + +//***************************************************************************** +// +//! TCP discconnect +//! +//! This function attempts to disconnect a TCP endpoint. +//! +//! \return None. +// +//***************************************************************************** +void +EthClientTCPDisconnect(void) +{ + g_sEnet.eState = iEthIdle; + + // + // Reset connection. + // + ResetConnection(); + + // + // Disable the TCP timer function calls. + // + HWREGBITW(&g_sEnet.ui32Flags, FLAG_TIMER_TCP_EN) = 0; +} + +//***************************************************************************** +// +//! Send a request to the server +//! +//! \param pi8Request request to be sent +//! \param ui32Size length of the request to be sent. This is usually the size +//! of the request minus the termination character. +//! +//! This function will send the request to the connected server +//! +//! \return the lwIP error code. +// +//***************************************************************************** +int32_t +EthClientSend(int8_t *pi8Request, uint32_t ui32Size) +{ + uint32_t ui32Index, ui32SendSize, ui32CurrentState; + + // + // Save off the current number of bytes used in the buffer and the current + // state. + // + ui32SendSize = g_sEnet.ui32SendSize; + ui32CurrentState = g_sEnet.eState; + + // + // Check that we have room in the buffer. + // + if (ui32SendSize + ui32Size <= SEND_BUFFER_SIZE) + { + // + // Fill the send buffer. + // + for (ui32Index = 0; ui32Index < ui32Size; ui32Index++) + { + g_pui8SendBuff[ui32SendSize + ui32Index] = + pi8Request[ui32Index]; + } + + // + // Increment the number of bytes we have to send. + // + g_sEnet.ui32SendSize += ui32Size; + + // + // Check if we have already sent some data in the buffer. + // This is determined by checking the number of bytes left to be sent + // and the current state. If we have then we need to update the index + // into the buffer. + // + if (g_sEnet.ui32SendSize != ui32SendSize && + g_sEnet.eState != ui32CurrentState && + ui32CurrentState == iEthSend) + { + g_sEnet.ui32SendIndex = ui32SendSize; + } + else + { + g_sEnet.ui32SendIndex = 0; + } + + // + // Set the state to Send and send on the next Tick. + // + g_sEnet.eState = iEthSend; + + return(ERR_OK); + } + else + { + // + // Tell the app we dont have enough memory. + // + return(ERR_MEM); + } +} + +//***************************************************************************** +// +//! DHCP connect +//! +//! This function obtains the MAC address from the User registers, starts the +//! DHCP timer and blocks until an IP address is obtained. +//! +//! \return None. +// +//***************************************************************************** +err_t +EthClientDHCPConnect(void) +{ + // + // Check if the DHCP has already been started. + // + if(HWREGBITW(&g_sEnet.ui32Flags, FLAG_DHCP_STARTED) == 0) + { + // + // Set the DCHP started flag. + // + HWREGBITW(&g_sEnet.ui32Flags, FLAG_DHCP_STARTED) = 1; + } + else + { + // + // If DHCP has already been started, we need to clear the IPs and + // switch to static. This forces the LWIP to get new IP address + // and retry the DHCP connection. + // + lwIPNetworkConfigChange(0, 0, 0, IPADDR_USE_STATIC); + + // + // Restart the DHCP connection. + // + lwIPNetworkConfigChange(0, 0, 0, IPADDR_USE_DHCP); + } + + return ERR_OK; +} + +//***************************************************************************** +// +//! Handler function when the DNS server gets a response or times out. +//! +//! This function is called when the DNS server resolves an IP or times out. +//! If the DNS server returns an IP structure that is not NULL, add the IP to +//! to the g_sEnet.sResolvedIP IP structure. +//! +//! \return None. +// +//***************************************************************************** +int32_t +EthClientDNSResolve(void) +{ + err_t iRet; + + if(HWREGBITW(&g_sEnet.ui32Flags, FLAG_TIMER_DNS_EN)) + { + return(ERR_INPROGRESS); + } + + // + // Set DNS config timer to true. + // + HWREGBITW(&g_sEnet.ui32Flags, FLAG_TIMER_DNS_EN) = 1; + + // + // Initialize the host name IP address found flag to false. + // + HWREGBITW(&g_sEnet.ui32Flags, FLAG_DNS_ADDRFOUND) = 0; + + // + // Set state. + // + g_sEnet.eState = iEthDNSWait; + + // + // Resolve host name. + // + if(g_sEnet.pcProxyName != 0) + { + iRet = dns_gethostbyname(g_sEnet.pcProxyName, &g_sEnet.sResolvedIP, + DNSServerFound, 0); + } + else + { + iRet = dns_gethostbyname(g_sEnet.pcHostName, &g_sEnet.sResolvedIP, + DNSServerFound, 0); + } + + // + // If ERR_OK is returned, the local DNS table resolved the host name. If + // ERR_INPROGRESS is returned, the DNS request has been queued and will be + // sent to the DNS server. + // + if(iRet == ERR_OK) + { + // + // Stop calling the DNS timer function. + // + HWREGBITW(&g_sEnet.ui32Flags, FLAG_TIMER_DNS_EN) = 0; + } + + // + // Return host name not found. + // + return(iRet); +} + +//***************************************************************************** +// +// Returns the weather server IP address for this interface. +// +// This function will read and return the server IP address that is currently +// in use. This could be the proxy server if the Internet proxy is enabled. +// +// \return Returns the weather server IP address for this interface. +// +//***************************************************************************** +uint32_t +EthClientServerAddrGet(void) +{ + // + // Return IP. + // + return((uint32_t)g_sEnet.sResolvedIP.addr); +} + +//***************************************************************************** +// +//! Returns the IP address for this interface. +//! +//! This function will read and return the currently assigned IP address for +//! the Tiva Ethernet interface. +//! +//! \return Returns the assigned IP address for this interface. +// +//***************************************************************************** +uint32_t +EthClientAddrGet(void) +{ + // + // Return IP. + // + return(lwIPLocalIPAddrGet()); +} + +//***************************************************************************** +// +// Returns the MAC address for the Tiva Ethernet controller. +// +// \param pui8MACAddr is the 6 byte MAC address assigned to the Ethernet +// controller. +// +// This function will read and return the MAC address for the Ethernet +// controller. +// +// \return Returns the weather server IP address for this interface. +// +//***************************************************************************** +void +EthClientMACAddrGet(uint8_t *pui8MACAddr) +{ + int32_t iIdx; + + for(iIdx = 0; iIdx < 6; iIdx++) + { + pui8MACAddr[iIdx] = g_sEnet.pui8MACAddr[iIdx]; + } +} + +//***************************************************************************** +// +// Set the proxy string for the Ethernet connection. +// +// \param pi8ProxyName is the string used as the proxy server name. +// +// This function sets the current proxy used by the Ethernet connection. The +// \e pi8ProxyName value can be 0 to indicate that no proxy is in use or it can +// be a pointer to a string that holds the name of the proxy server to use. +// The content of the pointer passed to \e pi8ProxyName should not be changed +// after this call as this function only stores the pointer and does not copy +// the data from this pointer. +// +// \return None. +// +//***************************************************************************** +void +EthClientProxySet(const char *pcProxyName, uint16_t ui16Port) +{ + // + // Save the new proxy string. + // + g_sEnet.pcProxyName = pcProxyName; + g_sEnet.ui16ProxyPort = ui16Port; + + // + // Reset the connection on any change to the proxy. + // + ResetConnection(); +} + +void +EthClientHostSet(const char *pcHostName, uint16_t ui16Port) +{ + // + // Save the new host setting. + // + g_sEnet.pcHostName = pcHostName; + g_sEnet.ui16HostPort = ui16Port; + + // + // Reset the connection on any change to the host. + // + ResetConnection(); +} + +//***************************************************************************** +// +// Initialize the Ethernet client +// +// This function initializes all the Ethernet components to not configured. +// This tells the SysTick interrupt which timer modules to call. +// +// \return None. +// +//***************************************************************************** +void +EthClientInit(uint32_t ui32SysClock, tEventFunction pfnEvent) +{ + uint32_t ui32User0, ui32User1; + + // + // Initialize all the Ethernet components to not configured. This tells + // the SysTick interrupt which timer modules to call. + // + HWREGBITW(&g_sEnet.ui32Flags, FLAG_TIMER_DHCP_EN) = 0; + HWREGBITW(&g_sEnet.ui32Flags, FLAG_TIMER_DNS_EN) = 0; + HWREGBITW(&g_sEnet.ui32Flags, FLAG_TIMER_TCP_EN) = 0; + + g_sEnet.eState = iEthNoConnection; + g_sEnet.pfnEvent = pfnEvent; + g_sEnet.pcProxyName = 0; + + // + // Convert the 24/24 split MAC address from NV ram into a 32/16 split MAC + // address needed to program the hardware registers, then program the MAC + // address into the Ethernet Controller registers. + // + FlashUserGet(&ui32User0, &ui32User1); + + g_sEnet.pui8MACAddr[0] = ((ui32User0 >> 0) & 0xff); + g_sEnet.pui8MACAddr[1] = ((ui32User0 >> 8) & 0xff); + g_sEnet.pui8MACAddr[2] = ((ui32User0 >> 16) & 0xff); + g_sEnet.pui8MACAddr[3] = ((ui32User1 >> 0) & 0xff); + g_sEnet.pui8MACAddr[4] = ((ui32User1 >> 8) & 0xff); + g_sEnet.pui8MACAddr[5] = ((ui32User1 >> 16) & 0xff); + + // + // Initialize lwIP with the system clock, MAC and use DHCP. + // + lwIPInit(ui32SysClock, g_sEnet.pui8MACAddr, 0, 0, 0, IPADDR_USE_DHCP); + + // + // Start lwIP tick interrupt. + // + HWREGBITW(&g_sEnet.ui32Flags, FLAG_TIMER_DHCP_EN) = 1; +} + +//***************************************************************************** +// +// Periodic Tick for the Ethernet client +// +// This function is the needed periodic tick for the Ethernet client. It needs +// to be called periodically through the use of a timer or systick. +// +// \return None. +// +//***************************************************************************** +#if NO_SYS +void +EthClientTick(uint32_t ui32TickMS) +{ + if(HWREGBITW(&g_sEnet.ui32Flags, FLAG_TIMER_DHCP_EN)) + { + lwIPTimer(ui32TickMS); + } +} +#endif // #if NO_SYS +//***************************************************************************** +// +// Required by lwIP library to support any host-related timer functions. +// +//***************************************************************************** + +void +lwIPHostTimerHandler(void) +{ + uint32_t ui32IPAddr; + err_t eError; +#if NO_SYS + if(HWREGBITW(&g_sEnet.ui32Flags, FLAG_TIMER_DNS_EN)) + { + dns_tmr(); + } + + if(HWREGBITW(&g_sEnet.ui32Flags, FLAG_TIMER_TCP_EN)) + { + tcp_tmr(); + } +#endif // #if NO_SYS + + // + // Check if we need to send. + // + if(g_sEnet.eState == iEthSend) + { + // + // Queue the send. + // + eError = tcp_write(g_sEnet.psTCP, + g_pui8SendBuff + g_sEnet.ui32SendIndex, + g_sEnet.ui32SendSize, TCP_WRITE_FLAG_COPY); + + // + // Write data for sending (but does not send it immediately). + // + if(eError == ERR_OK) + { + // + // Find out what we can send and send it. + // + tcp_output(g_sEnet.psTCP); + + // + // No more data to send. + // + g_sEnet.ui32SendSize = 0; + + } + + // + // Set state to Idle + // + g_sEnet.eState = iEthIdle; + } + + // + // Check for loss of link. + // + else if((g_sEnet.eState != iEthNoConnection) && + (lwIPLocalIPAddrGet() == 0xffffffff)) + { + // + // Reset the connection due to a loss of link. + // + ResetConnection(); + + // + // Signal a disconnect event. + // + g_sEnet.pfnEvent(ETH_CLIENT_EVENT_DISCONNECT, 0, 0); + } + else if(g_sEnet.eState == iEthNoConnection) + { + // + // Once link is detected start DHCP. + // + if(lwIPLocalIPAddrGet() != 0xffffffff) + { + EthClientDHCPConnect(); + g_sEnet.eState = iEthDHCPWait; + } + } + else if(g_sEnet.eState == iEthDHCPWait) + { + // + // Get IP address. + // + ui32IPAddr = lwIPLocalIPAddrGet(); + + // + // If IP Address has not yet been assigned, update the display + // accordingly. + // + if((ui32IPAddr != 0xffffffff) && (ui32IPAddr != 0)) + { + // + // Update the DHCP IP address. + // + g_sEnet.sIPAddr.addr = ui32IPAddr; + g_sEnet.eState = iEthIdle; + + // + // Stop DHCP timer since an address has been provided. + // + HWREGBITW(&g_sEnet.ui32Flags, FLAG_DHCP_STARTED) = 0; + + // + // Signal a connect event. + // + g_sEnet.pfnEvent(ETH_CLIENT_EVENT_DHCP, &g_sEnet.sIPAddr.addr, 4); + } + } + else if(g_sEnet.eState == iEthDNSWait) + { + // + // Check to see if the DNS timer has been turned off, which signals + // that the DNS lookup has failed. + // + if(HWREGBITW(&g_sEnet.ui32Flags, FLAG_TIMER_DNS_EN) == 0) + { + // + // Go back to idle. + // + g_sEnet.eState = iEthIdle; + + // + // Signal failure. + // + g_sEnet.pfnEvent(ETH_CLIENT_EVENT_DNS, 0, 0); + } + + // + // Check if the host name was resolved. + // + if(HWREGBITW(&g_sEnet.ui32Flags, FLAG_DNS_ADDRFOUND)) + { + // + // Stop calling the DNS timer function. + // + HWREGBITW(&g_sEnet.ui32Flags, FLAG_TIMER_DNS_EN) = 0; + + // + // Go back to idle. + // + g_sEnet.eState = iEthIdle; + + // + // Notify the main routine of the new Ethernet connection. + // + g_sEnet.pfnEvent(ETH_CLIENT_EVENT_DNS, &g_sEnet.sResolvedIP.addr, + 4); + } + } +} diff --git a/boards/ek-tm4c1294xl/drivers/eth_client_lwip.h b/boards/ek-tm4c1294xl/drivers/eth_client_lwip.h new file mode 100644 index 0000000..7894f1b --- /dev/null +++ b/boards/ek-tm4c1294xl/drivers/eth_client_lwip.h @@ -0,0 +1,88 @@ +//***************************************************************************** +// +// eth_client.h - Prototypes for the driver for the eth_client. +// +// Copyright (c) 2013-2014 Texas Instruments Incorporated. All rights reserved. +// Software License Agreement +// +// Texas Instruments (TI) is supplying this software for use solely and +// exclusively on TI's microcontroller products. The software is owned by +// TI and/or its suppliers, and is protected under applicable copyright +// laws. You may not combine this software with "viral" open-source +// software in order to form a larger program. +// +// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. +// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT +// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY +// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +// DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 2.1.0.12573 of the EK-TM4C1294XL Firmware Package. +// +//***************************************************************************** +#ifndef ETH_CLIENT_H_ +#define ETH_CLIENT_H_ + +//***************************************************************************** +// +// If building with a C++ compiler, make all of the definitions in this header +// have a C binding. +// +//***************************************************************************** +#ifdef __cplusplus +extern "C" +{ +#endif + +//***************************************************************************** +// +// Maximum size for the circular receive buffer. +// +//***************************************************************************** +#define SEND_BUFFER_SIZE 4096 + +//***************************************************************************** +// +// Events passed back to the application. +// +//***************************************************************************** +#define ETH_CLIENT_EVENT_DHCP 0x00000001 +#define ETH_CLIENT_EVENT_DISCONNECT 0x00000002 +#define ETH_CLIENT_EVENT_DNS 0x00000003 +#define ETH_CLIENT_EVENT_CONNECT 0x00000004 +#define ETH_CLIENT_EVENT_RECEIVE 0x00000005 +#define ETH_CLIENT_EVENT_SEND 0x00000006 +#define ETH_CLIENT_EVENT_ERROR 0x00000007 + +//***************************************************************************** +// +// The type definition for event functions. +// +//***************************************************************************** +typedef void (* tEventFunction)(uint32_t ui32Event, void* pvData, + uint32_t ui32Param); + +//***************************************************************************** +// +// Exported Ethernet function prototypes. +// +//***************************************************************************** +extern void EthClientInit(uint32_t ui32SysClock, tEventFunction pfnEvent); +extern void EthClientTick(uint32_t ui32TickMS); +extern uint32_t EthClientAddrGet(void); +extern void EthClientMACAddrGet(uint8_t *pui8Addr); + +extern int32_t EthClientTCPConnect(void); +extern void EthClientTCPDisconnect(void); +extern void EthClientProxySet(const char *pcProxyName, uint16_t ui16Port); +extern void EthClientHostSet(const char *pcHostName, uint16_t ui16Port); +extern int32_t EthClientDNSResolve(void); +extern uint32_t EthClientServerAddrGet(void); +extern int32_t EthClientSend(int8_t *pi8Request, uint32_t ui32Size); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/boards/ek-tm4c1294xl/drivers/exosite_hal_lwip.c b/boards/ek-tm4c1294xl/drivers/exosite_hal_lwip.c new file mode 100644 index 0000000..4cee9b8 --- /dev/null +++ b/boards/ek-tm4c1294xl/drivers/exosite_hal_lwip.c @@ -0,0 +1,1081 @@ +//***************************************************************************** +// +// exosite_hal_lwip.c - Abstraction Layer between exosite and eth_client_lwip. +// +// Copyright (c) 2013-2014 Texas Instruments Incorporated. All rights reserved. +// Software License Agreement +// +// Texas Instruments (TI) is supplying this software for use solely and +// exclusively on TI's microcontroller products. The software is owned by +// TI and/or its suppliers, and is protected under applicable copyright +// laws. You may not combine this software with "viral" open-source +// software in order to form a larger program. +// +// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. +// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT +// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY +// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +// DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 2.1.0.12573 of the EK-TM4C1294XL Firmware Package. +// +//***************************************************************************** + +#include +#include +#include +#include "inc/hw_types.h" +#include "inc/hw_ints.h" +#include "driverlib/eeprom.h" +#include "driverlib/interrupt.h" +#include "driverlib/sysctl.h" +#include "driverlib/systick.h" +#include "drivers/eth_client_lwip.h" +#include "drivers/http.h" +#include "utils/ringbuf.h" +#include "utils/ustdlib.h" +#include "exosite.h" +#include "exosite_hal_lwip.h" +#include "exosite_meta.h" +#include "lwipopts.h" + +#if RTOS_FREERTOS +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "semphr.h" +#endif + +//***************************************************************************** +// +// Defines for setting up the system clock. +// +//***************************************************************************** +#define SYSTICKHZ 100 +#define SYSTICKMS (1000 / SYSTICKHZ) +#define SYSTICKUS (1000000 / SYSTICKHZ) +#define SYSTICKNS (1000000000 / SYSTICKHZ) + +//***************************************************************************** +// +// Interrupt priority definitions. The top 3 bits of these values are +// significant with lower values indicating higher priority interrupts. +// +//***************************************************************************** +#define SYSTICK_INT_PRIORITY 0x80 +#define ETHERNET_INT_PRIORITY 0xC0 + +//***************************************************************************** +// +// Proxy info +// +//***************************************************************************** +bool g_bUseProxy = false; +char g_pcProxyAddress[50]; +uint16_t g_ui16ProxyPort = 0; + +//***************************************************************************** +// +// System clock speed. +// +//***************************************************************************** +extern uint32_t g_ui32SysClock; + +//***************************************************************************** +// +// Buffer used to hold proxy request message, and size of proxy request +// message. +// +//***************************************************************************** +char g_pcRequest[256] = {0}; +uint8_t g_ui8RequestSize = 0; + +//***************************************************************************** +// +// IP address. +// +//***************************************************************************** +char g_pcIPAddr[20]; + +//***************************************************************************** +// +// The current state of the exosite connection. +// +//***************************************************************************** +struct +{ + // + // Flags used by the application. + // + volatile uint32_t ui32Flags; + + // + // Client ID used to identify this client on the server/broker. + // + char *pcClientID; + + // + // Server/broker name. + // + char *pcServer; + + // + // Event handler for EXOSITE events. + // + tExositeEventHandler pfnEventHandler; + + // + // States. + // + volatile enum + { + EXOSITE_STATE_NOT_CONNECTED, + EXOSITE_STATE_CONNECTED_IDLE, + EXOSITE_STATE_PROXY_WAIT, + } eState; +} +g_sExosite; + +//***************************************************************************** +// +// EERPROM status. +// +//***************************************************************************** +uint32_t g_ui32EEStatus = 0; + +//***************************************************************************** +// +// Receive buffer config. +// +//***************************************************************************** +tRingBufObject g_sEnetBuffer; +uint8_t g_ui8Data[RECEIVE_BUFFER_SIZE]; + +//***************************************************************************** +// +// The interrupt handler for the SysTick interrupt. +// +//***************************************************************************** +void +SysTickIntHandler(void) +{ + // + // Call into Ethernet client layer. + // +#if NO_SYS + EthClientTick(10); +#endif + +} + +//***************************************************************************** +// +//! Enables the memory used to store any meta data. +//! +//! This function enables the EEPROM to be used to store any meta data. +//! +//! \return None. +// +//***************************************************************************** +void +exoHAL_EnableMeta(void) +{ + // + // Enable the EEPROM peripheral. + // + SysCtlPeripheralEnable(SYSCTL_PERIPH_EEPROM0); + + // + // Initialize the EEPROM + // + EEPROMInit(); + + // + // Indicate that the EEPROM is now initalized. + // + g_ui32EEStatus = EEPROM_INITALIZED; +} + +//***************************************************************************** +// +//! Function is a simple return to maintain compatibility with exostie.c/h. +//! +//! This function just returns. +//! +//! \return None. +// +//***************************************************************************** +void +exoHAL_EraseMeta(void) +{ + return; +} + +//***************************************************************************** +// +//! Write meta information to the nonvolatile memory (EEPROM). +//! +//! \param pucBuffer - string buffer containing info to write to meta. +//! \param iLength - size of string in bytes. +//! \param iOffset - offset from base of meta location to store the item. +//! +//! This function stores information to the NV meta structure. +//! +//! \return None. +// +//***************************************************************************** +void +exoHAL_WriteMetaItem(unsigned char * pucBuffer, int iLength, + int iOffset) +{ + // + // Make sure EEPROM is initialized. + // + if (g_ui32EEStatus == EEPROM_IDLE || g_ui32EEStatus == EEPROM_INITALIZED) + { + // + // Set EEPROM status to erasing. + // + g_ui32EEStatus = EEPROM_WRITING; + + // + // Write the info to the EEPROM. + // + EEPROMProgram((uint32_t *)pucBuffer, + (uint32_t)(EXOMETA_ADDR_OFFSET + iOffset), (uint32_t)iLength); + + // + // Set EEPROM status to IDLE. + // + g_ui32EEStatus = EEPROM_IDLE; + } + else + { + // + // Set EEPROM status to ERROR. + // + g_ui32EEStatus = EEPROM_ERROR; + } +} + +//***************************************************************************** +// +//! Read meta information from the nonvolatile memory (EEPROM). +//! +//! \param pucBuffer - buffer we can read meta info into. +//! \param iLength - size of the buffer (max 256 bytes). +//! \param iOffset - offset from base of meta to begin reading from. +//! +//! This function reads information from the NV meta structure. +//! +//! \return None. +// +//***************************************************************************** +void +exoHAL_ReadMetaItem(unsigned char * pucBuffer, int iLength, + int iOffset) +{ + // + // Make sure the EEPROM is initialized and idle. + // + if (g_ui32EEStatus == EEPROM_IDLE || g_ui32EEStatus == EEPROM_INITALIZED) + { + // + // Indicate that the EEPROM is now being read. + // + g_ui32EEStatus = EEPROM_READING; + + // + // Read the requested data. + // + EEPROMRead((uint32_t *)pucBuffer, + (uint32_t)(EXOMETA_ADDR_OFFSET + iOffset), (uint32_t)iLength); + + // + // Set EEPROM status to IDLE. + // + g_ui32EEStatus = EEPROM_IDLE; + } + else + { + // + // Set EEPROM status to ERROR. + // + g_ui32EEStatus = EEPROM_ERROR; + } +} + +//***************************************************************************** +// +// Reset the connection state. +// +//***************************************************************************** +void +exoHAL_ResetConnection(void) +{ + // + // Reset flags. + // + HWREGBITW(&g_sExosite.ui32Flags, FLAG_CONNECT_WAIT) = 0; + HWREGBITW(&g_sExosite.ui32Flags, FLAG_CONNECTED) = 0; + HWREGBITW(&g_sExosite.ui32Flags, FLAG_RECEIVED) = 0; + HWREGBITW(&g_sExosite.ui32Flags, FLAG_SENT) = 0; + HWREGBITW(&g_sExosite.ui32Flags, FLAG_BUSY) = 0; + HWREGBITW(&g_sExosite.ui32Flags, FLAG_PROXY_SET) = 0; + + // + // Empty the receive buffer. + // + RingBufFlush(&g_sEnetBuffer); + + // + // Reset state. + // + g_sExosite.eState = EXOSITE_STATE_NOT_CONNECTED; +} + +//***************************************************************************** +// +// Constructs proxy CONNECT request. +// +//***************************************************************************** +static void +exoHAL_ExositeConstructProxyRequest(void) +{ + char pcTemp[128]; + + // + // Construct the request. + // + usprintf(pcTemp, "%s:%d" ,EXOSITE_ADDRESS, EXOSITE_PORT); + HTTPMessageTypeSet(g_pcRequest, HTTP_MESSAGE_CONNECT, pcTemp); + + // + // Count the number of bytes in the transfer. + // + g_ui8RequestSize = strlen(g_pcRequest); +} + +//***************************************************************************** +// +// Network events handler. +// +//***************************************************************************** +void +exoHAL_ExositeEnetEvents(uint32_t ui32Event, void *pvData, uint32_t ui32Param) +{ + uint32_t ui32NumHeaders; + uint8_t *pD = (uint8_t *)pvData; + + // + // Handle events from the Ethernet client layer. + // + switch(ui32Event) + { + // + // Ethernet client has received data. + // + case ETH_CLIENT_EVENT_RECEIVE: + { + // + // Set the RECEIVED flag if we have a minimum of 50 bytes received. + // + if (ui32Param >= 50) + { + HWREGBITW(&g_sExosite.ui32Flags, FLAG_RECEIVED) = 1; + } + + if (RingBufFree(&g_sEnetBuffer) >= ui32Param) + { + // + // Write to the ring buffer. + // + RingBufWrite(&g_sEnetBuffer, pD, ui32Param); + } + else + { + } + + // + // Handle the received data based on the state of the EXOSITE + // transfer. + // + switch(g_sExosite.eState) + { + // + // Idle state. + // + case EXOSITE_STATE_CONNECTED_IDLE: + { + break; + } + + // + // Waiting for the proxy connect request to complete. + // + case EXOSITE_STATE_PROXY_WAIT: + { + // + // Check the response. + // + if(!HTTPResponseParse((char *)pD, g_pcRequest, + (uint32_t *)&ui32NumHeaders)) + { + break; + } + + if (ustrncmp((char *)pD, "200", 3)) + { + // + // Empty the receive buffer. + // + RingBufFlush(&g_sEnetBuffer); + + // + // Set the connected flag. + // + HWREGBITW(&g_sExosite.ui32Flags, FLAG_CONNECTED) = 1; + + // + // Clear the RECEIVED flag. + // + HWREGBITW(&g_sExosite.ui32Flags, FLAG_RECEIVED) = 0; + + // + // IDLE state. + // + g_sExosite.eState = EXOSITE_STATE_CONNECTED_IDLE; + + break; + } + break; + } + + default: + break; + } + break; + } + + // + // Ethernet client has connected to the specified server/host and port. + // + case ETH_CLIENT_EVENT_CONNECT: + { + // + // If there is a proxy, establish the connection. + // + if(g_bUseProxy && HWREGBITW(&g_sExosite.ui32Flags, FLAG_PROXY_SET)) + { + // + // Construct the CONNECT request. + // + exoHAL_ExositeConstructProxyRequest(); + EthClientSend((int8_t *)g_pcRequest, g_ui8RequestSize); + + // + // Wait for callback from the CONNECT request. + // + g_sExosite.eState = EXOSITE_STATE_PROXY_WAIT; + } + else + { + // + // Set the connected flag. + // + HWREGBITW(&g_sExosite.ui32Flags, FLAG_CONNECTED) = 1; + } + + break; + } + // + // Ethernet client has obtained IP address via DHCP. + // + case ETH_CLIENT_EVENT_DHCP: + { + break; + } + + // + // Ethernet client has received DNS response. + // + case ETH_CLIENT_EVENT_DNS: + { + if(ui32Param != 0) + { + // + // If DNS resolved successfully, initialize the socket and + // stack. + // + EthClientTCPConnect(); + } + else + { + // + // Clear the busy flag. + // + HWREGBITW(&g_sExosite.ui32Flags, FLAG_BUSY) = 0; + + // + // Clear the DNS flag. + // + HWREGBITW(&g_sExosite.ui32Flags, FLAG_DNS_INIT) = 0; + + // + // Update state machine. + // + g_sExosite.eState = EXOSITE_STATE_NOT_CONNECTED; + } + + break; + } + + // + // Ethernet client has disconnected from the server/host. + // + case ETH_CLIENT_EVENT_DISCONNECT: + { + // + // Close the socket. + // + exoHAL_SocketClose(0); + + break; + } + + // + // All other cases are unhandled. + // + case ETH_CLIENT_EVENT_SEND: + { + + break; + } + + + case ETH_CLIENT_EVENT_ERROR: + { + + break; + } + + default: + { + + break; + } + + } +} + +//***************************************************************************** +// +// Exosite init. +// +//***************************************************************************** +void +exoHAL_ExositeInit(void) +{ + if (HWREGBITW(&g_sExosite.ui32Flags, FLAG_ENET_INIT) == 0) + { + +#if NO_SYS + // + // Configure SysTick for a periodic interrupt. + // + SysTickPeriodSet(g_ui32SysClock / SYSTICKHZ); + SysTickEnable(); + SysTickIntEnable(); + + // + // Turn on interrupts. + // + IntMasterEnable(); + + // + // Set the interrupt priorities. We set the SysTick interrupt to a + // higher priority than the Ethernet interrupt to ensure that the file + // system tick is processed if SysTick occurs while the Ethernet + // handler is being processed. This is very likely since all the + // TCP/IP and HTTP work is done in the context of the Ethernet + // interrupt. + // + + IntPriorityGroupingSet(4); + IntPrioritySet(INT_EMAC0, ETHERNET_INT_PRIORITY); + IntPrioritySet(FAULT_SYSTICK, SYSTICK_INT_PRIORITY); +#endif + // + // Initialize the structure to known state. + // + g_sExosite.ui32Flags = 0; + g_sExosite.pcClientID = 0; + g_sExosite.pcServer = 0; + g_sExosite.eState = EXOSITE_STATE_NOT_CONNECTED; + + // + // Initialize the Ethernet Client. + // + EthClientInit(g_ui32SysClock, &exoHAL_ExositeEnetEvents); + + // + // Initialize the write pointer for the circular buffer. + // + RingBufInit(&g_sEnetBuffer, g_ui8Data, RECEIVE_BUFFER_SIZE); + + // + // Set the host address. + // + EthClientHostSet(EXOSITE_ADDRESS, EXOSITE_PORT); + + // + // Signal that we have initialized the Ethernet Client. + // + HWREGBITW(&g_sExosite.ui32Flags, FLAG_ENET_INIT) = 1; + } +} + +//***************************************************************************** +// +//! Reads and returns the UUID (MAC). +//! +//! \param ucIfNbr - The interface number (1-WiFi). +//! \param pucUUIDBuf - The buffer to return the hexadecimal MAC. +//! +//! This function reads the MAC address from the hardware. +//! +//! \return 0 if failure. Length of UUID if successful. +// +//***************************************************************************** +int +exoHAL_ReadUUID(unsigned char ucIfNbr, unsigned char * pucUUIDBuf) +{ + uint8_t pui8MACAddr[6]; + + // + // Initialize the Client which initializes the MAC. + // + exoHAL_ExositeInit(); + + // + // Get the MAC. + // + EthClientMACAddrGet(pui8MACAddr); + + // + // Fill pucUUIDBuf. + // + usprintf((char *)pucUUIDBuf,"%02x%02x%02x%02x%02x%02x", + (char)pui8MACAddr[0], + (char)pui8MACAddr[1], + (char)pui8MACAddr[2], + (char)pui8MACAddr[3], + (char)pui8MACAddr[4], + (char)pui8MACAddr[5]); + + // + // Return the size of the MAC. + // + return sizeof(pucUUIDBuf); +} + +//***************************************************************************** +// +// Set the proxy server name and port. +// +//***************************************************************************** +void +exoHAL_ExositeProxySet(char *pcProxy, uint16_t ui16Port) +{ + // + // Set the proxy server. + // + EthClientProxySet((const char *)pcProxy, ui16Port); + + // + // Set the proxy flag appropriately. + // + HWREGBITW(&g_sExosite.ui32Flags, FLAG_PROXY_SET) = 1; + +} + +//***************************************************************************** +// +//! Closes a socket. +//! +//! \param lSocket - socket handle. +//! +//! This function closes a socket by reseting the state flags in the +//! connection. +//! +//! \return None. +// +//***************************************************************************** +void +exoHAL_SocketClose(long lSocket) +{ + // + // TCP disconnect. + // + EthClientTCPDisconnect(); + + // + // Reset the connection state. + // + exoHAL_ResetConnection(); +} + +//***************************************************************************** +// +//! Opens a TCP socket. +//! +//! \param pucServer - socket handle. +//! +//! This function attempts to obtain an IP. Then configures the client +//! proxy, performs a DNS lookup and loops waiting for a connection. After +//! a set number of tries to connect it returns with an error. +//! +//! \return -1 for failure. else return 0. +// +//***************************************************************************** +long +exoHAL_SocketOpenTCP(unsigned char *pucServer) +{ + uint32_t ui32IPAddr, ui32Timeout; + int32_t i32Connected, i32Error; + + // + // Variable to track our while() loop count. + // + ui32Timeout = 5; + + // + // Initialize the exosite connection. + // + exoHAL_ExositeInit(); + + while(ui32Timeout) + { + // + // Decrement timeout count. + // + ui32Timeout--; + + // + // Get the current IP address. + // + ui32IPAddr = EthClientAddrGet(); + + // + // If IP is valid, print IP. + // + if(ui32IPAddr == 0 || ui32IPAddr == 0xffffffff) + { + // + // Delay, wait for response and continue. + // +#if NO_SYS + SysCtlDelay((g_ui32SysClock / SYSTICKMS) * 10); +#elif RTOS_FREERTOS + vTaskDelay(10 / portTICK_RATE_MS); +#endif // #if NO_SYS + continue; + } + else + { + + } + + // + // Set Proxy if not already. + // + if (g_bUseProxy && !HWREGBITW(&g_sExosite.ui32Flags, FLAG_PROXY_SET)) + { + // + // Set the proxy defined in exosite_hal_lwip.h + // + exoHAL_ExositeProxySet(g_pcProxyAddress, g_ui16ProxyPort); + } + + // + // If we are already initiated the DNS no need to do it again. + // + if (!HWREGBITW(&g_sExosite.ui32Flags, FLAG_DNS_INIT)) + { + // + // Resolve the host address. + // + i32Error = EthClientDNSResolve(); + + // + // If error, break. + // + if (i32Error != 0 && i32Error != -5) + { + break; + } + + // + // Set the DNS flag. + // + HWREGBITW(&g_sExosite.ui32Flags, FLAG_DNS_INIT) = 1; + + // + // Set the connect wait flag. + // + HWREGBITW(&g_sExosite.ui32Flags, FLAG_CONNECT_WAIT) = 1; + } + if (HWREGBITW(&g_sExosite.ui32Flags, FLAG_CONNECT_WAIT) == 0) + { + // + // Try to reconnect. + // + i32Error = EthClientTCPConnect(); + + // + // If error, break. + // + if (i32Error != 0) + { + break; + } + + // + // Set the connect wait flag. + // + HWREGBITW(&g_sExosite.ui32Flags, FLAG_CONNECT_WAIT) = 1; + } + + // + // See if we have connected to Exosite. + // + i32Connected = exoHAL_ServerConnect(0); + + // + // If connected, return success. + // else delay and decrement timeout. + // + if (i32Connected != -1) + { + + return 0; + } + else + { + // + // Delay and wait for response. + // +#if NO_SYS + SysCtlDelay(g_ui32SysClock / SYSTICKMS); +#elif RTOS_FREERTOS + vTaskDelay(1000 / portTICK_RATE_MS); +#endif // #if NO_SYS + + } + } + // + // We failed close the connection. + // + exoHAL_SocketClose(0); + + return -1; +} + +//***************************************************************************** +// +//! Checks the connection to the server. +//! +//! \param lSocket - socket handle. +//! +//! This function checks the connection to the server. +//! +//! \return -1 for failure. else: the socket handle +// +//***************************************************************************** +long +exoHAL_ServerConnect(long lSocket) +{ + // + // Check if we have connected to Exosite. + // + if (HWREGBITW(&g_sExosite.ui32Flags, FLAG_CONNECTED)) + { + return lSocket; + } + else + { + return -1; + } +} + +//***************************************************************************** +// +//! Sends data out to the Internet. +//! +//! \param lSocket - socket handle. +//! \param pcBuffer - string buffer containing info to send. +//! \param iLength - size of string in bytes. +//! +//! This function sends data out to the Internet. +//! +//! \return Number of bytes sent. +// +//***************************************************************************** +unsigned char +exoHAL_SocketSend(long lSocket, char * pcBuffer, int iLength) +{ + uint32_t ui32IPAddr; + + // + // Get the current IP address. + // + ui32IPAddr = EthClientAddrGet(); + + // + // If IP is invalid return error. + // + if(ui32IPAddr == 0 || ui32IPAddr == 0xffffffff ) + { + return 0; + } + + if (HWREGBITW(&g_sExosite.ui32Flags, FLAG_CONNECTED)) + { + // + // Send. + // + EthClientSend((int8_t *)pcBuffer, (uint32_t)iLength); + + // + // Set the SENT flag. + // + HWREGBITW(&g_sExosite.ui32Flags, FLAG_SENT) = 1; + + // + // Return the number of bytes sent. + // + return iLength; + } + else + { + return 0; + } +} + +//***************************************************************************** +// +//! Returns data from the buffer. +//! +//! \param lSocket - socket handle. +//! \param pcBuffer - string buffer to put info we receive. +//! \param iLength - size of buffer in bytes. +//! +//! This function reads data from the receive buffer. +//! +//! \return Number of bytes received. +// +//***************************************************************************** +unsigned char +exoHAL_SocketRecv(long lSocket, char * pcBuffer, int iLength) +{ + uint32_t ui32Used, ui32Timeout; + + ui32Timeout = 10; + + // + // Block until we receive our response. + // + while(HWREGBITW(&g_sExosite.ui32Flags, FLAG_SENT) == 1 && + HWREGBITW(&g_sExosite.ui32Flags, FLAG_RECEIVED) == 0 && + ui32Timeout) + { + // + // Decrement timeout + // + ui32Timeout--; + + // + // Delay. + // +#if NO_SYS + SysCtlDelay(g_ui32SysClock / 10); +#elif RTOS_FREERTOS + vTaskDelay(300 / portTICK_RATE_MS); +#endif // #if NO_SYS + } + + if(ui32Timeout != 0) + { + // + // Determine how much of the buffer have we used. + // + ui32Used = RingBufUsed(&g_sEnetBuffer); + + // + // If the number of bytes being requested is greater than what we have, + // only read the number of bytes out that we have. + // + if (ui32Used < iLength) + { + // + // Read from the buffer. + // + RingBufRead(&g_sEnetBuffer, (uint8_t *)pcBuffer, ui32Used); + return (unsigned char)ui32Used; + } + else + { + // + // Read from the buffer. + // + RingBufRead(&g_sEnetBuffer, (uint8_t *)pcBuffer, + (uint32_t)iLength); + return (unsigned char)iLength; + } + } + else + { + // + // Timeout. + // + } + + return 0; +} + +//***************************************************************************** +// +//! Delays for specified milliseconds. +//! +//! \param usDelay - milliseconds to delay. +//! +//! This function delays for specified milliseconds. +//! +//! \return None. +// +//***************************************************************************** +void +exoHAL_MSDelay(unsigned short usDelay) +{ +#if NO_SYS + uint32_t ui32Delay; + + // + // Determine delay based on the current clock speed. + // + ui32Delay = usDelay * ((g_ui32SysClock / SYSTICKMS) / 3); + + // + // Delay + // + SysCtlDelay(ui32Delay); + +#elif RTOS_FREERTOS + // + // Delay. + // + vTaskDelay(usDelay / portTICK_RATE_MS); +#endif // #if NO_SYS + +} diff --git a/boards/ek-tm4c1294xl/drivers/exosite_hal_lwip.h b/boards/ek-tm4c1294xl/drivers/exosite_hal_lwip.h new file mode 100644 index 0000000..87f5759 --- /dev/null +++ b/boards/ek-tm4c1294xl/drivers/exosite_hal_lwip.h @@ -0,0 +1,138 @@ +//***************************************************************************** +// +// exosite_hal_lwip.h - Abstraction layer between Excosite and eth_client_lwip. +// +// Copyright (c) 2013-2014 Texas Instruments Incorporated. All rights reserved. +// Software License Agreement +// +// Texas Instruments (TI) is supplying this software for use solely and +// exclusively on TI's microcontroller products. The software is owned by +// TI and/or its suppliers, and is protected under applicable copyright +// laws. You may not combine this software with "viral" open-source +// software in order to form a larger program. +// +// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. +// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT +// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY +// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +// DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 2.1.0.12573 of the EK-TM4C1294XL Firmware Package. +// +//***************************************************************************** + +#ifndef EXOSITE_HAL_LWIP_H +#define EXOSITE_HAL_LWIP_H + +#include +#include + +//***************************************************************************** +// +// If building with a C++ compiler, make all of the definitions in this header +// have a C binding. +// +//***************************************************************************** +#ifdef __cplusplus +extern "C" +{ +#endif + +//***************************************************************************** +// +// Proxy Config. +// +//***************************************************************************** +extern bool g_bUseProxy; +extern char g_pcProxyAddress[50]; +extern uint16_t g_ui16ProxyPort; + +//***************************************************************************** +// +// Exosite Config. +// +//***************************************************************************** +#define EXOSITE_ADDRESS "m2.exosite.com" +#define EXOSITE_PORT 80 + +//***************************************************************************** +// +// Meta Structure. +// +//***************************************************************************** +#define EXOMETA_ADDR_OFFSET 0 + +//***************************************************************************** +// +// Maximum length for the serial number. +// +//***************************************************************************** +#define EXOSITE_HAL_SN_MAXLENGTH 25 + +//***************************************************************************** +// +// Maximum size for the circular receive buffer. +// +//***************************************************************************** +#define RECEIVE_BUFFER_SIZE 1024 + +//***************************************************************************** +// +// EEPROM status. +// +//***************************************************************************** +#define EEPROM_INITALIZED 1 +#define EEPROM_IDLE 2 +#define EEPROM_READING 3 +#define EEPROM_WRITING 4 +#define EEPROM_ERASING 5 +#define EEPROM_ERROR 6 + +//***************************************************************************** +// +// Flag indexes for g_sExosite.ui32Flags +// +//***************************************************************************** +#define FLAG_ENET_INIT 0 +#define FLAG_CONNECTED 1 +#define FLAG_DNS_INIT 2 +#define FLAG_PROXY_SET 3 +#define FLAG_BUSY 4 +#define FLAG_SENT 5 +#define FLAG_RECEIVED 6 +#define FLAG_CONNECT_WAIT 7 + +//***************************************************************************** +// +// Prototypes. +// +//***************************************************************************** +typedef void (* tExositeEventHandler)(uint32_t ui32Event, void* pvData1, + uint16_t ui16Size1, void* pvData2, + uint16_t ui16Size2); + +int exoHAL_ReadUUID(unsigned char ucIfNbr, unsigned char * pucUUIDBuf); +void exoHAL_EnableMeta(void); +void exoHAL_EraseMeta(void); +void exoHAL_WriteMetaItem(unsigned char * pucBuffer, int iLength, int iOffset); +void exoHAL_ReadMetaItem(unsigned char * pucBuffer, int iLength, int iOffset); +void exoHAL_SocketClose(long ulSocket); +long exoHAL_SocketOpenTCP(unsigned char *pucServer); +long exoHAL_ServerConnect(long ulSocket); +unsigned char exoHAL_SocketSend(long lSocket, char * pcBuffer, int iLength); +unsigned char exoHAL_SocketRecv(long lSocket, char * pcBuffer, int iLength); +void exoHAL_MSDelay(unsigned short usDelay); +void exoHAL_Tick(unsigned long ulDelay); + +//***************************************************************************** +// +// Mark the end of the C bindings section for C++ compilers. +// +//***************************************************************************** +#ifdef __cplusplus +} +#endif + +#endif //EXOSITE_HAL_LWIP_H + diff --git a/boards/ek-tm4c1294xl/drivers/http.c b/boards/ek-tm4c1294xl/drivers/http.c new file mode 100644 index 0000000..22d4f0f --- /dev/null +++ b/boards/ek-tm4c1294xl/drivers/http.c @@ -0,0 +1,587 @@ +//***************************************************************************** +// +// http.c - HTTP request creation functions. +// +// Copyright (c) 2013-2014 Texas Instruments Incorporated. All rights reserved. +// Software License Agreement +// +// Texas Instruments (TI) is supplying this software for use solely and +// exclusively on TI's microcontroller products. The software is owned by +// TI and/or its suppliers, and is protected under applicable copyright +// laws. You may not combine this software with "viral" open-source +// software in order to form a larger program. +// +// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. +// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT +// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY +// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +// DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 2.1.0.12573 of the EK-TM4C1294XL Firmware Package. +// +//***************************************************************************** +#include +#include +#include +#include "inc/hw_types.h" +#include "utils/ustdlib.h" +#include "http.h" + +//***************************************************************************** +// +// Buffer used to store temporary strings for constructing/parsing requests. +// +//***************************************************************************** +static char g_pcTempData[256]; + +//***************************************************************************** +// +// Declarations for request type strings. +// +//***************************************************************************** +static char g_pcHttpConnect[] = "CONNECT "; +static char g_pcHttpGet[] = "GET "; +static char g_pcHttpPost[] = "POST "; +static char g_pcHttpPut[] = "PUT "; +static char g_pcHttpDelete[] = "DELETE "; +static char g_pcHttpHead[] = "HEAD "; +static char g_pcHttpTrace[] = "TRACE "; +static char g_pcHttpOptions[] = "OPTIONS "; +static char g_pcHttpPatch[] = "PATCH "; + +//***************************************************************************** +// +// HTTP suffixes used by HTTPMessageTypeSet(). Default is HTTP 1.1. +// +//***************************************************************************** +#ifdef USE_HTTP_1_0 +static const char g_pcSuffixHttp10[] = " HTTP/1.0\r\n\r\n"; +#else +static const char g_pcSuffixHttp11[] = " HTTP/1.1\r\n\r\n"; +#endif + +//***************************************************************************** +// +//! Extract the portion of a string up to a specified character. +//! +//! \param cWhichOne specifies the character to compare against. +//! \param pcSource is a pointer to the source/input string. +//! \param pcOutput is a pointer to the destination/output string. +//! \param pui32Size is a pointer to a variable that will receive the size of +//! the destination/output string. +//! +//! \return None. +// +//***************************************************************************** +static void +BufferFillToCharacter(char cWhichOne, char *pcSource, char *pcOutput, + uint32_t *pui32Size) +{ + // + // Search the string until the character is found. + // + *pui32Size = 0; + while(*pcSource) + { + if(*pcSource == cWhichOne) + { + pcOutput[*pui32Size] = 0; + pcSource++; + return; + } + else + { + pcOutput[*pui32Size] = *pcSource; + pcSource++; + *pui32Size += 1; + } + } + + return; +} + +//***************************************************************************** +// +//! Extract the portion of a string up to end-of-line (EOL). +//! +//! \param pcSource is a pointer to the source/input string. +//! \param pcOutput is a pointer to the destination/output string. +//! \param pui32Size is a pointer to a variable that will receive the size of +//! the destination/output string. +//! +//! \return None. +// +//***************************************************************************** +static void +BufferFillToEOL(char *pcSource, char *pcOutput, uint32_t *pui32Size) +{ + // + // Search the string until EOL is found. + // + *pui32Size = 0; + while(*pcSource) + { + if((*pcSource == '\r') && (*(pcSource+ 1) == '\n')) + { + pcOutput[*pui32Size] = 0; + pcSource += 2; + return; + } + else + { + pcOutput[*pui32Size] = *pcSource; + pcSource++; + *pui32Size += 1; + } + } + + return; +} + +static void +InsertRequest(char *pcDest, char *pcRequest) +{ + uint32_t i; + uint32_t ui32ReqSize; + uint32_t ui32DstSize; + + ui32ReqSize = strlen(pcRequest); + ui32DstSize = strlen(pcDest); + + pcDest[ui32DstSize + ui32ReqSize] = 0; + for(i = ui32DstSize; i-- > 0; ) + { + pcDest[ui32ReqSize + i] = pcDest[i]; + } + + for(i = 0; i < ui32ReqSize; i++) + { + pcDest[i] = pcRequest[i]; + } +} + +//***************************************************************************** +// +//! Set the HTTP message type. +//! +//! \param pcDest is a pointer to the destination/output string. +//! \param ui8Type is the HTTP request type. Macros such as HTTP_MESSAGE_GET +//! are defined in http.h. +//! \param pcResource is a pointer to a string containing the resource portion +//! of the HTTP message. The resource goes in between the type (ex: GET) and +//! HTTP suffix on the first line of a HTTP request. An example would be +//! index.html. +//! +//! This function should be called to start off a new HTTP request. +//! +//! \return None. +// +//***************************************************************************** +void +HTTPMessageTypeSet(char *pcDest, uint8_t ui8Type, char *pcResource) +{ + // + // Check to see if the resource and destination pointers are the same. If + // yes, insert the request type at the beginning of the resource string. + // + if(pcDest == pcResource) + { + // + // Add the request type to the buffer. + // + switch(ui8Type) + { + case HTTP_MESSAGE_CONNECT: + { + InsertRequest(pcDest, g_pcHttpConnect); + break; + } + case HTTP_MESSAGE_GET: + { + InsertRequest(pcDest, g_pcHttpGet); + break; + } + case HTTP_MESSAGE_POST: + { + InsertRequest(pcDest, g_pcHttpPost); + break; + } + case HTTP_MESSAGE_PUT: + { + InsertRequest(pcDest, g_pcHttpPut); + break; + } + case HTTP_MESSAGE_DELETE: + { + InsertRequest(pcDest, g_pcHttpDelete); + break; + } + case HTTP_MESSAGE_HEAD: + { + InsertRequest(pcDest, g_pcHttpHead); + break; + } + case HTTP_MESSAGE_TRACE: + { + InsertRequest(pcDest, g_pcHttpTrace); + break; + } + case HTTP_MESSAGE_OPTIONS: + { + InsertRequest(pcDest, g_pcHttpOptions); + break; + } + case HTTP_MESSAGE_PATCH: + { + InsertRequest(pcDest, g_pcHttpPatch); + break; + } + } + } + else + { + // + // Add the request type to the buffer. + // + switch(ui8Type) + { + case HTTP_MESSAGE_CONNECT: + { + usprintf(pcDest, g_pcHttpConnect); + break; + } + case HTTP_MESSAGE_GET: + { + usprintf(pcDest, g_pcHttpGet); + break; + } + case HTTP_MESSAGE_POST: + { + usprintf(pcDest, g_pcHttpPost); + break; + } + case HTTP_MESSAGE_PUT: + { + usprintf(pcDest, g_pcHttpPut); + break; + } + case HTTP_MESSAGE_DELETE: + { + usprintf(pcDest, g_pcHttpDelete); + break; + } + case HTTP_MESSAGE_HEAD: + { + usprintf(pcDest, g_pcHttpHead); + break; + } + case HTTP_MESSAGE_TRACE: + { + usprintf(pcDest, g_pcHttpTrace); + break; + } + case HTTP_MESSAGE_OPTIONS: + { + usprintf(pcDest, g_pcHttpOptions); + break; + } + case HTTP_MESSAGE_PATCH: + { + usprintf(pcDest, g_pcHttpPatch); + break; + } + } + + // + // Add the resource to the buffer. + // + strcat(pcDest, pcResource); + } + + // + // Finish the first "line" by adding the HTTP suffix. + // +#ifdef USE_HTTP_1_0 + strcat(pcDest, g_pcSuffixHttp10); +#else + strcat(pcDest, g_pcSuffixHttp11); +#endif +} + +//***************************************************************************** +// +//! Add a header to a HTTP request. +//! +//! \param pcDest is a pointer to the destination/output string. +//! \param pcHeaderName is a pointer to a string containing the header name. +//! \param pcHeaderValue is a pointer to a string containing the header data. +//! +//! Note that this function must be called after HTTPMessageTypeSet() as it +//! simply appends a header to an existing string/buffer. +//! +//! \return None. +// +//***************************************************************************** +void +HTTPMessageHeaderAdd(char *pcDest, char *pcHeaderName, char *pcHeaderValue) +{ + // + // Add the header name to the buffer. + // + strcat(pcDest, pcHeaderName); + + // + // Add ":" and space. + // + strcat(pcDest, ": "); + + // + // Add header value. + // + strcat(pcDest, pcHeaderValue); + + // + // Add \r and \n. + // + strcat(pcDest, "\r\n"); +} + +//***************************************************************************** +// +//! Add body data to to a HTTP request. +//! +//! \param pcDest is a pointer to the destination/output string. +//! \param pcBodyData is a pointer to a string containing the body data. This +//! can be anything from HTML to encoded data (such as JSON). +//! +//! Note that this function must be called after HTTPMessageTypeSet() and +//! HTTPMessageHeaderAdd() as it simply appends the body data to an existing +//! string/buffer. +//! +//! \return None. +// +//***************************************************************************** +void +HTTPMessageBodyAdd(char *pcDest, char *pcBodyData) +{ + // + // First, insert blank line between header section and body. + // + strcat(pcDest, "\r\n"); + + // + // Add body content. + // + strcat(pcDest, pcBodyData); + + // + // Add blank line. + // + strcat(pcDest, "\r\n\r\n"); +} + +//***************************************************************************** +// +//! Parse a HTTP response. +//! +//! \param pcData is a pointer to the source string/buffer. +//! \param pcResponseText is a pointer to a string that will receive the +//! response text from the first line of the HTTP response. +//! \param pui32NumHeaders is a pointer to a variable that will receive the +//! number of headers detected in pcData. +//! +//! Note that this function must be called after HTTPMessageTypeSet() as it +//! simply appends a header to an existing string/buffer. +//! +//! \return Returns the HTTP response code. If parsing error occurs, returns 0. +// +//***************************************************************************** +uint32_t +HTTPResponseParse(char *pcData, char *pcResponseText, uint32_t *pui32NumHeaders) +{ + uint32_t ui32Response = 0; + uint32_t ui32Size; + + // + // Look for "HTTP/n.n" piece. + // + BufferFillToCharacter(' ', pcData, g_pcTempData, &ui32Size); + pcData += (ui32Size + 1); + + // + // Fail if not a HTTP response. + // + if(ustrncmp(g_pcTempData, "HTTP/", 5)) + { + *pcResponseText = 0; + *pui32NumHeaders = 0; + return 0; + } + + // + // Get the return code. + // + BufferFillToCharacter(' ', pcData, g_pcTempData, &ui32Size); + pcData += (ui32Size + 1); + + // + // Convert return code to unsigned long. + // + ui32Response = ustrtoul(g_pcTempData, 0, 10); + + // + // Get the response text. + // + BufferFillToEOL(pcData, pcResponseText, &ui32Size); + pcData += (ui32Size + 2); + + // + // Parse the remainder of the packet. + // + *pui32NumHeaders = 0; + while(*pcData) + { + // + // Search line by line and count headers. Search until there is a blank + // line, which means end of headers. + // + BufferFillToEOL(pcData, g_pcTempData, &ui32Size); + pcData += (ui32Size + 2); + + // + // Blank line. For the purposes of this function, we're done. + // + if(ui32Size == 0) + { + break; + } + else + { + // + // Increment header counter. + // + *pui32NumHeaders += 1; + } + } + + return ui32Response; +} + +//***************************************************************************** +// +//! Extract a specified header from a HTTP response string/buffer. +//! +//! \param pcData is a pointer to the source string/buffer. +//! \param ui32HeaderIdx specifies the index of the header to extract. +//! \param pcHeaderName is a pointer to a string that will receive the name of +//! the header specified by ui32HeaderIdx. +//! \param pcHeaderValue is a pointer to a string that will receive the value of +//! the header specified by ui32HeaderIdx. +//! +//! Note that this function should be used in conjunction with +//! HTTPResponseParse() since it notifies the application of the number of +//! headers in a string/buffer. +//! +//! \return None. +// +//***************************************************************************** +void +HTTPResponseHeaderExtract(char *pcData, uint32_t ui32HeaderIdx, + char *pcHeaderName, char *pcHeaderValue) +{ + uint32_t ui32Size; + uint32_t ui32HeaderNumber = 0; + + // + // Read first line and discard. + // + BufferFillToEOL(pcData, g_pcTempData, &ui32Size); + pcData += (ui32Size + 2); + + // + // Find and return the requested header. + // + while(*pcData) + { + BufferFillToEOL(pcData, g_pcTempData, &ui32Size); + pcData += (ui32Size + 2); + + // + // Blank line, end of header section. + // + if(ui32Size == 0) + { + break; + } + else + { + if(ui32HeaderNumber == ui32HeaderIdx) + { + BufferFillToCharacter(':', g_pcTempData, pcHeaderName, + &ui32Size); + BufferFillToCharacter(0, &g_pcTempData[ui32Size + 2], + pcHeaderValue, &ui32Size); + pcHeaderValue[ui32Size] = 0; + + break; + } + else + { + // + // Increment header counter. + // + ui32HeaderNumber++; + } + } + } +} + +//***************************************************************************** +// +//! Extract the body from a HTTP response string/buffer. +//! +//! \param pcData is a pointer to the source string/buffer. +//! \param pcDest is a pointer to a string that will receive the body data. +//! +//! \return None. +// +//***************************************************************************** +void +HTTPResponseBodyExtract(char *pcData, char *pcDest) +{ + bool bBodyFound = false; + uint32_t ui32Size; + + // + // Find and return the body. + // + while(*pcData) + { + // + // Read lines until a blank line is found. This is the start of the + // body. + // + BufferFillToEOL(pcData, g_pcTempData, &ui32Size); + pcData += (ui32Size + 2); + + // + // Blank line, end of header section. + // + if(ui32Size == 0) + { + bBodyFound = true; + } + + // + // If the body has been found, start filling the buffer. + // + if(bBodyFound) + { + + pcDest[0] = 0; + strcat(pcDest, pcData); + break; + } + } +} diff --git a/boards/ek-tm4c1294xl/drivers/http.h b/boards/ek-tm4c1294xl/drivers/http.h new file mode 100644 index 0000000..a166bdd --- /dev/null +++ b/boards/ek-tm4c1294xl/drivers/http.h @@ -0,0 +1,75 @@ +//***************************************************************************** +// +// http.h - Prototypes for the HTTP protocol layer. +// +// Copyright (c) 2013-2014 Texas Instruments Incorporated. All rights reserved. +// Software License Agreement +// +// Texas Instruments (TI) is supplying this software for use solely and +// exclusively on TI's microcontroller products. The software is owned by +// TI and/or its suppliers, and is protected under applicable copyright +// laws. You may not combine this software with "viral" open-source +// software in order to form a larger program. +// +// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. +// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT +// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY +// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +// DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 2.1.0.12573 of the EK-TM4C1294XL Firmware Package. +// +//***************************************************************************** +#ifndef HTTP_H_ +#define HTTP_H_ + +//***************************************************************************** +// +// If building with a C++ compiler, make all of the definitions in this header +// have a C binding. +// +//***************************************************************************** +#ifdef __cplusplus +extern "C" +{ +#endif + +//***************************************************************************** +// +// HTTP request types used by HTTPMessageTypeSet(). +// +//***************************************************************************** +#define HTTP_MESSAGE_CONNECT 0x0 +#define HTTP_MESSAGE_GET 0x1 +#define HTTP_MESSAGE_POST 0x2 +#define HTTP_MESSAGE_PUT 0x3 +#define HTTP_MESSAGE_DELETE 0x4 +#define HTTP_MESSAGE_HEAD 0x5 +#define HTTP_MESSAGE_TRACE 0x6 +#define HTTP_MESSAGE_OPTIONS 0x7 +#define HTTP_MESSAGE_PATCH 0x8 + +//***************************************************************************** +// +// Exported function prototypes. +// +//***************************************************************************** +extern void HTTPMessageTypeSet(char *pcDest, uint8_t ui8Type, char *pcResource); +extern void HTTPMessageHeaderAdd(char *pcDest, char *pcHeaderName, + char *pcHeaderValue); +extern void HTTPMessageBodyAdd(char *pcDest, char *pcBodyData); + +extern uint32_t HTTPResponseParse(char *pcData, char *pcResponseText, + uint32_t *pui32NumHeaders); + +extern void HTTPResponseHeaderExtract(char *pcData, uint32_t ui32HeaderIdx, + char *pcHeaderName, char *pcHeaderValue); + +extern void HTTPResponseBodyExtract(char *pcData, char *pcDest); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/boards/ek-tm4c1294xl/drivers/pinout.c b/boards/ek-tm4c1294xl/drivers/pinout.c new file mode 100644 index 0000000..43c1c6e --- /dev/null +++ b/boards/ek-tm4c1294xl/drivers/pinout.c @@ -0,0 +1,301 @@ +//***************************************************************************** +// +// pinout.c - Function to configure the device pins on the EK-TM4C1294XL. +// +// Copyright (c) 2013-2014 Texas Instruments Incorporated. All rights reserved. +// Software License Agreement +// +// Texas Instruments (TI) is supplying this software for use solely and +// exclusively on TI's microcontroller products. The software is owned by +// TI and/or its suppliers, and is protected under applicable copyright +// laws. You may not combine this software with "viral" open-source +// software in order to form a larger program. +// +// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. +// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT +// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY +// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +// DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 2.1.0.12573 of the EK-TM4C1294XL Firmware Package. +// +//***************************************************************************** + +#include +#include +#include "inc/hw_gpio.h" +#include "inc/hw_memmap.h" +#include "inc/hw_types.h" +#include "driverlib/gpio.h" +#include "driverlib/pin_map.h" +#include "driverlib/rom.h" +#include "driverlib/rom_map.h" +#include "driverlib/sysctl.h" +#include "drivers/pinout.h" + +//***************************************************************************** +// +//! \addtogroup pinout_api +//! @{ +// +//***************************************************************************** + +//***************************************************************************** +// +//! Configures the device pins for the standard usages on the EK-TM4C1294XL. +//! +//! \param bEthernet is a boolean used to determine function of Ethernet pins. +//! If true Ethernet pins are configured as Ethernet LEDs. If false GPIO are +//! available for application use. +//! \param bUSB is a boolean used to determine function of USB pins. If true USB +//! pins are configured for USB use. If false then USB pins are available for +//! application use as GPIO. +//! +//! This function enables the GPIO modules and configures the device pins for +//! the default, standard usages on the EK-TM4C1294XL. Applications that +//! require alternate configurations of the device pins can either not call +//! this function and take full responsibility for configuring all the device +//! pins, or can reconfigure the required device pins after calling this +//! function. +//! +//! \return None. +// +//***************************************************************************** +void +PinoutSet(bool bEthernet, bool bUSB) +{ + // + // Enable all the GPIO peripherals. + // + ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); + ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB); + ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC); + ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD); + ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE); + ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF); + ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOG); + ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOH); + ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOJ); + ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOK); + ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOL); + ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOM); + ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPION); + ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOP); + ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOQ); + + // + // PA0-1 are used for UART0. + // + ROM_GPIOPinConfigure(GPIO_PA0_U0RX); + ROM_GPIOPinConfigure(GPIO_PA1_U0TX); + ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1); + + // + // PB0-1/PD6/PL6-7 are used for USB. + // PQ4 can be used as a power fault detect on this board but it is not + // the hardware peripheral power fault input pin. + // + if(bUSB) + { + HWREG(GPIO_PORTD_BASE + GPIO_O_LOCK) = GPIO_LOCK_KEY; + HWREG(GPIO_PORTD_BASE + GPIO_O_CR) = 0xff; + ROM_GPIOPinConfigure(GPIO_PD6_USB0EPEN); + ROM_GPIOPinTypeUSBAnalog(GPIO_PORTB_BASE, GPIO_PIN_0 | GPIO_PIN_1); + ROM_GPIOPinTypeUSBDigital(GPIO_PORTD_BASE, GPIO_PIN_6); + ROM_GPIOPinTypeUSBAnalog(GPIO_PORTL_BASE, GPIO_PIN_6 | GPIO_PIN_7); + ROM_GPIOPinTypeGPIOInput(GPIO_PORTQ_BASE, GPIO_PIN_4); + } + else + { + // + // Keep the default config for most pins used by USB. + // Add a pull down to PD6 to turn off the TPS2052 switch + // + ROM_GPIOPinTypeGPIOInput(GPIO_PORTD_BASE, GPIO_PIN_6); + MAP_GPIOPadConfigSet(GPIO_PORTD_BASE, GPIO_PIN_6, GPIO_STRENGTH_2MA, + GPIO_PIN_TYPE_STD_WPD); + + } + + // + // PF0/PF4 are used for Ethernet LEDs. + // + if(bEthernet) + { + // + // this app wants to configure for ethernet LED function. + // + ROM_GPIOPinConfigure(GPIO_PF0_EN0LED0); + ROM_GPIOPinConfigure(GPIO_PF4_EN0LED1); + + GPIOPinTypeEthernetLED(GPIO_PORTF_BASE, GPIO_PIN_0 | GPIO_PIN_4); + + } + else + { + + // + // This app does not want Ethernet LED function so configure as + // standard outputs for LED driving. + // + ROM_GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_0 | GPIO_PIN_4); + + // + // Default the LEDs to OFF. + // + ROM_GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_0 | GPIO_PIN_4, 0); + MAP_GPIOPadConfigSet(GPIO_PORTF_BASE, GPIO_PIN_0 | GPIO_PIN_4, + GPIO_STRENGTH_12MA, GPIO_PIN_TYPE_STD); + + + } + + // + // PJ0 and J1 are used for user buttons + // + ROM_GPIOPinTypeGPIOInput(GPIO_PORTJ_BASE, GPIO_PIN_0 | GPIO_PIN_1); + ROM_GPIOPinWrite(GPIO_PORTJ_BASE, GPIO_PIN_0 | GPIO_PIN_1, 0); + + // + // PN0 and PN1 are used for USER LEDs. + // + ROM_GPIOPinTypeGPIOOutput(GPIO_PORTN_BASE, GPIO_PIN_0 | GPIO_PIN_1); + MAP_GPIOPadConfigSet(GPIO_PORTN_BASE, GPIO_PIN_0 | GPIO_PIN_1, + GPIO_STRENGTH_12MA, GPIO_PIN_TYPE_STD); + + // + // Default the LEDs to OFF. + // + ROM_GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0 | GPIO_PIN_1, 0); +} + +//***************************************************************************** +// +//! This function writes a state to the LED bank. +//! +//! \param ui32LEDMask is a bit mask for which GPIO should be changed by this +//! call. +//! \param ui32LEDValue is the new value to be applied to the LEDs after the +//! ui32LEDMask is applied. +//! +//! The first parameter acts as a mask. Only bits in the mask that are set +//! will correspond to LEDs that may change. LEDs with a mask that is not set +//! will not change. This works the same as GPIOPinWrite. After applying the +//! mask the setting for each unmasked LED is written to the corresponding +//! LED port pin via GPIOPinWrite. +//! +//! \return None. +// +//***************************************************************************** +void +LEDWrite(uint32_t ui32LEDMask, uint32_t ui32LEDValue) +{ + + // + // Check the mask and set or clear the LED as directed. + // + if(ui32LEDMask & CLP_D1) + { + if(ui32LEDValue & CLP_D1) + { + GPIOPinWrite(CLP_D1_PORT, CLP_D1_PIN, CLP_D1_PIN); + } + else + { + GPIOPinWrite(CLP_D1_PORT, CLP_D1_PIN, 0); + } + } + + if(ui32LEDMask & CLP_D2) + { + if(ui32LEDValue & CLP_D2) + { + GPIOPinWrite(CLP_D2_PORT, CLP_D2_PIN, CLP_D2_PIN); + } + else + { + GPIOPinWrite(CLP_D2_PORT, CLP_D2_PIN, 0); + } + } + + if(ui32LEDMask & CLP_D3) + { + if(ui32LEDValue & CLP_D3) + { + GPIOPinWrite(CLP_D3_PORT, CLP_D3_PIN, CLP_D3_PIN); + } + else + { + GPIOPinWrite(CLP_D3_PORT, CLP_D3_PIN, 0); + } + } + + if(ui32LEDMask & CLP_D4) + { + if(ui32LEDValue & CLP_D4) + { + GPIOPinWrite(CLP_D4_PORT, CLP_D4_PIN, CLP_D4_PIN); + } + else + { + GPIOPinWrite(CLP_D4_PORT, CLP_D4_PIN, 0); + } + } +} + +//***************************************************************************** +// +//! This function reads the state to the LED bank. +//! +//! \param pui32LEDValue is a pointer to where the LED value will be stored. +//! +//! This function reads the state of the CLP LEDs and stores that state +//! information into the variable pointed to by pui32LEDValue. +//! +//! \return None. +// +//***************************************************************************** +void LEDRead(uint32_t *pui32LEDValue) +{ + *pui32LEDValue = 0; + + // + // Read the pin state and set the variable bit if needed. + // + if(GPIOPinRead(CLP_D4_PORT, CLP_D4_PIN)) + { + *pui32LEDValue |= CLP_D4; + } + + // + // Read the pin state and set the variable bit if needed. + // + if(GPIOPinRead(CLP_D3_PORT, CLP_D3_PIN)) + { + *pui32LEDValue |= CLP_D3; + } + + // + // Read the pin state and set the variable bit if needed. + // + if(GPIOPinRead(CLP_D2_PORT, CLP_D2_PIN)) + { + *pui32LEDValue |= CLP_D2; + } + + // + // Read the pin state and set the variable bit if needed. + // + if(GPIOPinRead(CLP_D1_PORT, CLP_D1_PIN)) + { + *pui32LEDValue |= CLP_D1; + } +} + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/boards/ek-tm4c1294xl/drivers/pinout.h b/boards/ek-tm4c1294xl/drivers/pinout.h new file mode 100644 index 0000000..291db7f --- /dev/null +++ b/boards/ek-tm4c1294xl/drivers/pinout.h @@ -0,0 +1,80 @@ +//***************************************************************************** +// +// pinout.h - Prototype for the function to configure the device pins on the +// EK-TM4C1294XL. +// +// Copyright (c) 2013-2014 Texas Instruments Incorporated. All rights reserved. +// Software License Agreement +// +// Texas Instruments (TI) is supplying this software for use solely and +// exclusively on TI's microcontroller products. The software is owned by +// TI and/or its suppliers, and is protected under applicable copyright +// laws. You may not combine this software with "viral" open-source +// software in order to form a larger program. +// +// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. +// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT +// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY +// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +// DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 2.1.0.12573 of the EK-TM4C1294XL Firmware Package. +// +//***************************************************************************** + +#ifndef __DRIVERS_PINOUT_H__ +#define __DRIVERS_PINOUT_H__ + +//***************************************************************************** +// +// If building with a C++ compiler, make all of the definitions in this header +// have a C binding. +// +//***************************************************************************** +#ifdef __cplusplus +extern "C" +{ +#endif + +//***************************************************************************** +// +// Define Board LED's +// +//***************************************************************************** +#define CLP_D1 1 +#define CLP_D2 2 +#define CLP_D3 4 +#define CLP_D4 8 + +#define CLP_D1_PORT GPIO_PORTN_BASE +#define CLP_D1_PIN GPIO_PIN_1 + +#define CLP_D2_PORT GPIO_PORTN_BASE +#define CLP_D2_PIN GPIO_PIN_0 + +#define CLP_D3_PORT GPIO_PORTF_BASE +#define CLP_D3_PIN GPIO_PIN_4 + +#define CLP_D4_PORT GPIO_PORTF_BASE +#define CLP_D4_PIN GPIO_PIN_0 + +//***************************************************************************** +// +// Prototypes. +// +//***************************************************************************** +extern void PinoutSet(bool bEthernet, bool bUSB); +extern void LEDWrite(uint32_t ui32LEDMask, uint32_t ui32LEDValue); +extern void LEDRead(uint32_t *pui32LEDValue); + +//***************************************************************************** +// +// Mark the end of the C bindings section for C++ compilers. +// +//***************************************************************************** +#ifdef __cplusplus +} +#endif + +#endif // __DRIVERS_PINOUT_H__ -- cgit v1.3.1