00001 /********************************************************************************* 00002 00003 Copyright 2006-2008 MakingThings 00004 00005 Licensed under the Apache License, 00006 Version 2.0 (the "License"); you may not use this file except in compliance 00007 with the License. You may obtain a copy of the License at 00008 00009 http://www.apache.org/licenses/LICENSE-2.0 00010 00011 Unless required by applicable law or agreed to in writing, software distributed 00012 under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 00013 CONDITIONS OF ANY KIND, either express or implied. See the License for 00014 the specific language governing permissions and limitations under the License. 00015 00016 *********************************************************************************/ 00017 00018 /* Library includes. */ 00019 #include <string.h> 00020 #include <stdio.h> 00021 00022 /* Scheduler includes. */ 00023 #include "FreeRTOS.h" 00024 #include "task.h" 00025 00026 /* Hardware specific headers. */ 00027 #include "Board.h" 00028 #include "AT91SAM7X256.h" 00029 00030 #include "config.h" 00031 #include "io.h" 00032 00033 #include "serial.h" 00034 #include "serial_internal.h" 00035 00036 #define DEFAULT_SERIAL_Q_LEN 100 00037 Serial_ Serial[ SERIAL_PORTS ]; 00038 00039 extern void ( SerialIsr_Wrapper )( void ); 00040 00041 static int Serial_Init( int index ); 00042 static int Serial_Deinit( int index ); 00043 static int Serial_SetDefault( int index ); 00044 static int Serial_SetDetails( int index ); 00045 00046 00047 /** \file serial.c 00048 Functions for working with the Serial Interface on the Make Controller Board. 00049 */ 00050 00051 /** \defgroup serial Serial 00052 Send and receive data via the Make Controller's serial ports. 00053 00054 There are 2 full serial ports on the Make Controller, and this library provides support for both of them. 00055 00056 Control all of the common serial characteristics including: 00057 - \b baud - the speed of the connection (110 - > 2M) in baud or raw bits per second. 9600 baud is the default setting. 00058 - \b bits - the size of each character (5 - 8). 8 bits is the default setting. 00059 - \b stopBits - the number of stop bits transmitted (1 or 2) 1 stop bit is the default setting. 00060 - \b parity - the parity policy (-1 is odd, 0 is none and 1 is even). Even is the default setting. 00061 - \b hardwareHandshake - whether hardware handshaking is used or not. HardwareHandshaking is off by default. 00062 00063 The subsystem is supplied with small input and output buffers (of 100 characters each) and at present 00064 the implementation is interrupt per character so it's not particularly fast. 00065 00066 \todo Convert to DMA interface for higher performance, and add support for debug UART 00067 00068 \ingroup Core 00069 @{ 00070 */ 00071 00072 /** 00073 Set the active state of a serial port. 00074 This is automatically set to 00075 true by any call to Serial_Write or Serial_Read. 00076 @param index Which serial port - SERIAL_0 or SERIAL_1 00077 @param state An integer specifying the active state - 1 (on) or 0 (off). 00078 @return CONTROLLER_OK (=0) on success. 00079 */ 00080 int Serial_SetActive( int index, int state ) 00081 { 00082 if ( index < 0 || index >= SERIAL_PORTS ) 00083 return CONTROLLER_ERROR_ILLEGAL_INDEX; 00084 00085 Serial_* sp = &Serial[ index ]; 00086 00087 if ( state && !sp->active ) 00088 return Serial_Init( index ); 00089 else if( !state && sp->active ) 00090 return Serial_Deinit( index ); 00091 00092 return CONTROLLER_OK; 00093 } 00094 00095 /** 00096 Read the active state of the Serial subsystem. 00097 @param index Which serial port - SERIAL_0 or SERIAL_1 00098 @return State - 1/non-zero (on) or 0 (off). 00099 */ 00100 bool Serial_GetActive( int index ) 00101 { 00102 if ( index < 0 || index >= SERIAL_PORTS ) 00103 return CONTROLLER_ERROR_ILLEGAL_INDEX; 00104 00105 Serial_* sp = &Serial[ index ]; 00106 00107 return sp->active; 00108 } 00109 00110 /** 00111 Write a block of data to the Serial port. Will block for the time specified (in ms) 00112 if the queue fills up. 00113 @param index Which serial port - SERIAL_0 or SERIAL_1 00114 @param buffer A pointer to the buffer to write from. 00115 @param count An integer specifying the number of bytes to write. 00116 @param timeout Time in milliseconds to block waiting for the queue to free up. 0 means don't wait. 00117 @return status. 00118 */ 00119 int Serial_Write( int index, uchar* buffer, int count, int timeout ) 00120 { 00121 if ( index < 0 || index >= SERIAL_PORTS ) 00122 return CONTROLLER_ERROR_ILLEGAL_INDEX; 00123 00124 Serial_* sp = &Serial[ index ]; 00125 00126 if ( !sp->active ) 00127 { 00128 int status = Serial_SetActive( index, 1 ); 00129 if ( status != CONTROLLER_OK ) 00130 return status; 00131 } 00132 00133 // Do the business 00134 while ( count ) 00135 { 00136 if( xQueueSend( sp->transmitQueue, buffer++, timeout ) == 0 ) 00137 return CONTROLLER_ERROR_QUEUE_ERROR; 00138 count--; 00139 } 00140 00141 /* Turn on the Tx interrupt so the ISR will remove the character from the 00142 queue and send it. This does not need to be in a critical section as 00143 if the interrupt has already removed the character the next interrupt 00144 will simply turn off the Tx interrupt again. */ 00145 sp->at91UARTRegs->US_IER = AT91C_US_TXRDY; 00146 00147 return CONTROLLER_OK; 00148 } 00149 00150 /** 00151 Read data from the Serial port. Will block for the time specified (in ms) if 00152 there are insufficient characters. Blocking can be avoided if Serial_GetReadable( ) 00153 is used to determine how many characters are available to read prior to calling 00154 this function. 00155 @param index Which serial port - SERIAL_0 or SERIAL_1 00156 @param buffer A pointer to the buffer to read into. 00157 @param size An integer specifying the maximum number of bytes to read. 00158 @param timeout Time in milliseconds to block waiting for the specified number of bytes. 0 means don't wait. 00159 @return number of bytes read (>=0) or error <0 . 00160 */ 00161 int Serial_Read( int index, uchar* buffer, int size, int timeout ) 00162 { 00163 if ( index < 0 || index >= SERIAL_PORTS ) 00164 return CONTROLLER_ERROR_ILLEGAL_INDEX; 00165 00166 Serial_* sp = &Serial[ index ]; 00167 00168 if ( !sp->active ) 00169 { 00170 int status = Serial_SetActive( index, 1 ); 00171 if ( status != CONTROLLER_OK ) 00172 return status; 00173 } 00174 00175 // Do the business 00176 int count = 0; 00177 while ( count < size ) 00178 { 00179 /* Place the character in the queue of characters to be transmitted. */ 00180 if( xQueueReceive( sp->receiveQueue, buffer++, timeout ) == 0 ) 00181 break; 00182 count++; 00183 } 00184 00185 return count; 00186 } 00187 00188 /** 00189 Returns the number of bytes in the queue waiting to be read. 00190 @param index Which serial port - SERIAL_0 or SERIAL_1 00191 @return bytes in the receive queue. 00192 */ 00193 int Serial_GetReadable( int index ) 00194 { 00195 if ( index < 0 || index >= SERIAL_PORTS ) 00196 return CONTROLLER_ERROR_ILLEGAL_INDEX; 00197 00198 Serial_* sp = &Serial[ index ]; 00199 00200 return uxQueueMessagesWaiting( sp->receiveQueue ); 00201 } 00202 00203 /** 00204 Sends a character (in the range of 0 to 255) to the write queue 00205 @param index Which serial port - SERIAL_0 or SERIAL_1 00206 @param character The character to be sent. Must be 0 <= c < 256. 00207 @return status. 00208 */ 00209 int Serial_SetChar( int index, int character ) 00210 { 00211 if ( index < 0 || index >= SERIAL_PORTS ) 00212 return CONTROLLER_ERROR_ILLEGAL_INDEX; 00213 00214 Serial_* sp = &Serial[ index ]; 00215 00216 if ( !sp->active ) 00217 { 00218 int status = Serial_SetActive( index, 1 ); 00219 if ( status != CONTROLLER_OK ) 00220 return status; 00221 } 00222 00223 if ( character >= 0 && character < 256 ) 00224 { 00225 unsigned char c = (unsigned char)character; 00226 if( xQueueSend( sp->transmitQueue, &c, 0 ) == 0 ) 00227 return CONTROLLER_ERROR_QUEUE_ERROR; 00228 sp->at91UARTRegs->US_IER = AT91C_US_TXRDY; 00229 } 00230 00231 return CONTROLLER_OK; 00232 } 00233 00234 /** 00235 Sets the serial baud rate. 00236 @param index Which serial port - SERIAL_0 or SERIAL_1 00237 @param baud The desired baud rate. 00238 @return status. 00239 */ 00240 int Serial_SetBaud( int index, int baud ) 00241 { 00242 if ( index < 0 || index >= SERIAL_PORTS ) 00243 return CONTROLLER_ERROR_ILLEGAL_INDEX; 00244 00245 Serial_* sp = &Serial[ index ]; 00246 00247 // If there are no default values, get some 00248 if ( !sp->detailsInitialized ) 00249 Serial_SetDefault( index ); 00250 00251 sp->baud = baud; 00252 Serial_SetDetails( index ); 00253 00254 return CONTROLLER_OK; 00255 } 00256 00257 /** 00258 Sets the number of bits per character. 5 - 8 are legal values. 8 is the default. 00259 @param index Which serial port - SERIAL_0 or SERIAL_1 00260 @param bits bits per character 00261 @return status. 00262 */ 00263 int Serial_SetBits( int index, int bits ) 00264 { 00265 if ( index < 0 || index >= SERIAL_PORTS ) 00266 return CONTROLLER_ERROR_ILLEGAL_INDEX; 00267 00268 Serial_* sp = &Serial[ index ]; 00269 00270 // If there are no default values, get some 00271 if ( !sp->detailsInitialized ) 00272 Serial_SetDefault( index ); 00273 00274 if ( sp->bits >= 5 && sp->bits <= 8 ) 00275 sp->bits = bits; 00276 else 00277 sp->bits = 8; 00278 00279 Serial_SetDetails( index ); 00280 00281 return CONTROLLER_OK; 00282 } 00283 00284 /** 00285 Sets the parity. -1 is odd, 0 is none, 1 is even. The default is none - 0. 00286 @param index Which serial port - SERIAL_0 or SERIAL_1 00287 @param parity -1, 0 or 1. 00288 @return status. 00289 */ 00290 int Serial_SetParity( int index, int parity ) 00291 { 00292 if ( index < 0 || index >= SERIAL_PORTS ) 00293 return CONTROLLER_ERROR_ILLEGAL_INDEX; 00294 00295 Serial_* sp = &Serial[ index ]; 00296 00297 // If there are no default values, get some 00298 if ( !sp->detailsInitialized ) 00299 Serial_SetDefault( index ); 00300 00301 if ( parity >= -1 && parity <= 1 ) 00302 sp->parity = parity; 00303 else 00304 sp->parity = 1; 00305 Serial_SetDetails( index ); 00306 00307 return CONTROLLER_OK; 00308 } 00309 00310 /** 00311 Sets the stop bits per character. 1 or 2 are legal values. 1 is the default. 00312 @param index Which serial port - SERIAL_0 or SERIAL_1 00313 @param stopBits stop bits per character 00314 @return status. 00315 */ 00316 int Serial_SetStopBits( int index, int stopBits ) 00317 { 00318 if ( index < 0 || index >= SERIAL_PORTS ) 00319 return CONTROLLER_ERROR_ILLEGAL_INDEX; 00320 00321 Serial_* sp = &Serial[ index ]; 00322 00323 // If there are no default values, get some 00324 if ( !sp->detailsInitialized ) 00325 Serial_SetDefault( index ); 00326 00327 if ( stopBits == 1 || stopBits == 2 ) 00328 sp->stopBits = stopBits; 00329 else 00330 sp->stopBits = 1; 00331 00332 Serial_SetDetails( index ); 00333 00334 return CONTROLLER_OK; 00335 } 00336 00337 /** 00338 Sets whether hardware handshaking is being used. 00339 @param index Which serial port - SERIAL_0 or SERIAL_1 00340 @param hardwareHandshake sets hardware handshaking on (1) or off (0) 00341 @return status. 00342 */ 00343 int Serial_SetHardwareHandshake( int index, int hardwareHandshake ) 00344 { 00345 if ( index < 0 || index >= SERIAL_PORTS ) 00346 return CONTROLLER_ERROR_ILLEGAL_INDEX; 00347 00348 Serial_* sp = &Serial[ index ]; 00349 00350 // If there are no default values, get some 00351 if ( !sp->detailsInitialized ) 00352 Serial_SetDefault( index ); 00353 00354 sp->hardwareHandshake = hardwareHandshake; 00355 Serial_SetDetails( index ); 00356 00357 return CONTROLLER_OK; 00358 } 00359 00360 /** 00361 Returns a single character from the receive queue if available. 00362 This character is returned unsigned - i.e. having a value of 0 - 255. 00363 The return value is -1 if there is no character waiting. 00364 @param index Which serial port - SERIAL_0 or SERIAL_1 00365 @return character from the queue or -1 if there is no character. 00366 */ 00367 int Serial_GetChar( int index ) 00368 { 00369 if ( index < 0 || index >= SERIAL_PORTS ) 00370 return CONTROLLER_ERROR_ILLEGAL_INDEX; 00371 00372 Serial_* sp = &Serial[ index ]; 00373 00374 if ( !sp->active ) 00375 { 00376 int status = Serial_SetActive( index, 1 ); 00377 if ( status != CONTROLLER_OK ) 00378 return -1; 00379 } 00380 00381 if ( uxQueueMessagesWaiting( sp->receiveQueue ) ) 00382 { 00383 unsigned char c; 00384 if( xQueueReceive( sp->receiveQueue, &c, 0 ) == 0 ) 00385 return -1; 00386 else 00387 return (int)c; 00388 } 00389 else 00390 return -1; 00391 } 00392 00393 /** 00394 Returns the current baud rate 00395 @param index Which serial port - SERIAL_0 or SERIAL_1 00396 @return baud 00397 */ 00398 int Serial_GetBaud( int index ) 00399 { 00400 if ( index < 0 || index >= SERIAL_PORTS ) 00401 return CONTROLLER_ERROR_ILLEGAL_INDEX; 00402 00403 Serial_* sp = &Serial[ index ]; 00404 00405 // If there are no default values, get some 00406 if ( !sp->detailsInitialized ) 00407 Serial_SetDefault( index ); 00408 00409 return sp->baud; 00410 } 00411 00412 /** 00413 Returns the number of bits for each character 00414 @param index Which serial port - SERIAL_0 or SERIAL_1 00415 @return bits 00416 */ 00417 int Serial_GetBits( int index ) 00418 { 00419 if ( index < 0 || index >= SERIAL_PORTS ) 00420 return CONTROLLER_ERROR_ILLEGAL_INDEX; 00421 00422 Serial_* sp = &Serial[ index ]; 00423 00424 // If there are no default values, get some 00425 if ( !sp->detailsInitialized ) 00426 Serial_SetDefault( index ); 00427 00428 return sp->bits; 00429 } 00430 00431 /** 00432 Returns the current parity. -1 means odd, 0 means none, 1 means even 00433 @param index Which serial port - SERIAL_0 or SERIAL_1 00434 @return parity 00435 */ 00436 int Serial_GetParity( int index ) 00437 { 00438 if ( index < 0 || index >= SERIAL_PORTS ) 00439 return CONTROLLER_ERROR_ILLEGAL_INDEX; 00440 00441 Serial_* sp = &Serial[ index ]; 00442 00443 // If there are no default values, get some 00444 if ( !sp->detailsInitialized ) 00445 Serial_SetDefault( index ); 00446 00447 return sp->parity; 00448 } 00449 00450 /** 00451 Returns the number of stop bits. 00452 @param index Which serial port - SERIAL_0 or SERIAL_1 00453 @return stopBits 00454 */ 00455 int Serial_GetStopBits( int index ) 00456 { 00457 if ( index < 0 || index >= SERIAL_PORTS ) 00458 return CONTROLLER_ERROR_ILLEGAL_INDEX; 00459 00460 Serial_* sp = &Serial[ index ]; 00461 00462 // If there are no default values, get some 00463 if ( !sp->detailsInitialized ) 00464 Serial_SetDefault( index ); 00465 00466 return sp->stopBits; 00467 } 00468 00469 /** 00470 Returns whether hardware handshaking is being employed or not. 00471 @param index Which serial port - SERIAL_0 or SERIAL_1 00472 @return hardwareHandshake 00473 */ 00474 int Serial_GetHardwareHandshake( int index ) 00475 { 00476 if ( index < 0 || index >= SERIAL_PORTS ) 00477 return CONTROLLER_ERROR_ILLEGAL_INDEX; 00478 00479 Serial_* sp = &Serial[ index ]; 00480 00481 // If there are no default values, get some 00482 if ( !sp->detailsInitialized ) 00483 Serial_SetDefault( index ); 00484 00485 return sp->hardwareHandshake; 00486 } 00487 00488 /** 00489 Clear out the serial port. 00490 Ensures that there are no bytes in the incoming buffer. 00491 @param index Which serial port - SERIAL_0 or SERIAL_1 00492 00493 \b Example 00494 \code 00495 Serial_SetActive(SERIAL_0, 1); 00496 Serial_Flush(SERIAL_0); // after starting up, make sure there's no junk in there 00497 \endcode 00498 */ 00499 void Serial_Flush( int index ) 00500 { 00501 char c; 00502 if ( index < 0 || index >= SERIAL_PORTS ) 00503 return; 00504 00505 while( Serial_GetReadable( index ) ) 00506 c = Serial_GetChar( index ); 00507 } 00508 00509 /** 00510 Reset the error flags in the serial system. 00511 In the normal course of operation, the serial system may experience 00512 a variety of different error modes, including buffer overruns, framing 00513 and parity errors, and more. When in an error state, the serial system 00514 may behave differently than normal. 00515 00516 Serial_ClearErrors() resets the appropriate status bits to a state of 00517 normal operation. It will only reset the error states if there are 00518 currently any errors. 00519 @param index Which serial port - SERIAL_0 or SERIAL_1 00520 @see Serial_GetErrors 00521 00522 \b Example 00523 00524 \code 00525 Serial_ClearErrors(SERIAL_0); 00526 // that's all there is to it. 00527 \endcode 00528 */ 00529 void Serial_ClearErrors( int index ) 00530 { 00531 if ( index < 0 || index >= SERIAL_PORTS ) 00532 return; 00533 00534 Serial_* sp = &Serial[ index ]; 00535 if( sp->at91UARTRegs->US_CSR & (AT91C_US_OVRE | AT91C_US_FRAME | AT91C_US_PARE) ) 00536 sp->at91UARTRegs->US_CR = AT91C_US_RSTSTA; // clear all errors 00537 } 00538 00539 /** 00540 Read whether there are any errors. 00541 We can check for three kinds of errors in the serial system: 00542 - buffer overrun 00543 - framing error 00544 - parity error 00545 00546 Each parameter will be set with a true or a false given the current 00547 error state. If you don't care to check one of the parameters, just 00548 pass in 0. 00549 00550 @param index Which serial port - SERIAL_0 or SERIAL_1 00551 @param overrun A bool that will be set with the overrun error state. 00552 @param frame A bool that will be set with the frame error state. 00553 @param parity A bool that will be set with the parity error state. 00554 @return True if there were any errors, false if there were no errors. 00555 @see Serial_ClearErrors( ) 00556 00557 \b Example 00558 \code 00559 bool over, fr, par; 00560 if( Serial_GetErrors( SERIAL_0, &over, &fr, &par ) ) 00561 { 00562 // if we wanted, we could just clear them all right here with Serial_ClearErrors() 00563 // but here we'll check to see what kind of errors we got 00564 if(over) 00565 { 00566 // then we have an overrun error 00567 } 00568 if(fr) 00569 { 00570 // then we have a framing error 00571 } 00572 if(par) 00573 { 00574 // then we have a parity error 00575 } 00576 } 00577 else 00578 { 00579 // there were no errors 00580 } 00581 \endcode 00582 */ 00583 bool Serial_GetErrors( int index, bool* overrun, bool* frame, bool* parity ) 00584 { 00585 bool retval = false; 00586 if ( index < 0 || index >= SERIAL_PORTS ) 00587 return false; 00588 00589 Serial_* sp = &Serial[ index ]; 00590 00591 bool ovre = sp->at91UARTRegs->US_CSR & AT91C_US_OVRE; 00592 if(ovre) 00593 retval = true; 00594 if(overrun) 00595 *overrun = ovre; 00596 00597 bool fr = sp->at91UARTRegs->US_CSR & AT91C_US_FRAME; 00598 if(fr) 00599 retval = true; 00600 if(frame) 00601 *frame = fr; 00602 00603 bool par = sp->at91UARTRegs->US_CSR & AT91C_US_PARE; 00604 if(par) 00605 retval = true; 00606 if(parity) 00607 *parity = par; 00608 00609 return retval; 00610 } 00611 00612 /** 00613 Start the transimission of a break. 00614 This has no effect if a break is already in progress. 00615 @param index Which serial port - SERIAL_0 or SERIAL_1 00616 00617 \b Example 00618 00619 \code 00620 Serial_StartBreak(SERIAL_0); 00621 \endcode 00622 */ 00623 void Serial_StartBreak( int index ) 00624 { 00625 if ( index < 0 || index >= SERIAL_PORTS ) 00626 return; 00627 Serial[ index ].at91UARTRegs->US_CR = AT91C_US_STTBRK; 00628 } 00629 00630 /** 00631 Stop the transimission of a break. 00632 This has no effect if there's not a break already in progress. 00633 @param index Which serial port - SERIAL_0 or SERIAL_1 00634 00635 \b Example 00636 00637 \code 00638 Serial_StopBreak(SERIAL_0); 00639 \endcode 00640 */ 00641 void Serial_StopBreak( int index ) 00642 { 00643 if ( index < 0 || index >= SERIAL_PORTS ) 00644 return; 00645 Serial[ index ].at91UARTRegs->US_CR = AT91C_US_STPBRK; 00646 } 00647 00648 /** @} 00649 */ 00650 00651 int Serial_Init( int index ) 00652 { 00653 if ( index < 0 || index >= SERIAL_PORTS ) 00654 return CONTROLLER_ERROR_ILLEGAL_INDEX; 00655 00656 Serial_* sp = &Serial[ index ]; 00657 00658 // default to SERIAL_0 values 00659 int id = AT91C_ID_US0; 00660 int rxPin = IO_PA00; 00661 int txPin = IO_PA01; 00662 long rxPinBit = IO_PA00_BIT; 00663 long txPinBit = IO_PA01_BIT; 00664 switch( index ) 00665 { 00666 case SERIAL_0: 00667 // values already set for this above 00668 sp->at91UARTRegs = AT91C_BASE_US0; 00669 break; 00670 case SERIAL_1: 00671 id = AT91C_ID_US1; 00672 rxPinBit = IO_PA05_BIT; 00673 txPinBit = IO_PA06_BIT; 00674 rxPin = IO_PA05; 00675 txPin = IO_PA06; 00676 sp->at91UARTRegs = AT91C_BASE_US1; 00677 break; 00678 } 00679 00680 // Enable the peripheral clock 00681 AT91C_BASE_PMC->PMC_PCER = 1 << id; 00682 00683 int status = Io_StartBits( rxPinBit | txPinBit, false ); 00684 if ( status != CONTROLLER_OK ) 00685 return status; 00686 00687 Io_SetPeripheralA( rxPin ); 00688 Io_SetPeripheralA( txPin ); 00689 Io_SetPio( rxPin, false ); 00690 Io_SetPio( txPin, false ); 00691 00692 // Create the queues 00693 if( sp->rxQSize == 0 ) 00694 sp->rxQSize = DEFAULT_SERIAL_Q_LEN; 00695 sp->receiveQueue = xQueueCreate( sp->rxQSize, 1 ); 00696 00697 if( sp->txQSize == 0 ) 00698 sp->txQSize = DEFAULT_SERIAL_Q_LEN; 00699 sp->transmitQueue = xQueueCreate( sp->txQSize, 1 ); 00700 00701 // Disable interrupts 00702 sp->at91UARTRegs->US_IDR = (unsigned int) -1; 00703 00704 // Timeguard disabled 00705 sp->at91UARTRegs->US_TTGR = 0; 00706 00707 unsigned int mask = 0x1 << id; 00708 00709 /* Disable the interrupt on the interrupt controller */ 00710 AT91C_BASE_AIC->AIC_IDCR = mask ; 00711 /* Save the interrupt handler routine pointer and the interrupt priority */ 00712 AT91C_BASE_AIC->AIC_SVR[ id ] = (unsigned int)SerialIsr_Wrapper; 00713 /* Store the Source Mode Register */ 00714 AT91C_BASE_AIC->AIC_SMR[ id ] = AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL | 4 ; 00715 /* Clear the interrupt on the interrupt controller */ 00716 AT91C_BASE_AIC->AIC_ICCR = mask ; 00717 00718 AT91C_BASE_AIC->AIC_IECR = mask; 00719 00720 sp->at91UARTRegs->US_IER = AT91C_US_RXRDY; 00721 00722 sp->active = true; 00723 00724 // If there are no default values, get some 00725 if ( !sp->detailsInitialized ) 00726 Serial_SetDefault( index ); 00727 // Most of the detail setting is done in here 00728 // Also Resets TXRX and re-enables RX 00729 Serial_SetDetails( index ); 00730 00731 return CONTROLLER_OK; 00732 } 00733 00734 int Serial_Deinit( int index ) 00735 { 00736 if ( index < 0 || index >= SERIAL_PORTS ) 00737 return CONTROLLER_ERROR_ILLEGAL_INDEX; 00738 00739 Serial_* sp = &Serial[ index ]; 00740 vQueueDelete( sp->receiveQueue ); 00741 vQueueDelete( sp->transmitQueue ); 00742 sp->active = false; 00743 return CONTROLLER_OK; 00744 } 00745 00746 int Serial_SetDetails( int index ) 00747 { 00748 if ( index < 0 || index >= SERIAL_PORTS ) 00749 return CONTROLLER_ERROR_ILLEGAL_INDEX; 00750 00751 Serial_* sp = &Serial[ index ]; 00752 00753 if ( sp->active ) 00754 { 00755 // Reset receiver and transmitter 00756 sp->at91UARTRegs->US_CR = AT91C_US_RSTRX | AT91C_US_RSTTX | AT91C_US_RXDIS | AT91C_US_TXDIS; 00757 00758 // MCK is 47923200 for the Make Controller Kit 00759 00760 // Calculate ( * 10 ) 00761 int baudValue = ( MCK * 10 ) / ( sp->baud * 16 ); 00762 // Round (and / 10) 00763 if ( ( baudValue % 10 ) >= 5 ) 00764 baudValue = ( baudValue / 10 ) + 1; 00765 else 00766 baudValue /= 10; 00767 00768 sp->at91UARTRegs->US_BRGR = baudValue; 00769 00770 sp->at91UARTRegs->US_MR = 00771 ( ( sp->hardwareHandshake ) ? AT91C_US_USMODE_HWHSH : AT91C_US_USMODE_NORMAL ) | 00772 ( AT91C_US_CLKS_CLOCK ) | 00773 ( ( ( sp->bits - 5 ) << 6 ) & AT91C_US_CHRL ) | 00774 ( ( sp->stopBits == 2 ) ? AT91C_US_NBSTOP_2_BIT : AT91C_US_NBSTOP_1_BIT ) | 00775 ( ( sp->parity == 0 ) ? AT91C_US_PAR_NONE : ( ( sp->parity == -1 ) ? AT91C_US_PAR_ODD : AT91C_US_PAR_EVEN ) ); 00776 // 2 << 14; // this last thing puts it in loopback mode 00777 00778 00779 sp->at91UARTRegs->US_CR = AT91C_US_RXEN | AT91C_US_TXEN; 00780 } 00781 return CONTROLLER_OK; 00782 } 00783 00784 int Serial_SetDefault( int index ) 00785 { 00786 if ( index < 0 || index >= SERIAL_PORTS ) 00787 return CONTROLLER_ERROR_ILLEGAL_INDEX; 00788 00789 Serial_* sp = &Serial[ index ]; 00790 00791 sp->baud = 9600; 00792 sp->bits = 8; 00793 sp->stopBits = 1; 00794 sp->parity = 0; 00795 sp->hardwareHandshake = 0; 00796 00797 sp->detailsInitialized = true; 00798 return CONTROLLER_OK; 00799 } 00800 00801 #ifdef OSC 00802 /** \defgroup SerialOSC Serial - OSC 00803 Configure the Serial Port and Read Characters via OSC. 00804 \ingroup OSC 00805 00806 \section devices Devices 00807 There are 2 serial ports, so use 0 or 1 as an index. 00808 00809 \section properties Properties 00810 The Serial Subsystem has the following properties: 00811 - baud 00812 - bits 00813 - stopbits 00814 - parity 00815 - hardwarehandshake 00816 - readable 00817 - char 00818 - block 00819 00820 \subsection Baud 00821 The Baud rate of the device. Valid from 110 baud to >2M baud. 00822 To set baud rate to 115200 on the first serial port, for example, send the message 00823 \verbatim /serial/0/baud 112500\endverbatim 00824 00825 \subsection Bits 00826 The number of bits per character. Can range from 5 to 8. 00827 To set the number of bits to 7 on the first serial port, for example, send the message 00828 \verbatim /serial/0/bits 7\endverbatim 00829 00830 \subsection StopBits 00831 The number of stop bits per character. Can be 1 or 2\n 00832 To set the number of stop bits to 2 on the second serial port, for example, send the message 00833 \verbatim /serial/1/stopbits 2\endverbatim 00834 00835 \subsection Parity 00836 The parity of the character. Can be -1 for odd, 0 for none or 1 for even. 00837 To set the parity to even, for example, send the message 00838 \verbatim /serial/0/parity 1\endverbatim 00839 00840 \subsection HardwareHandshake 00841 Whether hardware handshaking (i.e. CTS RTS) is being employed. 00842 To set hardware handshaking on, for example, send the message 00843 \verbatim /serial/0/hardwarehandshake 1\endverbatim 00844 00845 \subsection Readable 00846 How many characters are presently available to read. 00847 To check, for example, send the message 00848 \verbatim /serial/0/readable\endverbatim 00849 00850 \subsection Char 00851 Send and receive individual characters with the char property. 00852 To send a character 32 (a space), for example, send the message 00853 \verbatim /serial/0/char 32\endverbatim 00854 To get a character send the message 00855 \verbatim /serial/0/char\endverbatim 00856 In this case the reply will be an unsigned value between 0 and 255 or -1 if there is 00857 no character available. 00858 00859 \subsection Block 00860 This property allows for reading or writing a block of characters to/from the serial port. If you're 00861 writing a block, you must send the block you want to write as an OSC blob. 00862 00863 For example, to send a block: 00864 \verbatim /serial/1/block blockofchars\endverbatim 00865 To get a block, send the message 00866 \verbatim /serial/1/block\endverbatim 00867 In this case the reply will be a block of up to 100 unsigned chars, or the chars currently available to read 00868 from the serial port. 00869 00870 */ 00871 00872 #include "osc.h" 00873 #include "string.h" 00874 #include "stdio.h" 00875 00876 #include "types.h" 00877 00878 // Need a list of property names 00879 // MUST end in zero 00880 static char* SerialOsc_Name = "serial"; 00881 static char* SerialOsc_IntPropertyNames[] = { "active", "char", "baud", "bits", "stopbits", "parity", "hardwarehandshake", "readable", 0 }; // must have a trailing 0 00882 static char* SerialOsc_BlobPropertyNames[] = { "block", 0 }; // must have a trailing 0 00883 00884 int SerialOsc_IntPropertySet( int index, int property, int value ); 00885 int SerialOsc_IntPropertyGet( int index, int property ); 00886 00887 int SerialOsc_BlobPropertySet( int index, int property, uchar* blob, int length ); 00888 int SerialOsc_BlobPropertyGet( int index, int property, uchar* blob, int size ); 00889 00890 // Returns the name of the subsystem 00891 const char* SerialOsc_GetName( ) 00892 { 00893 return SerialOsc_Name; 00894 } 00895 00896 // Now getting a message. This is actually a part message, with the first 00897 // part (the subsystem) already parsed off. 00898 int SerialOsc_ReceiveMessage( int channel, char* message, int length ) 00899 { 00900 int status = Osc_IndexIntReceiverHelper( channel, message, length, SERIAL_PORTS, 00901 SerialOsc_Name, 00902 SerialOsc_IntPropertySet, SerialOsc_IntPropertyGet, 00903 SerialOsc_IntPropertyNames ); 00904 00905 if ( status != CONTROLLER_OK ) 00906 status = Osc_IndexBlobReceiverHelper( channel, message, length, SERIAL_PORTS, 00907 SerialOsc_Name, 00908 SerialOsc_BlobPropertySet, SerialOsc_BlobPropertyGet, 00909 SerialOsc_BlobPropertyNames ); 00910 00911 if ( status != CONTROLLER_OK ) 00912 return Osc_SendError( channel, SerialOsc_Name, status ); 00913 return CONTROLLER_OK; 00914 } 00915 // Set the index LED, property with the value 00916 int SerialOsc_IntPropertySet( int index, int property, int value ) 00917 { 00918 switch ( property ) 00919 { 00920 case 0: 00921 Serial_SetActive( index, value ); 00922 break; 00923 case 1: 00924 Serial_SetChar( index, value ); 00925 break; 00926 case 2: 00927 Serial_SetBaud( index, value ); 00928 break; 00929 case 3: 00930 Serial_SetBits( index, value ); 00931 break; 00932 case 4: 00933 Serial_SetStopBits( index, value ); 00934 break; 00935 case 5: 00936 Serial_SetParity( index, value ); 00937 break; 00938 case 6: 00939 Serial_SetHardwareHandshake( index, value ); 00940 break; 00941 } 00942 return CONTROLLER_OK; 00943 } 00944 00945 // Get the index, property 00946 int SerialOsc_IntPropertyGet( int index, int property ) 00947 { 00948 int value = 0; 00949 switch ( property ) 00950 { 00951 case 0: 00952 value = Serial_GetActive( index ); 00953 break; 00954 case 1: 00955 value = Serial_GetChar( index ); 00956 break; 00957 case 2: 00958 value = Serial_GetBaud( index ); 00959 break; 00960 case 3: 00961 value = Serial_GetBits( index ); 00962 break; 00963 case 4: 00964 value = Serial_GetStopBits( index ); 00965 break; 00966 case 5: 00967 value = Serial_GetParity( index ); 00968 break; 00969 case 6: 00970 value = Serial_GetHardwareHandshake( index ); 00971 break; 00972 case 7: 00973 value = Serial_GetReadable( index ); 00974 break; 00975 } 00976 00977 return value; 00978 } 00979 00980 // Get the index, property 00981 int SerialOsc_BlobPropertyGet( int index, int property, uchar* blob, int maxSize ) 00982 { 00983 int xfer = 0; 00984 switch ( property ) 00985 { 00986 case 0: 00987 { 00988 int length = Serial_GetReadable( index ); 00989 xfer = ( length < maxSize ) ? length : maxSize; 00990 if ( xfer > 0 ) 00991 Serial_Read( index, blob, xfer, 100 ); 00992 break; 00993 } 00994 } 00995 00996 return xfer; 00997 } 00998 00999 01000 // Set the index LED, property with the value 01001 int SerialOsc_BlobPropertySet( int index, int property, uchar* blob, int length ) 01002 { 01003 switch ( property ) 01004 { 01005 case 0: 01006 Serial_Write( index, blob, length, 100 ); 01007 break; 01008 } 01009 return CONTROLLER_OK; 01010 } 01011 01012 #endif
The Make Controller Kit is an open source project maintained by MakingThings.
MakingThings code is released under the Apache 2.0 license.
Bug tracker, development wiki and status can be found at http://dev.makingthings.com.
This document was last updated on 18 May 2009.