11#include " interrupt.h"
22#include " scss_registers.h"
3- #include " CurieMailboxMsg.h"
43#include " CurieMailbox.h"
54
65#define BUFSIZE 33
7- #define CHANNEL_STS_MASK 0x1
8- #define CHANNEL_INT_MASK 0x2
9- #define CTRL_WORD_MASK 0x7FFFFFFF
10- #define CHALL_STATUS_MASK 0xFFFF
11- #define CHANNEL_STS_BITS (CHANNEL_STS_MASK | CHANNEL_INT_MASK)
12-
136#define CAP_CHAN (chan ) chan = (chan >= CurieMailbox.numChannels) ?\
147 CurieMailbox.numChannels - 1 : ((chan < 0 ) \
158 ? 0 : chan)
169
17- /* Mailbox channel status register */
18- #define IO_REG_MAILBOX_CHALL_STS (SCSS_REGISTER_BASE + 0xAC0 )
19-
2010static CurieMailboxMsg buf[BUFSIZE];
2111static volatile unsigned int head;
2212static unsigned int tail;
2313
24- typedef struct mbox_channel mbox_channel_t ;
25- typedef struct mbox_intmask mbox_intmask_t ;
26-
27- /* Represents the registers for a single mailbox channel */
28- struct mbox_channel {
29- uint32_t ctrl;
30- uint32_t data[CHANNEL_DATA_WORDS];
31- uint32_t sts;
32- };
33-
34- /* Mailbox interrupt mask; right now we only care about the
35- * second byte, for SS mailbox interrupts (one bit per mailbox channel) */
36- struct mbox_intmask {
37- uint8_t lmt_intmask;
38- uint8_t ss_intmask;
39- uint8_t lmt_halt;
40- uint8_t ss_halt;
41- };
42-
43- static volatile mbox_intmask_t *intmask;
44- static volatile mbox_channel_t *mbox;
45-
4614CurieMailboxClass::CurieMailboxClass (void )
4715{
48- intmask = (mbox_intmask_t *)IO_REG_MAILBOX_INT_MASK;
49- mbox = (mbox_channel_t *)IO_REG_MAILBOX_BASE;
5016 head = 0 ;
5117 tail = 0 ;
5218}
@@ -64,95 +30,6 @@ static void buf_put (CurieMailboxMsg msg)
6430 head = (head + 1 ) % BUFSIZE;
6531}
6632
67- static uint16_t get_chall_sts (void )
68- {
69- return MMIO_REG_VAL (IO_REG_MAILBOX_CHALL_STS) & CHALL_STATUS_MASK;
70- }
71-
72- static void read_channel (int channel)
73- {
74- int i;
75- CurieMailboxMsg msg;
76-
77- /* Copy channel data into CurieMailboxMsg object */
78- msg.id = mbox[channel].ctrl & CTRL_WORD_MASK;
79- msg.channel = channel;
80-
81- for (i = 0 ; i < CHANNEL_DATA_WORDS; ++i) {
82- msg.data [i] = mbox[channel].data [i];
83- }
84-
85- /* Add CurieMailboxMsg object to buffer */
86- buf_put (msg);
87-
88- /* Clear channel status & interrupt flags */
89- mbox[channel].sts |= CHANNEL_STS_BITS;
90- }
91-
92- static void write_channel (CurieMailboxMsg msg)
93- {
94- int i;
95- uint32_t key;
96-
97- /* Can't write if channel status flag is set */
98- while ((mbox[msg.channel ].sts & CHANNEL_STS_MASK));
99-
100- key = interrupt_lock ();
101- /* Poplate channel payload */
102- mbox[msg.channel ].ctrl |= (msg.id & CTRL_WORD_MASK);
103- for (i = 0 ; i < CHANNEL_DATA_WORDS; ++i) {
104- mbox[msg.channel ].data [i] = msg.data [i];
105- }
106-
107- /* Trigger interupt to host */
108- mbox[msg.channel ].ctrl |= ~(CTRL_WORD_MASK);
109-
110- /* Wait for HW to set the channel status bit */
111- while (!(mbox[msg.channel ].sts & CHANNEL_STS_MASK));
112-
113- /* Wait for destination processor to clear channel status bit */
114- while ((mbox[msg.channel ].sts & CHANNEL_STS_MASK));
115- interrupt_unlock (key);
116- }
117-
118- static void mbox_isr (void )
119- {
120- int i;
121- uint32_t sts;
122-
123- sts = get_chall_sts ();
124- /* Get channel number */
125- for (i = 0 ; i < CurieMailbox.numChannels ; ++i) {
126- if (sts & (1 << (i * 2 + 1 ))) {
127- break ;
128- }
129- }
130-
131- read_channel (i);
132- }
133-
134- static void mbox_hardware_init (void )
135- {
136- int i;
137-
138- for (i = 0 ; i < CurieMailbox.numChannels ; ++i) {
139- mbox[i].sts &= ~(CHANNEL_STS_BITS);
140- }
141- }
142-
143- static void mbox_interrupts_init (bool master)
144- {
145- interrupt_disable (SOC_MBOX_INTERRUPT);
146-
147- /* Mask SS mailbox interrupts for all channels;
148- * Unmasking is done by enableReceive */
149- intmask->ss_intmask = 0xFF ;
150-
151- if (master) mbox_hardware_init ();
152- interrupt_connect (SOC_MBOX_INTERRUPT, mbox_isr);
153- interrupt_enable (SOC_MBOX_INTERRUPT);
154- }
155-
15633int CurieMailboxClass::available (void )
15734{
15835 return ((head + BUFSIZE) - tail) % BUFSIZE;
@@ -161,38 +38,40 @@ int CurieMailboxClass::available (void)
16138void CurieMailboxClass::enableReceive (int channel)
16239{
16340 CAP_CHAN (channel);
164- intmask-> ss_intmask &= ~( 1 << channel);
41+ mailbox_enable_receive ( channel);
16542}
16643
16744void CurieMailboxClass::disableReceive (int channel)
16845{
16946 CAP_CHAN (channel);
170- intmask-> ss_intmask |= 1 << channel;
47+ mailbox_disable_receive ( channel) ;
17148}
17249
173- void CurieMailboxClass::begin ( void )
50+ static void mbox_isr (CurieMailboxMsg msg )
17451{
175- mbox_interrupts_init ( false );
52+ buf_put (msg );
17653}
17754
178- void CurieMailboxClass::begin (bool master )
55+ void CurieMailboxClass::begin (void )
17956{
180- mbox_interrupts_init (master);
57+ /* Channel 7 is reserved for Serial */
58+ for (int i = 0 ; i < NUM_MAILBOX_CHANNELS - 1 ; ++i) {
59+ mailbox_register (i, mbox_isr);
60+ }
18161}
18262
18363void CurieMailboxClass::end (void )
18464{
185- /* Wait for all channels to be inactive */
186- while (get_chall_sts ());
187-
188- interrupt_disable (SOC_MBOX_INTERRUPT);
189- interrupt_disconnect (SOC_MBOX_INTERRUPT);
65+ /* Channel 7 is reserved for Serial */
66+ for (int i = 0 ; i < NUM_MAILBOX_CHANNELS - 1 ; ++i) {
67+ mailbox_register (i, 0 );
68+ }
19069}
19170
19271void CurieMailboxClass::put (CurieMailboxMsg msg)
19372{
19473 CAP_CHAN (msg.channel );
195- write_channel (msg);
74+ mailbox_write (msg);
19675}
19776
19877CurieMailboxMsg CurieMailboxClass::get (void )
0 commit comments