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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [freertos-6.1.1/] [Demo/] [H8S/] [RTOSDemo/] [serial/] [serial.c] - Blame information for rev 612

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

Line No. Rev Author Line
1 588 jeremybenn
/*
2
    FreeRTOS V6.1.1 - Copyright (C) 2011 Real Time Engineers Ltd.
3
 
4
    ***************************************************************************
5
    *                                                                         *
6
    * If you are:                                                             *
7
    *                                                                         *
8
    *    + New to FreeRTOS,                                                   *
9
    *    + Wanting to learn FreeRTOS or multitasking in general quickly       *
10
    *    + Looking for basic training,                                        *
11
    *    + Wanting to improve your FreeRTOS skills and productivity           *
12
    *                                                                         *
13
    * then take a look at the FreeRTOS books - available as PDF or paperback  *
14
    *                                                                         *
15
    *        "Using the FreeRTOS Real Time Kernel - a Practical Guide"        *
16
    *                  http://www.FreeRTOS.org/Documentation                  *
17
    *                                                                         *
18
    * A pdf reference manual is also available.  Both are usually delivered   *
19
    * to your inbox within 20 minutes to two hours when purchased between 8am *
20
    * and 8pm GMT (although please allow up to 24 hours in case of            *
21
    * exceptional circumstances).  Thank you for your support!                *
22
    *                                                                         *
23
    ***************************************************************************
24
 
25
    This file is part of the FreeRTOS distribution.
26
 
27
    FreeRTOS is free software; you can redistribute it and/or modify it under
28
    the terms of the GNU General Public License (version 2) as published by the
29
    Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
30
    ***NOTE*** The exception to the GPL is included to allow you to distribute
31
    a combined work that includes FreeRTOS without being obliged to provide the
32
    source code for proprietary components outside of the FreeRTOS kernel.
33
    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
34
    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
35
    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
36
    more details. You should have received a copy of the GNU General Public
37
    License and the FreeRTOS license exception along with FreeRTOS; if not it
38
    can be viewed here: http://www.freertos.org/a00114.html and also obtained
39
    by writing to Richard Barry, contact details for whom are available on the
40
    FreeRTOS WEB site.
41
 
42
    1 tab == 4 spaces!
43
 
44
    http://www.FreeRTOS.org - Documentation, latest information, license and
45
    contact details.
46
 
47
    http://www.SafeRTOS.com - A version that is certified for use in safety
48
    critical systems.
49
 
50
    http://www.OpenRTOS.com - Commercial support, development, porting,
51
    licensing and training services.
52
*/
53
 
54
 
55
/* BASIC INTERRUPT DRIVEN SERIAL PORT DRIVER for port 1.
56
 
57
Note that this driver is written to test the RTOS port and is not intended
58
to represent an optimised solution.  In particular no use is made of the DMA
59
peripheral. */
60
 
61
/* Standard include files. */
62
#include <stdlib.h>
63
 
64
/* Scheduler include files. */
65
#include "FreeRTOS.h"
66
#include "queue.h"
67
#include "task.h"
68
 
69
/* Demo application include files. */
70
#include "serial.h"
71
 
72
/* The queues used to communicate between the task code and the interrupt
73
service routines. */
74
static xQueueHandle xRxedChars;
75
static xQueueHandle xCharsForTx;
76
 
77
/* Hardware specific constants. */
78
#define serTX_INTERRUPT                         ( ( unsigned char ) 0x80 )
79
#define serRX_INTERRUPT                         ( ( unsigned char ) 0x40 )
80
#define serTX_ENABLE                            ( ( unsigned char ) 0x20 )
81
#define serRX_ENABLE                            ( ( unsigned char ) 0x10 )
82
 
83
/* Macros to turn on and off the serial port THRE interrupt while leaving the
84
other register bits in their correct state.   The Rx interrupt is always
85
enabled. */
86
#define serTX_INTERRUPT_ON()            SCR1 = serTX_INTERRUPT | serRX_INTERRUPT | serTX_ENABLE | serRX_ENABLE;                                                                 
87
#define serTX_INTERRUPT_OFF()           SCR1 =                                   serRX_INTERRUPT | serTX_ENABLE | serRX_ENABLE;
88
 
89
/* Bit used to switch on the channel 1 serial port in the module stop
90
register. */
91
#define serMSTP6                                        ( ( unsigned short ) 0x0040 )
92
 
93
/* Interrupt service routines.  Note that the Rx and Tx service routines can
94
cause a context switch and are therefore defined with the saveall attribute in
95
addition to the interrupt_handler attribute.  See the FreeRTOS.org WEB site
96
documentation for a full explanation.*/
97
void vCOM_1_Rx_ISR( void ) __attribute__ ( ( saveall, interrupt_handler ) );
98
void vCOM_1_Tx_ISR( void ) __attribute__ ( ( saveall, interrupt_handler ) );
99
void vCOM_1_Error_ISR( void ) __attribute__ ( ( interrupt_handler ) );
100
 
101
/*-----------------------------------------------------------*/
102
 
103
/*
104
 * Initialise port 1 for interrupt driven communications.
105
 */
106
xComPortHandle xSerialPortInitMinimal( unsigned long ulWantedBaud, unsigned portBASE_TYPE uxQueueLength )
107
{
108
        /* Create the queues used to communicate between the tasks and the
109
        interrupt service routines. */
110
        xRxedChars = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( signed char ) );
111
        xCharsForTx = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( signed char ) );
112
 
113
        /* No parity, 8 data bits and 1 stop bit is the default so does not require
114
        configuration - setup the remains of the hardware. */
115
        portENTER_CRITICAL();
116
        {
117
                /* Turn channel 1 on. */
118
                MSTPCR &= ~serMSTP6;
119
 
120
                /* Enable the channels and the Rx interrupt.  The Tx interrupt is only
121
                enabled when data is being transmitted. */
122
                SCR1 = serRX_INTERRUPT | serTX_ENABLE | serRX_ENABLE;
123
 
124
                /* Bit rate settings for 22.1184MHz clock only!. */
125
                switch( ulWantedBaud )
126
                {
127
                        case 4800       :       BRR1 = 143;
128
                                                        break;
129
                        case 9600       :       BRR1 = 71;
130
                                                        break;
131
                        case 19200      :       BRR1 = 35;
132
                                                        break;
133
                        case 38400      :       BRR1 = 17;
134
                                                        break;
135
                        case 57600      :       BRR1 = 11;
136
                                                        break;
137
                        case 115200     :       BRR1 = 5;
138
                                                        break;
139
                        default         :       BRR1 = 5;
140
                                                        break;
141
                }
142
        }
143
        portEXIT_CRITICAL();
144
 
145
        /* Unlike some ports, this driver code does not allow for more than one
146
        com port.  We therefore don't return a pointer to a port structure and can
147
        instead just return NULL. */
148
        return NULL;
149
}
150
/*-----------------------------------------------------------*/
151
 
152
signed portBASE_TYPE xSerialGetChar( xComPortHandle pxPort, signed char *pcRxedChar, portTickType xBlockTime )
153
{
154
        /* Get the next character from the buffer queue.  Return false if no characters
155
        are available, or arrive before xBlockTime expires. */
156
        if( xQueueReceive( xRxedChars, pcRxedChar, xBlockTime ) )
157
        {
158
                return pdTRUE;
159
        }
160
        else
161
        {
162
                return pdFALSE;
163
        }
164
}
165
/*-----------------------------------------------------------*/
166
 
167
signed portBASE_TYPE xSerialPutChar( xComPortHandle pxPort, signed char cOutChar, portTickType xBlockTime )
168
{
169
signed portBASE_TYPE xReturn = pdPASS;
170
 
171
        /* Return false if after the block time there is no room on the Tx queue. */
172
        portENTER_CRITICAL();
173
        {
174
                /* Send a character to the queue of characters waiting transmission.
175
                The queue is serviced by the Tx ISR. */
176
                if( xQueueSend( xCharsForTx, &cOutChar, xBlockTime ) != pdPASS )
177
                {
178
                        /* Could not post onto the queue. */
179
                        xReturn = pdFAIL;
180
                }
181
                else
182
                {
183
                        /* The message was posted onto the queue so we turn on the Tx
184
                        interrupt to allow the Tx ISR to remove the character from the
185
                        queue. */
186
                        serTX_INTERRUPT_ON();
187
                }
188
        }
189
        portEXIT_CRITICAL();
190
 
191
        return xReturn;
192
}
193
/*-----------------------------------------------------------*/
194
 
195
void vSerialClose( xComPortHandle xPort )
196
{
197
        /* Not supported. */
198
        ( void ) xPort;
199
}
200
/*-----------------------------------------------------------*/
201
 
202
void vCOM_1_Rx_ISR( void )
203
{
204
        /* This can cause a context switch so this macro must be the first line
205
        in the function. */
206
        portENTER_SWITCHING_ISR();
207
 
208
        /* As this is a switching ISR the local variables must be declared as
209
        static. */
210
        static char cRxByte;
211
        static portBASE_TYPE xHigherPriorityTaskWoken;
212
 
213
                xHigherPriorityTaskWoken = pdFALSE;
214
 
215
                /* Get the character. */
216
                cRxByte = RDR1;
217
 
218
                /* Post the character onto the queue of received characters - noting
219
                whether or not this wakes a task. */
220
                xQueueSendFromISR( xRxedChars, &cRxByte, &xHigherPriorityTaskWoken );
221
 
222
                /* Clear the interrupt. */
223
                SSR1 &= ~serRX_INTERRUPT;
224
 
225
        /* This must be the last line in the function.  We pass cTaskWokenByPost so
226
        a context switch will occur if the received character woke a task that has
227
        a priority higher than the task we interrupted. */
228
        portEXIT_SWITCHING_ISR( xHigherPriorityTaskWoken );
229
}
230
/*-----------------------------------------------------------*/
231
 
232
void vCOM_1_Tx_ISR( void )
233
{
234
        /* This can cause a context switch so this macro must be the first line
235
        in the function. */
236
        portENTER_SWITCHING_ISR();
237
 
238
        /* As this is a switching ISR the local variables must be declared as
239
        static. */
240
        static char cTxByte;
241
        static signed portBASE_TYPE xTaskWokenByTx;
242
 
243
                /* This variable is static so must be explicitly reinitialised each
244
                time the function executes. */
245
                xTaskWokenByTx = pdFALSE;
246
 
247
                /* The interrupt was caused by the THR becoming empty.  Are there any
248
                more characters to transmit?  Note whether or not the Tx interrupt has
249
                woken a task. */
250
                if( xQueueReceiveFromISR( xCharsForTx, &cTxByte, &xTaskWokenByTx ) == pdTRUE )
251
                {
252
                        /* A character was retrieved from the queue so can be sent to the
253
                        THR now. */
254
                        TDR1 = cTxByte;
255
 
256
                        /* Clear the interrupt. */
257
                        SSR1 &= ~serTX_INTERRUPT;
258
                }
259
                else
260
                {
261
                        /* Queue empty, nothing to send so turn off the Tx interrupt. */
262
                        serTX_INTERRUPT_OFF();
263
                }
264
 
265
        /* This must be the last line in the function.  We pass cTaskWokenByTx so
266
        a context switch will occur if the Tx'ed character woke a task that has
267
        a priority higher than the task we interrupted. */
268
        portEXIT_SWITCHING_ISR( xTaskWokenByTx );
269
}
270
/*-----------------------------------------------------------*/
271
 
272
/*
273
 * This ISR cannot cause a context switch so requires no special
274
 * considerations.
275
 */
276
void vCOM_1_Error_ISR( void )
277
{
278
volatile unsigned char ucIn;
279
 
280
        ucIn = SSR1;
281
        SSR1 = 0;
282
}
283
 

powered by: WebSVN 2.1.0

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