embox

Форк
0
/
bcm2835_mailbox.c 
69 строк · 2.0 Кб
1
/**
2
 * @file
3
 * @brief Mailbox Communication mechanism for Raspberry Pi
4
 *
5
 * @date 16.07.15
6
 * @author Michele Di Giorgio
7
 */
8

9
#include <errno.h>
10
#include <stdint.h>
11

12
#include <drivers/mailbox/bcm2835_mailbox.h>
13
#include <hal/reg.h>
14
#include <hal/mem_barriers.h>
15

16
static struct bcm2835_mailbox_regs volatile *const mailbox_regs =
17
        (struct bcm2835_mailbox_regs volatile *) BCM2835_MAILBOX_BASE;
18

19
/**
20
 * Read from memory mapped IO registers with a memory barrier around.
21
 * @param addr - pointer to register address
22
 *
23
 * @return data read (returns a memory location)
24
 */
25
static uint32_t read_mmio(uint32_t volatile *addr) {
26
    uint32_t n;
27
    n = REG_LOAD(addr);
28
    data_mem_barrier();
29
    return n;
30
}
31

32
/**
33
 * Write to memory mapped IO register with a memory barrier around.
34
 * @param addr - pointer to register address
35
 * @param val - data to be stored (a pointer to a memory location)
36
 */
37
static void write_mmio(uint32_t volatile *addr, uint32_t val) {
38
    data_mem_barrier();
39
    REG_STORE(addr, val);
40
}
41

42
int bcm2835_mailbox_write(uint32_t data, uint32_t channel) {
43
    /* validate channel number */
44
    if (channel > 15) {
45
        return -EINVAL;
46
    }
47
    /* lowest 4 bits of data must be 0 and combine data and the channel */
48
    uint32_t to_write = (data & BCM2835_MAILBOX_DATA_MASK) | channel;
49
    /* read the status field and wait until ready */
50
    while (read_mmio((uint32_t volatile *)&mailbox_regs->Status) & BCM2835_MAILBOX_FULL);
51
    write_mmio((uint32_t volatile *)&mailbox_regs->Write, to_write);
52
    return 0;
53
}
54

55
uint32_t bcm2835_mailbox_read(uint32_t channel) {
56
    uint32_t data;
57

58
    if (channel > 15) {
59
        return -EINVAL;
60
    }
61

62
    /* repeat reading if the channel was wrong */
63
    do {
64
        while (read_mmio((uint32_t volatile *)&mailbox_regs->Status) & BCM2835_MAILBOX_EMPTY);
65
        data = read_mmio((uint32_t volatile *)&mailbox_regs->Read);
66
    } while ((data & BCM2835_MAILBOX_CHANNEL_MASK) != channel);
67
    /* return the message only (top 28 bits of the read data) */
68
    return data & BCM2835_MAILBOX_DATA_MASK;
69
}
70

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.