Subversion Repositories Code-Repo

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
248 Kevin 1
#include <msp430.h>
2
#include <stdio.h>
3
#include <stdlib.h>
4
 
5
#include "hal_SPI.h"
6
#include "mmc.h"
7
#include "diskio.h"
8
#include "pff.h"
9
#include "player.h"
10
#include "adxl345.h"
11
 
12
/**
13
 * Takes an initialized DIR and returns the number of sub-dir and files
14
 */
15
FRESULT directory_info(char *path, int *dir_count, int *file_count) {
16
	FILINFO finfo;
17
	FRESULT result;
18
	DIR dir;
19
 
20
	*dir_count = 0;
21
	*file_count = 0;
22
 
23
	result = pf_opendir(&dir, path);
24
	if (result == FR_OK) {
25
		for (;;) {
26
			result = pf_readdir(&dir, &finfo);
27
			// Break upon end of list
28
			if (result != FR_OK || finfo.fname[0] == 0) break;
29
			// Increment the directory or file count
30
			if (finfo.fattrib & AM_DIR) {
31
				*dir_count = *dir_count + 1;
32
			} else {
33
				*file_count = *file_count + 1;
34
			}
35
		}
36
	}
37
 
38
	return result;
39
}
40
 
41
static int file_count, dir_count;
42
static char filename[16];
43
 
44
int main(void) {
45
    WDTCTL = WDTPW | WDTHOLD;	// Stop watchdog timer
46
 
47
    /* --- Set Oscillator Settings (8Mhz) --------------- */
48
    // Set DCO to 5, MOD to 0
49
    DCOCTL = CALDCO_16MHZ;
50
    // Set RSEL to 13
51
	BCSCTL1 = CALBC1_16MHZ;
52
	// MCLK = DCO/1, SMCLK = MCLK/1
53
	BCSCTL2 = SELM_0 | DIVM_0 | DIVS_0;
54
	// LFXT1 = VLOCLK, 1pF termination
55
	BCSCTL3 = LFXT1S_2 | XCAP_0;
56
	// Disable oscillator fault interrupt
57
	IE1 &= ~OFIE;
58
	/* -------------------------------------------------- */
59
 
60
	/* --- Initialize I/O Ports ------------------------- */
61
	P2SEL = 0x0;	// P2SEL resets to 0xC0
62
 
251 Kevin 63
	// SPI Pins (idle low)
64
	SPI_PxOUT &= ~(SPI_SIMO + SPI_SOMI + SPI_UCLK);
65
	SPI_PxDIR |= SPI_SIMO + SPI_UCLK;
66
	SPI_PxDIR &= ~SPI_SOMI;
67
	SPI_PxREN |= SPI_SOMI;
68
 
248 Kevin 69
	// SD Chip Select (idle high)
70
	MMC_CS_PxOUT |= MMC_CS;
71
	MMC_CS_PxDIR |= MMC_CS;
72
 
73
	// SD Card Detect (input)
74
	MMC_CD_PxDIR &= ~MMC_CD;
75
 
76
	// VS1053 Chip Select (idle high)
77
	VS10XX_CS_PxOUT |= VS10XX_CS;
78
	VS10XX_CS_PxDIR |= VS10XX_CS;
79
 
80
	// VS1053 Data/Command Select (idle high)
81
	VS10XX_DC_PxOUT |= VS10XX_DC;
82
	VS10XX_DC_PxDIR |= VS10XX_DC;
83
 
84
	// VS1053 DREQ Line (input)
85
	VS10XX_DREQ_PxDIR &= ~VS10XX_DREQ;
86
 
87
	// Accelerometer Chip Select (idle high)
88
	ADXL_CS_PxOUT |= ADXL_CS;
89
	ADXL_CS_PxDIR |= ADXL_CS;
90
 
91
	// Accelerometer Interrupt 1 (input)
92
	ADXL_INT1_PxDIR &= ~ADXL_INT1;
93
	ADXL_INT1_PxIES |= ADXL_INT1;	// Interrupt on High -> Low
94
	ADXL_INT1_PxIFG &= ~ADXL_INT1;	// Clear interrupt flag
95
 
96
	// Accelerometer Interrupt 2 (input)
97
	ADXL_INT2_PxDIR &= ~ADXL_INT2;
98
//	ADXL_INT2_PxIES |= ADXL_INT2;	// Interrupt on High -> Low
99
//	ADXL_INT2_PxIFG &= ~ADXL_INT2;	// Clear interrupt flag
100
//	ADXL_INT2_PxIE 	|= ADXL_INT2;	// Enable interrupt
101
 
102
	// Reset (idle low)
103
	CHIP_RESET_PxOUT &= ~CHIP_RESET;
104
	CHIP_RESET_PxDIR |= CHIP_RESET;
105
 
106
	// Red LED (idle low)
107
	LED_RED_PxOUT &= ~LED_RED;
108
	LED_RED_PxDIR |= LED_RED;
109
 
110
	// Green LED (idle low)
111
	LED_GREEN_PxOUT &= ~LED_GREEN;
112
	LED_GREEN_PxDIR |= LED_GREEN;
113
 
114
	// Initialize port 3 even though it doesnt exist on the device
115
	P3DIR = 0xFF;
116
	P3OUT = 0x00;
117
	/* -------------------------------------------------- */
118
 
119
	unsigned char status = 1;
120
	int acc_x, acc_y, acc_z;
121
	FATFS fs;
122
	FRESULT result = FR_NOT_READY;
123
 
251 Kevin 124
	// Delay for a bit to ensure that SD card powers up
125
	__delay_cycles(16000);
126
 
248 Kevin 127
	// Init SPI Module
128
	halSPISetup();
129
 
130
	// Attempt the startup procedure four times
131
	int i;
132
	for (i = 0; i < 4; i++) {
133
 
134
		// Initialize the accelerometer
135
		if (ADXLInit() == 0) {
136
 
137
			// Sum the accelerometer values to seed the randomizer
138
			ADXLRead(&acc_x, &acc_y, &acc_z);
139
			srand(acc_x + acc_y + acc_z);
140
 
141
			// Mount the SD card
142
			result = pf_mount(&fs);
143
			if (result == FR_OK) {
144
 
145
				// Acquire the number of subdirectories and files in the root directory
146
				result = directory_info("/", &dir_count, &file_count);
147
 
148
				if (result == FR_OK && file_count > 0) {
149
 
150
					CHIP_RESET_HIGH();
151
 
152
					if (VS1053Init() == 0) {
153
						LED_GREEN_HIGH();
154
						__delay_cycles(1000000);
155
						LED_GREEN_LOW();
156
 
157
						// If everything went well, play the first track
158
						status = 0;
159
						VS1053PlayFile("track1.mp3");
160
						break;
161
 
162
					} else { // VS1053Init()
163
						continue;
164
					}
165
 
166
				} else { // directory_info
167
					continue;
168
				}
169
 
170
			} else { // pf_mount()
171
				continue;
172
			}
173
 
174
		} else { // ADXLInit()
175
			continue;
176
		}
177
	}
178
 
179
	// If everything is ok, enable accelerometer interrupts
251 Kevin 180
	if (status != 0) {
248 Kevin 181
		// Otherwise turn off everything
182
		LED_RED_HIGH();
183
		void ADXLStandbyOn(void);
251 Kevin 184
 
185
	} else {
186
		ADXL_INT1_PxIE 	|= ADXL_INT1;	// Enable interrupt
187
		ADXLInitInterrupts();
248 Kevin 188
	}
189
 
251 Kevin 190
//	LED_RED_HIGH();
248 Kevin 191
	// Turn off all chips except the accelerometer
192
	CHIP_RESET_LOW();
193
	_BIS_SR(LPM4_bits + GIE);
251 Kevin 194
	while(1);
248 Kevin 195
}
196
 
197
#pragma vector=PORT1_VECTOR
198
__interrupt void Port1_Interrupt(void) {
199
 
200
	if (ADXL_INT1_PxIFG & ADXL_INT1) {
201
		LED_GREEN_HIGH();
202
 
203
		// Bring chips out of low-power state
204
		CHIP_RESET_HIGH();
205
		VSInitSoftware();
206
 
207
		// Play a random file
208
		int i = (rand() % file_count) + 1;
209
		snprintf(filename, 16, "track%d.mp3", i);
210
		VS1053PlayFile(filename);
211
 
212
		// Return chips to low-power state
213
		CHIP_RESET_LOW();
214
 
251 Kevin 215
		// Clear the interrupts on the ADXL chip
216
		ADXLClearInterrupts();
217
 
248 Kevin 218
		// Clear the interrupt flag
219
		ADXL_INT1_PxIFG &= ~ADXL_INT1;
251 Kevin 220
 
221
		LED_GREEN_LOW();
248 Kevin 222
	}
223
 
224
//	if (ADXL_INT2_PxIFG & ADXL_INT2) {
225
//		LED_RED_HIGH();
226
//		__delay_cycles(2000000);
227
//		LED_RED_LOW();
228
//
229
//		// Clear the interrupt flag
230
//		ADXL_INT2_PxIFG &= ~ADXL_INT2;
231
//	}
232
 
233
}