OpenCores
URL https://opencores.org/ocsvn/ao486/ao486/trunk

Subversion Repositories ao486

[/] [ao486/] [trunk/] [syn/] [components/] [sd_card/] [firmware/] [bsp/] [drivers/] [src/] [altera_avalon_jtag_uart_read.c] - Blame information for rev 8

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 8 alfik
/******************************************************************************
2
*                                                                             *
3
* License Agreement                                                           *
4
*                                                                             *
5
* Copyright (c) 2006 Altera Corporation, San Jose, California, USA.           *
6
* All rights reserved.                                                        *
7
*                                                                             *
8
* Permission is hereby granted, free of charge, to any person obtaining a     *
9
* copy of this software and associated documentation files (the "Software"),  *
10
* to deal in the Software without restriction, including without limitation   *
11
* the rights to use, copy, modify, merge, publish, distribute, sublicense,    *
12
* and/or sell copies of the Software, and to permit persons to whom the       *
13
* Software is furnished to do so, subject to the following conditions:        *
14
*                                                                             *
15
* The above copyright notice and this permission notice shall be included in  *
16
* all copies or substantial portions of the Software.                         *
17
*                                                                             *
18
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR  *
19
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,    *
20
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
21
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER      *
22
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING     *
23
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER         *
24
* DEALINGS IN THE SOFTWARE.                                                   *
25
*                                                                             *
26
* This agreement shall be governed in all respects by the laws of the State   *
27
* of California and by the laws of the United States of America.              *
28
*                                                                             *
29
******************************************************************************/
30
 
31
#include <string.h>
32
#include <fcntl.h>
33
#include <errno.h>
34
#include <limits.h>
35
 
36
#include <sys/stat.h>
37
 
38
#include "sys/alt_irq.h"
39
#include "sys/alt_alarm.h"
40
#include "sys/ioctl.h"
41
#include "alt_types.h"
42
 
43
#include "altera_avalon_jtag_uart_regs.h"
44
#include "altera_avalon_jtag_uart.h"
45
 
46
#include "sys/alt_log_printf.h"
47
 
48
#ifdef __ucosii__
49
#include "includes.h"
50
#endif /* __ucosii__ */
51
 
52
#ifdef ALTERA_AVALON_JTAG_UART_SMALL
53
 
54
/* ----------------------------------------------------------- */
55
/* ----------------------- SMALL DRIVER ---------------------- */
56
/* ----------------------------------------------------------- */
57
 
58
/* Read routine.  The small version blocks until it has at least one byte
59
 * available, it then returns as much as is immediately available without
60
 * waiting any more.  It's performance will be very poor without
61
 * interrupts.
62
 */
63
 
64
int
65
altera_avalon_jtag_uart_read(altera_avalon_jtag_uart_state* sp,
66
  char* buffer, int space, int flags)
67
{
68
  unsigned int base = sp->base;
69
 
70
  char * ptr = buffer;
71
  char * end = buffer + space;
72
 
73
  while (ptr < end)
74
  {
75
    unsigned int data = IORD_ALTERA_AVALON_JTAG_UART_DATA(base);
76
 
77
    if (data & ALTERA_AVALON_JTAG_UART_DATA_RVALID_MSK)
78
      *ptr++ = (data & ALTERA_AVALON_JTAG_UART_DATA_DATA_MSK) >> ALTERA_AVALON_JTAG_UART_DATA_DATA_OFST;
79
    else if (ptr != buffer)
80
      break;
81
    else if(flags & O_NONBLOCK)
82
      break;
83
 
84
  }
85
 
86
  if (ptr != buffer)
87
    return ptr - buffer;
88
  else if (flags & O_NONBLOCK)
89
    return -EWOULDBLOCK;
90
  else
91
    return -EIO;
92
}
93
 
94
#else /* !ALTERA_AVALON_JTAG_UART_SMALL */
95
 
96
/* ----------------------------------------------------------- */
97
/* ----------------------- FAST DRIVER ----------------------- */
98
/* ----------------------------------------------------------- */
99
 
100
int
101
altera_avalon_jtag_uart_read(altera_avalon_jtag_uart_state* sp,
102
  char * buffer, int space, int flags)
103
{
104
  char * ptr = buffer;
105
 
106
  alt_irq_context context;
107
  unsigned int n;
108
 
109
  /*
110
   * When running in a multi threaded environment, obtain the "read_lock"
111
   * semaphore. This ensures that reading from the device is thread-safe.
112
   */
113
  ALT_SEM_PEND (sp->read_lock, 0);
114
 
115
  while (space > 0)
116
  {
117
    unsigned int in, out;
118
 
119
    /* Read as much data as possible */
120
    do
121
    {
122
      in  = sp->rx_in;
123
      out = sp->rx_out;
124
 
125
      if (in >= out)
126
        n = in - out;
127
      else
128
        n = ALTERA_AVALON_JTAG_UART_BUF_LEN - out;
129
 
130
      if (n == 0)
131
        break; /* No more data available */
132
 
133
      if (n > space)
134
        n = space;
135
 
136
      memcpy(ptr, sp->rx_buf + out, n);
137
      ptr   += n;
138
      space -= n;
139
 
140
      sp->rx_out = (out + n) % ALTERA_AVALON_JTAG_UART_BUF_LEN;
141
    }
142
    while (space > 0);
143
 
144
    /* If we read any data then return it */
145
    if (ptr != buffer)
146
      break;
147
 
148
    /* If in non-blocking mode then return error */
149
    if (flags & O_NONBLOCK)
150
      break;
151
 
152
#ifdef __ucosii__
153
    /* OS Present: Pend on a flag if the OS is running, otherwise spin */
154
    if(OSRunning == OS_TRUE) {
155
      /*
156
       * When running in a multi-threaded mode, we pend on the read event
157
       * flag set and timeout event flag set in the isr. This avoids wasting CPU
158
       * cycles waiting in this thread, when we could be doing something more
159
       * profitable elsewhere.
160
       */
161
      ALT_FLAG_PEND (sp->events,
162
                     ALT_JTAG_UART_READ_RDY | ALT_JTAG_UART_TIMEOUT,
163
                     OS_FLAG_WAIT_SET_ANY + OS_FLAG_CONSUME,
164
                     0);
165
    }
166
    else {
167
      /* Spin until more data arrives or until host disconnects */
168
      while (in == sp->rx_in && sp->host_inactive < sp->timeout)
169
        ;
170
    }
171
#else
172
    /* No OS: Always spin */
173
    while (in == sp->rx_in && sp->host_inactive < sp->timeout)
174
      ;
175
#endif /* __ucosii__ */
176
 
177
    if (in == sp->rx_in)
178
      break;
179
  }
180
 
181
  /*
182
   * Now that access to the circular buffer is complete, release the read
183
   * semaphore so that other threads can access the buffer.
184
   */
185
 
186
  ALT_SEM_POST (sp->read_lock);
187
 
188
  if (ptr != buffer)
189
  {
190
    /* If we read any data then there is space in the buffer so enable interrupts */
191
    context = alt_irq_disable_all();
192
    sp->irq_enable |= ALTERA_AVALON_JTAG_UART_CONTROL_RE_MSK;
193
    IOWR_ALTERA_AVALON_JTAG_UART_CONTROL(sp->base, sp->irq_enable);
194
    alt_irq_enable_all(context);
195
  }
196
 
197
  if (ptr != buffer)
198
    return ptr - buffer;
199
  else if (flags & O_NONBLOCK)
200
    return -EWOULDBLOCK;
201
  else
202
    return -EIO;
203
}
204
 
205
#endif /* ALTERA_AVALON_JTAG_UART_SMALL */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.