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

Subversion Repositories openrisc

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 587 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
Changes from V1.2.5
56
 
57
        +  Clear overrun errors in the Rx ISR.  Overrun errors prevent any further
58
           characters being received.
59
 
60
Changes from V2.0.0
61
 
62
        + Use portTickType in place of unsigned pdLONG for delay periods.
63
        + cQueueReieveFromISR() used in place of xQueueReceive() in ISR.
64
*/
65
 
66
/* BASIC INTERRUPT DRIVEN SERIAL PORT DRIVER. */
67
 
68
/* Scheduler header files. */
69
#include "FreeRTOS.h"
70
#include "task.h"
71
#include "serial.h"
72
#include "queue.h"
73
 
74
/*
75
 * Prototypes for ISR's.  The PIC architecture means that these functions
76
 * have to be called from port.c.  The prototypes are not however included
77
 * in the header as the header is common to all ports.
78
 */
79
void vSerialTxISR( void );
80
void vSerialRxISR( void );
81
 
82
/* Hardware pin definitions. */
83
#define serTX_PIN       TRISCbits.TRISC6
84
#define serRX_PIN       TRISCbits.TRISC7
85
 
86
/* Bit/register definitions. */
87
#define serINPUT                                ( 1 )
88
#define serOUTPUT                               ( 0 )
89
#define serTX_ENABLE                    ( ( unsigned short ) 1 )
90
#define serRX_ENABLE                    ( ( unsigned short ) 1 )
91
#define serHIGH_SPEED                   ( ( unsigned short ) 1 )
92
#define serCONTINUOUS_RX                ( ( unsigned short ) 1 )
93
#define serCLEAR_OVERRUN                ( ( unsigned short ) 0 )
94
#define serINTERRUPT_ENABLED    ( ( unsigned short ) 1 )
95
#define serINTERRUPT_DISABLED   ( ( unsigned short ) 0 )
96
 
97
/* All ISR's use the PIC18 low priority interrupt. */
98
#define                                                 serLOW_PRIORITY ( 0 )
99
 
100
/*-----------------------------------------------------------*/
101
 
102
/* Queues to interface between comms API and interrupt routines. */
103
static xQueueHandle xRxedChars;
104
static xQueueHandle xCharsForTx;
105
 
106
/*-----------------------------------------------------------*/
107
 
108
xComPortHandle xSerialPortInitMinimal( unsigned long ulWantedBaud, unsigned portBASE_TYPE uxQueueLength )
109
{
110
unsigned long ulBaud;
111
 
112
        /* Calculate the baud rate generator constant.
113
        SPBRG = ( (FOSC / Desired Baud Rate) / 16 ) - 1 */
114
        ulBaud = configCPU_CLOCK_HZ / ulWantedBaud;
115
        ulBaud /= ( unsigned long ) 16;
116
        ulBaud -= ( unsigned long ) 1;
117
 
118
        /* Create the queues used by the ISR's to interface to tasks. */
119
        xRxedChars = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( char ) );
120
        xCharsForTx = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( char ) );
121
 
122
        portENTER_CRITICAL();
123
        {
124
                /* Start with config registers cleared, so we can just set the wanted
125
                bits. */
126
                TXSTA = ( unsigned short ) 0;
127
                RCSTA = ( unsigned short ) 0;
128
 
129
                /* Set the baud rate generator using the above calculated constant. */
130
                SPBRG = ( unsigned char ) ulBaud;
131
 
132
                /* Setup the IO pins to enable the USART IO. */
133
                serTX_PIN = serOUTPUT;
134
                serRX_PIN = serINPUT;
135
 
136
                /* Set the serial interrupts to use the same priority as the tick. */
137
                IPR1bits.TXIP = serLOW_PRIORITY;
138
                IPR1bits.RCIP = serLOW_PRIORITY;
139
 
140
                /* Setup Tx configuration. */
141
                TXSTAbits.BRGH = serHIGH_SPEED;
142
                TXSTAbits.TXEN = serTX_ENABLE;
143
 
144
                /* Setup Rx configuration. */
145
                RCSTAbits.SPEN = serRX_ENABLE;
146
                RCSTAbits.CREN = serCONTINUOUS_RX;
147
 
148
                /* Enable the Rx interrupt now, the Tx interrupt will get enabled when
149
                we have data to send. */
150
                PIE1bits.RCIE = serINTERRUPT_ENABLED;
151
        }
152
        portEXIT_CRITICAL();
153
 
154
        /* Unlike other ports, this serial code does not allow for more than one
155
        com port.  We therefore don't return a pointer to a port structure and
156
        can     instead just return NULL. */
157
        return NULL;
158
}
159
/*-----------------------------------------------------------*/
160
 
161
xComPortHandle xSerialPortInit( eCOMPort ePort, eBaud eWantedBaud, eParity eWantedParity, eDataBits eWantedDataBits, eStopBits eWantedStopBits, unsigned portBASE_TYPE uxBufferLength )
162
{
163
        /* This is not implemented in this port.
164
        Use xSerialPortInitMinimal() instead. */
165
}
166
/*-----------------------------------------------------------*/
167
 
168
portBASE_TYPE xSerialGetChar( xComPortHandle pxPort, signed char *pcRxedChar, portTickType xBlockTime )
169
{
170
        /* Get the next character from the buffer.  Return false if no characters
171
        are available, or arrive before xBlockTime expires. */
172
        if( xQueueReceive( xRxedChars, pcRxedChar, xBlockTime ) )
173
        {
174
                return pdTRUE;
175
        }
176
        else
177
        {
178
                return pdFALSE;
179
        }
180
}
181
/*-----------------------------------------------------------*/
182
 
183
portBASE_TYPE xSerialPutChar( xComPortHandle pxPort, signed char cOutChar, portTickType xBlockTime )
184
{
185
        /* Return false if after the block time there is no room on the Tx queue. */
186
        if( xQueueSend( xCharsForTx, ( const void * ) &cOutChar, xBlockTime ) != pdPASS )
187
        {
188
                return pdFAIL;
189
        }
190
 
191
        /* Turn interrupt on - ensure the compiler only generates a single
192
        instruction for this. */
193
        PIE1bits.TXIE = serINTERRUPT_ENABLED;
194
 
195
        return pdPASS;
196
}
197
/*-----------------------------------------------------------*/
198
 
199
void vSerialClose( xComPortHandle xPort )
200
{
201
        /* Not implemented for this port.
202
        To implement, turn off the interrupts and delete the memory
203
        allocated to the queues. */
204
}
205
/*-----------------------------------------------------------*/
206
 
207
#pragma interruptlow vSerialRxISR save=PRODH, PRODL, TABLAT, section(".tmpdata")
208
void vSerialRxISR( void )
209
{
210
char cChar;
211
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
212
 
213
        /* Get the character and post it on the queue of Rxed characters.
214
        If the post causes a task to wake force a context switch as the woken task
215
        may have a higher priority than the task we have interrupted. */
216
        cChar = RCREG;
217
 
218
        /* Clear any overrun errors. */
219
        if( RCSTAbits.OERR )
220
        {
221
                RCSTAbits.CREN = serCLEAR_OVERRUN;
222
                RCSTAbits.CREN = serCONTINUOUS_RX;
223
        }
224
 
225
        xQueueSendFromISR( xRxedChars, ( const void * ) &cChar, &xHigherPriorityTaskWoken );
226
 
227
        if( xHigherPriorityTaskWoken )
228
        {
229
                taskYIELD();
230
        }
231
}
232
/*-----------------------------------------------------------*/
233
 
234
#pragma interruptlow vSerialTxISR save=PRODH, PRODL, TABLAT, section(".tmpdata")
235
void vSerialTxISR( void )
236
{
237
char cChar, cTaskWoken = pdFALSE;
238
 
239
        if( xQueueReceiveFromISR( xCharsForTx, &cChar, &cTaskWoken ) == pdTRUE )
240
        {
241
                /* Send the next character queued for Tx. */
242
                TXREG = cChar;
243
        }
244
        else
245
        {
246
                /* Queue empty, nothing to send. */
247
                PIE1bits.TXIE = serINTERRUPT_DISABLED;
248
        }
249
}
250
 
251
 
252
 

powered by: WebSVN 2.1.0

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