1 /*!
2     \file    usbh_hid_mouse.c
3     \brief   USB host HID mouse driver
4 
5     \version 2020-08-04, V1.1.0, firmware for GD32VF103
6 */
7 
8 /*
9     Copyright (c) 2020, GigaDevice Semiconductor Inc.
10 
11     Redistribution and use in source and binary forms, with or without modification,
12 are permitted provided that the following conditions are met:
13 
14     1. Redistributions of source code must retain the above copyright notice, this
15        list of conditions and the following disclaimer.
16     2. Redistributions in binary form must reproduce the above copyright notice,
17        this list of conditions and the following disclaimer in the documentation
18        and/or other materials provided with the distribution.
19     3. Neither the name of the copyright holder nor the names of its contributors
20        may be used to endorse or promote products derived from this software without
21        specific prior written permission.
22 
23     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
27 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
30 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
32 OF SUCH DAMAGE.
33 */
34 
35 #include "usbh_hid_mouse.h"
36 #include "usbh_hid_parser.h"
37 
38 hid_mouse_info   mouse_info;
39 uint32_t         mouse_report_data[1];
40 
41 /* structures defining how to access items in a hid mouse report */
42 /* access button 1 state. */
43 static const hid_report_item prop_b1 =
44 {
45     (uint8_t *)(void *)mouse_report_data + 0, /* data */
46     1,     /* size */
47     0,     /* shift */
48     0,     /* count (only for array items) */
49     0,     /* signed? */
50     0,     /* min value read can return */
51     1,     /* max value read can return */
52     0,     /* min value device can report */
53     1,     /* max value device can report */
54     1      /* resolution */
55 };
56 
57 /* access button 2 state. */
58 static const hid_report_item prop_b2 =
59 {
60     (uint8_t *)(void *)mouse_report_data + 0, /* data */
61     1,     /* size */
62     1,     /* shift */
63     0,     /* count (only for array items) */
64     0,     /* signed? */
65     0,     /* min value read can return */
66     1,     /* max value read can return */
67     0,     /* min value device can report */
68     1,     /* max value device can report */
69     1      /* resolution */
70 };
71 
72 /* access button 3 state. */
73 static const hid_report_item prop_b3 =
74 {
75     (uint8_t *)(void *)mouse_report_data + 0, /* data */
76     1,     /* size */
77     2,     /* shift */
78     0,     /* count (only for array items) */
79     0,     /* signed? */
80     0,     /* min value read can return */
81     1,     /* max value read can return */
82     0,     /* min vale device can report */
83     1,     /* max value device can report */
84     1      /* resolution */
85 };
86 
87 /* access x coordinate change. */
88 static const hid_report_item prop_x =
89 {
90     (uint8_t *)(void *)mouse_report_data + 1, /* data */
91     8,     /* size */
92     0,     /* shift */
93     0,     /* count (only for array items) */
94     1,     /* signed? */
95     0,     /* min value read can return */
96     0xFFFF,/* max value read can return */
97     0,     /* min vale device can report */
98     0xFFFF,/* max value device can report */
99     1      /* resolution */
100 };
101 
102 /* access y coordinate change. */
103 static const hid_report_item prop_y =
104 {
105     (uint8_t *)(void *)mouse_report_data + 2, /* data */
106     8,     /* size */
107     0,     /* shift */
108     0,     /* count (only for array items) */
109     1,     /* signed? */
110     0,     /* min value read can return */
111     0xFFFF,/* max value read can return */
112     0,     /* min vale device can report */
113     0xFFFF,/* max value device can report */
114     1      /* resolution */
115 };
116 
117 /* local function prototypes ('static') */
118 static usbh_status usbh_hid_mouse_decode(usb_core_driver *pudev, usbh_host *puhost);
119 
120 /*!
121     \brief      initialize the mouse function
122     \param[in]  pudev: pointer to usb core instance
123     \param[in]  puhost: pointer to usb host
124     \param[out] none
125     \retval     none
126 */
usbh_hid_mouse_init(usb_core_driver * pudev,usbh_host * puhost)127 usbh_status usbh_hid_mouse_init (usb_core_driver *pudev, usbh_host *puhost)
128 {
129     usbh_hid_handler *hid = (usbh_hid_handler *)puhost->active_class->class_data;
130 
131     mouse_info.x = 0U;
132     mouse_info.y = 0U;
133     mouse_info.buttons[0] = 0U;
134     mouse_info.buttons[1] = 0U;
135     mouse_info.buttons[2] = 0U;
136 
137     mouse_report_data[0] = 0U;
138 
139     if(hid->len > sizeof(mouse_report_data)) {
140         hid->len = sizeof(mouse_report_data);
141     }
142 
143     hid->pdata = (uint8_t *)(void *)mouse_report_data;
144 
145     usbh_hid_fifo_init(&hid->fifo, puhost->dev_prop.data, HID_QUEUE_SIZE * sizeof(mouse_report_data));
146 
147     USR_MOUSE_Init();
148 
149     return USBH_OK;
150 }
151 
152 /*!
153     \brief      get mouse information
154     \param[in]  pudev: pointer to usb core instance
155     \param[in]  puhost: pointer to usb host
156     \param[out] none
157     \retval     mouse information
158 */
usbh_hid_mouse_info_get(usb_core_driver * pudev,usbh_host * puhost)159 hid_mouse_info *usbh_hid_mouse_info_get (usb_core_driver *pudev, usbh_host *puhost)
160 {
161     if(usbh_hid_mouse_decode(pudev, puhost)== USBH_OK) {
162         return &mouse_info;
163     } else {
164         return NULL;
165     }
166 }
167 
168 /*!
169     \brief      decode mouse data
170     \param[in]  pudev: pointer to usb core instance
171     \param[in]  puhost: pointer to usb host
172     \param[out] none
173     \retval     none
174 */
usbh_hid_mouse_machine(usb_core_driver * pudev,usbh_host * puhost)175 void usbh_hid_mouse_machine (usb_core_driver *pudev, usbh_host *puhost)
176 {
177     hid_mouse_info *m_pinfo = NULL;
178 
179     m_pinfo = usbh_hid_mouse_info_get(pudev, puhost);
180 
181     if (NULL != m_pinfo) {
182         /* handle mouse data position */
183         USR_MOUSE_ProcessData(&mouse_info);
184     }
185 }
186 
187 /*!
188     \brief      decode mouse information
189     \param[in]  pudev: pointer to usb core instance
190     \param[in]  puhost: pointer to usb host
191     \param[out] none
192     \retval     operation status
193 */
usbh_hid_mouse_decode(usb_core_driver * pudev,usbh_host * puhost)194 static usbh_status usbh_hid_mouse_decode(usb_core_driver *pudev, usbh_host *puhost)
195 {
196     usbh_hid_handler *hid = (usbh_hid_handler *)puhost->active_class->class_data;
197 
198     if (0U == hid->len) {
199         return USBH_FAIL;
200     }
201 
202     /* fill report */
203     if (usbh_hid_fifo_read(&hid->fifo, &mouse_report_data, hid->len) == hid->len) {
204         /* decode report */
205         mouse_info.x = (uint8_t)hid_item_read((hid_report_item *)&prop_x, 0U);
206         mouse_info.y = (uint8_t)hid_item_read((hid_report_item *)&prop_y, 0U);
207 
208         mouse_info.buttons[0] = (uint8_t)hid_item_read((hid_report_item *)&prop_b1, 0U);
209         mouse_info.buttons[1] = (uint8_t)hid_item_read((hid_report_item *)&prop_b2, 0U);
210         mouse_info.buttons[2] = (uint8_t)hid_item_read((hid_report_item *)&prop_b3, 0U);
211 
212         return USBH_OK;
213     }
214 
215     return USBH_FAIL;
216 }
217