From c3e4c9a25c2910d2d66d52215b3406b13d5b23d5 Mon Sep 17 00:00:00 2001 From: Yuval Adam Date: Sun, 29 Jun 2014 12:34:32 +0300 Subject: Add more board models --- boards/dk-tm4c129x/usb_otg_mouse/usb_dev_mouse.c | 556 +++++++++++++++++++++++ 1 file changed, 556 insertions(+) create mode 100644 boards/dk-tm4c129x/usb_otg_mouse/usb_dev_mouse.c (limited to 'boards/dk-tm4c129x/usb_otg_mouse/usb_dev_mouse.c') 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 +#include +#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); +} -- cgit v1.3.1