source: rtems/c/src/lib/libbsp/lm32/shared/milkymist_usbinput/usbinput.c @ f7bb9f9

4.115
Last change on this file since f7bb9f9 was f7bb9f9, checked in by Werner Almesberger <werner@…>, on 02/29/12 at 16:08:44

PR2028: Milkymist USB: forward MIDI messages.

Forward MIDI messages from the softusb controller to the application.

Signed-off-by: Gedare Bloom <gedare@…>

  • Property mode set to 100644
File size: 3.6 KB
Line 
1/*  usbinput.c
2 *
3 *  Milkymist USB input devices driver for RTEMS
4 *
5 *  The license and distribution terms for this file may be
6 *  found in the file LICENSE in this distribution or at
7 *  http://www.rtems.com/license/LICENSE.
8 *
9 *  $Id$
10 *
11 *  COPYRIGHT (c) 2010, 2011 Sebastien Bourdeauducq
12 */
13
14#define RTEMS_STATUS_CHECKS_USE_PRINTK
15
16#include <stdlib.h>
17#include <stdio.h>
18#include <errno.h>
19#include <sys/types.h>
20#include <rtems.h>
21#include <bsp.h>
22#include <bsp/irq-generic.h>
23#include <rtems/libio.h>
24#include <rtems/status-checks.h>
25#include "../include/system_conf.h"
26#include "milkymist_usbinput.h"
27
28static const unsigned char input_firmware[] = {
29#include "softusb-input.h"
30};
31
32#include "comloc.h"
33
34#define DEVICE_NAME "/dev/usbinput"
35
36static int mouse_consume;
37static int keyboard_consume;
38static int midi_consume;
39
40static rtems_id event_q;
41
42static rtems_isr interrupt_handler(rtems_vector_number n)
43{
44  unsigned char msg[8];
45  int i;
46
47  lm32_interrupt_ack(1 << MM_IRQ_USB);
48
49  while(mouse_consume != COMLOC_MEVT_PRODUCE) {
50    for(i=0;i<4;i++)
51      msg[i] = COMLOC_MEVT(4*mouse_consume+i);
52    rtems_message_queue_send(event_q, msg, 4);
53    mouse_consume = (mouse_consume + 1) & 0x0f;
54  }
55
56  while(keyboard_consume != COMLOC_KEVT_PRODUCE) {
57    for(i=0;i<8;i++)
58      msg[i] = COMLOC_KEVT(8*keyboard_consume+i);
59    rtems_message_queue_send(event_q, msg, 8);
60    keyboard_consume = (keyboard_consume + 1) & 0x07;
61  }
62
63  while(midi_consume != COMLOC_MIDI_PRODUCE) {
64    for(i=0;i<3;i++)
65      msg[i] = COMLOC_MIDI(4*midi_consume+i+1);
66    rtems_message_queue_send(event_q, msg, 3);
67    midi_consume = (midi_consume + 1) & 0x0f;
68  }
69
70}
71
72rtems_device_driver usbinput_initialize(
73  rtems_device_major_number major,
74  rtems_device_minor_number minor,
75  void *arg
76)
77{
78  rtems_status_code sc;
79  volatile unsigned int *usb_dmem
80    = (volatile unsigned int *)MM_SOFTUSB_DMEM_BASE;
81  volatile unsigned int *usb_pmem
82    = (volatile unsigned int *)MM_SOFTUSB_PMEM_BASE;
83  int i, nwords;
84  rtems_isr_entry dummy;
85
86  MM_WRITE(MM_SOFTUSB_CONTROL, SOFTUSB_CONTROL_RESET);
87  for(i=0;i<SOFTUSB_DMEM_SIZE/4;i++)
88    usb_dmem[i] = 0;
89  for(i=0;i<SOFTUSB_PMEM_SIZE/2;i++)
90    usb_pmem[i] = 0;
91  nwords = (sizeof(input_firmware)+1)/2;
92  for(i=0;i<nwords;i++)
93    usb_pmem[i] = ((unsigned int)(input_firmware[2*i]))
94      |((unsigned int)(input_firmware[2*i+1]) << 8);
95  MM_WRITE(MM_SOFTUSB_CONTROL, 0);
96
97  mouse_consume = 0;
98  keyboard_consume = 0;
99  midi_consume = 0;
100
101  sc = rtems_io_register_name(DEVICE_NAME, major, 0);
102  RTEMS_CHECK_SC(sc, "create USB input device");
103
104  sc = rtems_message_queue_create(
105    rtems_build_name('U', 'S', 'B', 'I'),
106    64,
107    8,
108    0,
109    &event_q
110  );
111  RTEMS_CHECK_SC(sc, "create USB event queue");
112
113  rtems_interrupt_catch(interrupt_handler, MM_IRQ_USB, &dummy);
114  bsp_interrupt_vector_enable(MM_IRQ_USB);
115
116  return RTEMS_SUCCESSFUL;
117}
118
119rtems_device_driver usbinput_open(
120  rtems_device_major_number major,
121  rtems_device_minor_number minor,
122  void *arg
123)
124{
125  uint32_t count;
126
127  rtems_message_queue_flush(event_q, &count);
128  return RTEMS_SUCCESSFUL;
129}
130
131rtems_device_driver usbinput_read(
132  rtems_device_major_number major,
133  rtems_device_minor_number minor,
134  void *arg
135)
136{
137  rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg;
138  rtems_status_code sc;
139
140  if(rw_args->count < 8) {
141    rw_args->bytes_moved = 0;
142    return RTEMS_UNSATISFIED;
143  }
144
145  sc = rtems_message_queue_receive(
146    event_q,
147    rw_args->buffer,
148    (size_t *)&rw_args->bytes_moved,
149    RTEMS_WAIT,
150    RTEMS_NO_TIMEOUT
151  );
152
153  if(sc == RTEMS_SUCCESSFUL)
154    return RTEMS_SUCCESSFUL;
155  else {
156    rw_args->bytes_moved = 0;
157    return RTEMS_UNSATISFIED;
158  }
159}
Note: See TracBrowser for help on using the repository browser.