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
 
63
	// SD Chip Select (idle high)
64
	MMC_CS_PxOUT |= MMC_CS;
65
	MMC_CS_PxDIR |= MMC_CS;
66
 
67
	// SD Card Detect (input)
68
	MMC_CD_PxDIR &= ~MMC_CD;
69
 
70
	// VS1053 Chip Select (idle high)
71
	VS10XX_CS_PxOUT |= VS10XX_CS;
72
	VS10XX_CS_PxDIR |= VS10XX_CS;
73
 
74
	// VS1053 Data/Command Select (idle high)
75
	VS10XX_DC_PxOUT |= VS10XX_DC;
76
	VS10XX_DC_PxDIR |= VS10XX_DC;
77
 
78
	// VS1053 DREQ Line (input)
79
	VS10XX_DREQ_PxDIR &= ~VS10XX_DREQ;
80
 
81
	// Accelerometer Chip Select (idle high)
82
	ADXL_CS_PxOUT |= ADXL_CS;
83
	ADXL_CS_PxDIR |= ADXL_CS;
84
 
85
	// Accelerometer Interrupt 1 (input)
86
	ADXL_INT1_PxDIR &= ~ADXL_INT1;
87
	ADXL_INT1_PxIES |= ADXL_INT1;	// Interrupt on High -> Low
88
	ADXL_INT1_PxIFG &= ~ADXL_INT1;	// Clear interrupt flag
89
	ADXL_INT1_PxIE 	|= ADXL_INT1;	// Enable interrupt
90
 
91
	// Accelerometer Interrupt 2 (input)
92
	ADXL_INT2_PxDIR &= ~ADXL_INT2;
93
//	ADXL_INT2_PxIES |= ADXL_INT2;	// Interrupt on High -> Low
94
//	ADXL_INT2_PxIFG &= ~ADXL_INT2;	// Clear interrupt flag
95
//	ADXL_INT2_PxIE 	|= ADXL_INT2;	// Enable interrupt
96
 
97
	// Reset (idle low)
98
	CHIP_RESET_PxOUT &= ~CHIP_RESET;
99
	CHIP_RESET_PxDIR |= CHIP_RESET;
100
 
101
	// Red LED (idle low)
102
	LED_RED_PxOUT &= ~LED_RED;
103
	LED_RED_PxDIR |= LED_RED;
104
 
105
	// Green LED (idle low)
106
	LED_GREEN_PxOUT &= ~LED_GREEN;
107
	LED_GREEN_PxDIR |= LED_GREEN;
108
 
109
	// Initialize port 3 even though it doesnt exist on the device
110
	P3DIR = 0xFF;
111
	P3OUT = 0x00;
112
	/* -------------------------------------------------- */
113
 
114
	unsigned char status = 1;
115
	int acc_x, acc_y, acc_z;
116
	FATFS fs;
117
	FRESULT result = FR_NOT_READY;
118
 
119
	// Init SPI Module
120
	halSPISetup();
121
 
122
//	__delay_cycles(32000000);
123
 
124
	// Attempt the startup procedure four times
125
	int i;
126
	for (i = 0; i < 4; i++) {
127
 
128
		// Initialize the accelerometer
129
		if (ADXLInit() == 0) {
130
 
131
			// Sum the accelerometer values to seed the randomizer
132
			ADXLRead(&acc_x, &acc_y, &acc_z);
133
			srand(acc_x + acc_y + acc_z);
134
 
135
			// Mount the SD card
136
			result = pf_mount(&fs);
137
			if (result == FR_OK) {
138
 
139
				// Acquire the number of subdirectories and files in the root directory
140
				result = directory_info("/", &dir_count, &file_count);
141
 
142
				if (result == FR_OK && file_count > 0) {
143
 
144
					CHIP_RESET_HIGH();
145
 
146
					if (VS1053Init() == 0) {
147
						LED_GREEN_HIGH();
148
						__delay_cycles(1000000);
149
						LED_GREEN_LOW();
150
 
151
						// If everything went well, play the first track
152
						status = 0;
153
						VS1053PlayFile("track1.mp3");
154
						break;
155
 
156
					} else { // VS1053Init()
157
						continue;
158
					}
159
 
160
				} else { // directory_info
161
					continue;
162
				}
163
 
164
			} else { // pf_mount()
165
				continue;
166
			}
167
 
168
		} else { // ADXLInit()
169
			continue;
170
		}
171
	}
172
 
173
	// If everything is ok, enable accelerometer interrupts
174
	if (status == 0) {
175
		ADXLInitInterrupts();
176
	} else {
177
		// Otherwise turn off everything
178
		LED_RED_HIGH();
179
		void ADXLStandbyOn(void);
180
	}
181
 
182
	// Turn off all chips except the accelerometer
183
	CHIP_RESET_LOW();
184
	_BIS_SR(LPM4_bits + GIE);
185
 
186
}
187
 
188
#pragma vector=PORT1_VECTOR
189
__interrupt void Port1_Interrupt(void) {
190
 
191
	if (ADXL_INT1_PxIFG & ADXL_INT1) {
192
		LED_GREEN_HIGH();
193
		__delay_cycles(1000000);
194
		LED_GREEN_LOW();
195
 
196
		// Bring chips out of low-power state
197
		CHIP_RESET_HIGH();
198
		VSInitSoftware();
199
 
200
		// Play a random file
201
		int i = (rand() % file_count) + 1;
202
		snprintf(filename, 16, "track%d.mp3", i);
203
		VS1053PlayFile(filename);
204
 
205
		// Return chips to low-power state
206
		CHIP_RESET_LOW();
207
 
208
		// Clear the interrupt flag
209
		ADXL_INT1_PxIFG &= ~ADXL_INT1;
210
	}
211
 
212
//	if (ADXL_INT2_PxIFG & ADXL_INT2) {
213
//		LED_RED_HIGH();
214
//		__delay_cycles(2000000);
215
//		LED_RED_LOW();
216
//
217
//		// Clear the interrupt flag
218
//		ADXL_INT2_PxIFG &= ~ADXL_INT2;
219
//	}
220
 
221
	ADXLClearInterrupts();
222
}