rpi midi recieve test
[rpimidirecv] / uart.c
1 #include <stdio.h>
2 #include <stdint.h>
3 #include <unistd.h>
4 #include <fcntl.h>
5 #include <sys/mman.h>
6 #include "uart.h"
7
8 #define CLK                             3000000
9
10 #define IOBASEADDR              0x3f000000
11 #define IOSIZE                  16777216
12 #define IOREGADDR(x)    ((x) | IOBASEADDR)
13
14 #define REG_UART_FLAGS  *(volatile uint32_t*)IOREGADDR(0x201018)
15 #define REG_UART_IBRD   *(volatile uint32_t*)IOREGADDR(0x201024)
16 #define REG_UART_FBRD   *(volatile uint32_t*)IOREGADDR(0x201028)
17 #define REG_UART_LCTL   *(volatile uint32_t*)IOREGADDR(0x20102c)
18 #define REG_UART_CTL    *(volatile uint32_t*)IOREGADDR(0x201030)
19
20 #define FLAGS_TXEMPTY   0x80
21 #define FLAGS_RXFULL    0x40
22 #define FLAGS_TXFULL    0x20
23 #define FLAGS_RXEMPTY   0x10
24 #define FLAGS_BUSY              0x08
25 #define FLAGS_CTS               0x01
26
27 #define LCTL_8BIT               0x60
28 #define LCTL_FIFOEN             0x10
29 #define LCTL_PAREN              0x02
30 #define LCLT_BRK                0x01
31
32 #define CTL_RXEN                0x200
33 #define CTL_TXEN                0x100
34 #define CTL_EN                  0x001
35
36 int uart_config(int rate)
37 {
38         int fd, div;
39         void *ptr;
40
41         if((fd = open("/dev/mem", O_RDWR)) == -1) {
42                 perror("failed to open /dev/mem");
43                 return 1;
44         }
45         if((ptr = mmap((void*)IOBASEADDR, IOSIZE, PROT_READ | PROT_WRITE,
46                                         MAP_SHARED | MAP_FIXED, fd, IOBASEADDR)) == (void*)-1) {
47                 perror("failed to map IO space");
48                 return 1;
49         }
50
51         REG_UART_CTL = 0;
52         while(REG_UART_FLAGS & FLAGS_BUSY);
53
54         div = (CLK << 6) / (rate << 4);
55         printf("setting divisor (i/f): %d %d\n", div >> 6, div & 0x3f);
56         REG_UART_IBRD = div >> 6;
57         REG_UART_FBRD = div & 0x3f;
58         REG_UART_LCTL = LCTL_8BIT | LCTL_FIFOEN;
59
60         REG_UART_CTL = CTL_RXEN | CTL_TXEN | CTL_EN;
61
62         munmap(ptr, IOSIZE);
63         close(fd);
64         return 0;
65 }