diff options
| author | Yuval Adam <yuv.adm@gmail.com> | 2014-06-29 12:34:32 +0300 |
|---|---|---|
| committer | Yuval Adam <yuv.adm@gmail.com> | 2014-06-29 12:34:32 +0300 |
| commit | c3e4c9a25c2910d2d66d52215b3406b13d5b23d5 (patch) | |
| tree | added370d1e356901f8579f076e3263fb0464db7 /boards/dk-tm4c129x/usb_otg_mouse/usb_dev_mouse.c | |
| parent | 990090a4cc9070837d31e66b58d40f0c3d038741 (diff) | |
Add more board models
Diffstat (limited to 'boards/dk-tm4c129x/usb_otg_mouse/usb_dev_mouse.c')
| -rw-r--r-- | boards/dk-tm4c129x/usb_otg_mouse/usb_dev_mouse.c | 556 |
1 files changed, 556 insertions, 0 deletions
diff --git a/boards/dk-tm4c129x/usb_otg_mouse/usb_dev_mouse.c b/boards/dk-tm4c129x/usb_otg_mouse/usb_dev_mouse.c new file mode 100644 index 0000000..9390d8c --- /dev/null +++ b/boards/dk-tm4c129x/usb_otg_mouse/usb_dev_mouse.c @@ -0,0 +1,556 @@ +//*****************************************************************************
+//
+// usb_dev_mouse.c - Main routines for the mouse device.
+//
+// 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 DK-TM4C129X Firmware Package.
+//
+//*****************************************************************************
+
+#include <stdbool.h>
+#include <stdint.h>
+#include "inc/hw_memmap.h"
+#include "driverlib/gpio.h"
+#include "driverlib/rom.h"
+#include "driverlib/systick.h"
+#include "grlib/grlib.h"
+#include "grlib/widget.h"
+#include "usblib/usblib.h"
+#include "usblib/usbhid.h"
+#include "usblib/device/usbdevice.h"
+#include "usblib/device/usbdhid.h"
+#include "usblib/device/usbdhidmouse.h"
+#include "utils/uartstdio.h"
+#include "usb_mouse_structs.h"
+#include "drivers/touch.h"
+#include "usb_otg_mouse.h"
+
+//*****************************************************************************
+//
+// The GPIO pin which is connected to the select button.
+//
+//*****************************************************************************
+#define SEL_BTN_PORT GPIO_PORTP_BASE
+#define SEL_BTN_PIN GPIO_PIN_1
+
+//*****************************************************************************
+//
+// The defines used with the g_ui32Commands variable.
+//
+//*****************************************************************************
+#define UPDATE_TICK_EVENT 0x80000000
+
+//*****************************************************************************
+//
+// The incremental update for the mouse.
+//
+//*****************************************************************************
+#define MOUSE_MOVE_INC ((char)4)
+#define MOUSE_MOVE_DEC ((char)-4)
+
+//*****************************************************************************
+//
+// The HID mouse report offsets for this mouse application.
+//
+//*****************************************************************************
+#define HID_REPORT_BUTTONS 0
+#define HID_REPORT_X 1
+#define HID_REPORT_Y 2
+
+//*****************************************************************************
+//
+// Holds command bits used to signal the main loop to perform various tasks.
+//
+//*****************************************************************************
+volatile uint32_t g_ui32Commands;
+
+//*****************************************************************************
+//
+// Holds the current state of the touchscreen - pressed or not.
+//
+//*****************************************************************************
+volatile bool g_bScreenPressed;
+
+//*****************************************************************************
+//
+// Holds the current state of the user button - pressed or not.
+//
+//*****************************************************************************
+volatile bool g_bButtonPressed;
+
+
+//*****************************************************************************
+//
+// A flag used to indicate whether or not we are currently connected to the USB
+// host.
+//
+//*****************************************************************************
+volatile bool g_bConnected;
+
+//*****************************************************************************
+//
+// Holds the previous press position for the touchscreen.
+//
+//*****************************************************************************
+volatile int32_t g_i32ScreenStartX;
+volatile int32_t g_i32ScreenStartY;
+
+//*****************************************************************************
+//
+// Holds the current press position for the touchscreen.
+//
+//*****************************************************************************
+volatile int32_t g_i32ScreenX;
+volatile int32_t g_i32ScreenY;
+
+//*****************************************************************************
+//
+// The system tick timer rate.
+//
+//*****************************************************************************
+#define SYSTICKS_PER_SECOND 100
+#define MS_PER_SYSTICK (1000 / SYSTICKS_PER_SECOND)
+
+//*****************************************************************************
+//
+// Global system tick counter holds elapsed time since the application started
+// expressed in 100ths of a second.
+//
+//*****************************************************************************
+volatile uint32_t g_ui32SysTickCount;
+
+//*****************************************************************************
+//
+// Global system tick counter hold the g_ui32SysTickCount the last time
+// GetTickms() was called.
+//
+//*****************************************************************************
+static uint32_t g_ui32LastTick;
+
+//*****************************************************************************
+//
+// The number of system ticks to wait for each USB packet to be sent before
+// we assume the host has disconnected. The value 50 equates to half a second.
+//
+//*****************************************************************************
+#define MAX_SEND_DELAY 50
+
+//*****************************************************************************
+//
+// This enumeration holds the various states that the mouse can be in during
+// normal operation.
+//
+//*****************************************************************************
+volatile enum
+{
+ //
+ // Unconfigured.
+ //
+ eMouseStateUnconfigured,
+
+ //
+ // No keys to send and not waiting on data.
+ //
+ eMouseStateIdle,
+
+ //
+ // Waiting on data to be sent out.
+ //
+ eMouseStateSend
+}
+g_iMouseState = eMouseStateUnconfigured;
+
+
+uint32_t
+MouseHandler(void *pvCBData, uint32_t ui32Event, uint32_t ui32MsgData,
+ void *pvMsgData)
+{
+ switch(ui32Event)
+ {
+ //
+ // The USB host has connected to and configured the device.
+ //
+ case USB_EVENT_CONNECTED:
+ {
+ UARTprintf("Host connected.\n");
+ g_iMouseState = eMouseStateIdle;
+ g_bConnected = true;
+ break;
+ }
+
+ //
+ // The USB host has disconnected from the device.
+ //
+ case USB_EVENT_DISCONNECTED:
+ {
+ UARTprintf("Host disconnected.\n");
+ g_bConnected = false;
+ g_iMouseState = eMouseStateUnconfigured;
+ break;
+ }
+
+ //
+ // A report was sent to the host. We are now free to send another.
+ //
+ case USB_EVENT_TX_COMPLETE:
+ {
+ g_iMouseState = eMouseStateIdle;
+ break;
+ }
+ }
+ return(0);
+}
+
+//***************************************************************************
+//
+// Wait for a period of time for the state to become idle or unconfigured.
+//
+// \param ui32TimeoutTick is the number of system ticks to wait before
+// declaring a timeout and returning \b false.
+//
+// This function polls the current mouse state for ui32TimeoutTicks system
+// ticks waiting for it to either become idle or unconfigured. If the state
+// becomes one of these, the function returns true. If ui32TimeoutTicks
+// occur prior to the state becoming idle or unconfigured, false is returned
+// to indicate a timeout.
+//
+// \return Returns \b true on success or \b false on timeout.
+//
+//***************************************************************************
+bool
+WaitForSendIdle(uint32_t ui32TimeoutTicks)
+{
+ uint32_t ui32Start, ui32Now, ui32Elapsed;
+
+ ui32Start = g_ui32SysTickCount;
+ ui32Elapsed = 0;
+
+ while(ui32Elapsed < ui32TimeoutTicks)
+ {
+ //
+ // Is the mouse is idle or we have disconnected, return immediately.
+ //
+ if((g_iMouseState == eMouseStateIdle) ||
+ (g_iMouseState == eMouseStateUnconfigured))
+ {
+ return(true);
+ }
+
+ //
+ // Determine how much time has elapsed since we started waiting. This
+ // should be safe across a wrap of g_ui32SysTickCount. I suspect you
+ // won't likely leave the app running for the 497.1 days it will take
+ // for this to occur but you never know...
+ //
+ ui32Now = g_ui32SysTickCount;
+ ui32Elapsed = (ui32Start < ui32Now) ? (ui32Now - ui32Start) :
+ (((uint32_t)0xFFFFFFFF - ui32Start) + ui32Now + 1);
+ }
+
+ //
+ // If we get here, we timed out so return a bad return code to let the
+ // caller know.
+ //
+ return(false);
+}
+
+//*****************************************************************************
+//
+// This is the interrupt handler for the SysTick interrupt. It is called
+// periodically and updates a global tick counter then sets a flag to tell the
+// main loop to check to see if a new HID report should be sent to the host.
+//
+//*****************************************************************************
+void
+SysTickHandler(void)
+{
+ g_ui32SysTickCount++;
+ g_ui32Commands |= UPDATE_TICK_EVENT;
+}
+
+//*****************************************************************************
+//
+// This function handles updates due to the touchscreen and buttons.
+//
+// This function is called from the main loop each time the touchscreen state
+// needs to be checked. If it detects an update it will schedule an transfer
+// to the host.
+//
+// Returns Returns \b true on success or \b false if an error is detected.
+//
+//*****************************************************************************
+bool
+TouchEventHandler(void)
+{
+ uint32_t ui32Retcode;
+ int32_t i32DeltaX, i32DeltaY;
+ bool bSuccess;
+ bool bBtnPressed;
+
+ //
+ // Assume all is well until we determine otherwise.
+ //
+ bSuccess = true;
+
+ //
+ // Get the current state of the select button.
+ //
+ bBtnPressed = (ROM_GPIOPinRead(SEL_BTN_PORT, SEL_BTN_PIN) & SEL_BTN_PIN) ?
+ false : true;
+
+ //
+ // Is someone pressing the screen or has the button changed state? If so,
+ // we determine how far they have dragged their finger/stylus and use this
+ // to calculate mouse position changes to send to the host.
+ //
+ if(g_bScreenPressed || (bBtnPressed != g_bButtonPressed))
+ {
+ //
+ // Calculate how far we moved since the last time we checked. This
+ // rather odd layout prevents a compiler warning about undefined order
+ // of volatile accesses.
+ //
+ i32DeltaX = g_i32ScreenX;
+ i32DeltaX -= g_i32ScreenStartX;
+ i32DeltaY = g_i32ScreenY;
+ i32DeltaY -= g_i32ScreenStartY;
+
+ //
+ // Reset our start position.
+ //
+ g_i32ScreenStartX = g_i32ScreenX;
+ g_i32ScreenStartY = g_i32ScreenY;
+
+ //
+ // Was there any movement or change in button state?
+ //
+ if(i32DeltaX || i32DeltaY || (bBtnPressed != g_bButtonPressed))
+ {
+ //
+ // Yes - send a report back to the host after clipping the deltas
+ // to the maximum we can support.
+ //
+ i32DeltaX = (i32DeltaX > 127) ? 127 : i32DeltaX;
+ i32DeltaX = (i32DeltaX < -128) ? -128 : i32DeltaX;
+ i32DeltaY = (i32DeltaY > 127) ? 127 : i32DeltaY;
+ i32DeltaY = (i32DeltaY < -128) ? -128 : i32DeltaY;
+
+ //
+ // Remember the current button state.
+ //
+ g_bButtonPressed = bBtnPressed;
+
+ //
+ // Send the report back to the host.
+ //
+ g_iMouseState = eMouseStateSend;
+ ui32Retcode = USBDHIDMouseStateChange((void *)&g_sMouseDevice,
+ (char)i32DeltaX, (char)i32DeltaY,
+ (bBtnPressed ?
+ MOUSE_REPORT_BUTTON_1 : 0));
+
+ //
+ // Did we schedule the report for transmission?
+ //
+ if(ui32Retcode == MOUSE_SUCCESS)
+ {
+ //
+ // Wait for the host to acknowledge the transmission if all went
+ // well.
+ //
+ bSuccess = WaitForSendIdle(MAX_SEND_DELAY);
+
+ //
+ // Did we time out waiting for the packet to be sent?
+ //
+ if (!bSuccess)
+ {
+ //
+ // Yes - assume the host disconnected and go back to
+ // waiting for a new connection.
+ //
+ UARTprintf("Send timed out!\n");
+ g_bConnected = 0;
+ }
+ }
+ else
+ {
+ //
+ // An error was reported when trying to send the report. This
+ // may be due to host disconnection but could also be due to a
+ // clash between our attempt to send a report and the driver
+ // sending the last report in response to an idle timer timeout
+ // so we don't jump to the conclusion that we were disconnected
+ // in this case.
+ //
+ UARTprintf("Can't send report.\n");
+ bSuccess = false;
+ }
+ }
+ }
+
+ return(bSuccess);
+}
+
+//*****************************************************************************
+//
+// This function is called by the touchscreen driver whenever there is a
+// change in press state or position.
+//
+//*****************************************************************************
+int32_t
+DeviceMouseTouchCallback(uint32_t ui32Message, int32_t i32X, int32_t i32Y)
+{
+ switch(ui32Message)
+ {
+ //
+ // The touchscreen has been pressed. Remember where we are so that
+ // we can determine how far the pointer moves later.
+ //
+ case WIDGET_MSG_PTR_DOWN:
+ g_i32ScreenStartX = i32X;
+ g_i32ScreenStartY = i32Y;
+ g_i32ScreenX = i32X;
+ g_i32ScreenY = i32Y;
+ g_bScreenPressed = true;
+ break;
+
+ //
+ // The touchscreen is no longer being pressed.
+ //
+ case WIDGET_MSG_PTR_UP:
+ g_bScreenPressed = false;
+ break;
+
+ //
+ // The user is dragging his/her finger/stylus over the touchscreen.
+ //
+ case WIDGET_MSG_PTR_MOVE:
+ g_i32ScreenX = i32X;
+ g_i32ScreenY = i32Y;
+ break;
+ }
+
+ //
+ // Tell the mouse driver we handled the message.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+// This function initializes the mouse in device mode.
+//
+//*****************************************************************************
+void
+DeviceInit(void)
+{
+ //
+ // Initialize the touchscreen driver and install our event handler.
+ //
+ TouchScreenInit(g_ui32SysClock);
+ TouchScreenCallbackSet(DeviceMouseTouchCallback);
+
+ //
+ // Set the system tick to fire 100 times per second.
+ //
+ ROM_SysTickPeriodSet(g_ui32SysClock / SYSTICKS_PER_SECOND);
+ ROM_SysTickIntEnable();
+ ROM_SysTickEnable();
+
+ //
+ // Pass the USB library our device information, initialize the USB
+ // controller and connect the device to the bus.
+ //
+ USBDHIDMouseInit(0, (tUSBDHIDMouseDevice *)&g_sMouseDevice);
+}
+
+//*****************************************************************************
+//
+// This is the main loop that runs the mouse device application.
+//
+//*****************************************************************************
+void
+DeviceMain(void)
+{
+ bool bRetcode;
+
+ if(g_iMouseState == eMouseStateUnconfigured)
+ {
+ return;
+ }
+
+ //
+ // If it is time to check the touchscreen state then do so.
+ //
+ if(g_ui32Commands & UPDATE_TICK_EVENT)
+ {
+ g_ui32Commands &= ~UPDATE_TICK_EVENT;
+ TouchEventHandler();
+
+ //
+ // Wait for the last data to go out before sending more data. Also
+ // ensure that we drop out if the device is disconnected.
+ //
+ bRetcode = WaitForSendIdle(MAX_SEND_DELAY);
+
+ //
+ // If we timed out, assume the host disconnected and start looking
+ // for a new connection.
+ //
+ if(!bRetcode)
+ {
+ g_iMouseState = eMouseStateUnconfigured;
+ }
+ }
+}
+
+//*****************************************************************************
+//
+// This function returns the number of ticks since the last time this function
+// was called.
+//
+//*****************************************************************************
+uint32_t
+GetTickms(void)
+{
+ uint32_t ui32RetVal, ui32Saved;
+
+ ui32RetVal = g_ui32SysTickCount;
+ ui32Saved = ui32RetVal;
+
+ if(ui32Saved > g_ui32LastTick)
+ {
+ ui32RetVal = ui32Saved - g_ui32LastTick;
+ }
+ else
+ {
+ ui32RetVal = g_ui32LastTick - ui32Saved;
+ }
+
+ //
+ // This could miss a few milliseconds but the timings here are on a
+ // much larger scale.
+ //
+ g_ui32LastTick = ui32Saved;
+
+ //
+ // Return the number of milliseconds since the last time this was called.
+ //
+ return(ui32RetVal * MS_PER_SYSTICK);
+}
|
