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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [freertos-6.1.1/] [Demo/] [OpenRISC_SIM_GCC/] [serial/] [serial.c] - Blame information for rev 584

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 584 jeremybenn
//--------------------------------------------------------------------------//
2
//----------------------- COPIED FROM AVR32 EXAMPLE ------------------------//
3
//--------------------------------------------------------------------------//
4
 
5
/*This file has been prepared for Doxygen automatic documentation generation.*/
6
/*! \file *********************************************************************
7
 *
8
 * \brief FreeRTOS Serial Port management example for AVR32 UC3.
9
 *
10
 * - Compiler:           IAR EWAVR32 and GNU GCC for AVR32
11
 * - Supported devices:  All AVR32 devices can be used.
12
 * - AppNote:
13
 *
14
 * \author               Atmel Corporation: http://www.atmel.com \n
15
 *                       Support and FAQ: http://support.atmel.no/
16
 *
17
 *****************************************************************************/
18
 
19
/* Copyright (c) 2007, Atmel Corporation All rights reserved.
20
 *
21
 * Redistribution and use in source and binary forms, with or without
22
 * modification, are permitted provided that the following conditions are met:
23
 *
24
 * 1. Redistributions of source code must retain the above copyright notice,
25
 * this list of conditions and the following disclaimer.
26
 *
27
 * 2. Redistributions in binary form must reproduce the above copyright notice,
28
 * this list of conditions and the following disclaimer in the documentation
29
 * and/or other materials provided with the distribution.
30
 *
31
 * 3. The name of ATMEL may not be used to endorse or promote products derived
32
 * from this software without specific prior written permission.
33
 *
34
 * THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED
35
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
36
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND
37
 * SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,
38
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
39
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
40
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
41
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
42
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
43
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
44
 */
45
 
46
 
47
/*
48
  BASIC INTERRUPT DRIVEN SERIAL PORT DRIVER FOR USART.
49
*/
50
 
51
/* Scheduler includes. */
52
#include "FreeRTOS.h"
53
#include "queue.h"
54
#include "task.h"
55
 
56
/* Demo application includes. */
57
#include "serial.h"
58
#include "uart.h"
59
 
60
/*-----------------------------------------------------------*/
61
 
62
/* Constants to setup and access the USART. */
63
#define serINVALID_COMPORT_HANDLER        ( ( xComPortHandle ) 0 )
64
#define serINVALID_QUEUE                  ( ( xQueueHandle ) 0 )
65
#define serHANDLE                         ( ( xComPortHandle ) 1 )
66
#define serNO_BLOCK                       ( ( portTickType ) 0 )
67
 
68
/*-----------------------------------------------------------*/
69
 
70
/* Queues used to hold received characters, and characters waiting to be
71
transmitted. */
72
static xQueueHandle xRxedChars;
73
static xQueueHandle xCharsForTx;
74
 
75
/*-----------------------------------------------------------*/
76
 
77
/* Forward declaration. */
78
static void vprvSerialCreateQueues( unsigned portBASE_TYPE uxQueueLength,
79
                                                                        xQueueHandle *pxRxedChars,
80
                                                                        xQueueHandle *pxCharsForTx );
81
 
82
/*-----------------------------------------------------------*/
83
// TODO : Porting
84
static portBASE_TYPE prvUSART_ISR_NonNakedBehaviour( void )
85
{
86
        /* Now we can declare the local variables. */
87
        signed portCHAR     cChar;
88
        portBASE_TYPE     xHigherPriorityTaskWoken = pdFALSE;
89
        unsigned portLONG     ulStatus;
90
        // FIXME
91
        #define ADDR_UART_BASE          (0x90000000)
92
        volatile portBASE_TYPE  *usart = ADDR_UART_BASE;
93
        portBASE_TYPE retstatus;
94
 
95
        /* What caused the interrupt? */
96
        // FIXME
97
        // ulStatus = usart->csr & usart->imr;
98
 
99
        // TODO : TX RADY INTERRUPT, FIXME
100
        // if (ulStatus & AVR32_USART_CSR_TXRDY_MASK)
101
        if (ulStatus & 0x1)
102
        {
103
                /* The interrupt was caused by the THR becoming empty.  Are there any
104
                more characters to transmit?
105
                Because FreeRTOS is not supposed to run with nested interrupts, put all OS
106
                calls in a critical section . */
107
                portENTER_CRITICAL();
108
                        retstatus = xQueueReceiveFromISR( xCharsForTx, &cChar, &xHigherPriorityTaskWoken );
109
                portEXIT_CRITICAL();
110
 
111
                if (retstatus == pdTRUE)
112
                {
113
                        /* A character was retrieved from the queue so can be sent to the
114
                         THR now. */
115
                        // FIXME
116
                        // usart->thr = cChar;
117
                }
118
                else
119
                {
120
                        /* Queue empty, nothing to send so turn off the Tx interrupt. */
121
                        // FIXME
122
                        // usart->idr = AVR32_USART_IDR_TXRDY_MASK;
123
                }
124
        }
125
 
126
        // TODO : RX RADY INTERRUPT, FIXME
127
        // if (ulStatus & AVR32_USART_CSR_RXRDY_MASK)
128
        if (ulStatus & 0x2)
129
        {
130
                /* The interrupt was caused by the receiver getting data. */
131
                // FIXME
132
                // cChar = usart->rhr; 
133
 
134
                /* Because FreeRTOS is not supposed to run with nested interrupts, put all OS
135
                calls in a critical section . */
136
                portENTER_CRITICAL();
137
                        xQueueSendFromISR(xRxedChars, &cChar, &xHigherPriorityTaskWoken);
138
                portEXIT_CRITICAL();
139
        }
140
 
141
        /* The return value will be used by portEXIT_SWITCHING_ISR() to know if it
142
        should perform a vTaskSwitchContext(). */
143
        return ( xHigherPriorityTaskWoken );
144
}
145
/*-----------------------------------------------------------*/
146
 
147
/*
148
 * USART interrupt service routine.
149
 */
150
// FIXME it was __naked__ fuction
151
static void vUSART_ISR( void )
152
{
153
        /* This ISR can cause a context switch, so the first statement must be a
154
        call to the portENTER_SWITCHING_ISR() macro.  This must be BEFORE any
155
        variable declarations. */
156
        portENTER_SWITCHING_ISR();                      // TODO
157
 
158
        prvUSART_ISR_NonNakedBehaviour();
159
 
160
        /* Exit the ISR.  If a task was woken by either a character being received
161
        or transmitted then a context switch will occur. */
162
        portEXIT_SWITCHING_ISR();                       // TODO
163
}
164
/*-----------------------------------------------------------*/
165
 
166
 
167
// TODO : porting
168
/*
169
 * Init the serial port for the Minimal implementation.
170
 */
171
xComPortHandle xSerialPortInitMinimal( unsigned portLONG ulWantedBaud, unsigned portBASE_TYPE uxQueueLength )
172
{
173
        xComPortHandle xReturn = serHANDLE;
174
        // FIXME
175
        #define ADDR_UART_BASE          (0x90000000)
176
        volatile portBASE_TYPE  *usart = ADDR_UART_BASE;
177
        int cd; /* USART Clock Divider. */
178
 
179
        /* Create the rx and tx queues. */
180
        vprvSerialCreateQueues( uxQueueLength, &xRxedChars, &xCharsForTx );
181
 
182
        /* Configure USART. */
183
        if( ( xRxedChars != serINVALID_QUEUE ) &&
184
                ( xCharsForTx != serINVALID_QUEUE ) &&
185
                ( ulWantedBaud != ( unsigned portLONG ) 0 ) )
186
        {
187
                portENTER_CRITICAL();
188
                {
189
                        if( cd > 65535 )
190
                        {
191
                                /* Baudrate is too low */
192
                                return serINVALID_COMPORT_HANDLER;
193
                        }
194
 
195
                        // FIXME
196
                        // INTC_register_interrupt((__int_handler)&vUSART_ISR, serialPORT_USART_IRQ, INT1);     // interrupt register
197
                }
198
                portEXIT_CRITICAL();
199
        }
200
        else
201
        {
202
                xReturn = serINVALID_COMPORT_HANDLER;
203
        }
204
 
205
        return xReturn;
206
}
207
/*-----------------------------------------------------------*/
208
 
209
signed portBASE_TYPE xSerialGetChar( xComPortHandle pxPort, signed portCHAR *pcRxedChar, portTickType xBlockTime )
210
{
211
        /* The port handle is not required as this driver only supports UART0. */
212
        ( void ) pxPort;
213
 
214
        /* Get the next character from the buffer.  Return false if no characters
215
        are available, or arrive before xBlockTime expires. */
216
        if( xQueueReceive( xRxedChars, pcRxedChar, xBlockTime ) )
217
        {
218
                return pdTRUE;
219
        }
220
        else
221
        {
222
                return pdFALSE;
223
        }
224
}
225
/*-----------------------------------------------------------*/
226
 
227
void vSerialPutString( xComPortHandle pxPort, const signed portCHAR * const pcString, unsigned portSHORT usStringLength )
228
{
229
        signed portCHAR *pxNext;
230
 
231
        /* NOTE: This implementation does not handle the queue being full as no
232
        block time is used! */
233
 
234
        /* The port handle is not required as this driver only supports UART0. */
235
        ( void ) pxPort;
236
 
237
        /* Send each character in the string, one at a time. */
238
        pxNext = ( signed portCHAR * ) pcString;
239
        while( *pxNext )
240
        {
241
                xSerialPutChar( pxPort, *pxNext, serNO_BLOCK );
242
                pxNext++;
243
        }
244
}
245
/*-----------------------------------------------------------*/
246
 
247
signed portBASE_TYPE xSerialPutChar( xComPortHandle pxPort, signed portCHAR cOutChar, portTickType xBlockTime )
248
{
249
        // FIXME
250
        #define ADDR_UART_BASE          (0x90000000)
251
        volatile portBASE_TYPE  *usart = ADDR_UART_BASE;
252
 
253
        /* Place the character in the queue of characters to be transmitted. */
254
        if( xQueueSend( xCharsForTx, &cOutChar, xBlockTime ) != pdPASS )
255
        {
256
                return pdFAIL;
257
        }
258
 
259
        /* Turn on the Tx interrupt so the ISR will remove the character from the
260
        queue and send it.   This does not need to be in a critical section as
261
        if the interrupt has already removed the character the next interrupt
262
        will simply turn off the Tx interrupt again. */
263
 
264
        // FIXME
265
        // usart->ier = (1 << AVR32_USART_IER_TXRDY_OFFSET);
266
        // TODO : Turn on TX interrupt
267
 
268
        return pdPASS;
269
}
270
/*-----------------------------------------------------------*/
271
 
272
void vSerialClose( xComPortHandle xPort )
273
{
274
  /* Not supported as not required by the demo application. */
275
}
276
/*-----------------------------------------------------------*/
277
 
278
/*###########################################################*/
279
 
280
/*
281
 * Create the rx and tx queues.
282
 */
283
static void vprvSerialCreateQueues(  unsigned portBASE_TYPE uxQueueLength, xQueueHandle *pxRxedChars, xQueueHandle *pxCharsForTx )
284
{
285
        /* Create the queues used to hold Rx and Tx characters. */
286
        xRxedChars = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR ) );
287
        xCharsForTx = xQueueCreate( uxQueueLength + 1, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR ) );
288
 
289
        /* Pass back a reference to the queues so the serial API file can
290
        post/receive characters. */
291
        *pxRxedChars = xRxedChars;
292
        *pxCharsForTx = xCharsForTx;
293
}
294
/*-----------------------------------------------------------*/

powered by: WebSVN 2.1.0

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