Subversion Repositories Code-Repo

Compare Revisions

Ignore whitespace Rev 247 → Rev 248

/MSP430/MSP430_Audio_Cube/main.c
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();
}