@@ -121,20 +121,89 @@ use self::fpu_consts::*;
121121
122122/// Priority Grouping
123123///
124- /// Determines the split of group priority from subpriority .
124+ /// Determines the split of preemption priority from sub-priority .
125125#[ derive( Debug , Clone , Copy ) ]
126126#[ repr( u8 ) ]
127127pub enum PriorityGrouping {
128- /// 4 bits for group priorities, 0 bits for subpriorities
129- Group4Sub0 = 0b011 , // 0b0xx
130- /// 3 bits for group priorities, 1 bit for subpriorities
131- Group3Sub1 = 0b100 ,
132- /// 2 bits for group priorities, 2 bits for subpriorities
133- Group2Sub2 = 0b101 ,
134- /// 1 bit for group priorities, 3 bits for subpriorities
135- Group1Sub3 = 0b110 ,
136- /// 0 bits for group priorities, 4 bits for subpriorities
137- Group0Sub4 = 0b111 ,
128+ /// Priority grouping 0
129+ Prigroup0 = 0 ,
130+ /// Priority grouping 1
131+ Prigroup1 = 1 ,
132+ /// Priority grouping 2
133+ Prigroup2 = 2 ,
134+ /// Priority grouping 3
135+ Prigroup3 = 3 ,
136+ /// Priority grouping 4
137+ Prigroup4 = 4 ,
138+ /// Priority grouping 5
139+ Prigroup5 = 5 ,
140+ /// Priority grouping 6
141+ Prigroup6 = 6 ,
142+ /// Priority grouping 7
143+ Prigroup7 = 7 ,
144+ }
145+
146+ impl PriorityGrouping {
147+ #[ inline]
148+ const fn preemption_priority_bits ( & self , nvic_prio_bits : u8 ) -> u8 {
149+ let bits = 7 - * self as u8 ;
150+
151+ if bits > nvic_prio_bits {
152+ nvic_prio_bits
153+ } else {
154+ bits
155+ }
156+ }
157+
158+ #[ inline]
159+ const fn sub_priority_bits ( & self , nvic_prio_bits : u8 ) -> u8 {
160+ let bits = * self as u8 + nvic_prio_bits;
161+
162+ if bits <= 7 {
163+ 0
164+ } else {
165+ bits - 7
166+ }
167+ }
168+
169+ /// Encode `preemption_priority` and `sub_priority` to fit in `nvic_prio_bits`.
170+ #[ inline]
171+ pub const fn encode_priority (
172+ & self ,
173+ nvic_prio_bits : u8 ,
174+ preemption_priority : u8 ,
175+ sub_priority : u8 ,
176+ ) -> u8 {
177+ let preemption_priority_bits = self . preemption_priority_bits ( nvic_prio_bits) ;
178+ let sub_priority_bits = self . sub_priority_bits ( nvic_prio_bits) ;
179+
180+ let premption_priority_mask = ( 1 << preemption_priority_bits) - 1 ;
181+ let sub_priority_mask = ( 1 << sub_priority_bits) - 1 ;
182+
183+ debug_assert ! ( preemption_priority <= premption_priority_mask) ;
184+ debug_assert ! ( sub_priority <= sub_priority_mask) ;
185+
186+ let priority = ( ( preemption_priority & premption_priority_mask) << sub_priority_bits)
187+ | ( sub_priority & sub_priority_mask) ;
188+
189+ // Priority is stored in the highest bits.
190+ priority << ( 8 - nvic_prio_bits)
191+ }
192+
193+ /// Decode priority stored in `nvic_prio_bits` into a tuple consisting of
194+ /// the preemption priority and sub-priority.
195+ #[ inline]
196+ pub const fn decode_priority ( & self , nvic_prio_bits : u8 , mut priority : u8 ) -> ( u8 , u8 ) {
197+ // Priority is stored in the highest bits.
198+ priority >>= 8 - nvic_prio_bits;
199+
200+ let sub_priority_bits = self . sub_priority_bits ( nvic_prio_bits) ;
201+
202+ let preemption_priority = priority >> sub_priority_bits;
203+ let sub_priority = priority & ( ( 1 << sub_priority_bits) - 1 ) ;
204+
205+ ( preemption_priority, sub_priority)
206+ }
138207}
139208
140209#[ cfg( has_fpu) ]
@@ -895,11 +964,14 @@ impl SCB {
895964 #[ inline]
896965 pub fn get_priority_grouping ( & self ) -> PriorityGrouping {
897966 match self . aircr . read ( ) & SCB_AIRCR_PRIGROUP_MASK >> SCB_AIRCR_PRIGROUP_POS {
898- 0b111 => PriorityGrouping :: Group0Sub4 ,
899- 0b110 => PriorityGrouping :: Group1Sub3 ,
900- 0b101 => PriorityGrouping :: Group2Sub2 ,
901- 0b100 => PriorityGrouping :: Group3Sub1 ,
902- /* 0b0xx */ _ => PriorityGrouping :: Group4Sub0 ,
967+ 0 => PriorityGrouping :: Prigroup0 ,
968+ 1 => PriorityGrouping :: Prigroup1 ,
969+ 2 => PriorityGrouping :: Prigroup2 ,
970+ 3 => PriorityGrouping :: Prigroup3 ,
971+ 4 => PriorityGrouping :: Prigroup4 ,
972+ 5 => PriorityGrouping :: Prigroup5 ,
973+ 6 => PriorityGrouping :: Prigroup6 ,
974+ _ => PriorityGrouping :: Prigroup7 ,
903975 }
904976 }
905977}
0 commit comments