Jump to content
43oh

mbeals

Members
  • Content Count

    347
  • Joined

  • Last visited

Reputation Activity

  1. Like
    mbeals got a reaction from bluehash in Laser Controller   
    I'm finishing up the design of a project for school, and since it is MSP430 based, figured I would share it.
     
    The board is designed to be a controller for a DPSS laser.  The laser takes 5V power, 2 digital inputs (enable and trigger) and provides two analog voltage outputs (diode current and diode temperature).
     
    The controller is designed using the MSP430F5172 and has the following features:
     
    1. CLI control over either RS232 or BT serial port.
    2. External interlock to control laser enable line.  Interlock is monitored by MCU and can be bypassed
    3. Breakout for front panel control: 7 3V, debounced GPIO pins plus I2C bus.
    4. Header for HD44780 20x4 LCD connected to MCU via I2C port expander.
    5. Triggering can be performed by an internally generated signal or from an external source.
    6.  Expansion port to enable the addition of hardware pulse delay circuitry
    7.  External trigger output, with programmable phase delay from main laser trigger
    8.  All external connections (RS232, trigger, interlock) on independent (isolated) grounds to protect against ESD and provide ground loop isolation
     
    I chose the F5172 for it's 5V tolerant inputs but I'm hoping to be able to implement a sort of digital PLL using the TimerD perhip and its high resolution mode so that I can read an external trigger signal and output a phase delayed version to the laser.  We use this laser with a high speed holography system and typically trigger the laser with a TTL off of the cameras...but due to line latency need to tweak the timings to get them to line up.  I wasn't sure if I could hit the resolution I needed, so I added the expansion port to make it easy to upgrade the system.
     
    I still need to do a final design check on it and fix some resistor values, but plan on shipping it off to fab soon.
    pcb.brd
    pcb.sch


  2. Like
    mbeals reacted to Rickta59 in 1K serial gdb_bootloader   
    I'm actively optimizing this as we speak. I only started on this Thursday and posted what I had late Friday. It was 1950 bytes the first pass. But I was so excited about this I just had to share. Saturday, I spent the day on it and got the code size down to less than 1k. 
    The code is written in C++ using my fabooh framework. I've been trying to find a good app to use as the fabooh debut project. I think this will be it. This type of code needs to be small but needs the flexibility to use the various UART implementations. This code personifies what fabooh does well. So expect to see it real soon now, in the fabooh source tree.
     
    You can get yourself in a good position to use this code if you grab fabooh from github.com and take a look at it. https://github.com/RickKimball/msp430_code
    .
    Yes, I do check to see if there is code at 0xc000. If the memory contains 0xff, then I know the chip is erased and I automatically start the bootloader. If there is an instruction at 0xc000, then I actually check for the button state. 
    Originally, I had the ability to launch the newly added program using the gdb 'continue' command. However, for code size reasons, I took it out. I was also concerned that by having the ability to 'continue' people might get confused and think that it can do debugging. Which it can't.
     
    To do what you want is possible.
     
    -rick
  3. Like
    mbeals reacted to Rickta59 in 1K serial gdb_bootloader   
    Inspiration:
    So I'm looking at making a small msp430fr5739 based board. I was thinking that I would be able to use the msp430 launchpad to program them. However, I hit a snag in that they don't seem to recognize the msp430fr5739 as a valid device. I can use my FRAM boards to program them but not the $10 launchpad. Then there was all the hubbub about the new msp430g2955 chips and it got me thinking. Why should I let Texas Instruments determine how I program my chips?

    Investigation:
    I got to looking at BSL and then got discouraged trying to find a client that works on windows, linux and OSX. It mostly seemed like it was going to be a hassle. Then I got to thinking about just using GDB and its Remote Serial Protocol. If you use msp430-gdb and mspdebug, you use this interface over a local server socket. However, an often unnoticed feature of this protocol is that it can also be used with a regular serial port.

    Solution:
    I decided to implement a gdb stub server that you load once on your msp430 chip. You can think of it as a bootloader that happpens to use the Remote Serial Protocol. This allows you to load new programs on that chip without the need for a launchpad or an FET. All you need is a usb->serial port dongle. You can find these on ebay from $2-$10. They all go faster than the 9600 baud the virtual serial port the msp430 launchpad provides. It is likely you probably have one of these already. This scheme doesn't allow you to debug using msp430-gdb, but it does provide a way to load new code without having to deal with BSL or having to write any host side code.

    How it works:
    This version targets the msp430g2553 so that people can easily try it out. I'm guessing that most people don't have an msp430fr5739.  Load the attached code below to an msp430g2553 using your launchpad one time. At this point, you could remove that chip from your launchpad and throw it on a breadboard. You just need power, the caps and a pull up resistor. Then connect TX and RX to a serial to USB converter (ftdi, cp102, pl2303hx, etc..). For simplicity, we can just test with the launchpad itself and ignore the fact that there is an FET on the board and just use /dev/ttyACM0 or COM1: on windows.

    At reset time, the code looks at the state of the P1.3 button on the msp430g2553. If you are holding it down, the code starts a gdb bootload/server running on the msp430g2553. On your linux box, just start up msp430-gdb to connect to the chip over a serial port. You can't debug, but what you can do is erase your flash and load a new program. The gdb server code sits at memory 0xfa00 -> 0xfdff so you do lose some of your flash. *I've done some optimization see later posts in this thread *


    Loadable hex file:
    The gdb_bootloader.hex file from the zip file must be loaded on an msp430g2553. I'll post code and support for other chips at a later date. I'm excited about this concept and wanted to let people try it out.

    To load the gdb_stub firmware ( do this one time )
    $ mspdebug rf2500 "prog gdb_bootloader.hex" MSPDebug version 0.21 - debugging tool for MSP430 MCUs Copyright (C) 2009-2012 Daniel Beer <dlbeer@gmail.com> This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Trying to open interface 1 on 057 rf2500: warning: can't detach kernel driver: No data available Initializing FET... FET protocol version is 30066536 Set Vcc: 3000 mV Configured for Spy-Bi-Wire fet: FET returned error code 4 (Could not find device or device not supported) fet: command C_IDENT1 failed fet: identify failed Trying again... Initializing FET... FET protocol version is 30066536 Set Vcc: 3000 mV Configured for Spy-Bi-Wire Sending reset... Device ID: 0x2553 Code start address: 0xc000 Code size : 16384 byte = 16 kb RAM start address: 0x200 RAM end address: 0x3ff RAM size : 512 byte = 0 kb Device: MSP430G2553/G2403 Number of breakpoints: 2 fet: FET returned NAK warning: device does not support power profiling Chip ID data: 25 53 Erasing... Programming... Writing 970 bytes at fa00... Writing 32 bytes at ffe0... Done, 1002 bytes total OK. Once you have that installed, you no longer need to use your launchpad to load new code. To load programs on your chip now, just connect a usb->serial dongle up to the msp430g2553 directly and connect to that via msp430-gdb. Here are the steps to load a blink program using msp430-gdb via the serial port:
    $ msp430-gdb blink.elf GNU gdb (GDB) 7.2 Copyright (C) 2010 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "--host=i686-pc-linux-gnu --target=msp430". For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>... Reading symbols from /home2/kimballr/github/msp430_code/fabooh/examples/basic/blink/blink.elf...done. (gdb) set remotebaud 9600 (gdb) target remote /dev/ttyACM0 Remote debugging using /dev/ttyACM0 _reset_vector__ () at ../../../gcc/gcc/config/msp430/crt0.S:103 103 ../../../gcc/gcc/config/msp430/crt0.S: No such file or directory. in ../../../gcc/gcc/config/msp430/crt0.S (gdb) erase Erasing all flash memory complete (gdb) load Loading section .text, size 0x96 lma 0xc000 Loading section .vectors, size 0x20 lma 0xffe0 Start address 0xc000, load size 182 Transfer rate: 264 bytes/sec, 16 bytes/write. (gdb) quit A debugging session is active. Inferior 1 [Remote target] will be killed. Quit anyway? (y or n) y OK, now there are two things on your msp430g2553 chip. At 0xfa00 there is the boot loader, it is run first before your blink.elf code. It checks the button to see if you are holding it down. If not, then it runs the blink.elf code. If you are holding it down, it runs the gdb server instead and allows you to reload code. So just press reset to start the blink. Press and hold the P1.3 switch down and press reset to start the gdb stub server.

    Pretty simple huh? I think so.

    -rick

    The files in the attached zip only work with the msp430g2553 at this time:

    [Edit: Updated version 04-07-2013 3:43 PM]


    Source Code:
    ... fast track to how to get started ...

    http://forum.43oh.com/topic/3661-1k-serial-gdb-bootloader/?p=33112

    I'm actively optimizing this code. I only started on this project on Thursday and posted what I had late Friday. It was 1950 bytes the first pass. But I was so excited about this concept, I just had to share. Saturday, I spent the day on it and got the code size down to less than 1k.

    The code is written in C++ using my fabooh framework. I've been trying to find a good app to use as the fabooh debut project. I think this will be it. This type of code needs to be small but needs the flexibility to use various UART implementations. This code personifies what fabooh does well. So expect to see it real soon now, in the fabooh source tree.

    You can get yourself in a good position to use this code if you grab fabooh from github.com and take a look at it. https://github.com/RickKimball/msp430_code
  4. Like
    mbeals got a reaction from bluehash in Contest : Show off your Avatars   
    I'm in and here's my submission:
     

     
    I however cannot get it to animate in the post...please click to see it in action
  5. Like
    mbeals reacted to GG430 in Decoding TI's pin packages   
    True, this is kind of a confusing system. cde captured your examples. MSP430 specific there are a couple others.
     
    MSP430F2274IDA
    MSP430F2274IDAT
    MSP430F2274IDAR
     
    MSP430F2274TDA
    MSP430F2274TDAT
    MSP430F2274TDAR
     
    DA = Package (http://www.ti.com/sc/docs/psheets/mechanic.htm)
    I/T = -40 to 85 DEG C / -40 to 105 DEG C
    S = Special Temp Range, like MSP430L092SPW is 0 to 50 DEG C
     
    _/T/R = Tube or Tray delivery / Mini Reel 250 pcs. / Large Reel, depends on package size, usually 2500 pcs.
     
    MSP430F2274MDATEP
     
    M = Military -55 to 125 DEG C
    EP = Enhanced Product
    Q1 = Q100 Automotive Qualified
     
    The MSP430s are all lead free, therefore no differentiation.
     
     
  6. Like
    mbeals reacted to cde in Decoding TI's pin packages   
    http://focus.ti.com/quality/docs/gencontent.tsp?templateId=5909&navigationId=11753&contentId=5055
     
    E4 and g4 refer to lead free packaging and molding options (see link).
     
    R is normally for Large Tape & Reel (3000) vs the non-r 250 reel.
     
    And they used to have some for temperature rating, but they pretty much phased those out a few years ago.
  7. Like
    mbeals got a reaction from GeekDoc in Contest : Show off your Avatars   
    Someone should enter @@LariSan into this.
  8. Like
    mbeals got a reaction from bluehash in Seeed - Free $10 coupon with PCB order - good until 1/20   
    I just ordered a set of boards with my free coupon and it went through without a problem.  Looks like the issue is fixed.
  9. Like
    mbeals reacted to oPossum in Implementing clock delay   
    Looks good. 74AHC164 may be a better choice for this application - it doesn't have the output latch that is not needed and just adds more latency. The delay per stage is 62.5 nS -  everything is on the same clock. tpd is simply one limiting factor for max clock rate.
  10. Like
    mbeals got a reaction from tingo in Multidrop UART   
    Nope that's the right part.  For all intents and purposes RS422 is equivalent to full duplex RS485.  Half duplex RS485 is a single set of differential pairs.  RS422 just adds a second pair (4 wires total) with one pair handling RX and the other TX.  There are some minor differences between the two standards, but for a device like this, they shouldn't be an issue. 
  11. Like
    mbeals got a reaction from pine in Is it just me or tonight TI doubled LaunchPad price?   
    huh...I never made that connection...$4.30 => 430
  12. Like
    mbeals reacted to bluehash in Coders needed - Free Hardware   
    Update 4/28/2013 - Boards arrived.
     
    Hi Everyone,
    4DSystems approached 43oh if any of its members are interested in coding up examples for their Intelligent Display Module with the MSP430 Launchpad. In return you get the display for free. The display is intelligent and comes with its own software to program it. The LP will just send it data eg. sensor data. That's what I get from it.
    I'll also be asking them for some displays for giveaways.
     
     
    This is open for members with >=100 Reputation points. You can see your points in any post that you make on the left side, in your profile.
     
    Just list your name here if you are interested. I'll ask again if you are "really" interested once the displays are ready to ship. You may also need to make sure you have time for this. It should not just sit on your desk. You may ask questions too. This is the first time this is being tried out, so ask away.
    List: 1.  2.  

  13. Like
    mbeals reacted to oPossum in Implementing clock delay   
    Use timer capture to determine exactly when the source pulse occurred and then use timer compare to recreate the pulse some exact time later. There will be a minimum delay due to ISR latency and the time it takes to setup the timer compare, probably less than 50 cycles. The max delay would be aprox 65480 cycles.
  14. Like
    mbeals got a reaction from OppaErich in Is it just me or tonight TI doubled LaunchPad price?   
    huh...I never made that connection...$4.30 => 430
  15. Like
    mbeals got a reaction from chemuduguntar in debugging UART communications   
    If i'm reading that right, you are using the TX isr to trigger the same isr in rapid succession....not sure of the implications of that.  The original code also did not wait for the TX buffer to be ready for writing.  I think if you move the loop to main and make your transmit function wait for the buffer, it might work better.
     
    try something like:
     
    void transmit_char(int pos) {        while (! (UCA0TXIFG & IFG2));         UCA0TXBUF = pi[pos];  }  
    and call it inside main.
     
    In psuedo code:
     

    interrupt(USCIAB0TX_VECTOR) uart_transmit_isr() {     P1OUT ^= BIT6 | BIT0; }   void main() {     WDTCTL = WDTPW + WDTHOLD;       // configure clocks     DCOCTL = CALDCO_16MHZ;     BCSCTL1 = CALBC1_16MHZ;       // i/o     P1DIR = BIT6 | BIT0;     P1OUT = 0x00;       P1SEL |= BIT1 | BIT2;     P1SEL2 |= BIT1 | BIT2;       // initialise usci     UCA0CTL1 |= UCSSEL_2; // hold reset, set smclk     UCA0BR0 = 0x82;     UCA0BR1 = 0x06;     UCA0MCTL = UCBRS2 | UCBRS1;       UCA0CTL1 &= ~(UCSWRST);       IE2 |= UCA0TXIE;       __enable_interrupt();      //Transmit the chars    while(1)    {     transmit_char(pos);     pos++;         if (pi[pos] == '\0') pos = 0;    }   }
  16. Like
    mbeals reacted to DanAndDusty in ADC10 Speed tests using hardware UART   
    Hi all,
     
    Here is a little snippet of code I wrote to test the speed of the ADC10 at a variety of settings, and also to discover just how easy using the hardware UART turned out to be. I used the 2553 as it has a hardware UART.
     
    It sets the MCLK to a variety of speeds (I used CCS to read the calibration constants in the flash and coded them into the program). Then counts the number of samples that can be taken in 1 second using all the possible values for the SHT bits.
     
    The details are then written out to the UART at 9600 so I can see how speed affects the number of samples per second. To verify that the SHT settings are sufficient I also display the max/min readings taken. I had a potentiometer connected VCC/GND to pin P1.4 (INCH4).. Testing with different resistors between the POT and INCH4 I found that it wasn't until about 10K ohms that the ADC couldn't read the max Voltage at the fastest SHT settings.
     
    These are the readings I got

    Using Speed 1MHz Using ADC10SHT_0 (x4) There were 15,031 samples per sec - readings range from [1,020] to [1,023] There were 15,030 samples per sec - readings range from [1,018] to [1,023] There were 15,031 samples per sec - readings range from [1,020] to [1,023] There were 15,031 samples per sec - readings range from [1,020] to [1,023] There were 15,031 samples per sec - readings range from [1,020] to [1,023] Using ADC10SHT_1 (x8) There were 15,031 samples per sec - readings range from [1,020] to [1,023] There were 15,031 samples per sec - readings range from [1,018] to [1,023] There were 15,031 samples per sec - readings range from [1,020] to [1,023] There were 15,031 samples per sec - readings range from [1,020] to [1,023] There were 15,031 samples per sec - readings range from [1,020] to [1,023] Using ADC10SHT_2 (x16) There were 15,030 samples per sec - readings range from [1,018] to [1,023] There were 15,030 samples per sec - readings range from [1,019] to [1,023] There were 15,030 samples per sec - readings range from [1,018] to [1,023] There were 15,031 samples per sec - readings range from [1,018] to [1,023] There were 15,030 samples per sec - readings range from [1,018] to [1,023] Using ADC10SHT_3 (x64) There were 15,030 samples per sec - readings range from [1,017] to [1,023] There were 15,030 samples per sec - readings range from [1,017] to [1,023] There were 15,030 samples per sec - readings range from [1,017] to [1,023] There were 15,030 samples per sec - readings range from [1,017] to [1,023] There were 15,030 samples per sec - readings range from [1,017] to [1,023] Using Speed 8MHz Using ADC10SHT_0 (x4) There were 120,640 samples per sec - readings range from [1,018] to [1,023] There were 120,408 samples per sec - readings range from [1,018] to [1,023] There were 120,308 samples per sec - readings range from [1,018] to [1,023] There were 120,420 samples per sec - readings range from [1,018] to [1,023] There were 119,489 samples per sec - readings range from [1,018] to [1,023] Using ADC10SHT_1 (x8) There were 122,614 samples per sec - readings range from [1,017] to [1,023] There were 122,614 samples per sec - readings range from [1,017] to [1,023] There were 122,615 samples per sec - readings range from [1,017] to [1,023] There were 122,615 samples per sec - readings range from [1,017] to [1,023] There were 122,614 samples per sec - readings range from [1,017] to [1,023] Using ADC10SHT_2 (x16) There were 113,886 samples per sec - readings range from [1,016] to [1,023] There were 113,886 samples per sec - readings range from [1,017] to [1,023] There were 113,885 samples per sec - readings range from [1,016] to [1,023] There were 113,885 samples per sec - readings range from [1,016] to [1,023] There were 113,885 samples per sec - readings range from [1,016] to [1,023] Using ADC10SHT_3 (x64) There were 50,897 samples per sec - readings range from [1,015] to [1,023] There were 50,897 samples per sec - readings range from [1,013] to [1,023] There were 50,897 samples per sec - readings range from [1,013] to [1,023] There were 50,896 samples per sec - readings range from [1,016] to [1,023] There were 50,897 samples per sec - readings range from [1,012] to [1,023] Using Speed 12MHz Using ADC10SHT_0 (x4) There were 184,092 samples per sec - readings range from [1,013] to [1,023] There were 184,092 samples per sec - readings range from [1,013] to [1,023] There were 184,092 samples per sec - readings range from [1,012] to [1,023] There were 184,092 samples per sec - readings range from [1,013] to [1,023] There were 184,092 samples per sec - readings range from [1,013] to [1,023] Using ADC10SHT_1 (x8) There were 159,657 samples per sec - readings range from [1,013] to [1,023] There were 159,658 samples per sec - readings range from [1,013] to [1,023] There were 159,658 samples per sec - readings range from [1,013] to [1,023] There were 159,657 samples per sec - readings range from [1,013] to [1,023] There were 159,657 samples per sec - readings range from [1,013] to [1,023] Using ADC10SHT_2 (x16) There were 123,543 samples per sec - readings range from [1,014] to [1,023] There were 123,543 samples per sec - readings range from [1,014] to [1,023] There were 123,543 samples per sec - readings range from [1,014] to [1,023] There were 123,543 samples per sec - readings range from [1,014] to [1,023] There were 123,543 samples per sec - readings range from [1,014] to [1,023] Using ADC10SHT_3 (x64) There were 52,702 samples per sec - readings range from [1,014] to [1,023] There were 52,722 samples per sec - readings range from [1,013] to [1,023] There were 52,708 samples per sec - readings range from [1,012] to [1,023] There were 52,702 samples per sec - readings range from [1,011] to [1,023] There were 52,709 samples per sec - readings range from [1,013] to [1,023] Using Speed 16MHz Using ADC10SHT_0 (x4) There were 203,974 samples per sec - readings range from [1,016] to [1,023] There were 203,979 samples per sec - readings range from [1,016] to [1,023] There were 204,158 samples per sec - readings range from [1,016] to [1,023] There were 204,059 samples per sec - readings range from [1,016] to [1,023] There were 204,135 samples per sec - readings range from [1,016] to [1,023] Using ADC10SHT_1 (x8) There were 171,828 samples per sec - readings range from [1,007] to [1,023] There were 171,828 samples per sec - readings range from [1,006] to [1,023] There were 171,828 samples per sec - readings range from [1,007] to [1,023] There were 171,828 samples per sec - readings range from [1,006] to [1,023] There were 171,828 samples per sec - readings range from [1,006] to [1,023] Using ADC10SHT_2 (x16) There were 131,106 samples per sec - readings range from [1,013] to [1,023] There were 131,185 samples per sec - readings range from [1,013] to [1,023] There were 131,061 samples per sec - readings range from [1,013] to [1,023] There were 131,128 samples per sec - readings range from [1,013] to [1,023] There were 131,135 samples per sec - readings range from [1,012] to [1,023] Using ADC10SHT_3 (x64) There were 54,328 samples per sec - readings range from [1,014] to [1,023] There were 54,336 samples per sec - readings range from [1,009] to [1,023] There were 54,326 samples per sec - readings range from [1,014] to [1,023] There were 54,324 samples per sec - readings range from [1,010] to [1,023] There were 54,332 samples per sec - readings range from [1,015] to [1,023]
     
    And here is the code

    /* ****************************************************************************************** * * * * * ADC-SpeedTest - This program samples the ADC at high speed using a variety of * * * settings for Sample & Hold Times and CPU clock speed * * * * * * While doing this it keeps track of the highest/lowest readings * * * (to ensure that the SHT values are sufficient to capture * * * the full range. * * * * * * Once readings are taken they are written out using the hardware * * * UART at 9600,8,1,none * * * * * ****************************************************************************************** */ #include volatile unsigned long samples = 0; // How many samples have we had? volatile int timer_ticks = 0; // How many timer ticks have we had? volatile long max_reading=0; // Whats the highest reading we have had? volatile long min_reading=1023; // Whats the lowest reading we have had? int cur_sht = 0; // What SHT are we using now? int sht_count = 0; // How many runs at this SHT have we had? int cur_speed = 0; // What speed are we running at? const unsigned SHT_vals[] = { ADC10SHT_0,ADC10SHT_1,ADC10SHT_2,ADC10SHT_3 // What values do we need for each of the SHTs? }; const char *SHT_strs[] = { // Descriptive Strings for the SHTs "ADC10SHT_0 (x4)", "ADC10SHT_1 (x8)", "ADC10SHT_2 (x16)", "ADC10SHT_3 (x64)" }; const char *SPEEDS_STR[] = { // Descriptive strings for the processor speeds "1MHz","8MHz","12MHz","16MHz" }; const char SPEEDS_UCABR0[] = { // Values to use for UCABR0 for each proc speed (9600 baudrate) 104, 0x41, 0xE2, 0x82 }; const char SPEEDS_UCABR1[] = { // Values to use for each UCABR1 0, 0x03, 0x04, 0x06 }; const int SPEEDS_CCR[] = { // CCR Values to use for each proc speed (to trigger at 1/1000th sec) 1000-1, 8000-1, 12000-1,16000-1 }; const char SPEEDS_BCS[] = { // BCS Values to use for each processor speed (Grabbed from the calib section of the flash) 0x86, 0x8D, 0x8E, 0x8F }; const char SPEEDS_DCO[] = { // DCO values to use for each processor speed (Grabbed from the calib section of the flash) 0xD6, 0x94, 0x9D, 0x95 }; void serial_puts(const char *); // Put a string (NULL Terminated) out via the UART void serial_putch(char); // put a single char out via the UART void serial_putl(long); // Write a long number as ascii out via the UART void show_sht(void); // Write the SHT settings out of the serial port void show_speed(void); // Write the CPU Speed settings out of the serial port void set_speed(void); // Set the processor speed and associated variables void main(void) { WDTCTL = WDTPW + WDTHOLD; // Hold the WDT BCSCTL1 = CALBC1_16MHZ; // Set the CPU to 16MHz DCOCTL = CALDCO_16MHZ; ADC10CTL0 &= ~ENC; // Disable ADC conversion (Can't configure if enabled) ADC10CTL0 = SREF_0 | ADC10SHT_0 | ADC10ON | ADC10IE; // GND to Vcc, 4 x ADC10CLK Ticks, ADC on, Enable Interrupt ADC10CTL1 = INCH_4 | SHS_0 | ADC10DIV_0 | ADC10SSEL_0 | CONSEQ_0; // ADC Chan 4, ADC10 SC, /1 CLK, ADC10 OSC, Sing Chan/Sing Conv P1SEL = BIT1 + BIT2; // Enable P1.1, P1.2 as Hardware UART P1SEL2 = BIT1 + BIT2; UCA0CTL1 |= UCSSEL_2; // UART clocked from SMCLK UCA0BR0 = 0x82; // 16,000,000/9600 = 0x682 UCA0BR1 = 0x06; UCA0MCTL = UCBRS0; // No modulation UCA0CTL1 &= ~UCSWRST; // reset usci CCTL0 = CCIE; // Enable interrupts on Timer TACTL = TASSEL_2 | ID_0 | MC_1; // SMCLK, /1, Up to CCR0 CCR0 = 16000 - 1; // One Thousandth of a second set_speed(); // Set clock speed, baudrate divisors etc show_speed(); // Send speed details to UART show_sht(); // Send SHT details to UART while(1) { min_reading = 1023; // Clear min/max readings max_reading = 0; samples = 0; // And counters timer_ticks = 0; TACTL |= TACLR; // Reset the timer CCTL0 |= CCIE; // Enable timer interrupts ADC10CTL0 |= ENC | ADC10SC; // Enable ADC and Start conversion _bis_SR_register(CPUOFF | GIE); // Pause CPU and enable interrupts ADC10CTL0 &= ~ENC; // Turn off the encoder CCTL0 &= ~ CCIE; // Disable interrupts while(ADC10CTL1 & ADC10BUSY); // While til pending ADC done ADC10CTL0 &= ~ADC10IFG; // Ensure pending ifgs are cleared serial_puts(" There were "); serial_putl(samples); serial_puts(" samples per sec - readings range from ["); serial_putl(min_reading); serial_puts("] to ["); serial_putl(max_reading); serial_puts("]\n\r"); if(++sht_count == 5) { // Take readings for 5 seconds per Speed/SHT combo sht_count = 0; cur_sht++; if(cur_sht == 4) { // There are 4 SHT settings per speed cur_sht = 0; cur_speed++; if(cur_speed == 4) { // And we have 4 speeds cur_speed = 0; } set_speed(); // Set speed details show_speed(); // Show the details } show_sht(); // Show the SHT settings ADC10CTL0 = SREF_0 | SHT_vals[cur_sht] | ADC10ON | ADC10IE; // Setup ADC10 } } } /* ********************************************************************************************** * * * set_speed(void) - Sets the DCO/BCS registers so MCLK is desired speed, * * UART baudrate divisors for 9600 * * CCR0 so ticks are 1/1000 seconds * * NOTE: Must pause to allow the clocks to settle down * * * * ********************************************************************************************** */ void set_speed(void) { BCSCTL1 = SPEEDS_BCS[cur_speed]; // Set MCLK to desired speed DCOCTL = SPEEDS_DCO[cur_speed]; UCA0BR0 = SPEEDS_UCABR0[cur_speed]; // set bitrate divisors depending on speed UCA0BR1 = SPEEDS_UCABR1[cur_speed]; CCR0 = SPEEDS_CCR[cur_speed]; // And CCR so each tick is 1/1000 seconds __delay_cycles(20000); // Wait for clocks etc to settle down } /* ********************************************************************************************** * * show_sht(void) - Writes out description of the SHT settings to the UART * * ********************************************************************************************** */ void show_sht(void) { serial_puts(" Using "); serial_puts(SHT_strs[cur_sht]); serial_puts("\n\r"); } /* ********************************************************************************************** * * show_speed(void)- Writes out description of the CPU speed settings to the UART * * ********************************************************************************************** */ void show_speed(void) { serial_puts("Using Speed "); serial_puts(SPEEDS_STR[cur_speed]); serial_puts("\n\r"); } /* ********************************************************************************************** * * serial_putl(long val) - Writes out a long number as ASCII through the UART * * * For ease of reading the numbers there are ',' chars * * * written out as thou separators * * * Leading 0s are skipped * * * * * * NOTE:- At the moment all numbers are assumed to be +ve (can't have a -ve number of * * * readings so not needed in this project * * * * * ********************************************************************************************** */ void serial_putl(long val) { long digit; char ch; char had_digit = 0; digit = 1000000; // Allow for upto 1M Samples per sec while(digit >0 ) { ch = val / digit; if(had_digit && (digit == 100000 || digit == 100)) { serial_putch(','); // If a digit has been written then put a thou sep } if(ch >0 || had_digit || digit == 1) { // Skip 0s if not had a char left and not on units serial_putch('0' + ch); had_digit = 1; } val -= digit * ch; digit /= 10; } } /* ********************************************************************************************** * * * * * serial_puts(const char *ptr) - Writes out a NULL terminated string through the UART* * * * * ********************************************************************************************** */ void serial_puts(const char *ptr) { while(*ptr) { // Go until we are at the NULL serial_putch(*(ptr++)); // put out the single char } } /* ********************************************************************************************** * * * * * serial_putch(char c) - Writes out a single ASCII char through the UART * * * * * ********************************************************************************************** */ void serial_putch(char c) { while ( !(IFG2 & UCA0TXIFG) ) // Wait if there is a transmission ongoing ; UCA0TXBUF = c; // Put the char into the UART TX buffer } /* ********************************************************************************************** * * * * * ADC_ISR(void) - ISR for when the ADC has completed a conversion * * * It keeps track of the min and max readings * * * And keeps track of the number of readings taken * * * * * ********************************************************************************************** */ #pragma vector=ADC10_VECTOR __interrupt void ADC_ISR(void) { ADC10CTL0 |= ADC10SC; // Start Conversion as soon as possible here if(ADC10MEM > max_reading) { max_reading = ADC10MEM; // Keep track of highest reading } if(ADC10MEM < min_reading) { min_reading = ADC10MEM; // And the minimum } samples++; // And bump the number of reaings } /* ********************************************************************************************** * * * * * TIMERA_ISR(void) - ISR for the timer CCR0 * * * simple routine.. keeps track of the number of ticks * * * All ticks should be 1/1000 sec * * * When 1000 ticks have happened the CPU is re-enabled so the * * * details can be sent out of the UART * * * * * ********************************************************************************************** */ #pragma vector=TIMER0_A0_VECTOR __interrupt void TIMERA_ISR(void) { timer_ticks++; // Bump the count if(timer_ticks == 1000) { __bic_SR_register_on_exit(CPUOFF + GIE); // After 1000 ticks re-enable the processor } }
     
    I hope someone finds this snippet useful
     
    Dan
  17. Like
    mbeals reacted to roadrunner84 in Pointer to Register?   
    When I saw this code
    motors[1].speed = 0; motors[1].TCCR[0] = &MOTOR2_in1CCR; motors[1].TCCR[1] = &MOTOR2_in2CCR; motors[1].PORT[0] = MOTOR2_in1PORT; motors[1].PORT[1] = MOTOR2_in2PORT; motors[1].PIN[0] = MOTOR2_in1PIN; motors[1].PIN[1] = MOTOR2_in2PIN; The first thing I thought was "why are TCCR pointers, but PORT not?"You use this switch on much places to determine the port registers depending on the value of a variable. Instead you could use a similar mechanism here.
    You wouldn't need to store all port related pointers, just a base pointer; the relative position of the port related registers is similar for every port. This means you could determine the position of one from another.
    If PIN is your base, then the position of POUT would be as POUT = PIN + (P1OUT-P1IN).
    Say what again? If P1OUT is X bytes further in memory than P1IN, than any POUT would be 1 byte further in memory relative to the corresponding PIN. So (P1OUT-P1IN) would be X, we add this X to the pointer PIN to get any POUT.
  18. Like
    mbeals reacted to yyrkoon in Pointer to Register?   
    mbeals, not sure how you feel about C++, but at first look, it seems almost a perfect fit for a C++ template class. Granted, I have been using C++ template classes a lot myself lately so I am kind of always looking for way to make things "fit" into template classes . . .
     
    Something like this: Nokia 5110 C++ Template Class The specific device is not all that interesting for your case, but look at how pointers to ports, etc are being passed around at object instance time. For that specific case, the values passed in ( by reference ) take on no extra overhead.
     
    What I was thinking in your case however, was about creating an object instance for each motor, with its own configuration, like port, pins, and various helper methods ( ChangeSpeed(), ChangeDirection() , etc ) for each object.
     
    Perhaps . . . I have not really thought it thru 100%.
  19. Like
    mbeals reacted to roadrunner84 in Launchpad as external programmer   
    I'm not really sure what you mean, but if you use the reset line for programming, the capacitor should not exceed 2.2nF (that is nano, not micro). Also, the recommended pull up resistor is 47k, but 33k might just work as well. R6 should be 0 ohms (or a shortcut) and D4 should not be placed.
  20. Like
    mbeals got a reaction from sirri in light alarm clock project using msp430   
    You are correct.
  21. Like
    mbeals got a reaction from sirri in light alarm clock project using msp430   
    Pull the RST jumper too.  There are hold up resistors on the RST line on both sides of the header.  So with VCC pulled, the RST line is still holding the emulation side's VCC rail high.
  22. Like
    mbeals got a reaction from roadrunner84 in light alarm clock project using msp430   
    Pull the RST jumper too.  There are hold up resistors on the RST line on both sides of the header.  So with VCC pulled, the RST line is still holding the emulation side's VCC rail high.
  23. Like
    mbeals got a reaction from jsolarski in Project deathbot   
    My mouser order came early!  So instead of spending an afternoon working, I went out to the lab and soldered it up.  Don't make fun of my SMD work...this is only my second attempt at it.
     
    I plan to start writing firmware tonight once I get home, but winter carnival starts tonight, so we shall see how far I get with it.
     
    EDIT:  IT'S ALIVE!!!!
     
    Well...at least I can program it and the UART is capable of transmitting....but I very rarely have anything work out of the gate.  I also read the datasheet closer, and my pinout problem isn't nearly as bad as I thought it was.  I should still have full control in both directions...I just won't have control over the decay mode.


  24. Like
    mbeals got a reaction from tripwire in Is This a decent way to prevent EMP damage on a electronic?   
    an anti static bag is a Faraday cage.  The idea isn't to throw the device into a cage at the last minute, but rather to build the shielding into the device itself so that it is always protected.  Obviously this is impossible for devices that require wireless communication, but it is possible to isolate the main electronics (e.g. with optoisolators) from the RF side such that only one small piece of the system is vulnerable.  Even then, it depends on the strength of the EMP, and circuits can be electrically hardened to tolerate the transients produced by the pulse.  So in an idea device, you would have sensitive electronics shielded inside a robust Faraday cage, coupled non-electrically to hardened electronics that cannot be shielded.     
     
    Electronics can be designed that can function (not just survive powered down) in very strong fields and perform quite happily.  Of course this level of engineering is quite involved and expensive, which is why these things only exist in applications that require them.
  25. Like
    mbeals reacted to oPossum in Int To Hexa ?   
    void uint32hex(uint32_t x, char *s)
    {
    unsigned n = 8;
    s += n;
    *s-- = 0;
    do {
    *s-- = "0123456789ABCDEF"[x & 15];
    x >>= 4;
    } while(--n);
    }

×
×
  • Create New...