Jump to content
43oh

NatureTM

Members
  • Content Count

    218
  • Joined

  • Last visited

  • Days Won

    13

Reputation Activity

  1. Like
    NatureTM got a reaction from hoangnguyen578 in Launchpad TV output   
    I went to a white elephant "The Office" watching party last Thursday. I gave my TVOut demo with the emergency broadcast system screen as my white elephant gift. Anyway, it got me looking at the code again. I realized it would be really easy to increase the resolution now that we have chips with greater than 2K flash.
     
    I pretty much changed two lines of code, created some new images, and uploaded it to an MSP430G2452 with 8K. The resolution is now 192x240. It's still a funky aspect ratio limited by code space and USI frequency, but I expect to get it to do 384x240 when I get my hands on one of the new 16K chips. I also realized I had some really goofy code due to a misunderstanding of pointers. I fixed that, and it no longer needs to compile as C++.
     

    /* Monochrome NTSC composite video output for TI's Launchpad. * * Schmatic: * 470 * P1.2 SYNC --------/\/\/\--------| * |----- RCA jack Signal * 220 | * P1.6 VOUT --------/\/\/\--------| * * Launchpad GND ------------------------ RCA jack GND * * * By: NatureTM * more info on naturetm.com */ #include #define TACCR0 TA0CCR0 #define TACCR1 TA0CCR1 #define TACCTL0 TA0CCTL0 #define TACCTL1 TA0CCTL1 #define TIMERA0_VECTOR TIMER0_A0_VECTOR #define TIMERA1_VECTOR TIMER0_A1_VECTOR // Image file #include "teh_real_nature.h" //#include "gina_close.h" //#include "gina_wide.h" //#include "ebs2.h" #define SYNC BIT2 #define VOUT BIT6 //#define NS_TICK 62.5 // NS = nanoseconds #define TICKS_HSYNC 72 #define TICKS_SHORT_SYNC 38 #define TICKS_HBLANK 163 #define TICKS_SCANLINE 1017 #define TICKS_HALF_SCANLINE 508 #define TICKS_RIGHT_EDGE 973 #define ROW_HEIGHT 1 // in scanlines #define WORDS_SCANLINE 12 unsigned int* currentRowPtr; unsigned int imageOffset; unsigned int scanline = 0; char imageLine; char subRowCounter; unsigned int sleep; int main(){ DCOCTL = CALDCO_16MHZ; BCSCTL1 = CALBC1_16MHZ; WDTCTL = WDTPW + WDTHOLD; // Stop WDT _BIS_SR(GIE); //enable interrupts USICKCTL = USIDIV1 + USISSEL1 + USISSEL0;// + USICKPL; // USI Clock = SMCLK / 4 USICNT = USI16B; // 16 bit shift out USICTL0 |= USIMST; // Use internal clock source USICTL0 &= ~USISWRST; // Clear USI reset bit (enable USI) USICTL0 |= USILSB; // USISR output LSB first USICTL0 |= USIGE; TACTL |= MC_0; // Stop timer A TACTL |= TASSEL1; // TASrc = SMClk = MClk TACTL &= ~TASSEL0; TACTL |= TACLR; // Clear the timer CCR0 = TICKS_SCANLINE; // Scanline timing - CCR0 triggers hSync CCR1 = TICKS_HSYNC; // End of hSync TACTL |= MC_1; // Up mode, Start TACCTL0 |= CCIE; // Enable Timer A CCR0 interrupt TACCTL1 |= OUTMOD_3; // TimerA reset sync pin on CCR0 TACCTL1 |= CCIE; // Enable Timer A CCR1 interrupt P1SEL = SYNC; // Allow timerA to set sync pin low on beginning of scanline P1DIR = SYNC + VOUT + BIT5; } // vsync broad sync pulse section void vSyncTripleBroad(){ int count; for(count = 0; count < 3; count++){ while(TAR < TICKS_HALF_SCANLINE - TICKS_HSYNC){} P1OUT = SYNC; while(TAR < TICKS_HALF_SCANLINE){} P1OUT = 0; while(TAR < TICKS_SCANLINE - TICKS_HSYNC){} P1OUT = SYNC; while(TAR > TICKS_SCANLINE - TICKS_HSYNC){} P1OUT = 0; } } // vsync short sync pulse section void vSyncTripleShort(){ int count; for (count = 0; count < 3; count++){ while(TAR < TICKS_SHORT_SYNC){} P1OUT = SYNC; while(TAR < TICKS_HALF_SCANLINE){} P1OUT = 0; while(TAR < TICKS_HALF_SCANLINE + TICKS_SHORT_SYNC){} P1OUT = SYNC; while(TAR > TICKS_HALF_SCANLINE + TICKS_SHORT_SYNC){} P1OUT = 0; } } // This ISR is run at the beginning of every scanline and keeps track of which // scanline we are on. At the beginning of a frame, it handles vSync output in // software. Next, it hands over control of the sync pin to TimerA, allowing // hsync timing to be done in hardware. #pragma vector=TIMERA0_VECTOR __interrupt void Timer_A0 (void){ // software vSync if(scanline == 0){ P1OUT = 0; P1SEL = 0; // let software control P1.5 instead of TACCR0 vSyncTripleShort(); vSyncTripleBroad(); vSyncTripleShort(); scanline = 8; // vSync takes several scanlines P1SEL = SYNC; // let TimerA handle hSync } // visible area starts/vBlank over else if(scanline == 21){ scanline++; TACCTL1 |= CCIE; // Start drawing picture subRowCounter = 0; imageOffset = 0; } else if(scanline < 263){ scanline++; } // bottom of screen, get ready for vSync else{ TACCTL1 &= ~CCIE; // Stop drawing picture scanline = 0; } } // After vSync, this ISR begins USI output of the image. #pragma vector=TIMERA1_VECTOR __interrupt void Timer_A1 (void){ int wordCounter = 0; TAIV = 0; // Clear TimerA's interrupt vector register; USICTL0 |= USIOE; // USI output enabled USICTL0 |= USIPE6; // Port 1.6 USI data out while (TAR < TICKS_HBLANK){} do{ USICNT |= 16; USISR = currentRowPtr[wordCounter]; wordCounter++; // software delay allowing full USI shift out sleep = 0; while(sleep < 2) sleep++; _nop(); _nop(); _nop(); _nop(); _nop(); _nop(); _nop(); }while(wordCounter < WORDS_SCANLINE); if(subRowCounter == ROW_HEIGHT){ subRowCounter = 0; imageOffset += WORDS_SCANLINE; } subRowCounter++; currentRowPtr = (unsigned int*)image + imageOffset; while(TAR < TICKS_RIGHT_EDGE){} // Wait for edge of screen USICTL0 &= ~(USIPE6 + USIOE); // Release control of video pin to software }
     
    It needs to be flashed in CCS under Debug mode (without optimizations.) Compiling in Release mode with optimizations leads to distorted video. It probably could be fixed for release mode or mspgcc by tweaking the software delay toward the bottom. Changing that "sleep" variable to volatile might just be enough (a thought I had just now, not tested.)
     
    Files, demo images, and information on how to create your own images available on my bloggity-bloggy-blog. I find the word blog amusing.
    http://naturetm.com/?p=147
  2. Like
    NatureTM reacted to bluehash in Launchpad TV output   
    Woah! Miss nature looks good.
     
    Nice work NTM!
  3. Like
    NatureTM got a reaction from Rickta59 in Launchpad TV output   
    I went to a white elephant "The Office" watching party last Thursday. I gave my TVOut demo with the emergency broadcast system screen as my white elephant gift. Anyway, it got me looking at the code again. I realized it would be really easy to increase the resolution now that we have chips with greater than 2K flash.
     
    I pretty much changed two lines of code, created some new images, and uploaded it to an MSP430G2452 with 8K. The resolution is now 192x240. It's still a funky aspect ratio limited by code space and USI frequency, but I expect to get it to do 384x240 when I get my hands on one of the new 16K chips. I also realized I had some really goofy code due to a misunderstanding of pointers. I fixed that, and it no longer needs to compile as C++.
     

    /* Monochrome NTSC composite video output for TI's Launchpad. * * Schmatic: * 470 * P1.2 SYNC --------/\/\/\--------| * |----- RCA jack Signal * 220 | * P1.6 VOUT --------/\/\/\--------| * * Launchpad GND ------------------------ RCA jack GND * * * By: NatureTM * more info on naturetm.com */ #include #define TACCR0 TA0CCR0 #define TACCR1 TA0CCR1 #define TACCTL0 TA0CCTL0 #define TACCTL1 TA0CCTL1 #define TIMERA0_VECTOR TIMER0_A0_VECTOR #define TIMERA1_VECTOR TIMER0_A1_VECTOR // Image file #include "teh_real_nature.h" //#include "gina_close.h" //#include "gina_wide.h" //#include "ebs2.h" #define SYNC BIT2 #define VOUT BIT6 //#define NS_TICK 62.5 // NS = nanoseconds #define TICKS_HSYNC 72 #define TICKS_SHORT_SYNC 38 #define TICKS_HBLANK 163 #define TICKS_SCANLINE 1017 #define TICKS_HALF_SCANLINE 508 #define TICKS_RIGHT_EDGE 973 #define ROW_HEIGHT 1 // in scanlines #define WORDS_SCANLINE 12 unsigned int* currentRowPtr; unsigned int imageOffset; unsigned int scanline = 0; char imageLine; char subRowCounter; unsigned int sleep; int main(){ DCOCTL = CALDCO_16MHZ; BCSCTL1 = CALBC1_16MHZ; WDTCTL = WDTPW + WDTHOLD; // Stop WDT _BIS_SR(GIE); //enable interrupts USICKCTL = USIDIV1 + USISSEL1 + USISSEL0;// + USICKPL; // USI Clock = SMCLK / 4 USICNT = USI16B; // 16 bit shift out USICTL0 |= USIMST; // Use internal clock source USICTL0 &= ~USISWRST; // Clear USI reset bit (enable USI) USICTL0 |= USILSB; // USISR output LSB first USICTL0 |= USIGE; TACTL |= MC_0; // Stop timer A TACTL |= TASSEL1; // TASrc = SMClk = MClk TACTL &= ~TASSEL0; TACTL |= TACLR; // Clear the timer CCR0 = TICKS_SCANLINE; // Scanline timing - CCR0 triggers hSync CCR1 = TICKS_HSYNC; // End of hSync TACTL |= MC_1; // Up mode, Start TACCTL0 |= CCIE; // Enable Timer A CCR0 interrupt TACCTL1 |= OUTMOD_3; // TimerA reset sync pin on CCR0 TACCTL1 |= CCIE; // Enable Timer A CCR1 interrupt P1SEL = SYNC; // Allow timerA to set sync pin low on beginning of scanline P1DIR = SYNC + VOUT + BIT5; } // vsync broad sync pulse section void vSyncTripleBroad(){ int count; for(count = 0; count < 3; count++){ while(TAR < TICKS_HALF_SCANLINE - TICKS_HSYNC){} P1OUT = SYNC; while(TAR < TICKS_HALF_SCANLINE){} P1OUT = 0; while(TAR < TICKS_SCANLINE - TICKS_HSYNC){} P1OUT = SYNC; while(TAR > TICKS_SCANLINE - TICKS_HSYNC){} P1OUT = 0; } } // vsync short sync pulse section void vSyncTripleShort(){ int count; for (count = 0; count < 3; count++){ while(TAR < TICKS_SHORT_SYNC){} P1OUT = SYNC; while(TAR < TICKS_HALF_SCANLINE){} P1OUT = 0; while(TAR < TICKS_HALF_SCANLINE + TICKS_SHORT_SYNC){} P1OUT = SYNC; while(TAR > TICKS_HALF_SCANLINE + TICKS_SHORT_SYNC){} P1OUT = 0; } } // This ISR is run at the beginning of every scanline and keeps track of which // scanline we are on. At the beginning of a frame, it handles vSync output in // software. Next, it hands over control of the sync pin to TimerA, allowing // hsync timing to be done in hardware. #pragma vector=TIMERA0_VECTOR __interrupt void Timer_A0 (void){ // software vSync if(scanline == 0){ P1OUT = 0; P1SEL = 0; // let software control P1.5 instead of TACCR0 vSyncTripleShort(); vSyncTripleBroad(); vSyncTripleShort(); scanline = 8; // vSync takes several scanlines P1SEL = SYNC; // let TimerA handle hSync } // visible area starts/vBlank over else if(scanline == 21){ scanline++; TACCTL1 |= CCIE; // Start drawing picture subRowCounter = 0; imageOffset = 0; } else if(scanline < 263){ scanline++; } // bottom of screen, get ready for vSync else{ TACCTL1 &= ~CCIE; // Stop drawing picture scanline = 0; } } // After vSync, this ISR begins USI output of the image. #pragma vector=TIMERA1_VECTOR __interrupt void Timer_A1 (void){ int wordCounter = 0; TAIV = 0; // Clear TimerA's interrupt vector register; USICTL0 |= USIOE; // USI output enabled USICTL0 |= USIPE6; // Port 1.6 USI data out while (TAR < TICKS_HBLANK){} do{ USICNT |= 16; USISR = currentRowPtr[wordCounter]; wordCounter++; // software delay allowing full USI shift out sleep = 0; while(sleep < 2) sleep++; _nop(); _nop(); _nop(); _nop(); _nop(); _nop(); _nop(); }while(wordCounter < WORDS_SCANLINE); if(subRowCounter == ROW_HEIGHT){ subRowCounter = 0; imageOffset += WORDS_SCANLINE; } subRowCounter++; currentRowPtr = (unsigned int*)image + imageOffset; while(TAR < TICKS_RIGHT_EDGE){} // Wait for edge of screen USICTL0 &= ~(USIPE6 + USIOE); // Release control of video pin to software }
     
    It needs to be flashed in CCS under Debug mode (without optimizations.) Compiling in Release mode with optimizations leads to distorted video. It probably could be fixed for release mode or mspgcc by tweaking the software delay toward the bottom. Changing that "sleep" variable to volatile might just be enough (a thought I had just now, not tested.)
     
    Files, demo images, and information on how to create your own images available on my bloggity-bloggy-blog. I find the word blog amusing.
    http://naturetm.com/?p=147
  4. Like
    NatureTM reacted to maxpenna in Flashing the missing DCO calibration constants   
    Hi everyone,
     
    I've added the checksum for proper verification of the data inside flash.
     
    I've also regrouped code some parts in functions.
     
    Finally, this version works with TI DCO calibration example in C (MSP430G2231 code examples), because I really don't understand asm.
     
    Is there some specific reason you used asm routine for DCO calibration?
     
    The attachment is the project in CCS4.
     
    Thank you all, comments appreciated
    dco_calibration.rar
  5. Like
    NatureTM reacted to TheDirty in Two questions on using CCS   
    If you go into the debug directory and find project-name.map Open that file and it contains a lot of information regarding the compile information including how much flash is used and not used.
     
    I'm not certain if the map file is created by default. You might need to go into the options to create it.
     
    Sorry, delayed response. I haven't been on in a while.
  6. Like
    NatureTM reacted to lpdc in RGB color matching game - MSP430G2231 + Launchpad + ADC   
    NOTE : A NEW IMPROVED VERSION CAN BE VIEWED ON PAGE 2
     
     
    Hello everyone,
    2 or 3 months ago, I announced here that, as a first project, I would like to program a color matching game inspired by the Amazing Dr. Boardman's Conundrum.
     
    I want to thank everyone who answered the post and gave me pointers.
    This is what I have achieved so far :
     


     
    Schematics of the circuit :
     

     
    The code is pasted below, largely inspired from the tutorials and examples at
    http://mspsci.blogspot.com/
    and
    http://www.msp430launchpad.com/2010/09/ ... chpad.html
    and
    http://blog.hodgepig.org/2010/09/30/jam-jar-lamp/
     
    As I said, this is my first try ever at programming micro controllers, so the code is probably rather ugly and not as efficient as it should.
     
    I am looking forward to any comments and suggestions as my goal is to learn and improve this program.
     
    As a next step, I would like to add a piezzo buzzer on the last available pin (2.6) in order to give some feedback during the game (modulating the sound according to the color difference). I have no clue yet how I will implement this. Any ideas/pointers welcome.
     
    Thanks again for the help, I would not have gone this far without it.
     

    /* ****** Color matching game. By Fabrice C. ****** This is my first program with a microcontroller so everything is probably not as pretty as it should... Original inspiration came from : http://www.fangletronics.com/2010/02/amazing-dr-boardmans-colour-conundrum.html A lot of code was inspired by the tutorials/examples from : http://mspsci.blogspot.com/ and http://www.msp430launchpad.com/2010/09/simple-adc-example-on-launchpad.html and http://blog.hodgepig.org/2010/09/30/jam-jar-lamp/ */ #include #include #include #include /****************************************************/ #define P1_LED_BIT (BIT0|BIT1|BIT2|BIT6|BIT7) #define P2_LED_BIT (BIT6) /****************************************************/ static volatile uint8_t led_brightness[6] = {0x00,0x00,0x00,0x00,0x00,0x00}; // This variable stores the brightness of the 2 RGB leds : {R1,G1,B1,R2,G2,B2} static volatile uint32_t sys_ticks = 0; // Used to keep track of PWM static volatile bool ADCDone = false; // Flag to check that the ADC sampling is done static volatile uint16_t ADCValue; // Result of ADC (converted value) static volatile int sampled_channel; // Channel being sampled by ADC static volatile int seed; // seed for random number generation /****************************************************/ static void cpu_init(void) // Initialisation of the micro controller { WDTCTL = WDTPW + WDTHOLD; // Stop Watch dog timer // configure system clock to about 16MHz BCSCTL1 &= ~(BIT0 + BIT1); // set bits 0 and 1 to 0 BCSCTL1 |= BIT2 + BIT3; // set bits 2 and 3 to 1 DCOCTL &= ~(BIT5 + BIT7); // set bits 5 and 7 to 0 DCOCTL |= BIT6; // set bit 6 to 1 // seems like overkill but lower frequencies generated // quite a lot of flickering. PWM algo/usage may need improvement _enable_interrupt(); // to be able to use interrupts // Without this the timer and ADC callback functions would never be called. } bool match(volatile int delta) // function returning true if the 2 RGB values are within // a distance "delta" (euclidian distance) { volatile int Dr; volatile int Dg; volatile int Db; Dr = led_brightness[0]-led_brightness[3]; Dg = led_brightness[1]-led_brightness[4]; Db = led_brightness[2]-led_brightness[5]; volatile unsigned int D;//no sqrt so no need for double D = (unsigned int)((Dr*Dr)+(Dg*Dg)+(Db*Db)); // cannot manage to do a sqrt without getting a compiling error // so I am comparing the 2 squared values instead. if ( D <= (delta*delta)) return true; else return false; } void win (void) // Procedure to show the player he won. Right now it is only blinking the LEDs // To do : add some music there { volatile int R; volatile int G; volatile int B; R= led_brightness[3]; G= led_brightness[4]; B= led_brightness[5]; // saves current RGB values of the target color //LEDs off led_brightness[0] = 0; led_brightness[1] = 0; led_brightness[2] = 0; led_brightness[3] = 0; led_brightness[4] = 0; led_brightness[5] = 0; unsigned int n; unsigned int i; for (i=0; i<10; i++) // blinks the 2 RGB leds 10 times { for (n=0; n<3000; n++); // delay // LEDs on led_brightness[0] = R; led_brightness[1] = G; led_brightness[2] = B; led_brightness[3] = R; led_brightness[4] = G; led_brightness[5] = B; for (n=0; n<3000; n++); //delay //LEDs off led_brightness[0] = 0; led_brightness[1] = 0; led_brightness[2] = 0; led_brightness[3] = 0; led_brightness[4] = 0; led_brightness[5] = 0; } } // Binary Code Modulation static void bcm_tick(uint8_t led_ticks) { uint8_t bcm1 = 0x00; uint8_t bcm2 = 0x00; // This commented code does not work so I used the code from // http://www.msp430launchpad.com/2010/09/simple-adc-example-on-launchpad.html // instead // if (led_brightness[0] <= led_ticks) // bcm1 |= BIT0; // if (led_brightness[1] <= led_ticks) // bcm1 |= BIT1; // if (led_brightness[2] <= led_ticks) // bcm1 |= BIT2; // // if (led_brightness[3] <= led_ticks) // bcm1 |= BIT6; // if (led_brightness[4] <= led_ticks) // bcm1 |= BIT7; //To be fixed : may want the BIT6 on this port to also stay on. // if (led_brightness[5] <= led_ticks) // bcm2 |= BIT7; // // P1OUT = bcm1; // P2OUT = bcm2; // switch(led_ticks) { case 0x1: case 0x2: case 0x4: case 0x8: case 0x10: case 0x20: case 0x40: case 0x80: // led_ticks is a power of 2 if (led_brightness[0] & led_ticks) bcm1 |= BIT0; if (led_brightness[1] & led_ticks) bcm1 |= BIT1; if (led_brightness[2] & led_ticks) bcm1 |= BIT2; if (led_brightness[3] & led_ticks) bcm1 |= BIT6; if (led_brightness[4] & led_ticks) bcm1 |= BIT7; //To be fixed : may want the BIT6 on this port to also stay on. // Especially if we want to put a buzzer on BIT6 if (led_brightness[5] & led_ticks) bcm2 |= BIT7; P1OUT = bcm1; P2OUT = bcm2; } } // Timer0 ISR #pragma vector=TIMERA0_VECTOR __interrupt void Timer_A (void) //Call back function when the timer ticks { bcm_tick(sys_ticks); sys_ticks++; // Following was meant to work with other BCM function but did does not work. // if (sys_ticks > 255 ) // sys_ticks = 0; // This was meant to enter low power mode but interrups stopped for some reason //__bis_SR_register(CPUOFF + GIE); //__bic_SR_register_on_exit(CPUOFF); } void Single_Measure(unsigned int chan) // Frunction starting the ADC sampling { ADC10CTL0 &= ~ENC; // Disable ADC ADC10CTL0 = ADC10SHT_3 + ADC10ON + ADC10IE; // 16 clock ticks, ADC On, enable ADC interrupt ADC10CTL1 = ADC10SSEL_3 + chan; // Set 'chan', SMCLK ADC10CTL0 |= ENC + ADC10SC; // Enable and start conversion } #pragma vector=ADC10_VECTOR __interrupt void ADC10_ISR (void) // Call back function for when the ADC sampling is done { ADCValue = ADC10MEM; //saves measured value from register into ADCValue variable ADCDone = true; // sets the flag acknowledging that the ADC is done //__bic_SR_register_on_exit(CPUOFF); } void Generate_New_Target(void) // Generates a random color for the target of the game { uint32_t T = 0; while (1) { led_brightness[3] = rand(); led_brightness[4] = rand(); led_brightness[5] = rand(); T = led_brightness[3] + led_brightness[4] + led_brightness[5]; // We check the total brightness of the 3 components as we don't want a // color to be too dark or too white if (500 > T < 200) break ; } } int main(void) // Main Program { cpu_init(); // setup LED pins P1DIR |= P1_LED_BIT; // All LED pins as outputs //select i/o function of pins P2SEL &= ~(BIT6|BIT7); // Acitvates the 2 ports on pins 12 and 13 //set them as outputs P2DIR = BIT6 | BIT7; P2OUT &= ~(BIT6|BIT7); P1OUT &= ~P1_LED_BIT; // Turn off LED // TimerA SMCLK in UP mode TACTL = TASSEL_2 | MC_1; // Enable interrupt for TACCR0 match TACCTL0 = CCIE; // Set TACCR0, starts timer. TACCR0 = 110; // This must be short enough to look good and long enough for TIMER0_ISR to complete // but I don't really understand the magic number //Measures the value of Channel 3 (R potentiometer) Single_Measure(INCH_3); while (1) // waits until the measurement is finished { if (ADCDone) break; } ADCDone = false; seed = ((uint32_t)ADCValue*255)/990; // uses the measured value as the seed for random number generation // if a constant seed is used, the order in which the target colors // are asked will always be the same when the micro controller is reset. // This way, provided the R potentiometer was changed since last time, // a new color will be asked first. (crude but it works most of the time) srand(seed); // Sets the R, G, and B brightness of the target color to a random value Generate_New_Target(); Single_Measure(INCH_3); sampled_channel = 1; // Keeps track of the channel being measured while(1) // Endless loop { if (ADCDone) // if we have a measurement result available { ADCDone = false; // my potentiometers are not the best ones, I never // manage to get the sampled value up to 1023 // so I clip everything to 990 in order to make // sure that the player can dial in a maximum // brightness value of FF if (ADCValue > 990) ADCValue = 990; switch(sampled_channel) { // adjust the brightness of a LED to the value // measured on the corresponding potentimeter // and makes ready to sample the next channel case 1: led_brightness[0] = ((uint32_t)ADCValue*255)/990; Single_Measure(INCH_4); sampled_channel = 2; break; case 2: led_brightness[1] = ((uint32_t)ADCValue*255)/990; Single_Measure(INCH_5); sampled_channel = 3; break; case 3: led_brightness[2] = ((uint32_t)ADCValue*255)/990; Single_Measure(INCH_3); sampled_channel = 1; break; } } // tests if the dialed in values are close enough to the target if (match(5) == true) { win(); // display winning animation // Sets a new color as target Generate_New_Target(); } } }
  7. Like
    NatureTM reacted to Rickta59 in Full-duplex software UART for launchpad   
    So this code snippet springs forth from my desire to use a terminal emulator ( I like putty best ) with my launchpad via the built-in COM port. Simple I think, someone must have already done this by now, no? Well, trying to find a working example for the launchpad led me down a lot of dead ends with nothing that worked well. I did find examples that were half-duplex and ones that required more Timer features than you find on the msp430g2231. Unfortunately, none of them fit my requirements.
     
    My goal was to find something that would allow me to use higher DCO clock speeds such as 16MHZ. I also wanted to be able to run reliably with 115k baud rates, so that I can connect a serial to TCP proxy and make my launchpad web enabled.
     
    I've implemented something here that meets both of those goals. Well sort of. I discovered that the COM port on the launchpad will only work up to 9600 baud. However, you can disconnect the jumpers and plug your RX/TX lines into an FT232RL device and get higher speeds. It also works well if your goal is to interface to some other device via TTL level RS232, say a GPS device.
     
    You can find the code here:
     
    https://github.com/RickKimball/msp430softserial
     
    Because everything is better with pictures, I took a snapshot of the RX line receiving the character 'U' at 9600 baud. 'U' is unique in that it forms a perfect clock wave 0 10101010 1 when you add the stop and start bits. The green line is the RX line, the red line is me toggling a debug pin inside of the RX ISR routine. I used a program called Soundcard Oscilloscope that helped me dial in the proper timing so that I was sampling in the center of each data bit. http://www.zeitnitz.de/Christian/scope_en
     

     
    In the picture above, you'll notice that the first red crossing takes longer than the other samplings, that is because we just ignore the value of the start bit and start sampling in the center of the first data bit.
     
    To use and test the code, download it from github and bring it into CCS. Once it is running figure out which COM port your launchpad is using and connect to it with a terminal emulator like putty or minicom using 9600 baud. The default configuration expects you to have soldered a 32.768k crystal to the launchpad board. It uses the crystal to calibrate the DCO for a higher MHZ speed. Don't worry, I don't write it to flash, I just calibrate it and use it. However, you can edit the config.h to modify the baud rate and MCLK speed. You can even run it at the default MCLK speed. See the config.h file comments for more information.
     
    I think I've commented the code fairly well. However, this is actually my first published project with the MSP430 launchpad so comments are welcome. So enjoy!
     
    -rick
  8. Like
    NatureTM reacted to RobG in How to safely connect a pot to the ADC   
    See the family user guide.
     
    Simplifying things, during sampling, a switch for the selected channel is closed and charges tiny capacitor (~27pF) and that is the only current flowing through this circuit, we are talking uA here over the period of few us. Once the cap is charged, there is no more current flowing. Then that switch is opened and another closed, one that connects the capacitor to a comparator. Comparator then compares capacitor's voltage to a reference voltage which is connected through resistor network (basically a DAC.)
    When the whole converting cycle is done, SAR's value is written to memory register.
     
    How SAR works?
    For example you have 15V voltage reference and a 4 bit SAR with a ladder of resistors that can output 0-15V, bit0 1V, bit1 2V, bit2 4V, and bit3 8V. It's output is connected to a comparator. S&H capacitor is also connected to a comparator and is charged during sampling cycle to 7V.
    Converting cycle begins and bit3 is turned on, comparing 8V to 7V, because it's bigger, bit3 stays off, next bit2 is on and 4V is compared to 7V, since 4V is smaller than 7V bit2 stays on, then bit1 is set, comparing 6V to 7V (6V because bit2 is still on 4V + 2V.) 6 is less than 7, bit1 is on. Next bit0, 7V is not more than 7V, bit0 is on. End of converting cycle, SAR register is 0111 and it's written to mem register.
     
    How many cycles this whole process takes?
    You must have enough cycles to charge the capacitor (sampling time,) the bigger output resistance of the measured circuit, the longer it will take to charge it. This usually takes few us, but sometimes when you have dividers with mega ohm resistors, it may take several tens of us.
    The comes converting, one cycle for each bit of resolution so 10bit ADC will require 10 cycles.
    Figuring out sampling time is important because it will introduce error if it is too short and the capacitor is not charged to the input voltage.
  9. Like
    NatureTM reacted to bluehash in Capacitive Touch Booster Pack for the Launchpad $4.30   
    $4.30 for the first 430 Hours(starting today). thats 18 days
     
    Blog Link
    TI Link
     
    It also comes with an Open Source GUI to view what
  10. Like
    NatureTM reacted to RobG in MSP430G2xx3!   
    Be careful when you order those, I made a costly mistake of ordering 8 resistor ones, which is actually 4 bit ladder, not 8 bit
  11. Like
    NatureTM reacted to Fe2o3Fish in MSP430G2xx3!   
    BTW, has you considered something simple like an R2R network in a SIP package???
    And an op-amp if you need to. For example:
     
    http://il.mouser.com/ProductDetail/Murata/RGSD8L104G/?qs=sGAEpiMZZMsmUjwTDAf1t8iW9d%2fGovU2
  12. Like
    NatureTM got a reaction from artifus in Flashing the missing DCO calibration constants   
    EDIT: Here's another really nice DCO calibration program. It's part of TinyOS-msp430. http://code.google.com/p/tinyos-msp430/ It's the file called calibrate-dco. As gordon, who discovered it said, "[it] appears to be a quite beefed-up DCO calibration app, with goodies on the side (taking silicon errata into account for various devices when calibrating)." It looks like it's built to be solid and reliable. I skimmed over the code and didn't see anything for calculating SegA checksum, but that usually isn't an issue for most non-critical applications.
     
    EDIT: maxpenna shared another version of the DCO calibration program. This is the one to use if you need a correct SegmentA checksum. It uses the C calibration function. You can get it here http://www.43oh.com/forum/download/file.php?id=292
     
    WARNING: Some of the programs in this thread will erase Segment A and only put back the DCO calibrations. They should not be used with chips that have an ADC12, as this process will destroy the ADC12 calibrations. Some of the programs do not calculate the Segment A checksum, so the integrity of Segment A cannot be verified during runtime after calibration. Still, I've been using it without any problems.
     
     
    There's been a bit of a discussion in another thread about an idea simpleavr had for adding the dco calibration constants to flash for the Value Line series. I've cobbled together some pieces of TI code and have it working. It seems to work great. Here's how I did it with CCS. I think the people on linux should be able to reproduce the result with a little adaptation.
     
    This requires the TI DCO library I modified in another thread and an external LF crystal like the one with Launchpad.
    http://naturetm.com/files/Launchpad%20setDCO%20lib.rar
     
    First, run this to calibrate the constants and write them to flash:
    EDIT: 43oh member zeke has made some changes to the code for finer tuning. Check page 2 for his code.

    //****************************************************************************** // MSP430F20xx Demo - DCO Calibration Constants Programmer // // NOTE: THIS CODE REPLACES THE TI FACTORY-PROGRAMMED DCO CALIBRATION // CONSTANTS LOCATED IN INFOA WITH NEW VALUES. USE ONLY IF THE ORIGINAL // CONSTANTS ACCIDENTALLY GOT CORRUPTED OR ERASED. // // Description: This code re-programs the F2xx DCO calibration constants. // A software FLL mechanism is used to set the DCO based on an external // 32kHz reference clock. After each calibration, the values from the // clock system are read out and stored in a temporary variable. The final // frequency the DCO is set to is 1MHz, and this frequency is also used // during Flash programming of the constants. The program end is indicated // by the blinking LED. // ACLK = LFXT1/8 = 32768/8, MCLK = SMCLK = target DCO // //* External watch crystal installed on XIN XOUT is required for ACLK *// // // MSP430F20xx // --------------- // /|\| XIN|- // | | | 32kHz // --|RST XOUT|- // | | // | P1.0|--> LED // | P1.4|--> SMLCK = target DCO // // A. Dannenberg // Texas Instruments Inc. // May 2007 // Built with CCE Version: 3.2.0 and IAR Embedded Workbench Version: 3.42A //****************************************************************************** #include "msp430x20x1.h" #include "DCO_Library.h" unsigned char CAL_DATA[8]; // Temp. storage for constants volatile unsigned int i; int j; char *Flash_ptrA; // Segment A pointer void Set_DCO(unsigned int setting); void main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop WDT for (i = 0; i < 0xfffe; i++); // Delay for XTAL stabilization P1OUT = 0x01; // Red LED on P1SEL = 0x10; // P1.4 SMCLK output P1DIR = 0x51; // P1.0,4,6 output j = 0; // Reset pointer Set_DCO(TI_DCO_16MHZ); // Set DCO and obtain constants CAL_DATA[j++] = DCOCTL; CAL_DATA[j++] = BCSCTL1; Set_DCO(TI_DCO_12MHZ); // Set DCO and obtain constants CAL_DATA[j++] = DCOCTL; CAL_DATA[j++] = BCSCTL1; Set_DCO(TI_DCO_8MHZ); // Set DCO and obtain constants CAL_DATA[j++] = DCOCTL; CAL_DATA[j++] = BCSCTL1; Set_DCO(TI_DCO_1MHZ); // Set DCO and obtain constants CAL_DATA[j++] = DCOCTL; CAL_DATA[j++] = BCSCTL1; Flash_ptrA = (char *)0x10C0; // Point to beginning of seg A FCTL2 = FWKEY + FSSEL0 + FN1; // MCLK/3 for Flash Timing Generator FCTL1 = FWKEY + ERASE; // Set Erase bit FCTL3 = FWKEY + LOCKA; // Clear LOCK & LOCKA bits *Flash_ptrA = 0x00; // Dummy write to erase Flash seg A FCTL1 = FWKEY + WRT; // Set WRT bit for write operation Flash_ptrA = (char *)0x10F8; // Point to beginning of cal consts for (j = 0; j < 8; j++) *Flash_ptrA++ = CAL_DATA[j]; // re-flash DCO calibration data FCTL1 = FWKEY; // Clear WRT bit FCTL3 = FWKEY + LOCKA + LOCK; // Set LOCK & LOCKA bit P1OUT = 0; while (1) { P1OUT ^= BIT6; // Toggle green LED for (i = 0; i < 0x4000; i++); // SW Delay } } void Set_DCO(unsigned int setting){ volatile unsigned int I; // P1DIR |= BIT0; // P1.0 output BCSCTL1 &= ~XTS; // external source is LF; BCSCTL3 &= ~(LFXT1S0 + LFXT1S1); // watch crystal mode BCSCTL3 |= XCAP0 + XCAP1; // ~12.5 pf cap on the watch crystal as recommended for( I = 0; I < 0xFFFF; I++){} // delay for ACLK startup if(TI_SetDCO(setting) == TI_DCO_NO_ERROR) // if setting the clock was successful, P1OUT |= BIT0; // bring P1.0 high (Launchpad red LED) else while(1); // trap if setting the clock isn't successful }
     
    The green light should start blinking in a few seconds, indicating success. Now we need to modify some linker and header files so CCS knows about the new calibrations.
     
    I'm using the MSP430G2231, so I duplicated the file C:\Program Files (x86)\Texas Instruments\ccsv4\msp430\include\msp430g2231.cmd in that directory, and renamed the duplicate as msp430g2231_mod.cmd. Now I can edit it without affecting the original. Edit msp430g2231_mod.cmd and change the calibration section at the bottom to this:
     

    /************************************************************ * Calibration Data in Info Mem ************************************************************/ CALDCO_16MHZ = 0x10F8; CALBC1_16MHZ = 0x10F9; CALDCO_12MHZ = 0x10FA; CALBC1_12MHZ = 0x10FB; CALDCO_8MHZ = 0x10FC; CALBC1_8MHZ = 0x10FD; CALDCO_1MHZ = 0x10FE; CALBC1_1MHZ = 0x10FF;
     
    Now the linker knows we have calibration data in that section when we use the modified file.
     
    When we create a new project in CCS or modify an existing one, CCS will want to use the default linking file, and the default header. Here's an example about how to configure a project to use the new constants.
    First create a new project. Within the project, there should be a file called something like lnk_msp430g2231.cmd. The last line of that file should be something like -l msp430g2231.cmd. Open it, and change the last line to reflect the new linker file so it reads -l msp430g2231_mod.cmd.
    Next, add the appropriate header file to the project. Right-click the project folder in the left pane of CCS and click "Add files to project..." In this example, I'm using C:\Program Files (x86)\Texas Instruments\ccsv4\msp430\include\msp430g2231.h. Now we have a copy of the file in the project we can safely edit. Edit the file so the calibration section looks like this:

    /************************************************************ * Calibration Data in Info Mem ************************************************************/ #ifndef __DisableCalData SFR_8BIT(CALDCO_16MHZ); /* DCOCTL Calibration Data for 16MHz */ SFR_8BIT(CALBC1_16MHZ); /* BCSCTL1 Calibration Data for 16MHz */ SFR_8BIT(CALDCO_12MHZ); /* DCOCTL Calibration Data for 12MHz */ SFR_8BIT(CALBC1_12MHZ); /* BCSCTL1 Calibration Data for 12MHz */ SFR_8BIT(CALDCO_8MHZ); /* DCOCTL Calibration Data for 8MHz */ SFR_8BIT(CALBC1_8MHZ); /* BCSCTL1 Calibration Data for 8MHz */ SFR_8BIT(CALDCO_1MHZ); /* DCOCTL Calibration Data for 1MHz */ SFR_8BIT(CALBC1_1MHZ); /* BCSCTL1 Calibration Data for 1MHz */ #endif /* #ifndef __DisableCalData */
     
    Now you can begin using the new calibration data in your program. When you #include the msp430g2231.h file, put it in quotes instead of <> to ensure it's loading the modified header local to the project directory.
     
    I tested the constants with a cheap oscilloscope and they seemed correct. My scope doesn't have great accuracy at high frequencies so they might be a little off, but nothing I can detect. It works with my composite video prog, so that's a pretty good sign.
     
    EDIT: Oops! I had an incorrectly named file in these instructions. Corrected.
  13. Like
    NatureTM got a reaction from hoangnguyen578 in Launchpad TV output   
    I got my Launchpad to output B/W composite video. It only displays one image without re-flashing though, so it's not extremely useful. The only external components are two resistors and a crystal oscillator. I plan on writing it up on my blog and releasing the source sometime this week, unless I get too busy with school. I wasn't sure if I'd be able to ever get this working, so I'm feelin' pretty good right now!
    Proof ;-)

     
    Code for use with an external oscillator:
    Launchpad_TV_Out.rar
     
    Code for if you have your DCO configuration constants calibrated:
    Launchpad_TV_Out_for_calibrated.rar
     
    EDIT: Here's the writeup!
    http://naturetm.com/?p=47
  14. Like
    NatureTM reacted to juani_c in Connector for 2013 target board with staples   
    In case somebody want to use that Launchpad's feature I made the connector with some 26/6 staples
     

     

     

  15. Like
    NatureTM got a reaction from jsolarski in Reading the ADC from any pin   
    I'm assuming you don't have an interrupt service routine coded. Since you have the ADC interrupt enabled, when the ADC finishes, the cpu will exit LPM0 and the program will jump to where the ADC10 ISR should be. If there's nothing there, you'll get unexpected behavior. You could either put something in the interrupt vector, or don't enable the interrupt.
     
    Also, for "k = (ADC10MEM / 1024) * 8;" the ADC1MEM / 1024 is integer division, and the result is rounded down to the nearest whole number. The result of ADC1MEM / 1024 will always be between 0 and 1, but rounded down, so always 0. You can use algebra to change the code so it will work: "k = (ADC10MEM * 8) / 1024;" That answer will still be rounded down, but at least give a result from 0 to 8. "k = (char)((ADC10MEM / (float)1024) * 8 + 0.5);" will round appropriately, but will be slower.
     
    I've got some example code for the ADC10 I'll just copy over from my blog:
     

    #include "msp430g2231.h" #define ANALOG_PIN 1 unsigned int analogRead(){ ADC10CTL0 |= ADC10SC; while(ADC10CTL1 & ADC10BUSY); return ADC10MEM; } void analogPinSelect(unsigned int pin){ if(pin < 8){ ADC10CTL0 &= ~ENC; ADC10CTL1 = pin << 12; ADC10CTL0 = ADC10ON + ENC + ADC10SHT_0; } } void main(void){ unsigned int analogValue; DCOCTL = CALDCO_1MHZ; BCSCTL1 = CALBC1_1MHZ; WDTCTL = WDTPW + WDTHOLD; // read adc repeatedly analogPinSelect(ANALOG_PIN); while(1){ analogValue = analogRead(); } }
     
    You should be able to work off that example and get what you need.
  16. Like
    NatureTM reacted to wilywyrm in MSP430G2xx3!   
    Don't know if anyone saw this yet, but I went to go look for a datasheet today and saw that the number of G2xx devices jumped from 20-something to 41! I clicked through, and sure enough, there are 2xx3 parts listed! Mind you, they're only preview and there's no way to get one yet, but now we know they're coming very soon!
  17. Like
    NatureTM got a reaction from GeekDoc in Reading the ADC from any pin   
    I'm assuming you don't have an interrupt service routine coded. Since you have the ADC interrupt enabled, when the ADC finishes, the cpu will exit LPM0 and the program will jump to where the ADC10 ISR should be. If there's nothing there, you'll get unexpected behavior. You could either put something in the interrupt vector, or don't enable the interrupt.
     
    Also, for "k = (ADC10MEM / 1024) * 8;" the ADC1MEM / 1024 is integer division, and the result is rounded down to the nearest whole number. The result of ADC1MEM / 1024 will always be between 0 and 1, but rounded down, so always 0. You can use algebra to change the code so it will work: "k = (ADC10MEM * 8) / 1024;" That answer will still be rounded down, but at least give a result from 0 to 8. "k = (char)((ADC10MEM / (float)1024) * 8 + 0.5);" will round appropriately, but will be slower.
     
    I've got some example code for the ADC10 I'll just copy over from my blog:
     

    #include "msp430g2231.h" #define ANALOG_PIN 1 unsigned int analogRead(){ ADC10CTL0 |= ADC10SC; while(ADC10CTL1 & ADC10BUSY); return ADC10MEM; } void analogPinSelect(unsigned int pin){ if(pin < 8){ ADC10CTL0 &= ~ENC; ADC10CTL1 = pin << 12; ADC10CTL0 = ADC10ON + ENC + ADC10SHT_0; } } void main(void){ unsigned int analogValue; DCOCTL = CALDCO_1MHZ; BCSCTL1 = CALBC1_1MHZ; WDTCTL = WDTPW + WDTHOLD; // read adc repeatedly analogPinSelect(ANALOG_PIN); while(1){ analogValue = analogRead(); } }
     
    You should be able to work off that example and get what you need.
  18. Like
    NatureTM reacted to zeke in TI buying National Semiconductor   
    Uhm... National Semiconductor != NXP Semiconductors
     
    If it did then this announcement would be even bigger than it is.
  19. Like
    NatureTM got a reaction from bluehash in TI buying National Semiconductor   
    Apparently the acquisition will amount to TI controlling 17% of the analog market. Unless there's quite a few chips that are exclusive to TI and National, it should be cool for now.
     
    It does look like National is pretty profitable and would be much more so if TI were to take over administrative operations:
     

    TI National SG&A % of revenue 10.9 19.3
    http://www.ti.com/corp/docs/investor/compinfo/ti-national-ir-presentation.pdf
     
    Despite what TI says, I doubt they will want to continue producing the National chips for too long. I would imagine they must be cannibalizing themselves on products for which both companies have an offering.
     
    Edit: Replaced "NXP" with "National." Thanks Zeke, I think I read misread NSC as NXP in that doc and just went with it.
  20. Like
    NatureTM reacted to bluehash in Parts Tracker   
    App looks snazzy.
  21. Like
    NatureTM reacted to RobG in TI introduces new line of value chips MSP430AF   
    The first chip in this line, MSP430AF0401, will be a major upgrade to the existing G value line.
    TI did not provide any official documentation, but our reliable sources at TI tell us that the chip will include:
     
    Same low price as G line chips
    Increased power supply range, 1.8V to 6V, allowing it to work directly with standard TTL and HCT.
    Same low power consumption as G line
    16k Flash
    A whopping 2k of RAM
    The all new 8ch ADC16 (yes, 16 bit samples!)
    Dual channel DAC16
    Three timers with 4 CCRs each (finally, enough timer to do what I want!)
    Timer C will be 32-bit and will have 8 CCRs (sweet!)
    An improved WDT with more intervals to choose from
    Two USART modules capable of SPI, I2C, UART (do I have to say more?)
    TI2P module, which uses new protocol (TI Interconnect Protocol) to communicate with new line of expander chips from TI (forget about 595, 164, 165, 24LC32, etc., everything stays in the family now.) The first chip, TI2P430AF595, will be similar to 595, but will come in 20-pin package, have 16 configurable outputs (8 sources and 8 drains!) capable of directly driving 8 x 8 matrices of LEDs or displays.
     
    There are also features which cannot be disclosed at this time, but they will sure make everybody very happy and surprised.
    A new development board is also scheduled to be released, LaunchPad AF, which will come with a new version of CCS, version 5, and will be available for Windows, Linux, and Mac OS X.
    The new board will cost $4.01!
  22. Like
    NatureTM reacted to Fe2o3Fish in Special TI eStore offers for Facebook critters   
    FYI, FWIW, IYGARA -- This just popped up on my Facebook feed:
     
    Interested in TI Microcontroller development tools? You
  23. Like
    NatureTM reacted to zeke in Addiction to buying parts   
    So, I'd like to bring to this topic a new entry for all of you that lust after electronic parts.
     
    I give you MDFLY.
     
    I just blew a wad of dough there. Excellent prices on SMD resistor kits and capacitor kits.
     
    Just check this out. It's a set of meter probes that let you measure SMD parts. How cool is that?!
     
    No one can touch them on what they offer. Not even Digikey.
     
    Okay, dealextreme could probably touch them but only because they're probably cousins or something.
  24. Like
    NatureTM got a reaction from sergeymkl in MD5 hashing in pure assembly   
    I liked that you picked a relatively complex project. Good work!
  25. Like
    NatureTM got a reaction from gatesphere in Arduino for the launchpad   
    I've got a couple snippets that are similar to arduino functions. I just assumed this stuff was already out there.
     
    Here's what I have for millis and delayMillis:
     

    #include "msp430g2231.h" #define MCLK_FREQUENCY 1000000 #define WDT_DIVIDER 512 const unsigned long WDT_FREQUENCY = MCLK_FREQUENCY / WDT_DIVIDER; volatile unsigned long wdtCounter = 0; unsigned long millis(){ return wdtCounter / ((float)WDT_FREQUENCY / 1000); } void delayMillis(unsigned long milliseconds){ // todo: handle rollover unsigned long wakeTime = wdtCounter + (milliseconds * WDT_FREQUENCY / 1000); while(wdtCounter < wakeTime); } void main(void){ DCOCTL = CALDCO_1MHZ; BCSCTL1 = CALBC1_1MHZ; WDTCTL = WDTPW + WDTTMSEL + WDTIS1; IE1 |= WDTIE; _BIS_SR(GIE); // toggle pin every second P1DIR |= BIT0; while(1){ P1OUT ^= BIT0; delayMillis(1000); } } #pragma vector=WDT_VECTOR __interrupt void watchdog_timer(void){ wdtCounter++; }
     
    And here's what I have for analogRead:
     

    #include "msp430g2231.h" #define ANALOG_PIN 4 unsigned int analogRead(){ ADC10CTL0 |= ADC10SC; while(ADC10CTL1 & ADC10BUSY); return ADC10MEM; } void analogPinSelect(unsigned int pin){ if(pin < 8){ ADC10CTL0 &= ~ENC; ADC10CTL1 = pin << 12; ADC10CTL0 = ADC10ON + ENC + ADC10SHT_0; } } void main(void){ unsigned int analogValue; DCOCTL = CALDCO_1MHZ; BCSCTL1 = CALBC1_1MHZ; WDTCTL = WDTPW + WDTHOLD; // read adc repeatedly analogPinSelect(ANALOG_PIN); while(1){ analogValue = analogRead(); } }
×
×
  • Create New...