1. diff --git a/src/lib/ioreg.rs b/src/lib/ioreg.rs
  2. index 3f99731..bf010f2 100644
  3. --- a/src/lib/ioreg.rs
  4. +++ b/src/lib/ioreg.rs
  5. @@ -15,6 +15,40 @@
  6.  
  7. #![macro_escape]
  8.  
  9. +/**
  10. + * I wish this would work
  11. + */
  12. +/*
  13. +pub macro_rules! ioregion(
  14. + ($link:ident $s:ident:$width:ty -> $($reg:ident:$ty:ty),+) => (
  15. + extern {
  16. + #[link_name=(stringify!($link))] pub static $s : $link;
  17. + }
  18. + struct $link {
  19. + $(
  20. + pub $reg : VolatileCellRestricted<$ty,$width>,
  21. + )+
  22. + }
  23. + );
  24. +)*/
  25. +/**
  26. + * TODO:
  27. + * * wish: remove $st by making struct type name anonymous/generated
  28. + * * is order guaranteed? Reference Manual says something about #[repr(...)] attribute
  29. + */
  30. +pub macro_rules! ioregion(
  31. + ($link:meta $st:ident,$s:ident:$width:ty -> $($reg:ident:$ty:ty),+) => (
  32. + extern {
  33. + #[$link] pub static $s : $st;
  34. + }
  35. + struct $st {
  36. + $(
  37. + pub $reg : VolatileCellRestricted<$ty,$width>,
  38. + )+
  39. + }
  40. + );
  41. +)
  42. +
  43. macro_rules! ioreg(
  44. ($io:ident: $ty:ty, $($reg:ident),+) => (
  45. #[allow(uppercase_variables)]
  46. diff --git a/src/lib/volatile_cell.rs b/src/lib/volatile_cell.rs
  47. index df64a57..12181a4 100644
  48. --- a/src/lib/volatile_cell.rs
  49. +++ b/src/lib/volatile_cell.rs
  50. @@ -52,3 +52,43 @@ impl<T> VolatileCell<T> {
  51. }
  52. }
  53. }
  54. +
  55. +pub struct VolatileCellRestricted<REST,T> {
  56. + cell : VolatileCell<T>
  57. +}
  58. +
  59. +pub struct R;
  60. +pub struct W;
  61. +pub struct RW;
  62. +
  63. +pub trait VolatileCellReadable<T> {
  64. + fn get(&self) -> T;
  65. +}
  66. +
  67. +pub trait VolatileCellWritable<T> {
  68. + fn set(&self, value: T);
  69. +}
  70. +
  71. +impl<T> VolatileCellReadable<T> for VolatileCellRestricted<R,T> {
  72. + fn get(&self) -> T {
  73. + self.cell.get()
  74. + }
  75. +}
  76. +
  77. +impl<T> VolatileCellWritable<T> for VolatileCellRestricted<W,T> {
  78. + fn set(&self, value: T) {
  79. + self.cell.set(value)
  80. + }
  81. +}
  82. +
  83. +impl<T> VolatileCellReadable<T> for VolatileCellRestricted<RW,T> {
  84. + fn get(&self) -> T {
  85. + self.cell.get()
  86. + }
  87. +}
  88. +
  89. +impl<T> VolatileCellWritable<T> for VolatileCellRestricted<RW,T> {
  90. + fn set(&self, value: T) {
  91. + self.cell.set(value)
  92. + }
  93. +}
  94.  
  95.  
  96. # So with this in zinc code one can define IO registers like this:
  97.  
  98. use lib::volatile_cell::VolatileCellRestricted;
  99. use lib::volatile_cell::{R,RW,W};
  100.  
  101. #[path="../../lib/ioreg.rs"] mod ioreg;
  102.  
  103. ioregion!(link_name="k20_iomem_MCG" _MCG, MCG:u8 -> C1:RW, C2:RW, C3:RW, C4:RW, C5:RW, C6:RW, S:R)
  104.  
  105.  
  106.  
  107. # And in the apps/ it works like this:
  108.  
  109. The biggest issue is that the app code needs to include this:
  110.  
  111. pub use zinc::lib::volatile_cell::VolatileCellReadable;
  112. pub use zinc::lib::volatile_cell::VolatileCellWritable;
  113.  
  114. But afterwards it works as expected:
  115.  
  116. MCG.C1.set(0); // works
  117. MCG.S.set(0) // compilation error, because S is RO
  118. let _ = MCG.S.get(); // works