Jump to content
43oh

oPossum

Members
  • Content Count

    925
  • Joined

  • Last visited

  • Days Won

    103

Reputation Activity

  1. Like
    oPossum reacted to pabigot in GCC optimization bug?   
    1 is an expression of type (signed) int, and shifting it 15 positions left overflows the representation of a signed int on the MSP430, producing undefined behavior allowing the compiler to do whatever it wants. 
    Try

    if (P2IN&SLAVE_DATA) value+=(1U<<i); and see if that works better for you. Also look for other cases where the same problem occurs. In most situations of left shift you want the value-to-be-shifted to be unsigned.
  2. Like
    oPossum got a reaction from dannyboy in MOSFET failures I can't explain   
    The gate of the STP16NF06 should be driven with at least 8 volts. See figure 6 in the spec sheet.
     
    There aren't many MOSFETs that can be directly driven by the MSP430.
  3. Like
    oPossum reacted to sn00p in 16 channel software PWM using a single timer   
    Well I never, I was offered a solution by somebody else....
     
    instead of:
    volatile TPWM *pa; // Active list entry the actual declaration should be:
    volatile TPWM * volatile pa; // Active list entry This fixes the issue.
  4. Like
    oPossum got a reaction from advaneharshal in tone generator on MSP430 g2553   
    /*     *** NOTE: THIS IS LICENSED (C)OPYRIGHTED SOFTWARE - DO NOT REMOVE THE FOLLOWING 20 LINES ***         Copyright (C) 2013  Kevin Timmerman     This program is free software: you can redistribute it and/or modify     it under the terms of the GNU General Public License as published by     the Free Software Foundation, either version 3 of the License, or     (at your option) any later version.     This program is distributed in the hope that it will be useful,     but WITHOUT ANY WARRANTY; without even the implied warranty of     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the     GNU General Public License for more details.     You should have received a copy of the GNU General Public License     along with this program.  If not, see <http://www.gnu.org/licenses/>         Revision History     ----------------     001 2013.05.10     Written for doomedeggplant who is to lazy to do his homework     */ #include <msp430.h> #include <stdint.h> static uint32_t gpi(unsigned n){     static const uint32_t nt[]={         0x19F10C37,0x1B7BF1E9,0x1D1E52F3,0x1ED994C9,0x20AF3220,0x22A0BC34,         0x24AFDC18,0x26DE542B,0x292E0191,0x2BA0DDCE,0x2E390075,0x30F8A0F2};     static const unsigned f=116;unsigned o=0;while(n<f)n+=12,++o;return nt[n-f]>>o; }static volatile uint32_t pi=0,pa=0; static volatile int32_t t; static void p(const uint8_t *b,const uint8_t*const e,int s,const uint8_t m){     while(P1IN&BIT3);t=10;while(b!=e){P1OUT&=~m;pa=pi=0;t+=13115L;while(t>0);         P1OUT|=m;pi=gpi(*;t+=32787L;while(t>0);b+=s;}P1OUT&=~m;pa=pi=0; }void main(void){     WDTCTL=WDTPW|WDTHOLD;DCOCTL=0;BCSCTL1=CALBC1_16MHZ;DCOCTL=CALDCO_16MHZ;     P1DIR=~BIT3&~BIT1;P1REN=BIT3;P1OUT=BIT2|BIT3;P1SEL=BIT4|BIT1;     TA0CCR0=(16000000L/(1L<<16))-1;TA0CTL=TASSEL_2|MC_1;     TA0CCTL0|=CCIE;_enable_interrupts();     for(;{static const uint8_t z[]="<=>?@ABCDEF"; p(z,z+sizeof(z)-1,1,BIT6);p(z+sizeof(z)-2,z-1,-1,BIT0);} } #pragma vector=TIMER0_A0_VECTOR __interrupt void timer_a0_isr(void){(pa&(1UL<<31))?(P1OUT|=BIT5):(P1OUT&=~BIT5);pa+=pi;--t;} Extra credit: http://forum.43oh.com/topic/2047-rtttl-ring-tone-text-transfer-language-player/?p=17515
  5. Like
    oPossum got a reaction from pine in [Aug-2013] TIDeals - EK-LM4F232 Development Board $30 Off   
    They should bundle it with a heat gun, solder paste, and a Tiva chip.
     
    "Some assembly required"
  6. Like
    oPossum got a reaction from GeekDoc in 15 channel PWM with async serial control   
    This is derived from 16 channel PWM with a single timer.
     
    The ISR has be extended to handle PWM and async serial reception. The first timer capture/compare is used for timing the serial bits and the second is used for PWM.
     
    This is the ISR...

    __interrupt void Timer0_A1(void) { static unsigned bit_mask = 0; // Serial rx data bitmask static unsigned rx_data; // Serial rx data // const unsigned x = TAIV; // Clear interrupt flag, get vector // if(x == 4) { // --- CCR2 - PWM P1OUT &= ~pa->port_off; // Port pins off P2OUT &= ~pa->port_off >> 8; // P1OUT |= pa->port_on; // Port pins on P2OUT |= pa->port_on >> 8; // pa = pa->next; // Next node in list TACCR2 = pa->time; // Update timer compare time // } else if(x == 2) { // --- CCR1 - Serial rx if(TACCTL1 & CAP) { // Start bit (capture mode) rx_data = 0; // Clear rx data bit_mask = 1; // Begin with bit 0 TACCTL1 &= ~CAP; // Switch from capture to compare mode TACCR1 += 2500; // Set timer for middle of first data bit } else { // Data/stop (compare mode) if(bit_mask & 0x0100) { // Stop bit? *head++ = rx_data; // Add rx data to ring buffer if(head >= &rx_buf[sizeof(rx_buf)/sizeof(rx_buf[0])]) head = rx_buf; TACCTL1 |= CAP; // Switch from compare to capture mode } else { // Data bit if(TACCTL1 & SCCI) rx_data |= bit_mask; // Update rx data bit_mask <<= 1; // Next data bit TACCR1 += 1667; // Set timer for middle of next bit } } } }
     
    The PWM code is unchanged, but now is only executed when the interrupt vector indicates capture/compare 2 match.
    The serial code begins in capture mode. When a falling edge is detected the mode is changed to compare to sample in the middle of each data bit and the stop bit. A ring buffer is used to prevent loss of received data.
     
    Two test cases are provided. The first allows the brightness of the Lauchpads LED to be set using 0 to 9 and a to j.
    The second test case implements a simple serial protocol to set the PWM value of all 15 outputs. The packet format is...
    0x55 0xAA PWM0 PWM1 ...... PWM13 PWM14 Checksum
    Addressing could easily be added to allow multiple MSP430 on the same serial line.
     
    Since this code uses only a single TimerA module, it can run on any MSP430 with a TimerA.
     

    #include "msp430g2553.h" #include "string.h" typedef struct { // PWM ISR linked list node struct unsigned time; // Time for on/off action to occur unsigned port_off; // Port pins to turn off unsigned port_on; // Port pins to turn on void *next; // Next node in linked list } TPWM; // TPWM pw[16], *pi; // Array and inactive list head volatile TPWM *pa; // Active node unsigned char rx_buf[32]; unsigned char *head, *tail; void pwm_set(const unsigned pin, const unsigned time) { const unsigned mask = 1 << pin; // const unsigned tm = time & 0xFF00; // Limit closeness of entries TPWM *b, *p, *n; // // // -- Try to find existing active node for this pin for(b = &pw[0], p = b->next; p != &pw[0]; b = p, p = b->next) { if(p->port_off & mask) { // Found it if(p->time == tm) return; // - Time is the same, nothing to do, return... while(pa != p); // Wait for this node to be active while(pa == p); // Wait for this node to become inactive // Safe to remove now if(p->port_off == mask) { // - Node is only used for this pin, remove it b->next = p->next; // Remove link p->next = pi; // Add to inactive list pi = p; // } else { // - Node is used for multiple pins p->port_off &= ~mask; // Remove this pin from the node } // break; // Found the pin, so stop searching } // } // // - Update first node in list if(tm == 0) { // If time is 0, turn off and return pw[0].port_on &= ~mask; // pw[0].port_off |= mask; // return; // } else { // If time is non-zero, turn on pw[0].port_on |= mask; // pw[0].port_off &= ~mask; // if(time == 0xFFFF) return; // If max, no need to turn off, so return } // // // Find where the new turn off node will go for(b = &pw[0], p = b->next; p != &pw[0]; b = p, p = b->next) if(p->time >= tm) break; // Stop when an entry of >= time is found // if(p->time == tm) { // If same time, use existing node p->port_off |= mask; // Add this pin return; // All done... } // // n = pi; // Get a node from the inactive list pi = n->next; // // n->port_off = mask; // Setup new node n->port_on = 0; // n->time = tm; // // n->next = p; // Insert node in to active list b->next = n; // } void pwm_init(void) { unsigned n; memset(pw, 0, sizeof(pw)); // Clear entire array pa = &pw[0]; // Active list always begins with first array element pa->next = &pw[0]; // Begin with only 1 node in list pi = &pw[1]; // First inactive node is second array element for(n = 1; n < sizeof(pw)/sizeof(TPWM) - 1; ++n) // Link the inactive nodes pw[n].next = &pw[n + 1]; // // TACTL = TASSEL_2 + MC_2 + ID_0; // Setup timer, continuous mode, SMCLK/1 TACCTL2 = CCIE; // Enable timer interrupt _EINT(); // Enable interrupts } #pragma vector = TIMER0_A1_VECTOR __interrupt void Timer0_A1(void) { static unsigned bit_mask = 0; // Serial rx data bitmask static unsigned rx_data; // Serial rx data // const unsigned x = TAIV; // Clear interrupt flag, get vector // if(x == 4) { // --- CCR2 - PWM P1OUT &= ~pa->port_off; // Port pins off P2OUT &= ~pa->port_off >> 8; // P1OUT |= pa->port_on; // Port pins on P2OUT |= pa->port_on >> 8; // pa = pa->next; // Next node in list TACCR2 = pa->time; // Update timer compare time // } else if(x == 2) { // --- CCR1 - Serial rx if(TACCTL1 & CAP) { // Start bit (capture mode) rx_data = 0; // Clear rx data bit_mask = 1; // Begin with bit 0 TACCTL1 &= ~CAP; // Switch from capture to compare mode TACCR1 += 2500; // Set timer for middle of first data bit } else { // Data/stop (compare mode) if(bit_mask & 0x0100) { // Stop bit? *head++ = rx_data; // Add rx data to ring buffer if(head >= &rx_buf[sizeof(rx_buf)/sizeof(rx_buf[0])]) head = rx_buf; TACCTL1 |= CAP; // Switch from compare to capture mode } else { // Data bit if(TACCTL1 & SCCI) rx_data |= bit_mask; // Update rx data bit_mask <<= 1; // Next data bit TACCR1 += 1667; // Set timer for middle of next bit } } } } unsigned char get_rx(void) { const unsigned char c = *tail++; if(tail >= &rx_buf[sizeof(rx_buf)/sizeof(rx_buf[0])]) tail = rx_buf; return c; } void protocol(void) { static unsigned state = 0; unsigned n; unsigned char pwm[15]; unsigned char checksum; unsigned char c; for(; { c = get_rx(); switch(state) { case 0: // First byte of packet must be 0x55 if(c == 0x55) ++state; break; case 1: // Second byte of packet must be 0xAA if(c == 0xAA) { n = 0; checksum = 0; ++state; } else { state = 0; } break; case 2: // Get 15 PWM bytes pwm[n++] = c; checksum += c; if(n >= 15) ++state; break; case 3: // Get checksum if(c == checksum) { // Update PWM if checksum is valid for(n = 0; n < 15; ++n) { pwm_set((n < 2) ? n : n + 1, (unsigned)pwm[n] << 8); } } state = 0; // Next packet break; } } } void main(void) { unsigned char c; WDTCTL = WDTPW | WDTHOLD; // Disable watchdog DCOCTL = 0; // Run at 16 MHz BCSCTL1 = CALBC1_16MHZ; // DCOCTL = CALDCO_16MHZ; // P1OUT = P2OUT = 0; // P1DIR = 0xFF ^ BIT2; // P1.2 is serial in, all other output P1SEL = BIT2; // Enable capture interrupt P2SEL = 0; // Allow P2.6 and P2.7 to be used as GPIO P2DIR = 0xFF; // Enable all P2 pins as output pwm_init(); // Initialize software PWM TACCTL1 = CM_2 | CAP | CCIE; // Enable capture on falling edge head = tail = rx_buf; // Init rx ring buffer pointers #if 0 protocol(); // Serial control of all 15 PWM outputs #else for(; { // Control LP LEDs with 0-9 and a-j if(head != tail) { c = get_rx(); if(c >= '0' && c <= '9') { pwm_set(0, (c - '0') * 7000); } else if(c >= 'a' && c <= 'j') { pwm_set(6, (c - 'a') * 7000); } } } #endif }
  7. Like
    oPossum got a reaction from vintilatimea in Interfacing with DHT11 Humidty + Temp sensor   
    This code will display the DHT11 hex data, and humidity and temperature in decimal.
    It uses software UART so it will work on all versions of the Launchpad.
    DHT11 is connect to P1.4



     
    #include <msp430.h> #include <stdlib.h> volatile unsigned txdata = 0; #pragma vector = TIMER0_A0_VECTOR __interrupt void Timer0_A0(void) { if(txdata) { (txdata & 1) ? (CCTL0 &= ~OUTMOD2) : (CCTL0 |= OUTMOD2); txdata >>= 1; CCR0 += 104; } else { CCTL0 &= ~CCIE; } } void putc(const char c) { while(CCTL0 & CCIE); txdata = 0x0200 | (c << 1); CCR0 = TAR + 16; CCTL0 = OUTMOD0 | CCIE; } void print(const char *s) { while(*s) putc(*s++); } void print_hex_digit(unsigned n) { putc("0123456789ABCDEF"[n & 0x0F]); } void print_hex_byte(unsigned n) { print_hex_digit(n >> 4); print_hex_digit(n); } void print_dec2(int n) { // Print 2 decimal digits 0 to 99 const div_t d = div(n, 10); if(d.quot) putc('0' + d.quot); putc('0' + d.rem); } int read_dht(unsigned char *p) { // Note: TimerA must be continuous mode (MC_2) at 1 MHz const unsigned b = BIT4; // I/O bit const unsigned char *end = p + 6; // End of data buffer register unsigned char m = 1; // First byte will have only start bit register unsigned st, et; // Start and end times // p[0] = p[1] = p[2] = p[3] = p[4] = p[5] = 0; // Clear data buffer // P1OUT &= ~b; // Pull low P1DIR |= b; // Output P1REN &= ~b; // Drive low st = TAR; while((TAR - st) < 18000); // Wait 18 ms P1REN |= b; // Pull low P1OUT |= b; // Pull high P1DIR &= ~b; // Input // st = TAR; // Get start time for timeout while(P1IN & if((TAR - st) > 100) return -1; // Wait while high, return if no response et = TAR; // Get start time for timeout do { // st = et; // Start time of this bit is end time of previous bit while(!(P1IN & ) if((TAR - st) > 100) return -2; // Wait while low, return if stuck low while(P1IN & if((TAR - st) > 200) return -3; // Wait while high, return if stuck high et = TAR; // Get end time if((et - st) > 110) *p |= m; // If time > 110 us, then it is a one bit if(!(m >>= 1)) m = 0x80, ++p; // Shift mask, move to next byte when mask is zero } while(p < end); // Do until array is full // p -= 6; // Point to start of buffer if(p[0] != 1) return -4; // No start bit if(((p[1] + p[2] + p[3] + p[4]) & 0xFF) != p[5]) return -5; // Bad checksum // return 0; // Good read } void main(void) { unsigned char dht[6]; // Data from DHT11 int err; // unsigned n; // // WDTCTL = WDTPW | WDTHOLD; // Disable watchdog reset DCOCTL = 0; // Run at 1 MHz BCSCTL1 = CALBC1_1MHZ; // DCOCTL = CALDCO_1MHZ; // CCTL0 = OUT; // Setup serial tx I/O P1SEL = BIT1; // P1DIR = BIT1; // TACTL = TASSEL_2 | MC_2; // TimerA SMCLK, continuous __enable_interrupt(); // // for(; { // for-ever while(CCTL0 & CCIE); // Wait for any serial tx to finish err = read_dht(dht); // Read DHT11 if(err) { // If error... print("Error -"); // putc('0' - err); // print("\r\n"); // } else { // No error... for(n = 0; n < sizeof(dht); ++n) { // Show hex data print_hex_byte(dht[n]); // putc(' '); // } // print(" "); // print_dec2(dht[1]); // Show humimidy print(" RH "); // print_dec2(dht[3]); // Show temperature print(" C\r\n"); // } // __delay_cycles(1000000); // Wait a while } // }  
     
  8. Like
    oPossum reacted to bluehash in TI Back to School Promotion   
    TI just emailed me about a promotion they are going to run in the coming weeks. Make sure you check their site and facebook pages.
     
    Week 1: MSP430 LaunchPad - $6.99

    Week 2: MSP-SA430-SUB1GHZ
  9. Like
    oPossum reacted to dubnet in CC430 Kits Need TLC - Free to Caring Members   
    Rats!  So close but yet so far.....  :grin:
  10. Like
    oPossum reacted to ike in autorouting for custom PCB   
    http://en.wikipedia.org/wiki/Travelling_salesman_problem
  11. Like
    oPossum got a reaction from PTB in [Aug-2013] TIDeals - EK-LM4F232 Development Board $30 Off   
    They should bundle it with a heat gun, solder paste, and a Tiva chip.
     
    "Some assembly required"
  12. Like
    oPossum reacted to HanzZ in QSimKit - MSP430 simulator   
    Hi,
     
    as my diploma thesis I'm writting MSP430 simulator called QSimKit. It's not finished yet, but it's in state when it's starting to be useful and I would like to get more people to test it, share their opinions, find bugs and basically to create community of people interested in MSP430 simulation.
     
    Releases:
    Version 0.0.3 (2014-02-04), Changelog At first some facts about QSimKit:
    It's written under GPLv2+ in C++/Qt, has been tested on Linux or Windows together with msp430gcc. It supports peripherals (as plugins) written in C++ or Python. Currently there's LED, oscillator, button and HD44708 LCD (not fully implemented yet). MCUs are plugins too and theoretically it's possible to add support for more MCUs (not just MSP430). It can support all MSP430 variants, but only few are supported right now, because I haven't created package data for all MSP430 variants yet. In graphical user interface (Check screenshot), you can do following:
    Add peripherals, connect them to MCU. See the source code of program you are simulating together with Dwarf debugging data (you can see the value of local variables for example) and current instruction. Step the simulation, add breakpoints based on PC register or value of memory. Track pins in oscilloscope-like view. See the registers and other important values from MCU (frequency, BasicClock registers, ...) MSP430 MCU plugin can do following:
    Load ELF/A43 code. Supports all instructions. Supports BasicClock module (TImerA/TimerB). Support for USCI-SPI [NEW in 0.0.3] Support for USART-SPI [NEW in 0.0.3] Initial USI support (just SPI mode). Peripherals:
    Button LCD - HD44708 (only initial support) LED Crystal Oscillator SD Card (only initial support) [NEW in 0.0.2]  
    As I stated earlier, it's not finished yet, but some testers to help me testing are welcome. I can also help anyone who would like to help with development. There is no development documentation yet, but if you tell me what you would like to do, I can write relevant docs to help you.
     
    If you think you have found a bug or you have some feature request, please create ticket on GitHub, I don't want this forum thread to be an issue tracker. You can also find me on IRC in #qsimkit at freenode or as HanzZ in #43oh channel.
  13. Like
    oPossum got a reaction from xpg in [Aug-2013] TIDeals - EK-LM4F232 Development Board $30 Off   
    They should bundle it with a heat gun, solder paste, and a Tiva chip.
     
    "Some assembly required"
  14. Like
    oPossum got a reaction from dubnet in [Aug-2013] TIDeals - EK-LM4F232 Development Board $30 Off   
    They should bundle it with a heat gun, solder paste, and a Tiva chip.
     
    "Some assembly required"
  15. Like
    oPossum got a reaction from Rickta59 in [Aug-2013] TIDeals - EK-LM4F232 Development Board $30 Off   
    They should bundle it with a heat gun, solder paste, and a Tiva chip.
     
    "Some assembly required"
  16. Like
    oPossum got a reaction from spirilis in [Aug-2013] TIDeals - EK-LM4F232 Development Board $30 Off   
    They should bundle it with a heat gun, solder paste, and a Tiva chip.
     
    "Some assembly required"
  17. Like
    oPossum got a reaction from roadrunner84 in LCD library in Assembly   
    The mask is needed when RRA is used. Bit 15 is unmodified for both the 8 and 16 bit forms. It does not shift in a zero anywhere.
     
    CLC / RRC.B could be used to shift in zero bits.
     
    The 20 bit MSP430 have a limited barrel shift of up to 4 bits.
  18. Like
    oPossum got a reaction from Hex in simple stepper control   
    #pragma vector = TIMER0_A0_VECTOR
    __interrupt void Timer0_A0 (void)              // Timer0 A0 interrupt service routine
    {
        static const uint8_t steps[8] = {
    #if 0   // Full step
            BIT0 | BIT1,
            BIT0 | BIT1,
                   BIT1 | BIT2,
                   BIT1 | BIT2,
                          BIT2 | BIT4,
                          BIT2 | BIT4                               
            BIT0 |               BIT4,
            BIT0 |               BIT4
    #else   // Half step
            BIT0 | BIT1,
                   BIT1,
                   BIT1 | BIT2,
                          BIT2,
                          BIT2 | BIT4,
                                 BIT4,
            BIT0 |               BIT4,
            BIT0
    #endif
        };
        static unsigned step = 0;
        
        P1OUT = (P1OUT & ~(BIT0 | BIT1 | BIT2 | BIT4)) | steps[7 & step++];
    }

     
  19. Like
    oPossum reacted to bluehash in Simulating a TI calculator with crazy 11-bit opcodes   
    .. Via reddit:
    http://files.righto.com/calculator/TI_calculator_simulator.html
  20. Like
    oPossum got a reaction from RobG in JustPad   
    The idea is that you only install what is needed for a specific application - it would rarely be fully populated. It is intentionally all thru-hole so anyone can assemble it.
  21. Like
    oPossum reacted to simpleavr in JustPad   
    I am sure the smd way is easier for many of us. It may not be true though for someone starting w/ a radio shack iron and w/o knowledge / access of flux, solder paste, tweeters, magnifying glasses, etc. It's easier for pcb makers to go smd as drilling is not desired. But I would imagine a beginner would start w/ a $10 iron + tube of solder kit. Thru hole will appeal to them.
     
    The bbusb ready 2" x 2" board would even be better and again you can populate according to your needs on different projects, doesn't need to usb.
     
    http://forum.43oh.com/topic/2962-bit-bang-usb-on-msp430g2452/?p=31708
     
    I wonder what oPossum's board looks like, there were 19 downloads on the eagle files so I would imagine someone had it fabricated. If that is so, please post picture on the physical object.
  22. Like
    oPossum got a reaction from roadrunner84 in JustPad   
    The idea is that you only install what is needed for a specific application - it would rarely be fully populated. It is intentionally all thru-hole so anyone can assemble it.
  23. Like
    oPossum got a reaction from OppaErich in Yep... Just yep... :)   
    Only on the Ohms scale.
  24. Like
    oPossum got a reaction from bluehash in Yep... Just yep... :)   
    Only on the Ohms scale.
  25. Like
    oPossum reacted to cde in Neat ws2811 "Water Torture" effect   
    Not 430, but the video made it look very cool.
     

     
    Source code available
    http://rurandom.org/justintime/index.php?title=WS2811_%22Water_torture%22
    https://github.com/DannyHavenith/ws2811/blob/master/src/water_torture.hpp
×
×
  • Create New...