static void renderMenu() { byte i; byte n; byte page = __kernel_menu_selectedProgram / __KERNEL_MENU_MAX_PROGRAMS_PER_PAGE; char __lcd_buffer[17]; halLcdClearScreen(); halLcdPrintLineCol("BOT MK1", 0, 1, OVERWRITE_TEXT); { // Write program page number X:X sprintf(__lcd_buffer, "%d:%d", page + 1, __kernel_menu_totalPages); halLcdPrintLineCol(__lcd_buffer, 0, 13, OVERWRITE_TEXT); } { // Write programs available at current page for ( i = 0, n = ( page * __KERNEL_MENU_MAX_PROGRAMS_PER_PAGE ) ; i < __KERNEL_MENU_MAX_PROGRAMS_PER_PAGE && ( n + i ) < __kernel_menu_storedPrograms ; i++ ) { halLcdPrintLineCol(__kernel_menu_programs[n + i].tag, i + 2, 3, OVERWRITE_TEXT); } } // Write currently selected program renderTickle(); }
/**********************************************************************//** * @brief Disables the recording peripherals and the microphone. * * @param none * * @return none *************************************************************************/ static void shutdownRecord(void) { halLcdSetBackLight(lcdBackLightLevelSettingLOCAL); TBCTL &= ~MC0; ADC12CTL0 &= ~( ADC12ENC + ADC12ON ); FCTL1 = FWKEY; // Disable Flash write FCTL3 = FWKEY + LOCK; // Lock Flash memory // Power-down MSP430 modules ADC12CTL1 &= ~ADC12CONSEQ_2; // Stop conversion immediately ADC12CTL0 &= ~ADC12ENC; // Disable ADC12 conversion ADC12CTL0 = 0; // Switch off ADC12 & ref voltage TBCTL = 0; // Disable Timer_B LED_PORT_OUT &= ~LED_1; // Turn off LED AUDIO_PORT_OUT &= ~MIC_POWER_PIN; // Turn of MIC AUDIO_PORT_SEL &= ~MIC_INPUT_PIN; saveSettings(); // Store lastAudioByte to Flash halLcdPrintLine(" DONE ", 6, INVERT_TEXT | OVERWRITE_TEXT); halLcdPrintLineCol("Record", 8, 1, OVERWRITE_TEXT); halLcdPrintLineCol("Play", 8, 12, OVERWRITE_TEXT); buttonsPressed = 0; halButtonsInterruptEnable( BUTTON_S1); }
/**********************************************************************//** * @brief Plays back the audio data stored in Flash memory using * the integrated DMA controller and the DAC12 module. * * @param mode The mode of audio record * * - AUDIO_TEST_MODE ...for production test * - AUDIO_DEMO_MODE ...called for user sample code * * @return none *************************************************************************/ void audioPlayBack(unsigned char mode) { // Power-up external hardware AUDIO_PORT_DIR |= AUDIO_OUT_PWR_PIN; AUDIO_PORT_OUT &= ~AUDIO_OUT_PWR_PIN; AUDIO_OUT_SEL |= AUDIO_OUT_PIN; // P4.4 = TB4 LED_PORT_OUT |= LED_1; // Turn on LED if (mode == AUDIO_TEST_MODE) PlaybackPtr = (unsigned long)(MemstartTest); else PlaybackPtr = (unsigned long)(Memstart); PlaybackPtr ++; /* Setup Timer0_A for playback */ // Use SMCLK as Timer0_A source, enable overflow interrupt TBCTL = TBSSEL_2 + TBIE; // Set output resolution (8 bit. Add 10 counts of headroom for loading TBCCR1 TBCCR0 = 255 ; TBCCR4 = 255 >> 1; // Default output ~Vcc/2 // Reset OUT1 on EQU1, set on EQU0. Load TBCCR1 when TBR counts to 0. TBCCTL4 = OUTMOD_7 + CLLD_1; // Start Timer_B in UP mode (counts up to TBCCR0) TBCTL |= MC0; halLcdPrintLine(" Playing ", 6, INVERT_TEXT | OVERWRITE_TEXT); halLcdPrintLineCol(" Stop ", 8, 1, OVERWRITE_TEXT); halButtonsInterruptDisable( BUTTON_S2 ); // Activate LPM during DMA playback, wake-up when finished __bis_SR_register(LPM0_bits + GIE); // Enable interrupts, enter LPM0 __no_operation(); halLcdPrintLine(" DONE ", 6, INVERT_TEXT | OVERWRITE_TEXT); halButtonsInterruptEnable( BUTTON_S2 ); halLcdPrintLineCol("Record", 8, 1, OVERWRITE_TEXT); halLcdPrintLineCol("Play", 8, 12, OVERWRITE_TEXT); // Power-down MSP430 modules TBCTL = 0; // Disable Timer_B PWM generation AUDIO_OUT_SEL &= ~AUDIO_OUT_PIN; // P4.4 = TB4 LED_PORT_OUT &= ~LED_1; // Turn off LED buttonsPressed = 0; }
static void clearTickles() { byte i; for ( i = 0 ; i < __KERNEL_MENU_MAX_PROGRAMS_PER_PAGE ; i++ ) { halLcdPrintLineCol(" ", i + 2, 1, OVERWRITE_TEXT); } }
static void onProgramUpdate() { if ( __test_accel_killProgram ) { kerMenu_exitProgram(); } else if ( __test_accel_updateVector ) { halAccelerometerRead( &__test_accel_dx, &__test_accel_dy, &__test_accel_dz ); sprintf(__lcd_buffer, "%04d", __test_accel_dx); halLcdPrintLineCol(__lcd_buffer, 2, 5, OVERWRITE_TEXT); sprintf(__lcd_buffer, "%04d", __test_accel_dy); halLcdPrintLineCol(__lcd_buffer, 3, 5, OVERWRITE_TEXT); sprintf(__lcd_buffer, "%04d", __test_accel_dz); halLcdPrintLineCol(__lcd_buffer, 4, 5, OVERWRITE_TEXT); __test_accel_updateVector = FALSE; } }
/**********************************************************************//** * @brief Executes the "Voice Rec" menu option in the User Experience * example code. Calls the necessary functions according to the * user selection of "Record", "Play", or Exit (center D-pad btn press) * * - Initializes the LCD to display the "Record" and "Play" selections * - Enters LPM3 to be awoken and continue code execution after a button press * - According to the user selection records audio, plays audio, or exits * * @param none * * @return none *************************************************************************/ void audio(void) { unsigned char quit = 0; halLcdClearScreen(); while (!quit) { buttonsPressed = 0; halLcdPrintLineCol("Record", 8, 1, OVERWRITE_TEXT); halLcdPrintLineCol("Play", 8, 12, OVERWRITE_TEXT); __bis_SR_register(LPM3_bits + GIE); //Returns if button pressed __no_operation(); if (buttonsPressed & BUTTON_S1) { halLcdPrintLineCol("Record", 8, 1, INVERT_TEXT | OVERWRITE_TEXT); audioRecord( AUDIO_DEMO_MODE ); halLcdPrintLineCol("Record", 8, 1, OVERWRITE_TEXT); } if (buttonsPressed & BUTTON_S2) { halLcdPrintLineCol("Play", 8, 12, INVERT_TEXT | OVERWRITE_TEXT); audioPlayBack( AUDIO_DEMO_MODE ); halLcdPrintLineCol("Play", 8, 12, OVERWRITE_TEXT); } if (buttonsPressed & BUTTON_SELECT) quit = 1; } }
/**********************************************************************//** * @brief Global API call to record audio on the mike. * * - Initializes the record using setupRecord() * - Erases the memory reserved for audio recording * - Records until the memory is full using record() * - Shuts down the record using shutdownRecord() * * @param mode The mode of audio record * * - AUDIO_TEST_MODE ...for production test * - AUDIO_DEMO_MODE ...called for user sample code * * @return none *************************************************************************/ void audioRecord(unsigned char mode) { unsigned char i; setupRecord(); halLcdPrintLine(" Erasing ", 6, INVERT_TEXT | OVERWRITE_TEXT); halLcdPrintLineCol("----", 8, 12, OVERWRITE_TEXT); // Not used in User Experience sample code if (mode == AUDIO_TEST_MODE) { flashErase(MemstartTest, Memend); __data16_write_addr((unsigned short)&DMA0DA, MemstartTest); DMA0SZ = (long) (Memend - MemstartTest); record(); if (DMA0SZ != ( long) (Memend - MemstartTest)) lastAudioByte = Memend - DMA0SZ; else lastAudioByte = Memend; } // Always used in User Experience sample code else { flashEraseBank(AUDIO_MEM_START[0]); flashEraseBank(AUDIO_MEM_START[1]); flashEraseBank(AUDIO_MEM_START[2]); flashErase(AUDIO_MEM_START[3], AUDIO_MEM_START[4]); for (i=0;i<3;i++) { __data16_write_addr((unsigned short)&DMA0DA, AUDIO_MEM_START[i]); DMA0SZ = AUDIO_MEM_START[i+1] - AUDIO_MEM_START[i] - 1; record(); if (DMA0SZ != AUDIO_MEM_START[i+1] - AUDIO_MEM_START[i] - 1) { lastAudioByte = AUDIO_MEM_START[i+1] - DMA0SZ; break; } else lastAudioByte = AUDIO_MEM_START[i+1]-1; } } shutdownRecord(); }
static void onProgramStart() { halAccelerometerInit(); halTimer_b_enableInterruptCCR0(); halLcdPrintLine("ACCEL. VECTOR", 0, INVERT_TEXT); /* 012345 * 0 ACCEL.VECTOR * 1 * 2 X: 0000 * 3 Y: 0000 * 4 Z: 0000 * */ halLcdPrintLineCol("X:", 2, 2, OVERWRITE_TEXT); halLcdPrintLineCol("Y:", 3, 2, OVERWRITE_TEXT); halLcdPrintLineCol("Z:", 4, 2, OVERWRITE_TEXT); __test_accel_killProgram = FALSE; __test_accel_updateVector = FALSE; TB0CCR0 = 32 * 25; // Each 25 milliseconds it will update the window state }
/**********************************************************************//** * @brief Executes the record. * * - Unlocks the Flash and initialize to long-word write mode * - Initializes the Timer to trigger ADC12 samples * - When the operation is done, locks the flash, disables the DMA, and stops * the timer * * @param none * * @return none *************************************************************************/ static void record(void) { halLcdPrintLine(" Recording ", 6, INVERT_TEXT | OVERWRITE_TEXT); halLcdPrintLineCol("Stop", 8, 12, OVERWRITE_TEXT); FCTL3 = FWKEY; // Unlock the flash for write FCTL1 = FWKEY + BLKWRT; DMA0CTL = DMADSTINCR_3 + DMAEN + DMADSTBYTE + DMASRCBYTE + DMAIE; // Enable Long-Word write, all 32 bits will be written once // 4 bytes are loaded TBCCTL1 &= ~CCIFG; TBCTL |= MC0; __bis_SR_register(LPM0_bits + GIE); // Enable interrupts, enter LPM0 __no_operation(); TBCTL &= ~MC0; DMA0CTL &= ~( DMAEN + DMAIE); FCTL3 = FWKEY + LOCK; // Lock the flash from write }
static void renderTickle() { clearTickles(); halLcdPrintLineCol("x", ( __kernel_menu_selectedProgram % __KERNEL_MENU_MAX_PROGRAMS_PER_PAGE ) + 2, 1, INVERT_TEXT); }
/**********************************************************************//** * @brief Executes the "PMM-MCLK" menu option in the User Experience * example code. This menu option allows one to change the frequency * of operation for the MSP430 and the VCore setting. * * @param none * * @return none *************************************************************************/ void menuPMMMCLK( void ) { unsigned char menuLeftPos = 2, menuRightPos = 0, menuRightMaxAllowed = 5; unsigned char ledOn, quit = 0; volatile unsigned int i; halButtonsInterruptDisable( BUTTON_ALL ); halButtonsInterruptEnable( BUTTON_SELECT + BUTTON_S1 + \ BUTTON_S2 + BUTTON_RIGHT ); halAccelerometerShutDown(); halLcdClearScreen(); halBoardOutputSystemClock(); halLcdPrintLineCol(&VcoreText[0], 0, 1, OVERWRITE_TEXT ); for (i=0;i < MCLK_MENU_MAX+1; i++) halLcdPrintLineCol(&MCLKText[i*6], i, 12, OVERWRITE_TEXT ); halLcdPrintLineCol(&VcoreText[menuLeftPos*6 + 6], \ menuLeftPos+1, 1, INVERT_TEXT | OVERWRITE_TEXT); halLcdPrintLineCol(&MCLKText[menuRightPos*6 + 6], \ menuRightPos+1, 12, INVERT_TEXT | OVERWRITE_TEXT); buttonsPressed = 0; for (i = menuRightMaxAllowed; i < MCLK_MENU_MAX; i++) { halLcdLine(96, 12*(i+1)+6, 136, 12*(i+1)+6, PIXEL_ON); halLcdLine(96, 12*(i+1)+7, 136, 12*(i+1)+7, PIXEL_ON); } ledOn = 0; halLcdPrintLine(" LED", 6, 0); halLcdPrintLine(" OFF", 7, 0); halLcdImage(IMG_RIGHT_FILLED, 4, 32, 10, 75); halBoardSetVCore(menuLeftPos); halBoardSetSystemClock(menuRightPos); while (!quit) { // The LED can be enabled to show the relative difference between // frequencies of operation. while (!buttonsPressed) if (ledOn) { LED_PORT_OUT ^= LED_1; for (i=0; i < 0xFFFF; i++) if (buttonsPressed) break; } else { // To emulate a real application instead of continuous jumps, use nops __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); } if (buttonsPressed & BUTTON_S1) { /* * Disabled for MSP430F5438 RTM Silicon halLcdPrintLineCol(&VcoreText[menuLeftPos*6 + 6], menuLeftPos+1, \ 1, OVERWRITE_TEXT); if (++ menuLeftPos >= VCORE_MENU_MAX) { menuLeftPos = 0; menuRightMaxAllowed = MAX_MCLK_ALLOWED[ menuLeftPos ]; if (menuRightPos >= menuRightMaxAllowed) { halLcdPrintLineCol(&MCLKText[menuRightPos*6 + 6], menuRightPos+1, \ 12, OVERWRITE_TEXT); menuRightPos = menuRightMaxAllowed - 1; halLcdPrintLineCol(&MCLKText[menuRightPos*6 + 6], menuRightPos+1, \ 12, INVERT_TEXT | OVERWRITE_TEXT); } for (i = menuRightMaxAllowed; i < MCLK_MENU_MAX; i++) { halLcdLine(96, 12*(i+1)+6, 136, 12*(i+1)+6, PIXEL_ON); halLcdLine(96, 12*(i+1)+7, 136, 12*(i+1)+7, PIXEL_ON); } } else { for (i=menuRightMaxAllowed+1; i< MAX_MCLK_ALLOWED[menuLeftPos]+1; i ++) halLcdPrintLineCol(&MCLKText[i*6], i, 12, OVERWRITE_TEXT ); menuRightMaxAllowed = MAX_MCLK_ALLOWED[menuLeftPos]; } halLcdPrintLineCol(&VcoreText[menuLeftPos*6 + 6], menuLeftPos+1, \ 1, INVERT_TEXT | OVERWRITE_TEXT); */ } if ( buttonsPressed & BUTTON_S2 ) { halLcdPrintLineCol(&MCLKText[menuRightPos*6 + 6], \ menuRightPos+1, 12, OVERWRITE_TEXT); if ( ++menuRightPos >= menuRightMaxAllowed ) menuRightPos = 0; halLcdPrintLineCol(&MCLKText[menuRightPos*6 + 6], \ menuRightPos+1, 12, INVERT_TEXT| OVERWRITE_TEXT); } if ( buttonsPressed & BUTTON_RIGHT ) { ledOn = 1 - ledOn; if ( ledOn ) halLcdPrintLineCol("ON ", 7, 6, OVERWRITE_TEXT); else { halLcdPrintLineCol("OFF", 7, 6, OVERWRITE_TEXT); LED_PORT_OUT &= ~LED_1; } } if ( buttonsPressed & (BUTTON_S1 | BUTTON_S2) ) { halBoardSetVCore(menuLeftPos); halBoardSetSystemClock(menuRightPos); //halBoardDisableSVS(); } if ( buttonsPressed & BUTTON_SELECT ) quit = 1; buttonsPressed = 0; } halBoardSetSystemClock( SYSCLK_16MHZ ); halBoardStopOutputSystemClock(); LED_PORT_OUT &= ~LED_1; }
__interrupt void on_button_interruption(void) { halButtons_setInterruptions(BUTTON_ALL, OFF); halJoystick_setInterruptions(JOYSTICK_ALL, OFF); switch ( P2IFG ) { case JOYSTICK_RIGHT: edit_mode++; if ( edit_mode > EDIT_SECONDS ) edit_mode = OFF; break; case JOYSTICK_LEFT: edit_mode--; if ( edit_mode < 0 ) edit_mode = EDIT_SECONDS; break; case JOYSTICK_UP: if ( time_base < 10000 ) time_base *= 10; break; case JOYSTICK_DOWN: if ( time_base > 1 ) time_base /= 10; break; case JOYSTICK_CENTER: stop_cron = ~stop_cron; break; case BUTTON_S1: increase_cron_unit(); halLcdPrintLine(lcd_clear, LINE_CRON, OVERWRITE_TEXT); write_cron(); break; case BUTTON_S2: decrease_cron_unit(); halLcdPrintLine(lcd_clear, LINE_CRON, OVERWRITE_TEXT); write_cron(); break; } write_time_base(); halLcdPrintLine(lcd_clear, LINE_TIME_UNIT_SEL, OVERWRITE_TEXT); if ( edit_mode != OFF ) { switch ( edit_mode ) { case EDIT_HOURS: halLcdPrintLineCol("HH", LINE_TIME_UNIT_SEL, 1, OVERWRITE_TEXT); break; case EDIT_MINUTES: halLcdPrintLineCol("MM", LINE_TIME_UNIT_SEL, 4, OVERWRITE_TEXT); break; case EDIT_SECONDS: halLcdPrintLineCol("SS", LINE_TIME_UNIT_SEL, 7, OVERWRITE_TEXT); break; } } halTimer_b_setCCRTimedInterruption(TIMER_CCR0, time_multiplier * time_base); P2IFG = 0; halButtons_setInterruptions(BUTTON_ALL, ON); halJoystick_setInterruptions(JOYSTICK_ALL, ON); }