0,0 → 1,222 |
#include <msp430.h> |
#include <stdio.h> |
#include <stdlib.h> |
|
#include "hal_SPI.h" |
#include "mmc.h" |
#include "diskio.h" |
#include "pff.h" |
#include "player.h" |
#include "adxl345.h" |
|
/** |
* Takes an initialized DIR and returns the number of sub-dir and files |
*/ |
FRESULT directory_info(char *path, int *dir_count, int *file_count) { |
FILINFO finfo; |
FRESULT result; |
DIR dir; |
|
*dir_count = 0; |
*file_count = 0; |
|
result = pf_opendir(&dir, path); |
if (result == FR_OK) { |
for (;;) { |
result = pf_readdir(&dir, &finfo); |
// Break upon end of list |
if (result != FR_OK || finfo.fname[0] == 0) break; |
// Increment the directory or file count |
if (finfo.fattrib & AM_DIR) { |
*dir_count = *dir_count + 1; |
} else { |
*file_count = *file_count + 1; |
} |
} |
} |
|
return result; |
} |
|
static int file_count, dir_count; |
static char filename[16]; |
|
int main(void) { |
WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer |
|
/* --- Set Oscillator Settings (8Mhz) --------------- */ |
// Set DCO to 5, MOD to 0 |
DCOCTL = CALDCO_16MHZ; |
// Set RSEL to 13 |
BCSCTL1 = CALBC1_16MHZ; |
// MCLK = DCO/1, SMCLK = MCLK/1 |
BCSCTL2 = SELM_0 | DIVM_0 | DIVS_0; |
// LFXT1 = VLOCLK, 1pF termination |
BCSCTL3 = LFXT1S_2 | XCAP_0; |
// Disable oscillator fault interrupt |
IE1 &= ~OFIE; |
/* -------------------------------------------------- */ |
|
/* --- Initialize I/O Ports ------------------------- */ |
P2SEL = 0x0; // P2SEL resets to 0xC0 |
|
// SD Chip Select (idle high) |
MMC_CS_PxOUT |= MMC_CS; |
MMC_CS_PxDIR |= MMC_CS; |
|
// SD Card Detect (input) |
MMC_CD_PxDIR &= ~MMC_CD; |
|
// VS1053 Chip Select (idle high) |
VS10XX_CS_PxOUT |= VS10XX_CS; |
VS10XX_CS_PxDIR |= VS10XX_CS; |
|
// VS1053 Data/Command Select (idle high) |
VS10XX_DC_PxOUT |= VS10XX_DC; |
VS10XX_DC_PxDIR |= VS10XX_DC; |
|
// VS1053 DREQ Line (input) |
VS10XX_DREQ_PxDIR &= ~VS10XX_DREQ; |
|
// Accelerometer Chip Select (idle high) |
ADXL_CS_PxOUT |= ADXL_CS; |
ADXL_CS_PxDIR |= ADXL_CS; |
|
// Accelerometer Interrupt 1 (input) |
ADXL_INT1_PxDIR &= ~ADXL_INT1; |
ADXL_INT1_PxIES |= ADXL_INT1; // Interrupt on High -> Low |
ADXL_INT1_PxIFG &= ~ADXL_INT1; // Clear interrupt flag |
ADXL_INT1_PxIE |= ADXL_INT1; // Enable interrupt |
|
// Accelerometer Interrupt 2 (input) |
ADXL_INT2_PxDIR &= ~ADXL_INT2; |
// ADXL_INT2_PxIES |= ADXL_INT2; // Interrupt on High -> Low |
// ADXL_INT2_PxIFG &= ~ADXL_INT2; // Clear interrupt flag |
// ADXL_INT2_PxIE |= ADXL_INT2; // Enable interrupt |
|
// Reset (idle low) |
CHIP_RESET_PxOUT &= ~CHIP_RESET; |
CHIP_RESET_PxDIR |= CHIP_RESET; |
|
// Red LED (idle low) |
LED_RED_PxOUT &= ~LED_RED; |
LED_RED_PxDIR |= LED_RED; |
|
// Green LED (idle low) |
LED_GREEN_PxOUT &= ~LED_GREEN; |
LED_GREEN_PxDIR |= LED_GREEN; |
|
// Initialize port 3 even though it doesnt exist on the device |
P3DIR = 0xFF; |
P3OUT = 0x00; |
/* -------------------------------------------------- */ |
|
unsigned char status = 1; |
int acc_x, acc_y, acc_z; |
FATFS fs; |
FRESULT result = FR_NOT_READY; |
|
// Init SPI Module |
halSPISetup(); |
|
// __delay_cycles(32000000); |
|
// Attempt the startup procedure four times |
int i; |
for (i = 0; i < 4; i++) { |
|
// Initialize the accelerometer |
if (ADXLInit() == 0) { |
|
// Sum the accelerometer values to seed the randomizer |
ADXLRead(&acc_x, &acc_y, &acc_z); |
srand(acc_x + acc_y + acc_z); |
|
// Mount the SD card |
result = pf_mount(&fs); |
if (result == FR_OK) { |
|
// Acquire the number of subdirectories and files in the root directory |
result = directory_info("/", &dir_count, &file_count); |
|
if (result == FR_OK && file_count > 0) { |
|
CHIP_RESET_HIGH(); |
|
if (VS1053Init() == 0) { |
LED_GREEN_HIGH(); |
__delay_cycles(1000000); |
LED_GREEN_LOW(); |
|
// If everything went well, play the first track |
status = 0; |
VS1053PlayFile("track1.mp3"); |
break; |
|
} else { // VS1053Init() |
continue; |
} |
|
} else { // directory_info |
continue; |
} |
|
} else { // pf_mount() |
continue; |
} |
|
} else { // ADXLInit() |
continue; |
} |
} |
|
// If everything is ok, enable accelerometer interrupts |
if (status == 0) { |
ADXLInitInterrupts(); |
} else { |
// Otherwise turn off everything |
LED_RED_HIGH(); |
void ADXLStandbyOn(void); |
} |
|
// Turn off all chips except the accelerometer |
CHIP_RESET_LOW(); |
_BIS_SR(LPM4_bits + GIE); |
|
} |
|
#pragma vector=PORT1_VECTOR |
__interrupt void Port1_Interrupt(void) { |
|
if (ADXL_INT1_PxIFG & ADXL_INT1) { |
LED_GREEN_HIGH(); |
__delay_cycles(1000000); |
LED_GREEN_LOW(); |
|
// Bring chips out of low-power state |
CHIP_RESET_HIGH(); |
VSInitSoftware(); |
|
// Play a random file |
int i = (rand() % file_count) + 1; |
snprintf(filename, 16, "track%d.mp3", i); |
VS1053PlayFile(filename); |
|
// Return chips to low-power state |
CHIP_RESET_LOW(); |
|
// Clear the interrupt flag |
ADXL_INT1_PxIFG &= ~ADXL_INT1; |
} |
|
// if (ADXL_INT2_PxIFG & ADXL_INT2) { |
// LED_RED_HIGH(); |
// __delay_cycles(2000000); |
// LED_RED_LOW(); |
// |
// // Clear the interrupt flag |
// ADXL_INT2_PxIFG &= ~ADXL_INT2; |
// } |
|
ADXLClearInterrupts(); |
} |