1//! Interrupt handling for cortex-m devices.
2use core::mem;
3use core::sync::atomic::{compiler_fence, Ordering};
4
5use cortex_m::interrupt::InterruptNumber;
6use cortex_m::peripheral::NVIC;
7use critical_section::CriticalSection;
8
9/// Generate a standard `mod interrupt` for a HAL.
10#[macro_export]
11macro_rules! interrupt_mod {
12 ($($irqs:ident),* $(,)?) => {
13 #[cfg(feature = "rt")]
14 pub use cortex_m_rt::interrupt;
15
16 /// Interrupt definitions.
17 pub mod interrupt {
18 pub use $crate::interrupt::{InterruptExt, Priority};
19 pub use crate::pac::Interrupt::*;
20 pub use crate::pac::Interrupt;
21
22 /// Type-level interrupt infrastructure.
23 ///
24 /// This module contains one *type* per interrupt. This is used for checking at compile time that
25 /// the interrupts are correctly bound to HAL drivers.
26 ///
27 /// As an end user, you shouldn't need to use this module directly. Use the [`crate::bind_interrupts!`] macro
28 /// to bind interrupts, and the [`crate::interrupt`] module to manually register interrupt handlers and manipulate
29 /// interrupts directly (pending/unpending, enabling/disabling, setting the priority, etc...)
30 pub mod typelevel {
31 use super::InterruptExt;
32
33 trait SealedInterrupt {}
34
35 /// Type-level interrupt.
36 ///
37 /// This trait is implemented for all typelevel interrupt types in this module.
38 pub trait Interrupt: SealedInterrupt {
39
40 /// Interrupt enum variant.
41 ///
42 /// This allows going from typelevel interrupts (one type per interrupt) to
43 /// non-typelevel interrupts (a single `Interrupt` enum type, with one variant per interrupt).
44 const IRQ: super::Interrupt;
45
46 /// Enable the interrupt.
47 #[inline]
48 unsafe fn enable() {
49 Self::IRQ.enable()
50 }
51
52 /// Disable the interrupt.
53 #[inline]
54 fn disable() {
55 Self::IRQ.disable()
56 }
57
58 /// Check if interrupt is enabled.
59 #[inline]
60 fn is_enabled() -> bool {
61 Self::IRQ.is_enabled()
62 }
63
64 /// Check if interrupt is pending.
65 #[inline]
66 fn is_pending() -> bool {
67 Self::IRQ.is_pending()
68 }
69
70 /// Set interrupt pending.
71 #[inline]
72 fn pend() {
73 Self::IRQ.pend()
74 }
75
76 /// Unset interrupt pending.
77 #[inline]
78 fn unpend() {
79 Self::IRQ.unpend()
80 }
81
82 /// Get the priority of the interrupt.
83 #[inline]
84 fn get_priority() -> crate::interrupt::Priority {
85 Self::IRQ.get_priority()
86 }
87
88 /// Set the interrupt priority.
89 #[inline]
90 fn set_priority(prio: crate::interrupt::Priority) {
91 Self::IRQ.set_priority(prio)
92 }
93
94 /// Set the interrupt priority with an already-acquired critical section
95 #[inline]
96 fn set_priority_with_cs(cs: critical_section::CriticalSection, prio: crate::interrupt::Priority) {
97 Self::IRQ.set_priority_with_cs(cs, prio)
98 }
99 }
100
101 $(
102 #[allow(non_camel_case_types)]
103 #[doc=stringify!($irqs)]
104 #[doc=" typelevel interrupt."]
105 pub enum $irqs {}
106 impl SealedInterrupt for $irqs{}
107 impl Interrupt for $irqs {
108 const IRQ: super::Interrupt = super::Interrupt::$irqs;
109 }
110 )*
111
112 /// Interrupt handler trait.
113 ///
114 /// Drivers that need to handle interrupts implement this trait.
115 /// The user must ensure `on_interrupt()` is called every time the interrupt fires.
116 /// Drivers must use use [`Binding`] to assert at compile time that the user has done so.
117 pub trait Handler<I: Interrupt> {
118 /// Interrupt handler function.
119 ///
120 /// Must be called every time the `I` interrupt fires, synchronously from
121 /// the interrupt handler context.
122 ///
123 /// # Safety
124 ///
125 /// This function must ONLY be called from the interrupt handler for `I`.
126 unsafe fn on_interrupt();
127 }
128
129 /// Compile-time assertion that an interrupt has been bound to a handler.
130 ///
131 /// For the vast majority of cases, you should use the `bind_interrupts!`
132 /// macro instead of writing `unsafe impl`s of this trait.
133 ///
134 /// # Safety
135 ///
136 /// By implementing this trait, you are asserting that you have arranged for `H::on_interrupt()`
137 /// to be called every time the `I` interrupt fires.
138 ///
139 /// This allows drivers to check bindings at compile-time.
140 pub unsafe trait Binding<I: Interrupt, H: Handler<I>> {}
141 }
142 }
143 };
144}
145
146/// Represents an interrupt type that can be configured by embassy to handle
147/// interrupts.
148pub unsafe trait InterruptExt: InterruptNumber + Copy {
149 /// Enable the interrupt.
150 #[inline]
151 unsafe fn enable(self) {
152 compiler_fence(Ordering::SeqCst);
153 NVIC::unmask(self)
154 }
155
156 /// Disable the interrupt.
157 #[inline]
158 fn disable(self) {
159 NVIC::mask(self);
160 compiler_fence(Ordering::SeqCst);
161 }
162
163 /// Check if interrupt is being handled.
164 #[inline]
165 #[cfg(not(armv6m))]
166 fn is_active(self) -> bool {
167 NVIC::is_active(self)
168 }
169
170 /// Check if interrupt is enabled.
171 #[inline]
172 fn is_enabled(self) -> bool {
173 NVIC::is_enabled(self)
174 }
175
176 /// Check if interrupt is pending.
177 #[inline]
178 fn is_pending(self) -> bool {
179 NVIC::is_pending(self)
180 }
181
182 /// Set interrupt pending.
183 #[inline]
184 fn pend(self) {
185 NVIC::pend(self)
186 }
187
188 /// Unset interrupt pending.
189 #[inline]
190 fn unpend(self) {
191 NVIC::unpend(self)
192 }
193
194 /// Get the priority of the interrupt.
195 #[inline]
196 fn get_priority(self) -> Priority {
197 Priority::from(NVIC::get_priority(self))
198 }
199
200 /// Set the interrupt priority.
201 #[inline]
202 fn set_priority(self, prio: Priority) {
203 unsafe {
204 let mut nvic: cortex_m::peripheral::NVIC = mem::transmute(());
205
206 // On thumbv6, set_priority must do a RMW to change 8bit in a 32bit reg.
207 #[cfg(armv6m)]
208 critical_section::with(|_| nvic.set_priority(self, prio.into()));
209 // On thumbv7+, set_priority does an atomic 8bit write, so no CS needed.
210 #[cfg(not(armv6m))]
211 nvic.set_priority(self, prio.into());
212 }
213 }
214
215 /// Set the interrupt priority with an already-acquired critical section
216 ///
217 /// Equivalent to `set_priority`, except you pass a `CriticalSection` to prove
218 /// you've already acquired a critical section. This prevents acquiring another
219 /// one, which saves code size.
220 #[inline]
221 fn set_priority_with_cs(self, _cs: CriticalSection, prio: Priority) {
222 unsafe {
223 let mut nvic: cortex_m::peripheral::NVIC = mem::transmute(());
224 nvic.set_priority(self, prio.into());
225 }
226 }
227}
228
229unsafe impl<T: InterruptNumber + Copy> InterruptExt for T {}
230
231impl From<u8> for Priority {
232 fn from(priority: u8) -> Self {
233 unsafe { mem::transmute(src:priority & PRIO_MASK) }
234 }
235}
236
237impl From<Priority> for u8 {
238 fn from(p: Priority) -> Self {
239 p as u8
240 }
241}
242
243#[cfg(feature = "prio-bits-0")]
244const PRIO_MASK: u8 = 0x00;
245#[cfg(feature = "prio-bits-1")]
246const PRIO_MASK: u8 = 0x80;
247#[cfg(feature = "prio-bits-2")]
248const PRIO_MASK: u8 = 0xc0;
249#[cfg(feature = "prio-bits-3")]
250const PRIO_MASK: u8 = 0xe0;
251#[cfg(feature = "prio-bits-4")]
252const PRIO_MASK: u8 = 0xf0;
253#[cfg(feature = "prio-bits-5")]
254const PRIO_MASK: u8 = 0xf8;
255#[cfg(feature = "prio-bits-6")]
256const PRIO_MASK: u8 = 0xfc;
257#[cfg(feature = "prio-bits-7")]
258const PRIO_MASK: u8 = 0xfe;
259#[cfg(feature = "prio-bits-8")]
260const PRIO_MASK: u8 = 0xff;
261
262/// The interrupt priority level.
263///
264/// NOTE: The contents of this enum differ according to the set `prio-bits-*` Cargo feature.
265#[cfg(feature = "prio-bits-0")]
266#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
267#[cfg_attr(feature = "defmt", derive(defmt::Format))]
268#[repr(u8)]
269#[allow(missing_docs)]
270pub enum Priority {
271 P0 = 0x0,
272}
273
274/// The interrupt priority level.
275///
276/// NOTE: The contents of this enum differ according to the set `prio-bits-*` Cargo feature.
277#[cfg(feature = "prio-bits-1")]
278#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
279#[cfg_attr(feature = "defmt", derive(defmt::Format))]
280#[repr(u8)]
281#[allow(missing_docs)]
282pub enum Priority {
283 P0 = 0x0,
284 P1 = 0x80,
285}
286
287/// The interrupt priority level.
288///
289/// NOTE: The contents of this enum differ according to the set `prio-bits-*` Cargo feature.
290#[cfg(feature = "prio-bits-2")]
291#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
292#[cfg_attr(feature = "defmt", derive(defmt::Format))]
293#[repr(u8)]
294#[allow(missing_docs)]
295pub enum Priority {
296 P0 = 0x0,
297 P1 = 0x40,
298 P2 = 0x80,
299 P3 = 0xc0,
300}
301
302/// The interrupt priority level.
303///
304/// NOTE: The contents of this enum differ according to the set `prio-bits-*` Cargo feature.
305#[cfg(feature = "prio-bits-3")]
306#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
307#[cfg_attr(feature = "defmt", derive(defmt::Format))]
308#[repr(u8)]
309#[allow(missing_docs)]
310pub enum Priority {
311 P0 = 0x0,
312 P1 = 0x20,
313 P2 = 0x40,
314 P3 = 0x60,
315 P4 = 0x80,
316 P5 = 0xa0,
317 P6 = 0xc0,
318 P7 = 0xe0,
319}
320
321/// The interrupt priority level.
322///
323/// NOTE: The contents of this enum differ according to the set `prio-bits-*` Cargo feature.
324#[cfg(feature = "prio-bits-4")]
325#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
326#[cfg_attr(feature = "defmt", derive(defmt::Format))]
327#[repr(u8)]
328#[allow(missing_docs)]
329pub enum Priority {
330 P0 = 0x0,
331 P1 = 0x10,
332 P2 = 0x20,
333 P3 = 0x30,
334 P4 = 0x40,
335 P5 = 0x50,
336 P6 = 0x60,
337 P7 = 0x70,
338 P8 = 0x80,
339 P9 = 0x90,
340 P10 = 0xa0,
341 P11 = 0xb0,
342 P12 = 0xc0,
343 P13 = 0xd0,
344 P14 = 0xe0,
345 P15 = 0xf0,
346}
347
348/// The interrupt priority level.
349///
350/// NOTE: The contents of this enum differ according to the set `prio-bits-*` Cargo feature.
351#[cfg(feature = "prio-bits-5")]
352#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
353#[cfg_attr(feature = "defmt", derive(defmt::Format))]
354#[repr(u8)]
355#[allow(missing_docs)]
356pub enum Priority {
357 P0 = 0x0,
358 P1 = 0x8,
359 P2 = 0x10,
360 P3 = 0x18,
361 P4 = 0x20,
362 P5 = 0x28,
363 P6 = 0x30,
364 P7 = 0x38,
365 P8 = 0x40,
366 P9 = 0x48,
367 P10 = 0x50,
368 P11 = 0x58,
369 P12 = 0x60,
370 P13 = 0x68,
371 P14 = 0x70,
372 P15 = 0x78,
373 P16 = 0x80,
374 P17 = 0x88,
375 P18 = 0x90,
376 P19 = 0x98,
377 P20 = 0xa0,
378 P21 = 0xa8,
379 P22 = 0xb0,
380 P23 = 0xb8,
381 P24 = 0xc0,
382 P25 = 0xc8,
383 P26 = 0xd0,
384 P27 = 0xd8,
385 P28 = 0xe0,
386 P29 = 0xe8,
387 P30 = 0xf0,
388 P31 = 0xf8,
389}
390
391/// The interrupt priority level.
392///
393/// NOTE: The contents of this enum differ according to the set `prio-bits-*` Cargo feature.
394#[cfg(feature = "prio-bits-6")]
395#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
396#[cfg_attr(feature = "defmt", derive(defmt::Format))]
397#[repr(u8)]
398#[allow(missing_docs)]
399pub enum Priority {
400 P0 = 0x0,
401 P1 = 0x4,
402 P2 = 0x8,
403 P3 = 0xc,
404 P4 = 0x10,
405 P5 = 0x14,
406 P6 = 0x18,
407 P7 = 0x1c,
408 P8 = 0x20,
409 P9 = 0x24,
410 P10 = 0x28,
411 P11 = 0x2c,
412 P12 = 0x30,
413 P13 = 0x34,
414 P14 = 0x38,
415 P15 = 0x3c,
416 P16 = 0x40,
417 P17 = 0x44,
418 P18 = 0x48,
419 P19 = 0x4c,
420 P20 = 0x50,
421 P21 = 0x54,
422 P22 = 0x58,
423 P23 = 0x5c,
424 P24 = 0x60,
425 P25 = 0x64,
426 P26 = 0x68,
427 P27 = 0x6c,
428 P28 = 0x70,
429 P29 = 0x74,
430 P30 = 0x78,
431 P31 = 0x7c,
432 P32 = 0x80,
433 P33 = 0x84,
434 P34 = 0x88,
435 P35 = 0x8c,
436 P36 = 0x90,
437 P37 = 0x94,
438 P38 = 0x98,
439 P39 = 0x9c,
440 P40 = 0xa0,
441 P41 = 0xa4,
442 P42 = 0xa8,
443 P43 = 0xac,
444 P44 = 0xb0,
445 P45 = 0xb4,
446 P46 = 0xb8,
447 P47 = 0xbc,
448 P48 = 0xc0,
449 P49 = 0xc4,
450 P50 = 0xc8,
451 P51 = 0xcc,
452 P52 = 0xd0,
453 P53 = 0xd4,
454 P54 = 0xd8,
455 P55 = 0xdc,
456 P56 = 0xe0,
457 P57 = 0xe4,
458 P58 = 0xe8,
459 P59 = 0xec,
460 P60 = 0xf0,
461 P61 = 0xf4,
462 P62 = 0xf8,
463 P63 = 0xfc,
464}
465
466/// The interrupt priority level.
467///
468/// NOTE: The contents of this enum differ according to the set `prio-bits-*` Cargo feature.
469#[cfg(feature = "prio-bits-7")]
470#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
471#[cfg_attr(feature = "defmt", derive(defmt::Format))]
472#[repr(u8)]
473#[allow(missing_docs)]
474pub enum Priority {
475 P0 = 0x0,
476 P1 = 0x2,
477 P2 = 0x4,
478 P3 = 0x6,
479 P4 = 0x8,
480 P5 = 0xa,
481 P6 = 0xc,
482 P7 = 0xe,
483 P8 = 0x10,
484 P9 = 0x12,
485 P10 = 0x14,
486 P11 = 0x16,
487 P12 = 0x18,
488 P13 = 0x1a,
489 P14 = 0x1c,
490 P15 = 0x1e,
491 P16 = 0x20,
492 P17 = 0x22,
493 P18 = 0x24,
494 P19 = 0x26,
495 P20 = 0x28,
496 P21 = 0x2a,
497 P22 = 0x2c,
498 P23 = 0x2e,
499 P24 = 0x30,
500 P25 = 0x32,
501 P26 = 0x34,
502 P27 = 0x36,
503 P28 = 0x38,
504 P29 = 0x3a,
505 P30 = 0x3c,
506 P31 = 0x3e,
507 P32 = 0x40,
508 P33 = 0x42,
509 P34 = 0x44,
510 P35 = 0x46,
511 P36 = 0x48,
512 P37 = 0x4a,
513 P38 = 0x4c,
514 P39 = 0x4e,
515 P40 = 0x50,
516 P41 = 0x52,
517 P42 = 0x54,
518 P43 = 0x56,
519 P44 = 0x58,
520 P45 = 0x5a,
521 P46 = 0x5c,
522 P47 = 0x5e,
523 P48 = 0x60,
524 P49 = 0x62,
525 P50 = 0x64,
526 P51 = 0x66,
527 P52 = 0x68,
528 P53 = 0x6a,
529 P54 = 0x6c,
530 P55 = 0x6e,
531 P56 = 0x70,
532 P57 = 0x72,
533 P58 = 0x74,
534 P59 = 0x76,
535 P60 = 0x78,
536 P61 = 0x7a,
537 P62 = 0x7c,
538 P63 = 0x7e,
539 P64 = 0x80,
540 P65 = 0x82,
541 P66 = 0x84,
542 P67 = 0x86,
543 P68 = 0x88,
544 P69 = 0x8a,
545 P70 = 0x8c,
546 P71 = 0x8e,
547 P72 = 0x90,
548 P73 = 0x92,
549 P74 = 0x94,
550 P75 = 0x96,
551 P76 = 0x98,
552 P77 = 0x9a,
553 P78 = 0x9c,
554 P79 = 0x9e,
555 P80 = 0xa0,
556 P81 = 0xa2,
557 P82 = 0xa4,
558 P83 = 0xa6,
559 P84 = 0xa8,
560 P85 = 0xaa,
561 P86 = 0xac,
562 P87 = 0xae,
563 P88 = 0xb0,
564 P89 = 0xb2,
565 P90 = 0xb4,
566 P91 = 0xb6,
567 P92 = 0xb8,
568 P93 = 0xba,
569 P94 = 0xbc,
570 P95 = 0xbe,
571 P96 = 0xc0,
572 P97 = 0xc2,
573 P98 = 0xc4,
574 P99 = 0xc6,
575 P100 = 0xc8,
576 P101 = 0xca,
577 P102 = 0xcc,
578 P103 = 0xce,
579 P104 = 0xd0,
580 P105 = 0xd2,
581 P106 = 0xd4,
582 P107 = 0xd6,
583 P108 = 0xd8,
584 P109 = 0xda,
585 P110 = 0xdc,
586 P111 = 0xde,
587 P112 = 0xe0,
588 P113 = 0xe2,
589 P114 = 0xe4,
590 P115 = 0xe6,
591 P116 = 0xe8,
592 P117 = 0xea,
593 P118 = 0xec,
594 P119 = 0xee,
595 P120 = 0xf0,
596 P121 = 0xf2,
597 P122 = 0xf4,
598 P123 = 0xf6,
599 P124 = 0xf8,
600 P125 = 0xfa,
601 P126 = 0xfc,
602 P127 = 0xfe,
603}
604
605/// The interrupt priority level.
606///
607/// NOTE: The contents of this enum differ according to the set `prio-bits-*` Cargo feature.
608#[cfg(feature = "prio-bits-8")]
609#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
610#[cfg_attr(feature = "defmt", derive(defmt::Format))]
611#[repr(u8)]
612#[allow(missing_docs)]
613pub enum Priority {
614 P0 = 0x0,
615 P1 = 0x1,
616 P2 = 0x2,
617 P3 = 0x3,
618 P4 = 0x4,
619 P5 = 0x5,
620 P6 = 0x6,
621 P7 = 0x7,
622 P8 = 0x8,
623 P9 = 0x9,
624 P10 = 0xa,
625 P11 = 0xb,
626 P12 = 0xc,
627 P13 = 0xd,
628 P14 = 0xe,
629 P15 = 0xf,
630 P16 = 0x10,
631 P17 = 0x11,
632 P18 = 0x12,
633 P19 = 0x13,
634 P20 = 0x14,
635 P21 = 0x15,
636 P22 = 0x16,
637 P23 = 0x17,
638 P24 = 0x18,
639 P25 = 0x19,
640 P26 = 0x1a,
641 P27 = 0x1b,
642 P28 = 0x1c,
643 P29 = 0x1d,
644 P30 = 0x1e,
645 P31 = 0x1f,
646 P32 = 0x20,
647 P33 = 0x21,
648 P34 = 0x22,
649 P35 = 0x23,
650 P36 = 0x24,
651 P37 = 0x25,
652 P38 = 0x26,
653 P39 = 0x27,
654 P40 = 0x28,
655 P41 = 0x29,
656 P42 = 0x2a,
657 P43 = 0x2b,
658 P44 = 0x2c,
659 P45 = 0x2d,
660 P46 = 0x2e,
661 P47 = 0x2f,
662 P48 = 0x30,
663 P49 = 0x31,
664 P50 = 0x32,
665 P51 = 0x33,
666 P52 = 0x34,
667 P53 = 0x35,
668 P54 = 0x36,
669 P55 = 0x37,
670 P56 = 0x38,
671 P57 = 0x39,
672 P58 = 0x3a,
673 P59 = 0x3b,
674 P60 = 0x3c,
675 P61 = 0x3d,
676 P62 = 0x3e,
677 P63 = 0x3f,
678 P64 = 0x40,
679 P65 = 0x41,
680 P66 = 0x42,
681 P67 = 0x43,
682 P68 = 0x44,
683 P69 = 0x45,
684 P70 = 0x46,
685 P71 = 0x47,
686 P72 = 0x48,
687 P73 = 0x49,
688 P74 = 0x4a,
689 P75 = 0x4b,
690 P76 = 0x4c,
691 P77 = 0x4d,
692 P78 = 0x4e,
693 P79 = 0x4f,
694 P80 = 0x50,
695 P81 = 0x51,
696 P82 = 0x52,
697 P83 = 0x53,
698 P84 = 0x54,
699 P85 = 0x55,
700 P86 = 0x56,
701 P87 = 0x57,
702 P88 = 0x58,
703 P89 = 0x59,
704 P90 = 0x5a,
705 P91 = 0x5b,
706 P92 = 0x5c,
707 P93 = 0x5d,
708 P94 = 0x5e,
709 P95 = 0x5f,
710 P96 = 0x60,
711 P97 = 0x61,
712 P98 = 0x62,
713 P99 = 0x63,
714 P100 = 0x64,
715 P101 = 0x65,
716 P102 = 0x66,
717 P103 = 0x67,
718 P104 = 0x68,
719 P105 = 0x69,
720 P106 = 0x6a,
721 P107 = 0x6b,
722 P108 = 0x6c,
723 P109 = 0x6d,
724 P110 = 0x6e,
725 P111 = 0x6f,
726 P112 = 0x70,
727 P113 = 0x71,
728 P114 = 0x72,
729 P115 = 0x73,
730 P116 = 0x74,
731 P117 = 0x75,
732 P118 = 0x76,
733 P119 = 0x77,
734 P120 = 0x78,
735 P121 = 0x79,
736 P122 = 0x7a,
737 P123 = 0x7b,
738 P124 = 0x7c,
739 P125 = 0x7d,
740 P126 = 0x7e,
741 P127 = 0x7f,
742 P128 = 0x80,
743 P129 = 0x81,
744 P130 = 0x82,
745 P131 = 0x83,
746 P132 = 0x84,
747 P133 = 0x85,
748 P134 = 0x86,
749 P135 = 0x87,
750 P136 = 0x88,
751 P137 = 0x89,
752 P138 = 0x8a,
753 P139 = 0x8b,
754 P140 = 0x8c,
755 P141 = 0x8d,
756 P142 = 0x8e,
757 P143 = 0x8f,
758 P144 = 0x90,
759 P145 = 0x91,
760 P146 = 0x92,
761 P147 = 0x93,
762 P148 = 0x94,
763 P149 = 0x95,
764 P150 = 0x96,
765 P151 = 0x97,
766 P152 = 0x98,
767 P153 = 0x99,
768 P154 = 0x9a,
769 P155 = 0x9b,
770 P156 = 0x9c,
771 P157 = 0x9d,
772 P158 = 0x9e,
773 P159 = 0x9f,
774 P160 = 0xa0,
775 P161 = 0xa1,
776 P162 = 0xa2,
777 P163 = 0xa3,
778 P164 = 0xa4,
779 P165 = 0xa5,
780 P166 = 0xa6,
781 P167 = 0xa7,
782 P168 = 0xa8,
783 P169 = 0xa9,
784 P170 = 0xaa,
785 P171 = 0xab,
786 P172 = 0xac,
787 P173 = 0xad,
788 P174 = 0xae,
789 P175 = 0xaf,
790 P176 = 0xb0,
791 P177 = 0xb1,
792 P178 = 0xb2,
793 P179 = 0xb3,
794 P180 = 0xb4,
795 P181 = 0xb5,
796 P182 = 0xb6,
797 P183 = 0xb7,
798 P184 = 0xb8,
799 P185 = 0xb9,
800 P186 = 0xba,
801 P187 = 0xbb,
802 P188 = 0xbc,
803 P189 = 0xbd,
804 P190 = 0xbe,
805 P191 = 0xbf,
806 P192 = 0xc0,
807 P193 = 0xc1,
808 P194 = 0xc2,
809 P195 = 0xc3,
810 P196 = 0xc4,
811 P197 = 0xc5,
812 P198 = 0xc6,
813 P199 = 0xc7,
814 P200 = 0xc8,
815 P201 = 0xc9,
816 P202 = 0xca,
817 P203 = 0xcb,
818 P204 = 0xcc,
819 P205 = 0xcd,
820 P206 = 0xce,
821 P207 = 0xcf,
822 P208 = 0xd0,
823 P209 = 0xd1,
824 P210 = 0xd2,
825 P211 = 0xd3,
826 P212 = 0xd4,
827 P213 = 0xd5,
828 P214 = 0xd6,
829 P215 = 0xd7,
830 P216 = 0xd8,
831 P217 = 0xd9,
832 P218 = 0xda,
833 P219 = 0xdb,
834 P220 = 0xdc,
835 P221 = 0xdd,
836 P222 = 0xde,
837 P223 = 0xdf,
838 P224 = 0xe0,
839 P225 = 0xe1,
840 P226 = 0xe2,
841 P227 = 0xe3,
842 P228 = 0xe4,
843 P229 = 0xe5,
844 P230 = 0xe6,
845 P231 = 0xe7,
846 P232 = 0xe8,
847 P233 = 0xe9,
848 P234 = 0xea,
849 P235 = 0xeb,
850 P236 = 0xec,
851 P237 = 0xed,
852 P238 = 0xee,
853 P239 = 0xef,
854 P240 = 0xf0,
855 P241 = 0xf1,
856 P242 = 0xf2,
857 P243 = 0xf3,
858 P244 = 0xf4,
859 P245 = 0xf5,
860 P246 = 0xf6,
861 P247 = 0xf7,
862 P248 = 0xf8,
863 P249 = 0xf9,
864 P250 = 0xfa,
865 P251 = 0xfb,
866 P252 = 0xfc,
867 P253 = 0xfd,
868 P254 = 0xfe,
869 P255 = 0xff,
870}
871