-
Notifications
You must be signed in to change notification settings - Fork 21
/
mailbox.c
64 lines (54 loc) · 1.44 KB
/
mailbox.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
/*
* Access system mailboxes
*/
#include "mailbox.h"
#include "barrier.h"
#include "memory.h"
/* Mailbox memory addresses */
static volatile unsigned int *MAILBOX0READ = (unsigned int *) mem_p2v(0x2000b880);
static volatile unsigned int *MAILBOX0STATUS = (unsigned int *) mem_p2v(0x2000b898);
static volatile unsigned int *MAILBOX0WRITE = (unsigned int *) mem_p2v(0x2000b8a0);
/* Bit 31 set in status register if the write mailbox is full */
#define MAILBOX_FULL 0x80000000
/* Bit 30 set in status register if the read mailbox is empty */
#define MAILBOX_EMPTY 0x40000000
unsigned int readmailbox(unsigned int channel)
{
unsigned int count = 0;
unsigned int data;
/* Loop until something is received from channel
* If nothing recieved, it eventually give up and returns 0xffffffff
*/
while(1)
{
while (*MAILBOX0STATUS & MAILBOX_EMPTY)
{
/* Need to check if this is the right thing to do */
flushcache();
/* This is an arbritarily large number */
if(count++ >(1<<25))
{
return 0xffffffff;
}
}
/* Read the data
* Data memory barriers as we've switched peripheral
*/
dmb();
data = *MAILBOX0READ;
dmb();
if ((data & 15) == channel)
return data;
}
}
void writemailbox(unsigned int channel, unsigned int data)
{
/* Wait for mailbox to be not full */
while (*MAILBOX0STATUS & MAILBOX_FULL)
{
/* Need to check if this is the right thing to do */
flushcache();
}
dmb();
*MAILBOX0WRITE = (data | channel);
}