Stefan Scholz / ETL
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers io_port.h Source File

io_port.h

Go to the documentation of this file.
00001 ///\file
00002 
00003 /******************************************************************************
00004 The MIT License(MIT)
00005 
00006 Embedded Template Library.
00007 https://github.com/ETLCPP/etl
00008 http://www.etlcpp.com
00009 
00010 Copyright(c) 2014 jwellbelove
00011 
00012 Permission is hereby granted, free of charge, to any person obtaining a copy
00013 of this software and associated documentation files(the "Software"), to deal
00014 in the Software without restriction, including without limitation the rights
00015 to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
00016 copies of the Software, and to permit persons to whom the Software is
00017 furnished to do so, subject to the following conditions :
00018 
00019 The above copyright notice and this permission notice shall be included in all
00020 copies or substantial portions of the Software.
00021 
00022 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00023 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00024 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
00025 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00026 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00027 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
00028 SOFTWARE.
00029 ******************************************************************************/
00030 
00031 #ifndef __ETL_IO_PORT__
00032 #define __ETL_IO_PORT__
00033 
00034 ///\defgroup io_port io port
00035 /// IO port access
00036 ///\ingroup utilities
00037 
00038 #include <stdint.h>
00039 #include <iterator>
00040 
00041 #include "platform.h "
00042 #include "nullptr.h "
00043 
00044 namespace etl
00045 {
00046   //***************************************************************************
00047   /// Read write port.
00048   //***************************************************************************
00049   template <typename T, uintptr_t ADDRESS = 0>
00050   class io_port_rw : public std::iterator<std::forward_iterator_tag, T>
00051   {
00052   public:
00053 
00054     typedef volatile T*       pointer;
00055     typedef volatile const T* const_pointer;
00056     typedef volatile T&       reference;
00057     typedef volatile const T& const_reference;
00058   
00059     /// Read.
00060     operator T() const
00061     {
00062       return *reinterpret_cast<const_pointer>(ADDRESS);
00063     }
00064 
00065     /// Read.
00066     T read() const
00067     {
00068       return *reinterpret_cast<const_pointer>(ADDRESS);
00069     }
00070 
00071     /// Write.
00072     void write(T value_)
00073     {
00074       *reinterpret_cast<pointer>(ADDRESS) = value_;
00075     }
00076 
00077     /// Write.
00078     io_port_rw& operator =(T value_)
00079     {
00080       *reinterpret_cast<pointer>(ADDRESS) = value_;
00081       return *this;
00082     }
00083 
00084     /// Read / Write
00085     reference operator *()
00086     {
00087       return *reinterpret_cast<pointer>(ADDRESS);
00088     }
00089 
00090     /// Read
00091     const_reference operator *() const
00092     {
00093       return *reinterpret_cast<const_pointer>(ADDRESS);
00094     }
00095 
00096     /// Increment
00097     io_port_rw& operator ++()
00098     {
00099       return *this;
00100     }
00101 
00102     /// Increment
00103     io_port_rw operator ++(int)
00104     {
00105       return *this;
00106     }
00107     
00108     /// Get the IO port address.
00109     pointer get_address()
00110     {
00111       return reinterpret_cast<pointer>(ADDRESS);
00112     }
00113 
00114     /// Get the IO port address.
00115     const_pointer get_address() const
00116     {
00117       return reinterpret_cast<const_pointer>(ADDRESS);
00118     }
00119 
00120   private:
00121 
00122     /// Disabled.
00123     io_port_rw& operator =(const io_port_rw&);
00124   };
00125 
00126   //***************************************************************************
00127   /// Read only port.
00128   //***************************************************************************
00129   template <typename T, uintptr_t ADDRESS = 0>
00130   class io_port_ro : public std::iterator<std::input_iterator_tag, T>
00131   {
00132   public:
00133 
00134     typedef volatile T*       pointer;
00135     typedef volatile const T* const_pointer;
00136     typedef volatile T&       reference;
00137     typedef volatile const T& const_reference;
00138 
00139     /// Read.
00140     operator T() const
00141     {
00142       return *reinterpret_cast<const_pointer>(ADDRESS);
00143     }
00144 
00145     /// Read.
00146     T read() const
00147     {
00148       return *reinterpret_cast<const_pointer>(ADDRESS);
00149     }
00150 
00151     /// Read
00152     const_reference operator *() const
00153     {
00154       return *reinterpret_cast<const_pointer>(ADDRESS);
00155     }
00156 
00157     /// Increment
00158     io_port_ro& operator ++()
00159     {
00160       return *this;
00161     }
00162 
00163     /// Increment
00164     io_port_ro operator ++(int)
00165     {
00166       return *this;
00167     }
00168 
00169     /// Get the IO port address.
00170     pointer get_address()
00171     {
00172       return reinterpret_cast<pointer>(ADDRESS);
00173     }
00174 
00175     /// Get the IO port address.
00176     const_pointer get_address() const
00177     {
00178       return reinterpret_cast<const_pointer>(ADDRESS);
00179     }
00180 
00181   private:
00182 
00183     /// Write disabled.
00184     void operator =(T value);
00185 
00186     /// Disabled.
00187     io_port_ro& operator =(const io_port_ro&);
00188   };
00189 
00190   //***************************************************************************
00191   /// Write only port.
00192   //***************************************************************************
00193   template <typename T, uintptr_t ADDRESS = 0>
00194   class io_port_wo : public std::iterator<std::output_iterator_tag, T>
00195   {
00196   public:
00197 
00198     typedef volatile T*       pointer;
00199     typedef volatile const T* const_pointer;
00200     typedef volatile T&       reference;
00201     typedef volatile const T& const_reference;
00202 
00203     /// Write.
00204     void operator =(T value)
00205     {
00206       *reinterpret_cast<pointer>(ADDRESS) = value;
00207     }
00208 
00209     /// Write.
00210     void write(T value_)
00211     {
00212       *reinterpret_cast<pointer>(ADDRESS) = value_;
00213     }
00214 
00215     /// Write
00216     io_port_wo& operator *()
00217     {
00218       return *this;
00219     }
00220 
00221     /// Increment
00222     io_port_wo& operator ++()
00223     {
00224       return *this;
00225     }
00226 
00227     /// Increment
00228     io_port_wo operator ++(int)
00229     {
00230       return *this;
00231     }
00232 
00233     /// Get the IO port address.
00234     pointer get_address()
00235     {
00236       return reinterpret_cast<pointer>(ADDRESS);
00237     }
00238 
00239     /// Get the IO port address.
00240     const_pointer get_address() const
00241     {
00242       return reinterpret_cast<const_pointer>(ADDRESS);
00243     }
00244 
00245   private:
00246 
00247     /// Read disabled.
00248     operator T() const;
00249 
00250     /// Disabled.
00251     io_port_wo& operator =(const io_port_wo&);
00252   };
00253 
00254   //***************************************************************************
00255   /// Write only port with shadow register.
00256   //***************************************************************************
00257   template <typename T, uintptr_t ADDRESS = 0>
00258   class io_port_wos : public std::iterator<std::forward_iterator_tag, T>
00259   {
00260   public:
00261 
00262     typedef volatile T*       pointer;
00263     typedef volatile const T* const_pointer;
00264     typedef volatile T&       reference;
00265     typedef volatile const T& const_reference;
00266 
00267     /// Read.
00268     operator T() const
00269     {
00270       return shadow_value;
00271     }
00272 
00273     /// Read.
00274     T read() const
00275     {
00276       return shadow_value;
00277     }
00278 
00279     /// Write.
00280     void write(T value_)
00281     {
00282       shadow_value = value_;
00283       *reinterpret_cast<pointer>(ADDRESS) = shadow_value;
00284     }
00285 
00286     /// Write.
00287     io_port_wos& operator =(T value_)
00288     {
00289       shadow_value = value_;
00290       *reinterpret_cast<pointer>(ADDRESS) = shadow_value;
00291       return *this;
00292     }
00293 
00294     /// Read / Write
00295     io_port_wos& operator *()
00296     {
00297       return *this;
00298     }
00299 
00300     /// Read
00301     const_reference operator *() const
00302     {
00303       return shadow_value;
00304     }
00305 
00306     /// Increment
00307     io_port_wos& operator ++()
00308     {
00309       return *this;
00310     }
00311 
00312     /// Increment
00313     io_port_wos operator ++(int)
00314     {
00315       return *this;
00316     }
00317 
00318     /// Get the IO port address.
00319     pointer get_address()
00320     {
00321       return reinterpret_cast<pointer>(ADDRESS);
00322     }
00323 
00324   private:
00325 
00326     /// Disabled.
00327     io_port_wos& operator =(const io_port_wos&);
00328 
00329     T shadow_value;
00330   };
00331 
00332   //***************************************************************************
00333   /// Read write port.
00334   /// Specialisation for dynamic addresses.
00335   //***************************************************************************
00336   template <typename T>
00337   class io_port_rw<T, 0> : public std::iterator<std::forward_iterator_tag, T>
00338   {
00339   public:
00340 
00341     typedef volatile T*       pointer;
00342     typedef volatile const T* const_pointer;
00343     typedef volatile T&       reference;
00344     typedef volatile const T& const_reference;
00345 
00346     /// Default constructor.
00347     io_port_rw()
00348       : address(std::nullptr)
00349     {
00350     }
00351 
00352     /// Constructor.
00353     io_port_rw(void* address_)
00354       : address(reinterpret_cast<pointer>(address_))
00355     {
00356     }
00357 
00358     /// Copy Constructor.
00359     io_port_rw(const io_port_rw& other_)
00360       : address(reinterpret_cast<pointer>(other_.address))
00361     {
00362     }
00363 
00364     /// Assignment.
00365     io_port_rw& operator =(const io_port_rw& other_)
00366     {
00367       address = other_.address;
00368       return *this;
00369     }
00370 
00371     /// Set the IO port address.
00372     void set_address(void* address_)
00373     {
00374       address = reinterpret_cast<pointer>(address_);
00375     }
00376 
00377     /// Get the IO port address.
00378     pointer get_address()
00379     {
00380       return address;
00381     }
00382 
00383     /// Get the IO port address.
00384     const_pointer get_address() const
00385     {
00386       return address;
00387     }
00388 
00389     /// Read.
00390     operator T() const
00391     {
00392       return *address;
00393     }
00394 
00395     /// Read.
00396     T read() const
00397     {
00398       return *address;
00399     }
00400 
00401     /// Write.
00402     void write(T value_)
00403     {
00404       *address = value_;
00405     }
00406 
00407     /// Write.
00408     io_port_rw& operator =(T value_)
00409     {
00410       *address = value_;
00411       return *this;
00412     }
00413 
00414     /// Read / Write
00415     reference operator *()
00416     {
00417       return *address;
00418     }
00419 
00420     /// Read
00421     const_reference operator *() const
00422     {
00423       return *address;
00424     }
00425 
00426     /// Increment
00427     io_port_rw& operator ++()
00428     {
00429       return *this;
00430     }
00431 
00432     /// Increment
00433     io_port_rw operator ++(int)
00434     {
00435       return *this;
00436     }
00437 
00438   private:
00439 
00440     pointer address;
00441   };
00442 
00443   //***************************************************************************
00444   /// Read only port.
00445   /// Specialisation for dynamic addresses.
00446   //***************************************************************************
00447   template <typename T>
00448   class io_port_ro<T, 0> : public std::iterator<std::input_iterator_tag, T>
00449   {
00450   public:
00451 
00452     typedef volatile T*       pointer;
00453     typedef volatile const T* const_pointer;
00454     typedef volatile T&       reference;
00455     typedef volatile const T& const_reference;
00456 
00457     /// Default constructor.
00458     io_port_ro()
00459       : address(std::nullptr)
00460     {
00461     }
00462 
00463     /// Constructor.
00464     io_port_ro(void* address_)
00465       : address(reinterpret_cast<pointer>(address_))
00466     {
00467     }
00468 
00469     /// Copy Constructor.
00470     io_port_ro(const io_port_ro& other_)
00471       : address(reinterpret_cast<pointer>(other_.address))
00472     {
00473     }
00474 
00475     /// Assignment.
00476     io_port_ro& operator =(const io_port_ro& other_)
00477     {
00478       address = other_.address;
00479       return *this;
00480     }
00481 
00482     /// Set the IO port address.
00483     void set_address(void* address_)
00484     {
00485       address = reinterpret_cast<pointer>(address_);
00486     }
00487 
00488     /// Get the IO port address.
00489     const_pointer get_address() const
00490     {
00491       return address;
00492     }
00493 
00494     /// Read.
00495     operator T() const
00496     {
00497       return *address;
00498     }
00499 
00500     /// Read.
00501     T read() const
00502     {
00503       return *address;
00504     }
00505 
00506     /// Read
00507     const_reference operator *() const
00508     {
00509       return *address;
00510     }
00511 
00512     /// Increment
00513     io_port_ro& operator ++()
00514     {
00515       return *this;
00516     }
00517 
00518     /// Increment
00519     io_port_ro operator ++(int)
00520     {
00521       return *this;
00522     }
00523 
00524   private:
00525 
00526     /// Write disabled.
00527     void operator =(T value);
00528 
00529     pointer address;
00530   };
00531 
00532   //***************************************************************************
00533   /// Write only port.
00534   /// Specialisation for dynamic addresses.
00535   //***************************************************************************
00536   template <typename T>
00537   class io_port_wo<T, 0> : public std::iterator<std::output_iterator_tag, T>
00538   {
00539   public:
00540 
00541     typedef volatile T*       pointer;
00542     typedef volatile const T* const_pointer;
00543     typedef volatile T&       reference;
00544     typedef volatile const T& const_reference;
00545 
00546     /// Default constructor.
00547     io_port_wo()
00548       : address(std::nullptr)
00549     {
00550     }
00551 
00552     /// Constructor.
00553     io_port_wo(void* address_)
00554       : address(reinterpret_cast<pointer>(address_))
00555     {
00556     }
00557 
00558     /// Copy Constructor.
00559     io_port_wo(const io_port_wo& other_)
00560       : address(reinterpret_cast<pointer>(other_.address))
00561     {
00562     }
00563 
00564     /// Assignment.
00565     io_port_wo& operator =(const io_port_wo& other_)
00566     {
00567       address = other_.address;
00568       return *this;
00569     }
00570 
00571     /// Set the IO port address.
00572     void set_address(void* address_)
00573     {
00574       address = reinterpret_cast<pointer>(address_);
00575     }
00576 
00577     /// Get the IO port address.
00578     pointer get_address()
00579     {
00580       return address;
00581     }
00582 
00583     /// Get the IO port address.
00584     const_pointer get_address() const
00585     {
00586       return address;
00587     }
00588 
00589     /// Write.
00590     void write(T value_)
00591     {
00592       *address = value_;
00593     }
00594 
00595     /// Write.
00596     void operator =(T value)
00597     {
00598       *address = value;
00599     }
00600 
00601     /// Write
00602     io_port_wo& operator *()
00603     {
00604       return *this;
00605     }
00606 
00607     /// Increment
00608     io_port_wo& operator ++()
00609     {
00610       return *this;
00611     }
00612 
00613     /// Write
00614     io_port_wo operator ++(int)
00615     {
00616       return *this;
00617     }
00618     
00619   private:
00620 
00621     /// Read disabled.
00622     operator T() const;
00623 
00624     pointer address;
00625   };
00626 
00627   //***************************************************************************
00628   /// Write only port with shadow register.
00629   /// Specialisation for dynamic addresses.
00630   //***************************************************************************
00631   template <typename T>
00632   class io_port_wos<T, 0> : public std::iterator<std::forward_iterator_tag, T>
00633   {
00634   public:
00635 
00636     typedef volatile T*       pointer;
00637     typedef volatile const T* const_pointer;
00638     typedef volatile T&       reference;
00639     typedef volatile const T& const_reference;
00640 
00641     class iterator : public std::iterator<std::bidirectional_iterator_tag, T>
00642     {
00643       typedef io_port_wos<T, 0> iop_t;
00644 
00645     public:
00646 
00647       iterator(iop_t& iop)
00648         : p_iop(&iop)
00649       {
00650       }
00651 
00652       iterator(const iterator& other)
00653         : p_iop(other.p_iop)
00654       {
00655       }
00656 
00657       iterator& operator =(const iterator& other)
00658       {
00659         p_iop = other.p_iop;
00660         return *this;
00661       }
00662 
00663       iop_t& operator *()
00664       {
00665         return *p_iop;
00666       }
00667 
00668       const iop_t& operator *() const
00669       {
00670         return *p_iop;
00671       }
00672 
00673       iterator& operator ++()
00674       {
00675         return *this;
00676       }
00677 
00678       iterator operator ++(int)
00679       {
00680         return *this;
00681       }
00682 
00683       iterator& operator --()
00684       {
00685         return *this;
00686       }
00687 
00688       iterator operator --(int)
00689       {
00690         return *this;
00691       }
00692 
00693     private:
00694 
00695       iop_t* p_iop;
00696     };
00697     
00698     /// Default constructor.
00699     io_port_wos()
00700       : address(std::nullptr)
00701     {
00702     }
00703 
00704     /// Constructor.
00705     io_port_wos(void* address_)
00706       : address(reinterpret_cast<pointer>(address_))
00707     {
00708     }
00709 
00710     /// Copy Constructor.
00711     io_port_wos(const io_port_wos& other_)
00712       : shadow_value(other_.shadow_value),
00713         address(reinterpret_cast<pointer>(other_.address))
00714     {
00715     }
00716 
00717     /// Assignment.
00718     io_port_wos& operator =(const io_port_wos& other_)
00719     {
00720       shadow_value = other_.shadow_value;
00721       address      = other_.address;
00722       return *this;
00723     }
00724 
00725     /// Set the IO port address.
00726     void set_address(void* address_)
00727     {
00728       address = reinterpret_cast<pointer>(address_);
00729     }
00730 
00731     /// Get the IO port address.
00732     pointer get_address()
00733     {
00734       return address;
00735     }
00736 
00737     /// Get the IO port address.
00738     const_pointer get_address() const
00739     {
00740       return address;
00741     }
00742 
00743     /// Get the iterator.
00744     iterator get_iterator()
00745     {
00746       return iterator(*this);
00747     }
00748 
00749     /// Read.
00750     operator T() const
00751     {
00752       return shadow_value;
00753     }
00754 
00755     /// Read.
00756     T read() const
00757     {
00758       return shadow_value;
00759     }
00760 
00761     /// Write.
00762     void write(T value_)
00763     {
00764       shadow_value = value_;
00765       *address = shadow_value;
00766     }
00767 
00768     /// Write.
00769     io_port_wos& operator =(T value_)
00770     {
00771       shadow_value = value_;
00772       *address     = shadow_value;
00773       return *this;
00774     }
00775 
00776     /// Read / Write
00777     io_port_wos&  operator *()
00778     {
00779       return *this;
00780     }
00781 
00782     /// Read
00783     const_reference operator *() const
00784     {
00785       return shadow_value;
00786     }
00787 
00788     /// Increment
00789     io_port_wos& operator ++()
00790     {
00791       return *this;
00792     }
00793 
00794     /// Increment
00795     io_port_wos operator ++(int)
00796     {
00797       return *this;
00798     }
00799     
00800   private:
00801 
00802     T       shadow_value;
00803     pointer address;
00804   };
00805 }
00806 
00807 #endif
00808