Skip to content

Commit 8f13227

Browse files
Extension Trait for Tasks and Events (#1)
* Add extension trait for tasks and events * Easier to maintain structure * Implement other crates, fix regex a bit * That's gross, but it works * Apply suggestions from code review Co-authored-by: Thales <[email protected]> * Remove nrf9160 impls * More inline always Co-authored-by: Thales <[email protected]>
1 parent 727846d commit 8f13227

File tree

13 files changed

+1272
-15
lines changed

13 files changed

+1272
-15
lines changed

examples/ppi-demo/src/main.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,8 @@ fn main() -> ! {
5959
let ppi_channels = ppi::Parts::new(p.PPI);
6060
let mut channel0 = ppi_channels.ppi0;
6161

62-
channel0.set_task_endpoint(&p.RADIO.tasks_disable as *const _ as u32);
63-
channel0.set_event_endpoint(&p.TIMER0.events_compare[0] as *const _ as u32);
62+
channel0.set_task_endpoint(&p.RADIO.tasks_disable);
63+
channel0.set_event_endpoint(&p.TIMER0.events_compare[0]);
6464
channel0.enable();
6565

6666
let radio = p.RADIO;

nrf-hal-common/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ cortex-m = "0.6.2"
2323
nb = "0.1.2"
2424
fpa = "0.1.0"
2525
rand_core = "0.5.1"
26+
cfg-if = "0.1.10"
2627

2728
[dependencies.void]
2829
default-features = false
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
use crate::ppi::Event;
2+
3+
// Event impls
4+
//
5+
// To reproduce, in the pac crate, search
6+
// `rg 'type EVENTS_.*crate::Reg' --type rust`
7+
// Find (regex):
8+
// `^src/(.*)\.rs:pub type (.*) = .*$`
9+
// Replace (regex):
10+
// `impl Event for crate::target::$1::$2 { }`
11+
impl Event for crate::target::ecb::EVENTS_ENDECB {}
12+
impl Event for crate::target::ecb::EVENTS_ERRORECB {}
13+
impl Event for crate::target::rng::EVENTS_VALRDY {}
14+
impl Event for crate::target::timer0::EVENTS_COMPARE {}
15+
impl Event for crate::target::uart0::EVENTS_CTS {}
16+
impl Event for crate::target::uart0::EVENTS_NCTS {}
17+
impl Event for crate::target::uart0::EVENTS_RXDRDY {}
18+
impl Event for crate::target::uart0::EVENTS_TXDRDY {}
19+
impl Event for crate::target::uart0::EVENTS_ERROR {}
20+
impl Event for crate::target::uart0::EVENTS_RXTO {}
21+
impl Event for crate::target::gpiote::EVENTS_IN {}
22+
impl Event for crate::target::gpiote::EVENTS_PORT {}
23+
impl Event for crate::target::power::EVENTS_POFWARN {}
24+
impl Event for crate::target::clock::EVENTS_HFCLKSTARTED {}
25+
impl Event for crate::target::clock::EVENTS_LFCLKSTARTED {}
26+
impl Event for crate::target::clock::EVENTS_DONE {}
27+
impl Event for crate::target::clock::EVENTS_CTTO {}
28+
impl Event for crate::target::spi0::EVENTS_READY {}
29+
impl Event for crate::target::twi0::EVENTS_STOPPED {}
30+
impl Event for crate::target::twi0::EVENTS_RXDREADY {}
31+
impl Event for crate::target::twi0::EVENTS_TXDSENT {}
32+
impl Event for crate::target::twi0::EVENTS_ERROR {}
33+
impl Event for crate::target::twi0::EVENTS_BB {}
34+
impl Event for crate::target::twi0::EVENTS_SUSPENDED {}
35+
impl Event for crate::target::spis1::EVENTS_END {}
36+
impl Event for crate::target::spis1::EVENTS_ENDRX {}
37+
impl Event for crate::target::spis1::EVENTS_ACQUIRED {}
38+
impl Event for crate::target::rtc0::EVENTS_TICK {}
39+
impl Event for crate::target::rtc0::EVENTS_OVRFLW {}
40+
impl Event for crate::target::rtc0::EVENTS_COMPARE {}
41+
impl Event for crate::target::wdt::EVENTS_TIMEOUT {}
42+
impl Event for crate::target::temp::EVENTS_DATARDY {}
43+
impl Event for crate::target::radio::EVENTS_READY {}
44+
impl Event for crate::target::radio::EVENTS_ADDRESS {}
45+
impl Event for crate::target::radio::EVENTS_PAYLOAD {}
46+
impl Event for crate::target::radio::EVENTS_END {}
47+
impl Event for crate::target::radio::EVENTS_DISABLED {}
48+
impl Event for crate::target::radio::EVENTS_DEVMATCH {}
49+
impl Event for crate::target::radio::EVENTS_DEVMISS {}
50+
impl Event for crate::target::radio::EVENTS_RSSIEND {}
51+
impl Event for crate::target::radio::EVENTS_BCMATCH {}
52+
impl Event for crate::target::lpcomp::EVENTS_READY {}
53+
impl Event for crate::target::lpcomp::EVENTS_DOWN {}
54+
impl Event for crate::target::lpcomp::EVENTS_UP {}
55+
impl Event for crate::target::lpcomp::EVENTS_CROSS {}
56+
impl Event for crate::target::ccm::EVENTS_ENDKSGEN {}
57+
impl Event for crate::target::ccm::EVENTS_ENDCRYPT {}
58+
impl Event for crate::target::ccm::EVENTS_ERROR {}
59+
impl Event for crate::target::aar::EVENTS_END {}
60+
impl Event for crate::target::aar::EVENTS_RESOLVED {}
61+
impl Event for crate::target::aar::EVENTS_NOTRESOLVED {}
62+
impl Event for crate::target::qdec::EVENTS_SAMPLERDY {}
63+
impl Event for crate::target::qdec::EVENTS_REPORTRDY {}
64+
impl Event for crate::target::qdec::EVENTS_ACCOF {}
65+
impl Event for crate::target::adc::EVENTS_END {}
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
use crate::ppi::Event;
2+
3+
// Event impls
4+
//
5+
// To reproduce, in the pac crate, search
6+
// `rg 'type EVENTS_.*crate::Reg' --type rust`
7+
// Find (regex):
8+
// `^src/(.*)\.rs:pub type (.*) = .*$`
9+
// Replace (regex):
10+
// `impl Event for crate::target::$1::$2 { }`
11+
impl Event for crate::target::rng::EVENTS_VALRDY {}
12+
impl Event for crate::target::timer0::EVENTS_COMPARE {}
13+
impl Event for crate::target::spis0::EVENTS_END {}
14+
impl Event for crate::target::spis0::EVENTS_ENDRX {}
15+
impl Event for crate::target::spis0::EVENTS_ACQUIRED {}
16+
impl Event for crate::target::gpiote::EVENTS_IN {}
17+
impl Event for crate::target::gpiote::EVENTS_PORT {}
18+
impl Event for crate::target::uart0::EVENTS_CTS {}
19+
impl Event for crate::target::uart0::EVENTS_NCTS {}
20+
impl Event for crate::target::uart0::EVENTS_RXDRDY {}
21+
impl Event for crate::target::uart0::EVENTS_TXDRDY {}
22+
impl Event for crate::target::uart0::EVENTS_ERROR {}
23+
impl Event for crate::target::uart0::EVENTS_RXTO {}
24+
impl Event for crate::target::clock::EVENTS_HFCLKSTARTED {}
25+
impl Event for crate::target::clock::EVENTS_LFCLKSTARTED {}
26+
impl Event for crate::target::clock::EVENTS_DONE {}
27+
impl Event for crate::target::clock::EVENTS_CTTO {}
28+
impl Event for crate::target::power::EVENTS_POFWARN {}
29+
impl Event for crate::target::power::EVENTS_SLEEPENTER {}
30+
impl Event for crate::target::power::EVENTS_SLEEPEXIT {}
31+
impl Event for crate::target::spim0::EVENTS_STOPPED {}
32+
impl Event for crate::target::spim0::EVENTS_ENDRX {}
33+
impl Event for crate::target::spim0::EVENTS_END {}
34+
impl Event for crate::target::spim0::EVENTS_ENDTX {}
35+
impl Event for crate::target::spim0::EVENTS_STARTED {}
36+
impl Event for crate::target::spi0::EVENTS_READY {}
37+
impl Event for crate::target::twim0::EVENTS_STOPPED {}
38+
impl Event for crate::target::twim0::EVENTS_ERROR {}
39+
impl Event for crate::target::twim0::EVENTS_SUSPENDED {}
40+
impl Event for crate::target::twim0::EVENTS_RXSTARTED {}
41+
impl Event for crate::target::twim0::EVENTS_TXSTARTED {}
42+
impl Event for crate::target::twim0::EVENTS_LASTRX {}
43+
impl Event for crate::target::twim0::EVENTS_LASTTX {}
44+
impl Event for crate::target::twi0::EVENTS_STOPPED {}
45+
impl Event for crate::target::twi0::EVENTS_RXDREADY {}
46+
impl Event for crate::target::twi0::EVENTS_TXDSENT {}
47+
impl Event for crate::target::twi0::EVENTS_ERROR {}
48+
impl Event for crate::target::twi0::EVENTS_BB {}
49+
impl Event for crate::target::twi0::EVENTS_SUSPENDED {}
50+
impl Event for crate::target::egu0::EVENTS_TRIGGERED {}
51+
impl Event for crate::target::ecb::EVENTS_ENDECB {}
52+
impl Event for crate::target::ecb::EVENTS_ERRORECB {}
53+
impl Event for crate::target::rtc0::EVENTS_TICK {}
54+
impl Event for crate::target::rtc0::EVENTS_OVRFLW {}
55+
impl Event for crate::target::rtc0::EVENTS_COMPARE {}
56+
impl Event for crate::target::pdm::EVENTS_STARTED {}
57+
impl Event for crate::target::pdm::EVENTS_STOPPED {}
58+
impl Event for crate::target::pdm::EVENTS_END {}
59+
impl Event for crate::target::wdt::EVENTS_TIMEOUT {}
60+
impl Event for crate::target::radio::EVENTS_READY {}
61+
impl Event for crate::target::radio::EVENTS_ADDRESS {}
62+
impl Event for crate::target::radio::EVENTS_PAYLOAD {}
63+
impl Event for crate::target::radio::EVENTS_END {}
64+
impl Event for crate::target::radio::EVENTS_DISABLED {}
65+
impl Event for crate::target::radio::EVENTS_DEVMATCH {}
66+
impl Event for crate::target::radio::EVENTS_DEVMISS {}
67+
impl Event for crate::target::radio::EVENTS_RSSIEND {}
68+
impl Event for crate::target::radio::EVENTS_BCMATCH {}
69+
impl Event for crate::target::radio::EVENTS_CRCOK {}
70+
impl Event for crate::target::radio::EVENTS_CRCERROR {}
71+
impl Event for crate::target::temp::EVENTS_DATARDY {}
72+
impl Event for crate::target::ccm::EVENTS_ENDKSGEN {}
73+
impl Event for crate::target::ccm::EVENTS_ENDCRYPT {}
74+
impl Event for crate::target::ccm::EVENTS_ERROR {}
75+
impl Event for crate::target::twis0::EVENTS_STOPPED {}
76+
impl Event for crate::target::twis0::EVENTS_ERROR {}
77+
impl Event for crate::target::twis0::EVENTS_RXSTARTED {}
78+
impl Event for crate::target::twis0::EVENTS_TXSTARTED {}
79+
impl Event for crate::target::twis0::EVENTS_WRITE {}
80+
impl Event for crate::target::twis0::EVENTS_READ {}
81+
impl Event for crate::target::uarte0::EVENTS_CTS {}
82+
impl Event for crate::target::uarte0::EVENTS_NCTS {}
83+
impl Event for crate::target::uarte0::EVENTS_RXDRDY {}
84+
impl Event for crate::target::uarte0::EVENTS_ENDRX {}
85+
impl Event for crate::target::uarte0::EVENTS_TXDRDY {}
86+
impl Event for crate::target::uarte0::EVENTS_ENDTX {}
87+
impl Event for crate::target::uarte0::EVENTS_ERROR {}
88+
impl Event for crate::target::uarte0::EVENTS_RXTO {}
89+
impl Event for crate::target::uarte0::EVENTS_RXSTARTED {}
90+
impl Event for crate::target::uarte0::EVENTS_TXSTARTED {}
91+
impl Event for crate::target::uarte0::EVENTS_TXSTOPPED {}
92+
impl Event for crate::target::qdec::EVENTS_SAMPLERDY {}
93+
impl Event for crate::target::qdec::EVENTS_REPORTRDY {}
94+
impl Event for crate::target::qdec::EVENTS_ACCOF {}
95+
impl Event for crate::target::qdec::EVENTS_DBLRDY {}
96+
impl Event for crate::target::qdec::EVENTS_STOPPED {}
97+
impl Event for crate::target::aar::EVENTS_END {}
98+
impl Event for crate::target::aar::EVENTS_RESOLVED {}
99+
impl Event for crate::target::aar::EVENTS_NOTRESOLVED {}
100+
impl Event for crate::target::saadc::EVENTS_STARTED {}
101+
impl Event for crate::target::saadc::EVENTS_END {}
102+
impl Event for crate::target::saadc::EVENTS_DONE {}
103+
impl Event for crate::target::saadc::EVENTS_RESULTDONE {}
104+
impl Event for crate::target::saadc::EVENTS_CALIBRATEDONE {}
105+
impl Event for crate::target::saadc::EVENTS_STOPPED {}
106+
impl Event for crate::target::comp::EVENTS_READY {}
107+
impl Event for crate::target::comp::EVENTS_DOWN {}
108+
impl Event for crate::target::comp::EVENTS_UP {}
109+
impl Event for crate::target::comp::EVENTS_CROSS {}
110+
impl Event for crate::target::pwm0::EVENTS_STOPPED {}
111+
impl Event for crate::target::pwm0::EVENTS_SEQSTARTED {}
112+
impl Event for crate::target::pwm0::EVENTS_SEQEND {}
113+
impl Event for crate::target::pwm0::EVENTS_PWMPERIODEND {}
114+
impl Event for crate::target::pwm0::EVENTS_LOOPSDONE {}
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
use crate::ppi::Event;
2+
3+
// Event impls
4+
//
5+
// To reproduce, in the pac crate, search
6+
// `rg 'type EVENTS_.*crate::Reg' --type rust`
7+
// Find (regex):
8+
// `^src/(.*)\.rs:pub type (.*) = .*$`
9+
// Replace (regex):
10+
// `impl Event for crate::target::$1::$2 { }`
11+
impl Event for crate::target::radio::EVENTS_READY {}
12+
impl Event for crate::target::radio::EVENTS_ADDRESS {}
13+
impl Event for crate::target::radio::EVENTS_PAYLOAD {}
14+
impl Event for crate::target::radio::EVENTS_END {}
15+
impl Event for crate::target::radio::EVENTS_DISABLED {}
16+
impl Event for crate::target::radio::EVENTS_DEVMATCH {}
17+
impl Event for crate::target::radio::EVENTS_DEVMISS {}
18+
impl Event for crate::target::radio::EVENTS_RSSIEND {}
19+
impl Event for crate::target::radio::EVENTS_BCMATCH {}
20+
impl Event for crate::target::radio::EVENTS_CRCOK {}
21+
impl Event for crate::target::radio::EVENTS_CRCERROR {}
22+
impl Event for crate::target::power::EVENTS_POFWARN {}
23+
impl Event for crate::target::power::EVENTS_SLEEPENTER {}
24+
impl Event for crate::target::power::EVENTS_SLEEPEXIT {}
25+
impl Event for crate::target::timer0::EVENTS_COMPARE {}
26+
impl Event for crate::target::rng::EVENTS_VALRDY {}
27+
impl Event for crate::target::uart0::EVENTS_CTS {}
28+
impl Event for crate::target::uart0::EVENTS_NCTS {}
29+
impl Event for crate::target::uart0::EVENTS_RXDRDY {}
30+
impl Event for crate::target::uart0::EVENTS_TXDRDY {}
31+
impl Event for crate::target::uart0::EVENTS_ERROR {}
32+
impl Event for crate::target::uart0::EVENTS_RXTO {}
33+
impl Event for crate::target::spis0::EVENTS_END {}
34+
impl Event for crate::target::spis0::EVENTS_ENDRX {}
35+
impl Event for crate::target::spis0::EVENTS_ACQUIRED {}
36+
impl Event for crate::target::gpiote::EVENTS_IN {}
37+
impl Event for crate::target::gpiote::EVENTS_PORT {}
38+
impl Event for crate::target::clock::EVENTS_HFCLKSTARTED {}
39+
impl Event for crate::target::clock::EVENTS_LFCLKSTARTED {}
40+
impl Event for crate::target::clock::EVENTS_DONE {}
41+
impl Event for crate::target::clock::EVENTS_CTTO {}
42+
impl Event for crate::target::spim0::EVENTS_STOPPED {}
43+
impl Event for crate::target::spim0::EVENTS_ENDRX {}
44+
impl Event for crate::target::spim0::EVENTS_END {}
45+
impl Event for crate::target::spim0::EVENTS_ENDTX {}
46+
impl Event for crate::target::spim0::EVENTS_STARTED {}
47+
impl Event for crate::target::spi0::EVENTS_READY {}
48+
impl Event for crate::target::wdt::EVENTS_TIMEOUT {}
49+
impl Event for crate::target::twim0::EVENTS_STOPPED {}
50+
impl Event for crate::target::twim0::EVENTS_ERROR {}
51+
impl Event for crate::target::twim0::EVENTS_SUSPENDED {}
52+
impl Event for crate::target::twim0::EVENTS_RXSTARTED {}
53+
impl Event for crate::target::twim0::EVENTS_TXSTARTED {}
54+
impl Event for crate::target::twim0::EVENTS_LASTRX {}
55+
impl Event for crate::target::twim0::EVENTS_LASTTX {}
56+
impl Event for crate::target::rtc0::EVENTS_TICK {}
57+
impl Event for crate::target::rtc0::EVENTS_OVRFLW {}
58+
impl Event for crate::target::rtc0::EVENTS_COMPARE {}
59+
impl Event for crate::target::twi0::EVENTS_STOPPED {}
60+
impl Event for crate::target::twi0::EVENTS_RXDREADY {}
61+
impl Event for crate::target::twi0::EVENTS_TXDSENT {}
62+
impl Event for crate::target::twi0::EVENTS_ERROR {}
63+
impl Event for crate::target::twi0::EVENTS_BB {}
64+
impl Event for crate::target::twi0::EVENTS_SUSPENDED {}
65+
impl Event for crate::target::egu0::EVENTS_TRIGGERED {}
66+
impl Event for crate::target::pdm::EVENTS_STARTED {}
67+
impl Event for crate::target::pdm::EVENTS_STOPPED {}
68+
impl Event for crate::target::pdm::EVENTS_END {}
69+
impl Event for crate::target::ecb::EVENTS_ENDECB {}
70+
impl Event for crate::target::ecb::EVENTS_ERRORECB {}
71+
impl Event for crate::target::lpcomp::EVENTS_READY {}
72+
impl Event for crate::target::lpcomp::EVENTS_DOWN {}
73+
impl Event for crate::target::lpcomp::EVENTS_UP {}
74+
impl Event for crate::target::lpcomp::EVENTS_CROSS {}
75+
impl Event for crate::target::temp::EVENTS_DATARDY {}
76+
impl Event for crate::target::ccm::EVENTS_ENDKSGEN {}
77+
impl Event for crate::target::ccm::EVENTS_ENDCRYPT {}
78+
impl Event for crate::target::ccm::EVENTS_ERROR {}
79+
impl Event for crate::target::i2s::EVENTS_RXPTRUPD {}
80+
impl Event for crate::target::i2s::EVENTS_STOPPED {}
81+
impl Event for crate::target::i2s::EVENTS_TXPTRUPD {}
82+
impl Event for crate::target::uarte0::EVENTS_CTS {}
83+
impl Event for crate::target::uarte0::EVENTS_NCTS {}
84+
impl Event for crate::target::uarte0::EVENTS_RXDRDY {}
85+
impl Event for crate::target::uarte0::EVENTS_ENDRX {}
86+
impl Event for crate::target::uarte0::EVENTS_TXDRDY {}
87+
impl Event for crate::target::uarte0::EVENTS_ENDTX {}
88+
impl Event for crate::target::uarte0::EVENTS_ERROR {}
89+
impl Event for crate::target::uarte0::EVENTS_RXTO {}
90+
impl Event for crate::target::uarte0::EVENTS_RXSTARTED {}
91+
impl Event for crate::target::uarte0::EVENTS_TXSTARTED {}
92+
impl Event for crate::target::uarte0::EVENTS_TXSTOPPED {}
93+
impl Event for crate::target::timer3::EVENTS_COMPARE {}
94+
impl Event for crate::target::comp::EVENTS_READY {}
95+
impl Event for crate::target::comp::EVENTS_DOWN {}
96+
impl Event for crate::target::comp::EVENTS_UP {}
97+
impl Event for crate::target::comp::EVENTS_CROSS {}
98+
impl Event for crate::target::twis0::EVENTS_STOPPED {}
99+
impl Event for crate::target::twis0::EVENTS_ERROR {}
100+
impl Event for crate::target::twis0::EVENTS_RXSTARTED {}
101+
impl Event for crate::target::twis0::EVENTS_TXSTARTED {}
102+
impl Event for crate::target::twis0::EVENTS_WRITE {}
103+
impl Event for crate::target::twis0::EVENTS_READ {}
104+
impl Event for crate::target::aar::EVENTS_END {}
105+
impl Event for crate::target::aar::EVENTS_RESOLVED {}
106+
impl Event for crate::target::aar::EVENTS_NOTRESOLVED {}
107+
impl Event for crate::target::qdec::EVENTS_SAMPLERDY {}
108+
impl Event for crate::target::qdec::EVENTS_REPORTRDY {}
109+
impl Event for crate::target::qdec::EVENTS_ACCOF {}
110+
impl Event for crate::target::qdec::EVENTS_DBLRDY {}
111+
impl Event for crate::target::qdec::EVENTS_STOPPED {}
112+
impl Event for crate::target::saadc::EVENTS_STARTED {}
113+
impl Event for crate::target::saadc::EVENTS_END {}
114+
impl Event for crate::target::saadc::EVENTS_DONE {}
115+
impl Event for crate::target::saadc::EVENTS_RESULTDONE {}
116+
impl Event for crate::target::saadc::EVENTS_CALIBRATEDONE {}
117+
impl Event for crate::target::saadc::EVENTS_STOPPED {}
118+
impl Event for crate::target::nfct::EVENTS_READY {}
119+
impl Event for crate::target::nfct::EVENTS_FIELDDETECTED {}
120+
impl Event for crate::target::nfct::EVENTS_FIELDLOST {}
121+
impl Event for crate::target::nfct::EVENTS_TXFRAMESTART {}
122+
impl Event for crate::target::nfct::EVENTS_TXFRAMEEND {}
123+
impl Event for crate::target::nfct::EVENTS_RXFRAMESTART {}
124+
impl Event for crate::target::nfct::EVENTS_RXFRAMEEND {}
125+
impl Event for crate::target::nfct::EVENTS_ERROR {}
126+
impl Event for crate::target::nfct::EVENTS_RXERROR {}
127+
impl Event for crate::target::nfct::EVENTS_ENDRX {}
128+
impl Event for crate::target::nfct::EVENTS_ENDTX {}
129+
impl Event for crate::target::nfct::EVENTS_AUTOCOLRESSTARTED {}
130+
impl Event for crate::target::nfct::EVENTS_COLLISION {}
131+
impl Event for crate::target::nfct::EVENTS_SELECTED {}
132+
impl Event for crate::target::nfct::EVENTS_STARTED {}
133+
impl Event for crate::target::pwm0::EVENTS_STOPPED {}
134+
impl Event for crate::target::pwm0::EVENTS_SEQSTARTED {}
135+
impl Event for crate::target::pwm0::EVENTS_SEQEND {}
136+
impl Event for crate::target::pwm0::EVENTS_PWMPERIODEND {}
137+
impl Event for crate::target::pwm0::EVENTS_LOOPSDONE {}

0 commit comments

Comments
 (0)