IEEE 802.15.4 subsystem
Sign in or create your account | Project List | Help
IEEE 802.15.4 subsystem Git Source Tree
Root/
Source at commit 86e556ce92af39a3353e0c6494ba20de59d47d4c created 10 years 4 months ago. By Werner Almesberger, First part of the board bringup: power and clock. | |
---|---|
1 | #include <stdint.h> |
2 | #include <stdlib.h> |
3 | #include <stdio.h> |
4 | #include <fcntl.h> |
5 | #include <sys/mman.h> |
6 | |
7 | |
8 | enum { |
9 | VDD_OFF = 1 << 6, /* VDD disable, PD06 */ |
10 | MxSx = 1 << 8, /* CMD, PD08 */ |
11 | CLK = 1 << 9, /* CLK, PD09 */ |
12 | SCLK = 1 << 10, /* DAT0, PD10 */ |
13 | SLP_TR = 1 << 11, /* DAT1, PD11 */ |
14 | IRQ = 1 << 12, /* DAT2, PD12 */ |
15 | nSEL = 1 << 13, /* DAT3/CD, PD13 */ |
16 | }; |
17 | |
18 | |
19 | #define SOC_BASE 0x10000000 |
20 | |
21 | #define REG(n) (*(volatile uint32_t *) (dsc->mem+(n))) |
22 | |
23 | #define CGU(n) REG(0x00000+(n)) |
24 | #define GPIO(n) REG(0x10000+(n)) |
25 | #define MSC(n) REG(0x21000+(n)) |
26 | |
27 | #define PDDATS GPIO(0x314) /* port D data set */ |
28 | #define PDDATC GPIO(0x318) /* port D data clear */ |
29 | #define PDFUNS GPIO(0x344) /* port D function set */ |
30 | #define PDFUNC GPIO(0x348) /* port D function clear */ |
31 | #define PDDIRS GPIO(0x364) /* port D direction set */ |
32 | #define PDDIRC GPIO(0x368) /* port D direction clear */ |
33 | |
34 | #define MSC_STRPCL MSC(0x00) /* Start/stop MMC/SD clock */ |
35 | #define MSC_CLKRT MSC(0x08) /* MSC Clock Rate */ |
36 | |
37 | #define CLKGR CGU(0x0020) /* Clock Gate */ |
38 | #define MSCCDR CGU(0x0068) /* MSC device clock divider */ |
39 | |
40 | |
41 | #define PAGE_SIZE 4096 |
42 | |
43 | |
44 | struct atusd_dsc { |
45 | int fd; |
46 | void *mem; |
47 | }; |
48 | |
49 | |
50 | struct atusd_dsc *atusd_open(void) |
51 | { |
52 | struct atusd_dsc *dsc; |
53 | |
54 | dsc = malloc(sizeof(*dsc)); |
55 | if (!dsc) { |
56 | perror("malloc"); |
57 | exit(1); |
58 | } |
59 | |
60 | dsc->fd = open("/dev/mem", O_RDWR); |
61 | if (dsc->fd < 0) { |
62 | perror("/dev/mem"); |
63 | exit(1); |
64 | } |
65 | dsc->mem = mmap(NULL, PAGE_SIZE*3*16, PROT_READ | PROT_WRITE, |
66 | MAP_SHARED, dsc->fd, SOC_BASE); |
67 | if (dsc->mem == MAP_FAILED) { |
68 | perror("mmap"); |
69 | exit(1); |
70 | } |
71 | |
72 | /* set the output levels */ |
73 | PDDATS = nSEL | VDD_OFF; |
74 | PDDATC = SCLK | SLP_TR; |
75 | |
76 | /* take the GPIOs away from the MMC controller */ |
77 | PDFUNC = MxSx | SCLK | SLP_TR | IRQ | nSEL; |
78 | PDFUNS = CLK; |
79 | |
80 | /* set the pin directions */ |
81 | PDDIRC = IRQ; |
82 | PDDIRS = MxSx | CLK | SCLK | SLP_TR | nSEL; |
83 | |
84 | /* enable power */ |
85 | PDDATC = VDD_OFF; |
86 | |
87 | /* set the MSC clock to 316 MHz / 21 = 16 MHz */ |
88 | MSCCDR = 20; |
89 | /* |
90 | * Enable the MSC clock. We need to do this before accessing any |
91 | * registers of the MSC block ! |
92 | */ |
93 | CLKGR &= ~(1 << 7); |
94 | /* bus clock = MSC clock / 1 */ |
95 | MSC_CLKRT = 0; |
96 | /* start MMC clock output */ |
97 | MSC_STRPCL = 2; |
98 | |
99 | return dsc; |
100 | } |
101 | |
102 | |
103 | void atusd_close(struct atusd_dsc *dsc) |
104 | { |
105 | /* stop the MMC clock */ |
106 | MSC_STRPCL = 1; |
107 | |
108 | /* cut the power */ |
109 | PDDATS = VDD_OFF; |
110 | |
111 | /* make all MMC pins inputs */ |
112 | PDDIRC = MxSx | CLK | SCLK | SLP_TR | IRQ | nSEL; |
113 | } |
114 |