summaryrefslogtreecommitdiff
path: root/firmware/src/p2m.c
blob: c43488e1be6c8d0f463e025822aed10c5f4c0504 (plain)
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
/* THIS SOFTWARE IS PROVIDED "AS IS".  NO WARRANTIES, WHETHER EXPRESS, IMPLIED
 * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
 * THE AUTHORS SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
 * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. USE IT AT YOUR OWN RISK */

#include <LPC17xx.h>

//#define IRQ_BLINKY
//#define BLINKY
//#define BLINKY
#define WM8523
//#define SPI

#ifdef DMA

#include "dac.h"
#include "sample.h"

int main (void) 
{
	dac_init();

	//	int i = 0;
	while(1) {
		//fiprintf(stderr, "Play #%d: %d samples\n\r", i++, sizeof(samples) / sizeof(short));
		dac_play_samples(samples, sizeof(samples) / sizeof(short));
	}
	return 0;
}

#endif
volatile uint32_t temp;

void _delay(uint32_t del);

#ifdef IRQ_BLINKY

volatile int resume = 0;

void TIMER0_IRQHandler (void) 
{  
  LPC_TIM0->IR = 1;			/* clear interrupt flag */
	resume = 1 - resume;
  //timer0_counter++;
  return;
}

int main (void) 
{
    LPC_SC->PCONP |= ( 1 << 15 ); // power up GPIO
    LPC_GPIO1->FIODIR |= 1 << 29; // puts P1.29 into output mode.

		int delayInMs = 1000;

		// Enable timer interrupts
		LPC_TIM0->MR0 = delayInMs * (9000000 / 1000-1); // interval
		LPC_TIM0->MCR = 3;				// Interrupt and Reset on MR0
		NVIC_EnableIRQ(TIMER0_IRQn);
		LPC_TIM0->TCR = 1;

    while(1) {
        LPC_GPIO1->FIOPIN |= 1 << 29; // make P1.29 high

				while(resume == 0) __WFI();

        LPC_GPIO1->FIOPIN &= ~( 1 << 29 ); // make P1.29 low

				while(resume == 1) __WFI();
    }

    return 0;
  
}

#endif/*IRQ_BLINKY*/

#ifdef BLINKY

int main (void) 
{
    LPC_SC->PCONP |= ( 1 << 15 ); // power up GPIO
    LPC_GPIO1->FIODIR |= 1 << 29; // puts P1.29 into output mode.
    while(1)
    {
        LPC_GPIO1->FIOPIN |= 1 << 29; // make P1.29 high
        _delay( 1 << 24 );
        LPC_GPIO1->FIOPIN &= ~( 1 << 29 ); // make P1.29 low
        _delay( 1 << 24 );
    }
    return 0;
  
}

#endif/*BLINKY*/

#ifdef UART

#include "LPC17xx.h"
#include <stdint.h>
#include "uart.h"

int main (void)
{ 
	/* SystemClockUpdate() updates the SystemFrequency variable */
	// SystemCoreClockUpdate();//SystemClockUpdate();
  UARTInit(0, 115200);	/* baud rate setting */
	//  UARTInit(1, 8000);	/* baud rate setting */

	LPC_SC->PCONP |= ( 1 << 15 ); // power up GPIO
	LPC_GPIO1->FIODIR |= 1 << 29; // puts P1.29 into output mode.

  while (1) {
		LPC_GPIO1->FIOPIN |= 1 << 29; // make P1.29 high

		//LPC_UART0->IER = IER_THRE | IER_RLS;			// Disable RBR
		UARTSend(0, (uint8_t *)"hello\n\r", 7);
		//LPC_UART0->IER = IER_THRE | IER_RLS | IER_RBR;	// Re-enable RBR

		_delay( 1 << 22 );

		///

		LPC_GPIO1->FIOPIN &= ~( 1 << 29 ); // make P1.29 low
		/*
		LPC_UART0->IER = IER_THRE | IER_RLS;			// Disable RBR
		UARTSend( 0, (uint8_t *)"l", 1);
		LPC_UART0->IER = IER_THRE | IER_RLS | IER_RBR;	// Re-enable RBR
		*/
		_delay( 1 << 22 );

  }
}

#endif/*UART*/

#ifdef WM8523

#include <ssp.h>
#include <GPIO.h>
#include <wm8523.h>
#include <led.h>
#include <cli.h>

int main (void)
{
	//	SystemCoreClockUpdate(); 
	//  SystemInit();

	led_init();
	cli_init();

	uint8_t portnum = 0;

	cli_printf("Init:\n");
	wm8523_init(portnum, WM8523_FS_44K1);

	if(wm8523_get_chip_id(portnum) != WM8532_CHIP_ID) {
		cli_printf("Bad chip ID\n");
		goto fail;
	}

	cli_printf("Reset registers:\n");
	wm8523_reset_registers(portnum);

	cli_printf("Power up:\n");
	wm8523_power_mode_t pwr =	WM8523_PWR_POWER_UP_TO_UNMUTE;
	wm8523_set_power_mode(portnum, pwr);

	cli_printf("Set aif control:\n");
  wm8523_aif_ctrl1_t ctl1;
  ctl1.fmt = WM8523_FMT_I2S;
	ctl1.wlen = WM8523_WLEN_32;
	ctl1.invctl = WM8523_INVCTL_SLAVE_RISING;
	ctl1.lrclkinvctl = WM8523_LRCLKINVCTL_SLAVE_NORMAL;
	ctl1.modesel = WM8523_MODESEL_SLAVE;
	ctl1.deemp = WM8523_DEEMPH_ENABLED;
	wm8523_set_aif_ctrl1(portnum, ctl1);

	cli_printf("Set aif control2:\n");
	wm8523_aif_ctrl2_t ctl2;
  ctl2.clkratio = WM8523_CLKRATIO_AUTO;
  ctl2.clkdiv = WM8523_CLKDIV_MCLK_4;
  ctl2.mix = WM8523_MIX_STEREO;
	wm8523_set_aif_ctrl2(portnum, ctl2);

	cli_printf("Set dac control3\n");
	wm8523_dac_ctrl3_t ctl3;
  ctl3.downramp = WM8523_VOL_DOWN_INSTANT;
  ctl3.upramp = WM8523_VOL_UP_INSTANT;
  ctl3.lmute = WM8523_DACL_UNMUTE;
  ctl3.rmute = WM8523_DACR_UNMUTE;
  ctl3.dac_zc = WM8523_ZERO_CROSSING_DISABLED;
	wm8523_set_dac_ctrl3(portnum, ctl3);

	/*
	// Init SPI
	GPIOSetDir(0, 16, 1);
	GPIOSetValue(0, 16, 1);

	SSP0Init();

	uint8_t src_addr[16]; //16 byte Write buffer
	uint8_t portnum = 0;

	// Set bitwidth to 16
	// Set interface format to I2S
	GPIOSetValue(0, 16, 0);
	src_addr[0] = 0x0 << 7 | 0x3; // write bit (0) | register 3
	src_addr[1] = 
		0x2 << 0 | // Set I2S mode
		0x0 << 2 | // Reserved
		0x0 << 3; // Set 16 bit
	// The rest are 0 as default which is correct
		
	SSPSend(portnum, (uint8_t *)src_addr, 2);
	GPIOSetValue(0, 16, 1);

	_delay(1 << 5);

	// Power up and unmute
	GPIOSetValue(0, 16, 0);
	src_addr[0] = 0x0 << 7 | 0x2; // write bit (0) | register 2 (power register)
	src_addr[1] = 0x2; // Set power mode: "power up and unmute"
	SSPSend(portnum, (uint8_t *)src_addr, 2);
	GPIOSetValue(0, 16, 1);
	*/


	//wm8523_init();

	//	WM8523_configure();

	//_delay(1 << 5);

	cli_printf("Play tone...\n");
	wm8523_tone();

	cli_printf("Blink!\n");

	// Indicate that we didn't crash before the end...
	while(1) { // slow blink
		led_toggle();
		_delay(1 << 21);
	}

fail:
	cli_printf("Error loop of death...\n");
	while(1) {  // fast blink
		led_toggle();
		_delay(1 << 17);
	}
}

#endif/*WM8523*/

#ifdef SPI
// 1. Introduction
/*
	SPI is one of the most used serial interfaces on PCB level. This tutorial
	explains how to use SPI to read or write data. For SPI the SPI library is
	required. It can be downloaded from our repository. The library provides
	commands for communicating over SPI.
*/

// 2. Includes
#include <LPC17xx.h>
//#include "lpc_types.h"
#include <ssp.h>
#include <GPIO.h>
#include <timer.h>
#include <led.h>

typedef unsigned char uint8_t;

int main (void)
{
	led_init(); // Bent code

	// 3. Initializing
	/*
		SPI uses 4 IO pins, 1 clock, 1 MOSI, data from master to slave, 1 MISO,
		data from slave to master and one Chip select pin. Every SPI IC has a Chip
		Select pin, when the pin is low that IC will be selected to communicate
		with. Every SPI IC that has a high value on the Chip Select pin will ignore
		all signals on their data pins. 1 normal IO pin is used for the Chip Select,
		the clock; MOSI and MISO are SPI pins. Any IO pin can be used for Chip
		Select, For the tutorial pin 0.0 is used.
		The timer has to be initialized to use it for delays and the GPIO pin for
		Chip Select has to be initialized as output and made high, the code for
		that is:
	*/
	//	TimerInit(0, 1000);

	GPIOSetDir(0, 16, 1);
	GPIOSetValue(0, 16, 1);

	/*
		There are 2 SPI channels, SSP0 and SSP1. SSP0 uses pin 0.15 for the clock;
		pin 0.17 for MISO and pin 0.18 for MOSI. SSP1 uses pin 0.7 for the clock;
		pin 0.8 for MISO and pin 0.9 for MOSI. To initialize a SPI port the
		command SSP*channelno*init(); is used. To initialize SPI channel 1 the
		command is:
	*/
	SSP0Init();

	/*
		Some variables are also needed. SPI needs 2 array buffers, one for data
		that has to be send trough the SPI slave and one for data received from
		the SPI slave. Also its recommended to declare a variable with the value
		of the SPI channel that is used:
	*/
	uint8_t src_addr[16]; //16 byte Write buffer
	uint8_t dest_addr[16]; //16 byte Read buffer
	uint8_t portnum = 0;

	// 4. Write data to SPI
	/*
		First the Chip Select has to be made low with the GPIOSetValue command:
		GPIOSetValue(0, 0, 0;)
		The data that has to be written should be placed in the src_addr array that
		was declared earlier. To write 5 bytes of data (0x48, 0x65, 0x6c, 0x6c,
		0x6f the ascii code for Hello) place the hex data in the buffer array:
	*/

	GPIOSetValue(0, 16, 0);

	src_addr[0] = 0x1 << 7;
	src_addr[1] = 0xff;
	src_addr[2] = 0xff;

	/*
		When the data is stored in the array all that is left is start the SPI data
		transmission with the SSPSend( portnum, (uint8_t *)src_addr, datanumbers);
		portnum is the used SPI port, (uint8_t *)src_addr is the send buffer,
		datanumbers is the amount of databytes to be send. The command needed to
		send the 5 databytes declared above is:
	*/
	SSPSend(portnum, (uint8_t *)src_addr, 1);
	
	/*
		After the data is send the Chip Select pin needs to be made high again with
		the command GPIOSetValue(0, 0, 1); . Also a small delay can be needed for
		some SPI IC’s, 1 millisecond is enough most of the time, the command for a
		small delay is: delayMs(0, 1);
	*/
	//	delayMs(0, 1);

	//	GPIOSetValue(0, 16, 1);

	// 5. Read data from SPI
	/*
		To read data the Chip Select has to be made low with GPIOSetValue(0,0,0); .
		To read data from SPI the command SSPReceive(portnum, (uint8_t *)dest_addr,
		datanumbers); is used. Portnum is the used SPI port, (uint8_t *)dest_addr
		is the receive buffer, datanumbers is the amount of databytes that have to
		be read. A command to read 4 databytes is:
	*/
	// GPIOSetValue(0, 16, 0);

 SSPReceive(portnum, (uint8_t *)dest_addr, 3);

 GPIOSetValue(0, 16, 1);
 /*
	 The 4 databytes are now stored in dest_addr[0] to dest_addr[3]
 */

 // Indicate that we didn't crash before the end...
 int i = 0;
 while(1) {
	 led_toggle();
	 _delay(1 << 21);
	 i = 1 - i;
 }
}

#endif/*SPI*/

void _delay(uint32_t del)
{
    uint32_t i;
    for(i=0;i<del;i++)
        temp = i;
}