10 /* McBSP Register Offsets. */
11 #define MCBSP_DRR_OFFSET 0x00
12 #define MCBSP_DXR_OFFSET 0x08
13 #define MCBSP_SPCR2_OFFSET 0x10
14 #define MCBSP_SPCR1_OFFSET 0x14
15 #define MCBSP_RCR2_OFFSET 0x18
16 #define MCBSP_RCR1_OFFSET 0x1C
17 #define MCBSP_XCR2_OFFSET 0x20
18 #define MCBSP_XCR1_OFFSET 0x24
19 #define MCBSP_SRGR2_OFFSET 0x28
20 #define MCBSP_SRGR1_OFFSET 0x2C
21 #define MCBSP_MCR2_OFFSET 0x30
22 #define MCBSP_MCR1_OFFSET 0x34
23 #define MCBSP_RCERA_OFFSET 0x38
24 #define MCBSP_RCERB_OFFSET 0x3C
25 #define MCBSP_XCERA_OFFSET 0x40
26 #define MCBSP_XCERB_OFFSET 0x44
27 #define MCBSP_PCR0_OFFSET 0x48
29 #define MCBSP_REV_OFFSET 0x7C
30 #define MCBSP_RINTCLR_OFFSET 0x80
31 #define MCBSP_XINTCLR_OFFSET 0x84
32 #define MCBSP_ROVFLCLR_OFFSET 0x88
33 #define MCBSP_SYSCONFIG_OFFSET 0x8C
34 #define MCBSP_THRSH2_OFFSET 0x90
35 #define MCBSP_THRSH1_OFFSET 0x94
36 #define MCBSP_IRQSTATUS_OFFSET 0xA0
38 #define MCBSP_IRQSTATUS_OFFSET 0xA0
39 #define MCBSP_IRQENABLE_OFFSET 0xA4
40 #define MCBSP_WAKEUPEN_OFFSET 0xA8
41 #define MCBSP_XCCR_OFFSET 0xAC
42 #define MCBSP_RCCR_OFFSET 0xB0
43 #define MCBSP_XBUFFSTAT_OFFSET 0xB4
44 #define MCBSP_RBUFFSTAT_OFFSET 0xB8
46 #define BITSPERSAMPLE 16
48 typedef unsigned int U32;
49 #define out_regl(a,d) *((volatile unsigned int *)(a)) = d
52 /* Reset the McBSP. */
53 static void reset_mcbsp (U32 mcbsp_base_addr, U32 enable)
56 ** Checking whether McBSP is providing the clock (Word and bit CLK)
57 ** or McBSP is master.
59 if (((*(volatile U32 *)(mcbsp_base_addr + MCBSP_PCR0_OFFSET)) & 0x0F00)
63 ** If McBSP is not master, then TX/RX/SCG are not enabled
64 ** and disabled between each call to the macbsp_write/read functions.
70 *((volatile U32 *)(mcbsp_base_addr + MCBSP_DXR_OFFSET))= 0x0;
73 /* The serial port transmitter is enabled. */
74 *((volatile U32 *)(mcbsp_base_addr + MCBSP_SPCR2_OFFSET)) |= 0x0001;
76 /* The serial port receiver is enabled. */
77 *((volatile U32 *)(mcbsp_base_addr + MCBSP_SPCR1_OFFSET)) |= 0x0001;
80 ** Sample rate generator is pulled out of reset.
81 ** Frame counters are loaded with their programmed values.
83 *((volatile U32 *)(mcbsp_base_addr + MCBSP_SPCR2_OFFSET)) |= 0x00C0;
88 ** The serial port transmitter is disabled and in reset state.
89 ** Frame-synchronization logic is reset.
91 *((volatile U32 *)(mcbsp_base_addr + MCBSP_SPCR2_OFFSET))
94 /* The serial port receiver is disabled and in reset state. */
95 *((volatile U32 *)(mcbsp_base_addr + MCBSP_SPCR1_OFFSET))
102 /* Writes TX data register by polling method. */
103 static int write_data_mcbsp(U32 mcbsp_base_addr, U32 data)
108 *((volatile U32 *)(mcbsp_base_addr + MCBSP_DXR_OFFSET)) = data;
110 /* If frame sync error - clear the error. */
111 if (*((volatile U32 *)(mcbsp_base_addr + MCBSP_SPCR2_OFFSET)) & 0x08)
113 printf("Frame sync error.\n");
115 *((volatile U32 *)(mcbsp_base_addr + MCBSP_SPCR2_OFFSET)) &= ~(0x08);
118 /* Wait for transmit confirmation. */
120 while ((*((volatile U32 *)(mcbsp_base_addr + MCBSP_SPCR2_OFFSET)) & 0x2)
123 if (attempts++ > 1000)
125 /* The attempt failed, so reset the Tx. */
126 *((volatile U32 *)(mcbsp_base_addr + MCBSP_SPCR2_OFFSET)) &= ~(0x1);
129 *((volatile U32 *)(mcbsp_base_addr + MCBSP_SPCR2_OFFSET)) |= 0x1;
131 printf("McBSP write failed.\n");
139 int main(int argc, char *argv[])
141 volatile unsigned int *regs;
142 unsigned int mcbsp_base_addr, sample;
149 f = fopen(argv[1], "rb");
152 printf("no file.\n");
157 memdev = open("/dev/mem", O_RDWR|O_SYNC);
160 printf("no memdev\n");
164 // 0x480022D8 ~ CONTROL_DEVCONF1
165 // 0x49024000 ~ McBSP3
166 regs = mmap(0, 0x10000, PROT_WRITE|PROT_READ, MAP_SHARED, memdev, 0x48000000);
167 if (regs == MAP_FAILED)
169 printf("mmap failed\n");
173 mcbsp_base_addr = (unsigned int)mmap(0, 0x2000, PROT_WRITE|PROT_READ, MAP_SHARED, memdev, 0x49024000);
174 if ((int)mcbsp_base_addr == (int)MAP_FAILED)
176 printf("mmap failed\n");
180 /* ----- clocks ----- */
183 ** Configure the CLKS input to 96M functional clk from PRCM
184 ** and not MCBSP.CLKS pin.(this is for McBSP2)
185 ** CONTROL_DEVCONF0 ,set bit 6 to zero.
187 regs[0x2274>>2] &= 0xFFFFFFBF;
189 // CONTROL_DEVCONF1 For McBSP3 we want to use the MCBSP.CLKS pin
190 regs[0x22D8>>2] |= 1;
192 /* CM_CLKSEL1_PLL 96 Mhz selected. */
193 regs[0x4d40>>2] &= 0xFFFFFFF7;
195 /* CM_FCLKEN_PER Enable the functional clock of McBSP3. */
196 regs[0x5000>>2] |= 0x00000002;
198 /* CM_ICLKEN_PER Enable the Interface clock of McBSP3 */
199 regs[0x5010>>2] |= 0x00000002;
201 /* McBSP3 selected. */
202 regs[0x5030>>2] |= 0x00000002;
204 /* ----- McBSP ----- */
206 /* Make all registers to zero to start with. */
207 out_regl((mcbsp_base_addr + MCBSP_SPCR2_OFFSET), 0);
208 out_regl((mcbsp_base_addr + MCBSP_SPCR1_OFFSET), 0);
209 // out_regl((mcbsp_base_addr + MCBSP_PCR0_OFFSET), 0);
210 out_regl((mcbsp_base_addr + MCBSP_XCR1_OFFSET), 0);
211 out_regl((mcbsp_base_addr + MCBSP_RCR1_OFFSET), 0);
212 out_regl((mcbsp_base_addr + MCBSP_XCR2_OFFSET), 0);
213 out_regl((mcbsp_base_addr + MCBSP_RCR2_OFFSET), 0);
214 out_regl((mcbsp_base_addr + MCBSP_SRGR1_OFFSET), 0);
215 out_regl((mcbsp_base_addr + MCBSP_SRGR2_OFFSET), 0);
217 /* Disable TX and RX DMA. */
218 out_regl((mcbsp_base_addr + MCBSP_XCCR_OFFSET), 0);
219 out_regl((mcbsp_base_addr + MCBSP_RCCR_OFFSET), 0);
220 out_regl((mcbsp_base_addr + MCBSP_THRSH2_OFFSET), 0);
221 out_regl((mcbsp_base_addr + MCBSP_THRSH1_OFFSET), 0);
222 out_regl((mcbsp_base_addr + MCBSP_IRQENABLE_OFFSET), 0);
223 out_regl((mcbsp_base_addr + MCBSP_IRQSTATUS_OFFSET), 0x7fbf); // clear IRQs
225 /* Set the audio configuration. */
228 ** Codec is slave McBSP is master
229 ** Enable the following bits FSXM, FSRM, CLKXM, CLKRM, CLKXP, CLKRP.
231 *((volatile U32 *)(mcbsp_base_addr + MCBSP_PCR0_OFFSET)) = 0x0f0C;//0x0f00; //0x0f03;
232 *((volatile U32 *)(mcbsp_base_addr + MCBSP_SPCR1_OFFSET)) |= 0x0008;
233 *((volatile U32 *)(mcbsp_base_addr + MCBSP_SPCR2_OFFSET)) |= 0x0008;
235 /* Tx word len1= 16bits, 1 word per frame. */
236 *((volatile U32 *)(mcbsp_base_addr + MCBSP_XCR1_OFFSET)) |= 0x40;
240 ** Tx word len2 = 16 bits, 1 word per frame.
241 ** No companding data starts with MSB first
242 ** Transmit frame-synchronization pulses after the first are ignored.
243 ** Tx Data delay - 1bit.
245 *((volatile U32 *)(mcbsp_base_addr + MCBSP_XCR2_OFFSET)) |= 0x8041;
247 /* Rx word len1 = 16bits, 1 word per frame. */
248 *((volatile U32 *)(mcbsp_base_addr + MCBSP_RCR1_OFFSET)) |= 0x40;
252 ** Rx word len2=16 bits ,1 word per frame.
253 ** No companding data starts with MSB first
254 ** Rx Data delay- 1bit.
256 *((volatile U32 *)(mcbsp_base_addr + MCBSP_RCR2_OFFSET)) |= 0x8041;
258 /* Configure the sample generator. */
261 ** McBSP sample rate generator register 1
262 ** Frame pulse width is 16 clk periods
263 ** Sample rate generator clock divider - 70
266 *((volatile U32 *)(mcbsp_base_addr + MCBSP_SRGR1_OFFSET))
267 = ((BITSPERSAMPLE - 1) << 8) | (8 - 1); // BCLK = 32fs
269 /* Next frame-sync signal becomes active after 32 clock periods. */
270 *((volatile U32 *)(mcbsp_base_addr + MCBSP_SRGR2_OFFSET)) =
272 0x1000 | ((BITSPERSAMPLE * 2) - 1);
274 /* Enable the sample rate generator. */
275 *((volatile U32 *)(mcbsp_base_addr + MCBSP_SPCR2_OFFSET)) |= 0x00C0;
277 /* Enable the Tx, Rx. */
278 *((volatile U32 *)(mcbsp_base_addr + MCBSP_SPCR1_OFFSET)) |= 1;
279 *((volatile U32 *)(mcbsp_base_addr + MCBSP_SPCR2_OFFSET)) |= 1;
283 /* Reset the device. */
284 reset_mcbsp(mcbsp_base_addr, 1);
286 /* must restore ?DMAEN bits to defaults */
287 out_regl((mcbsp_base_addr + MCBSP_XCCR_OFFSET), 8);
288 out_regl((mcbsp_base_addr + MCBSP_RCCR_OFFSET), 8);
297 ret = fread(&sample, 1, 2, f);
300 sample = (count & 0x80) ? 65536-10000 : 10000;
302 if (count > 200*1024) break;
305 ret = write_data_mcbsp(mcbsp_base_addr, sample);
309 /* Reset the device. */
310 reset_mcbsp(mcbsp_base_addr, 0);
312 munmap((void *)regs, 0x10000);
313 munmap((void *)mcbsp_base_addr, 0x2000);