Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
io_port.h
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
Generated on Tue Jul 12 2022 14:05:41 by
