avr/cpp/USART.h

Go to the documentation of this file.
00001 /**********************************************************************************************************************\
00002 
00003         C++ library for Atmel AVR microcontrollers
00004         Copyright (C) 2007 Lauri Kirikal, Mikk Leini, MT� TT� Robotiklubi
00005 
00006         This program is free software; you can redistribute it and/or
00007         modify it under the terms of the GNU General Public License
00008         as published by the Free Software Foundation; either version 2
00009         of the License, or (at your option) any later version.
00010 
00011         This program is distributed in the hope that it will be useful,
00012         but WITHOUT ANY WARRANTY; without even the implied warranty of
00013         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014         GNU General Public License for more details.
00015 
00016         You should have received a copy of the GNU General Public License
00017         along with this program; if not, write to the Free Software
00018         Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00019 
00020         See http://creativecommons.org/licenses/GPL/2.0/
00021 
00022         MT� TT� Robotiklubi  http://www.robotiklubi.ee robotiklubi@gmail.com
00023         Lauri Kirikal        laurikirikal@gmail.com
00024         Mikk Leini           mikk.leini@gmail.com
00025 
00026 \**********************************************************************************************************************/
00027 
00028 #ifndef __AVR_CPP_USART_H__
00029 #define __AVR_CPP_USART_H__
00030 
00031 #include "IO.h"
00032 #include "Interrupt.h"
00033 
00034 #define AsyncNormBaudCalc(BaudRate)             F_CPU / 16 / BaudRate - 1
00035 #define AsyncDblBaudCalc(BaudRate)              F_CPU / 8 / BaudRate - 1
00036 #define SyncMasterBaudCalc(BaudRate)    F_CPU / 2 / BaudRate - 1
00037 
00038 namespace AVRCpp
00039 {
00040         namespace USART
00041         {
00042                 enum ReadResult
00043                 {
00044                         Success,
00045                         Canceled,
00046                         DataOverRun,
00047                         FrameError,
00048                         ParityError
00049                         
00050                 }; // enum ReadResult
00051                 
00052                 enum Receiver
00053                 {
00054                         ReceiverEnable  = 0x10,
00055                         ReceiverDisable = 0x00
00056                         
00057                 }; // enum Receiver
00058                 
00059                 enum Transmitter
00060                 {
00061                         TransmitterEnable       = 0x08,
00062                         TransmitterDisable      = 0x00
00063                         
00064                 }; // enum Transmitter
00065                 
00066                 enum ParityCheck
00067                 {
00068                         NoParityCheck   = 0x00,
00069                         EvenParity              = 0x20,
00070                         OddParity               = 0x30
00071                         
00072                 }; // enum ParityCheck
00073                 
00074                 enum StopBit
00075                 {
00076                         NormalStopBit   = 0x00,
00077                         DoubledStopBit  = 0x08
00078                         
00079                 }; // enum StopBit
00080                 
00081                 enum CharacterSize 
00082                 {
00083                         CharacterSize5  = 0x00,
00084                         CharacterSize6  = 0x02,
00085                         CharacterSize7  = 0x04,
00086                         CharacterSize8  = 0x06,
00087                         CharacterSize9  = 0xF6
00088                         
00089                 }; // enum DataBitsCount
00090                 
00091                 enum SynchroEdge
00092                 {
00093                         ReceiveOnFall = 0x00,
00094                         ReceiveOnRise = 0x01
00095                         
00096                 }; // enum SynchroEdge
00097                 
00098                 enum Speed
00099                 {
00100                         NormalSpeed     = 0x00,
00101                         DoubleSpeed     = 0x02
00102                         
00103                 }; // enum Speed
00104                 
00105                 enum CommunicationMode
00106                 {
00107                         SingleProcessor = 0x00,
00108                         MultiProcessor  = 0x01
00109                         
00110                 }; // enum CommunicationMode
00111                 
00112                 
00113                 namespace Internal
00114                 {
00115                         enum CharacterSizeConstants
00116                         {
00117                                 CharacterSizeMaskC              = 0x06,
00118                                 CharacterSizeCheckMaskB = 0xF0,
00119                                 CharacterSize9FlagB             = 0x04, 
00120                                 
00121                         }; // enum CharacterSizeConstants
00122                         
00123                         enum RegisterSelect
00124                         {
00125                                 NoRegisterSelect        = 0x00,
00126                                 HasRegisterSelect       = 0x80
00127                                 
00128                         }; // enum RegisterSelect
00129                         
00130                         enum Mode
00131                         {
00132                                 Asynchronous    = 0x00,
00133                                 Synchronous             = 0x40
00134                                 
00135                         }; // enum Mode
00136                         
00137                         enum BitFlags
00138                         {
00139                                 NinthTransmitFlag               = 0x01,
00140                                 NinthReceiveFlag                = 0x02,
00141                                 ReceiveCompleteFlag             = 0x80,
00142                                 TransferCompleteFlag    = 0x40,
00143                                 DataRegisterEmptyFlag   = 0x20,
00144                                 FrameErrorFlag                  = 0x10,
00145                                 DataOverRunFlag                 = 0x08,
00146                                 ParityErrorFlag                 = 0x04,
00147                                 ErrorFlags                              = 0x1C,
00148                                 TransmitterEnableFlag   = 0x08,
00149                                 ReceiverEnableFlag              = 0x10,
00150                                 MultiProcessorFlag              = 0x01
00151                                 
00152                         }; // enum BitFlags
00153                         
00154                         template <
00155                                         class BaudRateRegisterHigh,
00156                                         class BaudRateRegisterLow,
00157                                         class ControlRegisterA,
00158                                         class ControlRegisterB,
00159                                         class ControlRegisterC,
00160                                         class DataRegister,
00161                                         class TransferClockPin,
00162                                         RegisterSelect registerSelect,
00163                                         bool & (* Cancel)() >
00164                         
00165                         struct USARTBase
00166                         {
00167                         private:
00168                                 
00169                                 typedef Bits<ControlRegisterB, NinthTransmitFlag>               NinthTransmitBit;
00170                                 typedef Bits<ControlRegisterB, NinthReceiveFlag>                NinthReceiveBit;
00171                                 typedef Bits<ControlRegisterA, ReceiveCompleteFlag>             ReceiveCompleteBit;
00172                                 typedef Bits<ControlRegisterA, TransferCompleteFlag>    TransferCompleteBit;
00173                                 typedef Bits<ControlRegisterA, DataRegisterEmptyFlag>   DataRegisterEmptyBit;
00174                                 typedef Bits<ControlRegisterA, FrameErrorFlag>                  FrameErrorBit;
00175                                 typedef Bits<ControlRegisterA, DataOverRunFlag>                 DataOverRunBit;
00176                                 typedef Bits<ControlRegisterA, ParityErrorFlag>                 ParityErrorBit;
00177                                 typedef Bits<ControlRegisterA, ErrorFlags>                              ErrorBits;
00178                                 typedef Bits<ControlRegisterB, TransmitterEnableFlag>   TransmitterEnableBit;
00179                                 typedef Bits<ControlRegisterB, ReceiverEnableFlag>              ReceiverEnableBit;
00180                                 typedef Bits<ControlRegisterA, MultiProcessorFlag>              MultiProcessorBit;
00181                                 
00182                                 typedef typename TransferClockPin::Input        SlavePin;
00183                                 typedef typename TransferClockPin::Output       MasterPin;
00184                                 
00185                         public:
00186                                 
00187                                 typedef DataRegister    Data;
00188                                 
00189                                 static inline void SetNinthBit() { NinthTransmitBit::Set(); }
00190                                 static inline void ClearNinthBit() { NinthTransmitBit::Clear(); }
00191                                 static inline bool IsNinthBitSet() { return NinthReceiveBit::IsSet(); }
00192                                 
00193                                 static inline void EnterMultiProcessorMode() { MultiProcessorBit::Set(); }
00194                                 static inline void EnterSingleProcessorMode() { MultiProcessorBit::Clear(); }
00195                                 static inline bool IsEnteredMultiProcessorMode() { return MultiProcessorBit::IsSet(); }
00196                                 
00197                                 static inline bool IsReceiveCompleted() { return ReceiveCompleteBit::IsSet(); }
00198                                 static inline bool IsTransferCompleted() { return TransferCompleteBit::IsSet(); }
00199                                 static inline bool IsDataRegisterEmpty() { return DataRegisterEmptyBit::IsSet(); }
00200                                 static inline bool IsAllDone() { return IsTransferCompleted() && IsReceiveCompleted(); }
00201                                 static inline bool WasFrameError() { return FrameErrorBit::IsSet(); }
00202                                 static inline bool WasDataOverRun() { return DataOverRunBit::IsSet(); }
00203                                 static inline bool WasParityError() { return ParityErrorBit::IsSet(); }
00204                                 static inline bool WasError() { return ErrorBits::IsAnySet(); }
00205                                 
00206                                 static inline void WaitUntilTransferCompleted() { while (!IsTransferCompleted() ); }
00207                                 static inline void WaitUntilReceiveCompleted() { while (!IsReceiveCompleted() ); }
00208                                 static inline void WaitUntilDataRegisterEmpty() { while (!IsDataRegisterEmpty() ); }
00209                                 static inline void WaitUntilAllDone() { while (!IsAllDone() ); }
00210                                 
00211                                 static inline void EnableTransmitter() { TransmitterEnableBit::Set(); }
00212                                 static inline void DisableTransmitter() { TransmitterEnableBit::Clear(); }
00213                                 static inline bool IsTransmitterEnabled() { return TransmitterEnableBit::IsSet(); }
00214                                 
00215                                 static inline void EnableReceiver() { ReceiverEnableBit::Set(); }
00216                                 static inline void DisableReceiver() { ReceiverEnableBit::Clear(); }
00217                                 static inline bool IsReceiverEnabled() { return ReceiverEnableBit::IsSet(); }
00218                                 
00219                                 static inline void ResetCancel() { Cancel() = false; }
00220                                 static inline void CancelReading() { Cancel() = true; }
00221                                 static inline bool IsCanceled() { return Cancel(); }
00222                                 
00223                         private:
00224                                 
00225                                 static inline bool WaitWhileReceiveCompletedOrCanceled()
00226                                 {
00227                                         ResetCancel();
00228                                         
00229                                         while (!IsReceiveCompleted() )
00230                                         {
00231                                                 if (IsCanceled() )
00232                                                         return true;
00233                                         }
00234                                         
00235                                         return false;
00236                                         
00237                                 } // WaitWhileReceiveCompletedOrCanceled
00238                                 
00239                                 static inline ReadResult DetailedErrorCheck()
00240                                 {
00241                                         if (WasFrameError() )
00242                                                 return FrameError;
00243                                         
00244                                         if (WasParityError() )
00245                                                 return ParityError;
00246                                         
00247                                         if (WasDataOverRun() )
00248                                                 return DataOverRun;
00249                                         
00250                                         return Success;
00251                                         
00252                                 } // DetailedErrorCheck
00253                                 
00254                         public:
00255                                 
00256                                 static inline void SetBaudRate(uint16_t baudRate)
00257                                 {
00258                                         BaudRateRegisterHigh::Set( (baudRate >> 8) & 0x0F);
00259                                         BaudRateRegisterLow::Set( (uint8_t)baudRate);
00260                                         
00261                                 } // SetBaudRate
00262                                 
00263                                 static inline void SetupMasterSync (
00264                                                 uint16_t baudRate,
00265                                                 Receiver receiver,
00266                                                 Transmitter transmitter,
00267                                                 ParityCheck parityCheck,
00268                                                 StopBit stopBit,
00269                                                 CharacterSize characterSize,
00270                                                 SynchroEdge synchroEdge,
00271                                                 CommunicationMode communicationMode )
00272                                 {       
00273                                         uint8_t savedSREG = SREG;
00274                                         
00275                                         GlobalInterrupts::Disable();
00276                                         
00277                                         MasterPin::InitOutput();
00278                                         SetBaudRate(baudRate);
00279                                                 
00280                                         ControlRegisterA::Set(communicationMode);
00281                                         ControlRegisterB::Set(receiver | transmitter | (characterSize & CharacterSizeCheckMaskB ? CharacterSize9FlagB : 0) ); 
00282                                         ControlRegisterC::Set(registerSelect | Synchronous | parityCheck | stopBit | synchroEdge | (characterSize & CharacterSizeMaskC) ); 
00283                                         
00284                                         SREG = savedSREG;
00285                                         
00286                                 } // SetupMasterSync
00287                                 
00288                                 static inline void SetupSlaveSync (
00289                                                 Receiver receiver,
00290                                                 Transmitter transmitter,
00291                                                 ParityCheck parityCheck,
00292                                                 StopBit stopBit,
00293                                                 CharacterSize characterSize,
00294                                                 SynchroEdge synchroEdge,
00295                                                 CommunicationMode communicationMode )
00296                                 {       
00297                                         uint8_t savedSREG = SREG;
00298                                         
00299                                         GlobalInterrupts::Disable();
00300                                         
00301                                         SlavePin::InitInput();
00302                                                 
00303                                         ControlRegisterA::Set(communicationMode);
00304                                         ControlRegisterB::Set(receiver | transmitter | (characterSize & CharacterSizeCheckMaskB ? CharacterSize9FlagB : 0) ); 
00305                                         ControlRegisterC::Set(registerSelect | Synchronous | parityCheck | stopBit | synchroEdge | (characterSize & CharacterSizeMaskC) ); 
00306                                         
00307                                         SREG = savedSREG;
00308                                         
00309                                 } // SetupSlaveSync
00310                                 
00311                                 
00312                                 static inline void SetupAsynchronous (
00313                                                 uint16_t baudRate,
00314                                                 Receiver receiver,
00315                                                 Transmitter transmitter,
00316                                                 ParityCheck parityCheck,
00317                                                 StopBit stopBit,
00318                                                 CharacterSize characterSize,
00319                                                 Speed speed,
00320                                                 CommunicationMode communicationMode )
00321                                 {
00322                                         uint8_t savedSREG = SREG;
00323                                         
00324                                         GlobalInterrupts::Disable();
00325                                         
00326                                         SetBaudRate(baudRate);
00327                                         
00328                                         ControlRegisterA::Set(speed | communicationMode);
00329                                         ControlRegisterB::Set(receiver | transmitter | (characterSize & CharacterSizeCheckMaskB ? CharacterSize9FlagB : 0) );
00330                                         ControlRegisterC::Set(registerSelect | Asynchronous | parityCheck | stopBit | (characterSize & CharacterSizeMaskC) ); 
00331                                         
00332                                         SREG = savedSREG;
00333                                         
00334                                 } // SetupAsynchronous
00335                                 
00336                                 static inline void WriteNinthSet(uint8_t data)
00337                                 {
00338                                         WaitUntilDataRegisterEmpty();
00339                                         
00340                                         SetNinthBit();
00341                                         
00342                                         Data::Set(data);
00343                                         
00344                                 } // WriteNinthSet
00345                                 
00346                                 static inline void WriteNinthCleared(uint8_t data)
00347                                 {
00348                                         WaitUntilDataRegisterEmpty();
00349                                         
00350                                         ClearNinthBit();
00351                                         
00352                                         Data::Set(data);
00353                                         
00354                                 } // WriteNinthCleared
00355                                 
00356                                 static inline void Write(uint8_t data)
00357                                 {
00358                                         WaitUntilDataRegisterEmpty();
00359                                         
00360                                         Data::Set(data);
00361                                         
00362                                 } // Write 1
00363                                 
00364                                 static inline void Write(uint8_t data, bool ninth)
00365                                 {
00366                                         WaitUntilDataRegisterEmpty();
00367                                         
00368                                         if (ninth)
00369                                                 SetNinthBit();
00370                                         else
00371                                                 ClearNinthBit();
00372                                         
00373                                         Data::Set(data);
00374                                         
00375                                 } // Write 2
00376                                 
00377                                 static inline bool Read(uint8_t &data)
00378                                 {
00379                                         if (WaitWhileReceiveCompletedOrCanceled() )
00380                                                 return false;
00381                                         
00382                                         {
00383                                                 bool result = !WasError();
00384                                                 
00385                                                 data = Data::Get();
00386                                                 
00387                                                 return result;
00388                                         }
00389                                         
00390                                 } // Read 1
00391                                 
00392                                 static inline bool Read(uint8_t &data, bool &ninth)
00393                                 {
00394                                         if (WaitWhileReceiveCompletedOrCanceled() )
00395                                                 return false;
00396                                         
00397                                         {
00398                                                 bool result = !WasError();
00399                                                 
00400                                                 ninth = IsNinthBitSet();
00401                                                 data = Data::Get();
00402                                                 
00403                                                 return result;
00404                                         }
00405                                         
00406                                 } // Read 2
00407                                 
00408                                 static inline bool SimpleRead(uint8_t &data)
00409                                 {
00410                                         bool result;
00411                                         
00412                                         while (!IsReceiveCompleted() );
00413                                         result = !WasError();
00414                                         data = Data::Get();
00415                                         return result;
00416                                         
00417                                 } // SimpleRead 1
00418                                 
00419                                 static inline bool SimpleRead(uint8_t &data, bool &ninth)
00420                                 {
00421                                         bool result;
00422                                         
00423                                         while (!IsReceiveCompleted() );
00424                                         result = !WasError();
00425                                         ninth = IsNinthBitSet();
00426                                         data = Data::Get();
00427                                         return result;
00428                                         
00429                                 } // SimpleRead 2
00430                                 
00431                                 static inline ReadResult DetailedRead(uint8_t &data)
00432                                 {
00433                                         if (WaitWhileReceiveCompletedOrCanceled() )
00434                                                 return Canceled;
00435                                         
00436                                         {
00437                                                 ReadResult result = DetailedErrorCheck();
00438                                                 
00439                                                 data = Data::Get();
00440                                                 
00441                                                 return result;
00442                                         }
00443                                         
00444                                 } // DetailedRead 1
00445                                 
00446                                 static inline ReadResult DetailedRead(uint8_t &data, bool &ninth)
00447                                 {
00448                                         if (WaitWhileReceiveCompletedOrCanceled() )
00449                                                 return Canceled;
00450                                         
00451                                         {
00452                                                 ReadResult result = DetailedErrorCheck();
00453                                                 
00454                                                 ninth = IsNinthBitSet();
00455                                                 data = Data::Get();
00456                                                 
00457                                                 return result;
00458                                         }
00459                                         
00460                                 } // DetailedRead 2
00461                                 
00462                                 static inline ReadResult DetailedSimpleRead(uint8_t &data)
00463                                 {
00464                                         while (!IsReceiveCompleted() );
00465                                         
00466                                         {
00467                                                 ReadResult result = DetailedErrorCheck();
00468                                                 
00469                                                 data = Data::Get();
00470                                                 
00471                                                 return result;
00472                                         }
00473                                         
00474                                 } // DetailedSimpleRead 1
00475                                 
00476                                 static inline ReadResult DetailedSimpleRead(uint8_t &data, bool &ninth)
00477                                 {
00478                                         while (!IsReceiveCompleted() );
00479                                         
00480                                         {
00481                                                 ReadResult result = DetailedErrorCheck();
00482                                                 
00483                                                 ninth = IsNinthBitSet();
00484                                                 data = Data::Get();
00485                                                 
00486                                                 return result;
00487                                         }
00488                                         
00489                                 } // DetailedSimpleRead 2
00490 
00491                                 static inline bool Flush()
00492                                 {
00493                                         uint8_t data;
00494                                         
00495                                         return Read(data);
00496                                         
00497                                 } // Flush
00498                                 
00499                         private:
00500                                 
00501                                 static inline void SendByteArray(uint8_t *byteData, uint16_t bytesCount)
00502                                 {
00503                                         register uint16_t i;
00504                                         
00505                                         for (i = 0; i < bytesCount; i++)
00506                                                 Write(byteData[i]);
00507                                         
00508                                 } // SendByteArray
00509                                 
00510                                 static inline bool ReceiveByteArray(uint8_t *byteData, uint16_t bytesCount)
00511                                 {
00512                                         register uint16_t i;
00513                                         
00514                                         for (i = 0; i < bytesCount; i++)
00515                                                 if (!Read(byteData[i]) )
00516                                                         return false;
00517                                         
00518                                         return true;
00519                                         
00520                                 } // ReceiveByteArray
00521                                 
00522                                 static inline ReadResult DetailedReceiveByteArray(uint8_t *byteData, uint16_t bytesCount)
00523                                 {
00524                                         register uint16_t i;
00525                                         ReadResult result;
00526                                         
00527                                         for (i = 0; i < bytesCount; i++)
00528                                                 if ((result = DetailedRead(byteData[i]) ) != Success)
00529                                                         return result;
00530                                         
00531                                         return Success;
00532                                         
00533                                 } // DetailedReceiveByteArray
00534                                 
00535                         public:
00536                                 
00537                                 static void SendText(char *text, uint16_t size)
00538                                 {
00539                                         register uint16_t i;
00540                                         
00541                                         for (i = 0; i < size; i++)
00542                                                 if (text[i])
00543                                                         Write(text[i]);
00544                                                 else
00545                                                         break;
00546                                         
00547                                         while (i < size)
00548                                         {
00549                                                 Write(0x00);
00550                                                 i++;
00551                                         }
00552                                         
00553                                 } // SendText
00554                                 
00555                                 template<typename Type> static void Send(Type &data)
00556                                 {
00557                                         SendByteArray((uint8_t *)(&data), sizeof(Type) );
00558                                         
00559                                 } // Send
00560                                 
00561                                 template<typename Type> static void SendArray(Type *data, uint16_t size)
00562                                 {
00563                                         SendByteArray((uint8_t *)(data), size * sizeof(Type) );
00564                                         
00565                                 } // SendArray
00566                                 
00567                                 template<typename Type> static bool Receive(Type &data)
00568                                 {
00569                                         return ReceiveByteArray((uint8_t *)(&data), sizeof(Type) );
00570                                         
00571                                 } // Receive
00572                                 
00573                                 template<typename Type> static bool ReceiveArray(Type *data, uint16_t size)
00574                                 {
00575                                         return ReceiveByteArray((uint8_t *)(data), size * sizeof(Type) );
00576                                         
00577                                 } // ReceiveArray
00578                                 
00579                                 template<typename Type> static ReadResult DetailedReceive(Type &data)
00580                                 {
00581                                         return DetailedReceiveByteArray((uint8_t *)(&data), sizeof(Type) );
00582                                         
00583                                 } // DetailedReceive
00584                                 
00585                                 template<typename Type> static ReadResult DetailedReceiveArray(Type *data, uint16_t size)
00586                                 {
00587                                         return DetailedReceiveByteArray((uint8_t *)(data), size * sizeof(Type) );
00588                                         
00589                                 } // DetailedReceiveArray
00590                                 
00591                         }; // struct USARTBase
00592                         
00593                 } // namespace Internal
00594                 
00595         } // namespace USART
00596         
00597 } // namespace AVRCpp
00598         
00599 #if defined(__AVR_ATmega8__)
00600 #include "atmega8/USART.h"
00601 #elif defined(__AVR_ATmega128__)
00602 #include "atmega128/USART.h"
00603 #elif defined(__AVR_ATmega64__)
00604 #include "atmega64/USART.h"
00605 #elif defined(__AVR_ATmega8515__)
00606 #include "atmega8515/USART.h"
00607 #elif defined(__AVR_AT90USB1287__)
00608 #include "at90usb1287/USART.h"
00609 #elif defined(__AVR_ATmega88__)
00610 #include "atmega88/USART.h"
00611 #elif defined(__AVR_ATmega48__)
00612 #include "atmega48/USART.h"
00613 #elif defined(__AVR_ATmega168__)
00614 #include "atmega168/USART.h"
00615 #elif defined(__AVR_ATmega164P__)
00616 #include "atmega164p/USART.h"
00617 #elif defined(__AVR_ATmega324P__)
00618 #include "atmega324p/USART.h"
00619 #elif defined(__AVR_ATmega644P__)
00620 #include "atmega644p/USART.h"
00621 #elif defined(__AVR_ATmega644__)
00622 #include "atmega644/USART.h"
00623 #else
00624 #error "Device is not selected or selected device is not supported."
00625 #endif
00626 
00627 #endif // ifndef __AVR_CPP_USART_H__

Generated on Sat Sep 15 23:40:05 2007 for AVR C++ Lib for AT90USB1287 by  doxygen 1.5.2
SourceForge.net Logo MTÜ TTÜ Robotiklubi