Jump to content


  • Content Count

  • Joined

  • Last visited

  • Days Won


Reputation Activity

  1. Like
    gordon reacted to bluehash in Something up with URL recognition?   
    Urls will only work in full editor.
  2. Like
    gordon reacted to oPossum in Launchpad Mini - revision 3   
    A few updates...
    - 2 or 4 pin pushbuttons
    - SPI MISO/MOSI reversing jumpers (J8)
    - Support for FTDI on 6 pin 100 mil header - requires 2 trace cuts and a jumper

  3. Like
    gordon got a reaction from advaneharshal in LP Booster Pack Eagle footprints   
    (OK, I have no idea where to put this. BH, feel free to move it around.)
    Continuing from viewtopic.php?f=9&t=1348&start=40#p11369
    This is the final version; I don't think it can be made any better as well as generic at the same time.
    All variants verified against the TI LaunchPad Eagle files.
    Thanks to SugarAddict for the corrections.
    Pro tip: make your References layer yellow (or any other unused bright color) while placing your components.
    Addendum: DipTrace users look here: viewtopic.php?f=35&t=2972
  4. Like
    gordon reacted to xpg in IPv6 with the Launchpad   
    Code is now available on github: https://github.com/xpgdk/net430. The code works, but has tons of issues.

    Currently implemented features are:

    - IPv6 Stateless autoconfiguration (based on router advertisments)
    - ICMP Ping
    - Simple TCP-stack
    What really is lacking is a proper API. Currently, it's quite difficult to deal with TCP-streams in a sane way, as the handler code receives the data one packet at a time. But it is doable, just not very efficient

    If anyone is interested in this, I might document the entire thing a bit further.

    The following video shows a MS430G2553 with a HD44780 character display being controlled by HTTP-GET requests:

  5. Like
    gordon reacted to pabigot in first look: BSP430   
    Having wrestled mspgcc mostly to a state of stability and feature-completeness, I've been moving back towards using the MSP430 for real application code. The next tool I needed was a board support environment that met my needs. I've got the first public release up at https://github.com/pabigot/bsp430 and thought people here might want to take a look. In the next month or two I'll be extending this with examples of much more complex features including full ChipCon radio support, the CC3000 WiFi module, and integration into FreeRTOS.
    Here's the blurb:
    BSP430 is a set of C language adaptation layers simplifying cross-MCU library and application development on Texas Instruments MSP430 microcontrollers. The target audience is experienced embedded systems developers who need full control over the microcontroller but are willing to trade a small amount of performance for improved component re-usability and rapid prototyping.
    For more details, the documentation is at http://pabigot.github.com/bsp430
  6. Like
    gordon reacted to xpg in Mailbox Notifier   
    The mailbox notifier is a simple system, which notifies about new mail in the physical mailbox. It consists of two parts: The transmitter and the receiver. The two components talk to each other using a 433MHz wireless protocol.
    The transmitter sits in the mailbox and detects if the mailbox

  7. Like
    gordon reacted to RobG in MTK3339 GPS   
    Finally got my memory chip and finished the logger software (still testing though.)

    Here's how it works.
    Code which uses logger is responsible for keeping track of time and write address.
    After GPS acquires location, memory address is set and timer is started.
    During each timer interrupt, location is parsed, then set using setLatitude(), setLongitude(), setTime(), and setDate().
    Then writeTimeStamp() or writeDelta() is called. Each write will increase memory location.
    Time stamp is 16 bytes long, delta is 4 bytes.
    getAbsLatDelta & getAbsLongDelta can be used to determine if there's movement. If there isn't, delta interval can be increased to preserve memory.
    One time stamp every minute and delta every 5 seconds will use 3600 bytes per hour.
    One time stamp every 5 minutes and delta every 10 seconds will use 1584bytes per hour.
    Attached logger code is complete, but should not be used as it is still in progress
  8. Like
    gordon reacted to Rickta59 in Example of GNU msp430 assembler ISR handler   
    Even though Energia is aimed at new users of the msp430, there is nothing stopping you from using the low level features of msp430-gcc and writing code in msp430 assembler. Looking around the net I'm guessing you will have little luck finding any examples of how to mix msp430 asm and ISR handlers. I'm going to try and fix that. The code below isn't a full working example. I'm presenting it mainly to show you how to use some of the features of GNU asm. I'll also try and explain some techniques I've found useful.
    The code below is similar to the 'C' version of the TimerSerial receive ISR handler in Energia. It basically sits around and waits for a serial character start bit to appear and drag the RX pin from high to low and then uses the counter compare feature of TimerA to sample the middle of each bit. It assembles these sampled bits into a byte and then stuffs it on the end of a ringbuffer if there is room.
    To write an ISR handler you need to create your code with a specific name. We will use a macro to setup the proper name as you will see below. The code shown here will setup a handler for the TIMERA1_VECTOR interrupt.
    The code:

    ;-------------------------------------------------------------------------------- ; File: rx_isr_asm.S - msp430 gcc asm version of SoftSerial_RX_ISR (faster code) ; ; Desc: This code handles receiving serial data using the TIMERA1 ISR ; It starts out in capture mode waiting for the start bit (transition from ; high to low) then switches to compare mode for 8 bits. It accumulates ; each lsb->msb received bit into a byte and stores it in a ringbuffer ; The code attempts to minimize register usage to just r15. ; ; This code is about ~21 cycles faster than the C version. ; However, the code size is about 22 bytes larger. Useful if you want ; to run your F_CPU at a really low frequency and still receive data ; ; Author: rick@kimballsoftware.com ; Date: 08-01-2012 ; #include #include "config.h" /* for F_CPU, BAUD_RATE, and RX_BUFFER_SIZE */ ;-------------------------------------------------------------------------------- ; --- Defines ;-------------------------------------------------------------------------------- #define PC r0 /* program counter */ #define TIMERA1_VEC 8 /* TIMERA1_VECTOR/2 (0x0010)/2 */ #define BIT_DUR (F_CPU/BAUD_RATE) /* cycle count between samples */ #define BIT_DUR_1_5 (BIT_DUR)+(F_CPU/BAUD_RATE/2) /* 1.5 times a BIT_DUR */ #define rb_head rx_buffer+0 /* offsets into ringbuffer_t struct */ #define rb_tail rx_buffer+2 #define rb_buf rx_buffer+4 ;-------------------------------------------------------------------------------- ; .interrupt - macro to declare an interrupt handler routine entry point ;-------------------------------------------------------------------------------- .macro .interrupt sn .global __isr_\sn __isr_\sn: .endm ;-------------------------------------------------------------------------------- ; --- BSS Data ;-------------------------------------------------------------------------------- .section .bss.rx_isr_asm .p2align 1,0 .lcomm state_vector,2 .lcomm rx_mask,2 .lcomm rx_data,2 ;-------------------------------------------------------------------------------- ; --- Code ;-------------------------------------------------------------------------------- .text .p2align 1,0 .global SoftSerial_RX_ISR .type SoftSerial_RX_ISR,@function .interrupt TIMERA1_VEC ;-------------------------------------------------------------------------------- SoftSerial_RX_ISR: ;-------------------------------------------------------------------------------- ; push, push, jump... ISR entry overhead 6 clocks push r15 ; preserve mov &TAIV, r15 ; reset interrupt flag by reading, we ignore btw add &state_vector,PC ; use state to jump directly to a handler without testing jmp handle_startbit ; 0 start bit jmp handle_databit_0_6 ; 2 bits 0 - 6 jmp handle_databit_0_6 ; 4 jmp handle_databit_0_6 ; 6 jmp handle_databit_0_6 ; 8 jmp handle_databit_0_6 ; 10 jmp handle_databit_0_6 ; 12 jmp handle_databit_0_6 ; 14 jmp handle_databit_7 ; 16 bit 7 handle_startbit: ; handle start bit add #2, &state_vector ; set next handler bic #CAP, &TACCTL1 ; go into compare mode add #BIT_DUR_1_5, &TA0CCR1 ; set next sample in the middle of D0 mov #0, &rx_data ; initialize recv byte mov #1, &rx_mask ; mask lsb -> msb jmp rx_isr_exit handle_databit_0_6: ; handle bits 0-6 add #2, &state_vector ; set next handler add #BIT_DUR, &TA0CCR1 ; set next sample time mov &rx_mask, r15 ; load mask bit #SCCI, &TACCTL1 ; check latched sampled data bit jz 1f bis r15, &rx_data ; if HI then set this bit 1: rla r15 ; make room for next data bit mov r15, &rx_mask jmp rx_isr_exit handle_databit_7: ; handle last bit and store in ringbuffer mov #0, &state_vector ; go back to capture handler bit #SCCI, &TACCTL1 ; check latched sample data bit jz 1f bis #BIT7, &rx_data 1: mov &rb_head, r15 ; load rx_buffer.head mov.b &rx_data, rb_buf(r15) ; rx_buffer.buffer[head] = rx_data inc r15 ; rx_buffer.head++ and #RX_BUFFER_SIZE-1, r15 ; take care of buffer wraparound, assumes power of 2 sized buf cmp r15, &rb_tail ; compare with tail jz 2f mov r15, &rb_head ; save new rx_buffer.head 2: bis #CAP, &TACCTL1 ; go back to capture mode rx_isr_exit: pop r15 ; standard exit ;xor.b #BIT6,&P1OUT ; uncomment to see where function ends. ; xor.b takes 5 clocks reti ; ISR exit overhead 5 cycles .Lfe1: .size SoftSerial_RX_ISR,.Lfe1-SoftSerial_RX_ISR ;-------------------------------------------------------------------------------- ; EOF rx_isr_asm.S ;--------------------------------------------------------------------------------

    /* config.h */ #define F_CPU 1000000 #define BAUD_RATE 4800 #define RX_BUFFER_SIZE 16 typedef struct { volatile unsigned head, tail; unsigned char buffer[RX_BUFFER_SIZE] } ringbuffer_t;
    Energia will compile any '.S' files it finds with msp430-gcc. This allows us to use the C preprocessor.

    #include #include "config.h" /* for F_CPU, BAUD_RATE, and RX_BUFFER_SIZE */
    In the case of the code above, we include the and "config.h" files. This provides our asm code with many constants we can use in the code. It also means we can define our own constants.
    GNU macros are an alternative to defines. The code above creates a macro called '.interrupt' which takes a number of the ISR you want to handle and does a global define of that name and its address.
    A little explanation of ISR handling is probably useful. Interrupt Service Routines in the msp430 are handled with the interrupt vector table. The table contains an array of entries that will handle each interrupt. Each ISR has an entry in this table which is really the address of a chunk of code than handles that ISR.
    The file defines constant with the names like "TIMERA1_VECTOR" which are really just the offsets from the start of the vector table. Depending on your processor the vector table can have 16, 32 or 64 entries. The launchpad chips have 16 entries. Each entry is a word address (2 bytes) that the processor jumps to when the ISR is triggered.
    To get our ISR wired up, we need to declare the proper global name so our code will get executed. So for the entry TIMERA1_VECTOR, it has a value of offset (0x0010) in the msp430g2231.h header file. We need to convert the offset into a numbered ISR name. The number is just half the offset. For TIMERA1_VECTOR it needs to be 8 and the name for our code will be '__isr_8'. I just defined my own constant called TIMERA1_VEC with a value of 8. There is probably a better way to do this and maybe Peter will chime in here.

    ;-------------------------------------------------------------------------------- ; .interrupt - macro to declare an interrupt handler routine entry point ;-------------------------------------------------------------------------------- .macro .interrupt sn .global __isr_\sn __isr_\sn: .endm ... then later .interrupt TIMERA1_VEC
    The code above shows the macro and how you would use it to declare the start of your ISR handler. When you instance the macro it takes any code between the .macro and .endm and uses your arguments to perform a replacement. In the case above, it substitutes '8' for any instances of \sn. Great! now we have defined all the glue for the ISR to get our code invoked. We just need to write the instructions that handles it.
    ISR handlers written in asm need to be careful of the registers they use. When an ISR routine starts the processor has pushed the address of the main threads next instruction on the stack along with the status register. If you want to use any registers in your code you have to save and restore them. At the end of your ISR handler you must exit with a 'RETI' instruction. This will pop the status register and the push the next saved next instruction into the PC register.
    The simplest ISR handler would just be a properly named interrupt handler and the 'RETI' instruction

    .interrupt TIMERA_VEC reti
    Even this simple handler is going to take away cycles from the main code. Each time this ISR handler is triggered it will use 11 clock cycles. 6 cycles to get from the running main thread to the first instruction you write. Then 5 clock cycles to restore the status register and pc register using the reti instruction.
    The ISR handler shown here is a lot more involved. It pushes r15 onto the stack so it has a register it can use. Just before reti the code pops that value back to its original value so the main thread isn't affected. I'm not going to walk through each line of the code. Let us take a look at one of the more interesting snippets of code:

    handle_databit_7: ; handle last bit and store in ringbuffer mov #0, &state_vector ; go back to capture handler bit #SCCI, &TACCTL1 ; check latched sample data bit jz 1f bis #BIT7, &rx_data 1: mov &rb_head, r15 ; load rx_buffer.head mov.b &rx_data, rb_buf(r15) ; rx_buffer.buffer[head] = rx_data inc r15 ; rx_buffer.head++ and #RX_BUFFER_SIZE-1, r15 ; take care of buffer wraparound, assumes power of 2 sized buf cmp r15, &rb_tail ; compare with tail jz 2f mov r15, &rb_head ; save new rx_buffer.head 2: bis #CAP, &TACCTL1 ; go back to capture mode
    In the code above you can see I'm freely mixing defined constants from config.h, msp430.h and my asm code. The 'handle_databit_7' function uses the rb_head and rb_tail defines to provided offsets into the address of the rx_buffer. 'rx_buffer' is the name of the ringbuffer defined in the external 'C' code you don't see. We just use rx_buffer and the linker will find it.
    You can look through the rest of the code and see some of the other GNU directives I used to declare some variables with the .lcomm directive. .lcomm variables will end up in the BSS section which uses some of your ram. They will get initialized to 0. The code goes into the .text section and will be stored in flash.
    Writing code in msp430 asm is going to take you longer and most of the time you don't need to resort to this. The msp430-gcc is very capable of optimizing the code to make it small and fast. Energia uses the -Os option to make small code. However sometimes you can do better. In the case of the code above, I was able to take some very reasonable 'C' code and reduce the cycle count down by about 20 cycles. Sometimes though, when you are doing communication code and running at a very low DCO clock frequency every cycle counts.
    Some useful tools you might want to look at are included with the msp430-gcc compiler. msp430-objdump, msp430-objcopy, msp430-nm and msp430-size.

    $ msp430-objdump -S yourprogram.elf | less # gets you an asm listing of your code $ msp430-objcopy -O ihex yourprogram.elf yourprogram.hex ; naken430util -disasm yourprogram.hex | less # cycle counts $ msp430-size yourprogram.elf # shows you the size of your code and how much bss and data you are using
    Well I hope this post is useful to someone and now there is a place on the net you can find an example of msp430 asm with ISR handling. Experiment with this option. If you find yourself wanting to tweak your code after you have done all the optimization you can in 'C' maybe this will give you the tools you need to make it work.
  9. Like
    gordon reacted to juani_c in Stellaris LaunchPad   

    Not much info yet, just the price; a $4.99 kit. :clap:

    EDIT1: Found an LCD boosterpack for this board http://www.kentecdisplay.com/uploads/so ... ide_03.pdf

    EDIT2: by the name of the boosterpack It looks like there will be one of the LM4F120 Series
    http://www.ti.com/mcu/docs/mculuminaryf ... mostrecent
  10. Like
    gordon got a reaction from viet_dtvt_bkdn in LCD instruction   
    You may want to study the information mentioned here: viewtopic.php?f=8&t=449#p4473 (and eventially the whole topic as well).
  11. Like
    gordon got a reaction from zborgerd in loop forever doing nothing   
    It must be noted that this behaviour is very highly likely to be compiler-dependent and should not ever be relied upon. GCC halts the CPU if execution falls off main(), for example.
  12. Like
    gordon reacted to campbellsan in YABB - Breadboard Booster on steroids   
    Here is the finished prototype board:

    Note the jumpers in the 'Program' state. Move them to the left if you wish to use those MSP pins in your project.
  13. Like
    gordon reacted to reagle in Launchpad Booster Pack library for DipTrace   
    Here is a library of DipTrace schematic symbols and footprints for those working on booster packs.
    I modeled them after gordon's Eagle library(viewtopic.php?f=35&t=1684), with slight modifications. I did three sizes:
    Full is assuming the pack covers the whole Launchpad
    Left is for those who want to align the left edge (USB) and leave the buttons open
    Min is just wide enough to fit two headers.
    Outline is done on assembly layer as a reference/guide and will not show up on silk
    Dimensions checked versus TI's official drawing and also the Launchpad sources in Eagle.
    Comments are welcomed!
    I'll be also hosting it and other Launchpad related projects on my blog (see signature)
  14. Like
    gordon got a reaction from viet_dtvt_bkdn in loop forever doing nothing   
    It must be noted that this behaviour is very highly likely to be compiler-dependent and should not ever be relied upon. GCC halts the CPU if execution falls off main(), for example.
  15. Like
    gordon reacted to oPossum in Software IIC master in C, C++ class and C++ template   
    This is software IIC master code in C, and C++ using a class and a template. There is also code/class/template for IIC EEPROM and the INA219 voltage/current monitor.
    There are 4 core functions...

    init(); // Init GPIO start(); // Start bit stop(); // Stop bit unsigned ex(unsigned); // Data byte & ack exchange
    and 3 helper functions that call ex();...

    unsigned write(unsigned); // Write a byte & ack, verify unsigned read(); // Read a byte & ack unsigned read_nak(); // Read a byte & nak
    Creating an instance of the IIC object is different for each code type:

    C: T_IIC iic = { BIT1, BIT0, &P2IN, &P2OUT, &P2DIR }; C++ class: CSWIIC iic(BIT1, BIT0, P2IN, P2OUT, P2DIR); C++ template: CSWIIC iic;
    The C functions require that the IIC structure be passed as the first argument. The C++ class and template use the usual class.function notation.

    C: iic_start(&iic); a = iic_write(&iic, ; iic_stop(&iic); C++ class or template: iic.start(); a = iic.write(; iic.stop();
    This is a disassembly of the start() function for all three versions. The C function and C++ class member function are identical code! The template allows the compiler to do compile time optimization that can not be done with C or C++ class. It is smaller, faster and uses less RAM.

  16. Like
    gordon reacted to oPossum in Printing to the CCS debugger console   
    The CCS RTS (run time support library) supports simple device drivers and streams. The printf() function uses this driver/stream system to print to the debugger console window. There isn't enough memory in any of the G series devices to use printf() due in part to the memory requirements of the RTS stream buffers.
    I created a very basic printf() that makes direct calls to user provided putc() and puts() functions. This reduces the memory use substantially. Using this simple printf() with the CCS debugger console can be done with this code....

    unsigned char _CIOBUF_[12 + 32]; // This *must* be global and named _CIOBUF_ // 12 bytes needed for header and null terminator // void putc(char c) // --- Send char to debugger using CIO { // static char * p = (char *)&_CIOBUF_[11]; // Pointer to string buffer // if(c) *p++ = c; // Append any non-null char to buffer // Write to host when buffer is full or char is null if((p >= (char *)&_CIOBUF_[sizeof(_CIOBUF_) - 1]) || (c == 0)) { *p = 0; // Null terminate string const unsigned l = p - (char *)&_CIOBUF_[10];// String lengh including null _CIOBUF_[0] = _CIOBUF_[5] = l & 0xFF; // Data and string length LSB _CIOBUF_[1] = _CIOBUF_[6] = l >> 8; // Data and string length MSB _CIOBUF_[2] = 0xF3; // Write command _CIOBUF_[3] = 1; _CIOBUF_[4] = 0; // stdout stream __asm(" .global C$$IO$$"); // CIO breakpoint __asm("C$$IO$$:nop"); // p = (char *)&_CIOBUF_[11]; // Reset string buffer pointer } // } void puts(char *s) { while (*s) putc(*s++); } // Send string to debugger inline void cio_flush(void) { cio_putc(0); } // Flush the CIO write buffer
    This works by filling a buffer with information that the debugger will read and interpret. The debugger sets a breakpoint at symbol C$$IO$$ and reads the buffer when the breakpoint is hit. Unfortunately there is quite a bit of overhead with this method so applications are limited. Increasing the buffer size (_CIOBUF_) will help performance by transferring more data with each breakpoint invocation.

  17. Like
    gordon reacted to oPossum in Volt/Amp/Watt meter   
    This is a simple voltage and current meter that uses the TI INA219 chip. Voltage measurement range is 0 to 26 volts with 4 mV resolution and current measurement range is -4 to +4 amps with 1 mV resolution (when using a 0.01 ohm shunt). The specs are inferior to a pair of quality multimeters, but it is a fraction of the price and shows wattage in addition to voltage and current. The Nokia 5110 display is used so the firmware could be enhanced to do simple graphing. Sending the measurements to a computer could also be done.
    Using the INA219 makes for a very simple circuit.

    The normal display is three lines with voltage, amperage and wattage.

    Pressing the P1.3 switch will show the 6 registers in the INA219 in hex and signed decimal.

    The code is written in C++ and uses templates for the LCD, IIC and INA219. Software SPI and IIC is used for maximum portability.
  18. Like
    gordon got a reaction from Alan in Updated compile of mspgcc and mspdebug on Linux   
    You can use my build script (attached to this post) (as a starting point) on two conditions:
    - I do not wish to provide any kind of support whatsoever regarding this script. It works and works well, has been for quite a long time now, and I am pretty tired of listening to statements to the contrary.
    - I do not wish to be associated with this script in any way, shape or form (otherwise #1 is bound to happen)
    I am also completely uninterested in any enhancements, bug fixes, colored output, error handling, and whatever else you can think of. Basically, you grab it, do whatever you want with it, and I never want to hear of it again.
    If you can live with this, by all means be my guest to re-use it. If you can't, consider the offer void. ("You" means anyone and everyone who wants this piece of code.)
  19. Like
    gordon reacted to jsolarski-backup in parallax rfid reader + back door   
    This is a project I have finished recently. Since I am lazy and didn't feel the need to use keys to access my apartment I decided to hook up an rfid reader to my back door, which in turn will open my breaker bar on my patio door.
    It is sorta of a kludge till I can find a stepper motor to replace my rube goldberg~esqe like device.
    How it lifts the breaker bar, it uses a solenoid to pull a large ball bearing that is attached to a string, that goes through a screw eye, then it attaches to the breaker bar.
    when the correct card is scanned it pulls on the balanced ball bearing, which it will then pull on the breaker bar to unlock the patio door.
    I use a overkill atx power supply to power everything, 12v for the solenoid, 5v for the rfid reader, and 3.3v to power the msp430. Since I have about 5 more atx power supplies sitting around, its not really a waste, just getting use out of something that taking up space in a closet.
    Please ignore all the ScotchLoks that I use. They are one of the best way to connect 2 wires together, and also having 2 bulk containers(2 wire and 3 wire, cnt 500), makes using them a no brainer on projects or other repairs.
    In the video, I am using the older code before I put the reset code in, so I had to manually reset the device every time the card was scanned.

    I am sure that the code can be improved but it works quite well at this time. It has been tested for the past few weeks with out issues. I know my delay kludge could be improved by use of the time but this leaves options open for upgrades at a later date (like adding a stepper motor).
    code http://justinstech.org/wp-content/uploads/2012/07/main.c

    //****************************************************************************** // MSP430F20xx Demo - Timer_A, Ultra-Low Pwr UART 2400 Echo, 32kHz ACLK // M. Buccini / L. Westlund // Texas Instruments Inc. // October 2005 // Built with CCE Version: 3.2.0 and IAR Embedded Workbench Version: 3.40A //****************************************************************************** // // This code has been modified to work with the parallax RFID reader for 2400 baud // It works and all but needs improvment. // Modifications By Justin Solarski // built with MSPGCC and a Text editor...CCE and IAR specific code commented out. // or removed. Delay may not work on CCE or IAR please use built in delay cycles. // Changed from running on the aclk/32K crystal to 8Mhz // removed all TX code because its not needed // // MSP430F20xx // ----------------- // /|\| XIN|- // | | | // --|RST XOUT|- // | | // | p1.7 |------\/\/>100ohm--->tip120 to solonoid // | | 2400 8N1 // | CCI0A/RXD/P1.1|<---------paralax RFID reader // #include //#include //for string comparison //string comparison failed do to non charactors in string........... #define RXD 0x02 // RXD on P1.1 // Conditions for 2400 Baud SW UART, ACLK = 32768 #define Bitime_5 1667 // old = 0x06 ~ 0.5 bit length + small adjustment #define Bitime 3333 // 0x0E = old aclk val 427us bit length ~ 2341 baud e=14 //****************************************************************************** unsigned int RXTXData; unsigned char BitCnt; unsigned char rfidtag[12]; unsigned int tagcnt = 0; unsigned char tag1[12] = {0x0a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0d}; //tag replaced by 0xff for security reasons, I doubt any one wants to break into my place // but just in case they do, they will have to do it the hard way. //****************************************************************************** void RX_Ready (void); void __inline__ msp_delay(register unsigned int n); void Check_rfid(void); //****************************************************************************** void main (void) { WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer BCSCTL1 = CALBC1_8MHZ; // Set range DCOCTL = CALDCO_8MHZ; // Set DCO step + modulation */ TACTL = TASSEL_2 + MC_2; // ACLK, continuous mode // tassel_1 =aclk tassel_2 = smclk P1SEL = RXD; // // P1DIR |= BIT0 + BIT7; P1OUT |= BIT0; P1OUT &= ~BIT7; //****************************************************************************** // Mainloop for (; { RX_Ready(); // UART ready to RX one Byte _BIS_SR(LPM0_bits + GIE); // Enter LPM3 w/ interr until char RXed //****************************************************************************** //when all 12 chars are recieved if ( tagcnt == 12) { Check_rfid(); } else { rfidtag[tagcnt] = RXTXData; tagcnt++; } } } //****************************************************************************** //check if RFID matches known rfid void Check_rfid(void) { unsigned char flag; unsigned int i; while(1) { for(i=0; i<12; i++) { if (rfidtag[i] == tag1[i]) // check tag against one in memory. { flag = 0x01; } //end if else { flag = 0x00; // moved to flag code 0x00, it was redundant to put reset code here // for(i=0; i<12; i++) //incoming data reset to 0 // { // rfidtag[i] = 0; // } // moved to flag code 0x00, it was redundant to put reset code here // tagcnt = 0; // WDTCTL = WDT_MRST_32; //reset msp430 after read and execute // while(1){ msp_delay(50000); } } //end else } //end for if (flag == 0x01) { P1OUT |= BIT7; msp_delay(50000); //delay kludge msp_delay(50000); msp_delay(50000); msp_delay(50000); msp_delay(50000); msp_delay(50000); msp_delay(50000); msp_delay(50000); //end of delay kludge for(i=0; i<12; i++) { rfidtag[i] = 0; } P1OUT ^= BIT7; tagcnt = 0; WDTCTL = WDT_MRST_32; //reset msp430 after read and execute while(1){ msp_delay(50000); } } //end if if (flag == 0x00) { for(i=0; i<12; i++) { rfidtag[i] = 0; } tagcnt = 0; WDTCTL = WDT_MRST_32; //reset msp430 after not the correct tag while(1){ msp_delay(50000); } } } //end while } //****************************************************************************** // delay loop used for mspgcc, if using IAR or CCE please replace with delay cycles void __inline__ msp_delay(register unsigned int n) { __asm__ __volatile__( " 1: \n" " dec %[n] \n" " jne 1b \n" : [n] "+r"(n)); } //****************************************************************************** // Function Readies UART to Receive Character into RXTXData Buffer void RX_Ready (void) { BitCnt = 0x8; // Load Bit counter CCTL0 = SCS + OUTMOD0 + CM1 + CAP + CCIE; // Sync, Neg Edge, Cap } //****************************************************************************** // Timer A0 interrupt service routine //#pragma vector=TIMERA0_VECTOR //__interrupt void Timer_A (void) __attribute__((interrupt(TIMERA0_VECTOR))) void CCR0_ISR(void) { CCR0 += Bitime; // Add Offset to CCR0 if( CCTL0 & CAP ) // Capture mode = start bit edge { CCTL0 &= ~ CAP; // Switch from capture to compare mode CCR0 += Bitime_5; } else { RXTXData = RXTXData >> 1; if (CCTL0 & SCCI) // Get bit waiting in receive latch RXTXData |= 0x80; BitCnt --; // All bits RXed? if ( BitCnt == 0) //>>>>>>>>>> Decode of Received Byte Here <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< { CCTL0 &= ~ CCIE; // All bits RXed, disable interrupt _BIC_SR_IRQ(LPM0_bits); // Clear LPM3 bits from 0(SR) } //>>>>>>>>>> Decode of Received Byte Here <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< } }
    If you have any suggestions, questions or criticism please let me know
    there are pictures of the each component on my blogpost that is linked above
  20. Like
    gordon reacted to spirilis in nrf24L01 registers/commands and functions(work in progress)   
    Got USI, USCI_A, USCI_B all working and confirmed with logic analyzer; had the LaunchPad blinking its red LED with my USCI_B boosterpak installed, responding to periodic (every 250ms) transmissions from an Arduino I had 2ft away. You could see the blinking stop when I hit the arduino's reset button or yanked the nRF transceiver from its shield.
    Likewise with a PTX test program on the MSP, I had an LED plugged into that arduino lighting up with a receiver sketch running on it.
    Need to examine the code/clean up anything excessively ugly and document it, then throw it up on github for all to see!
  21. Like
    gordon got a reaction from EngIP in Hate mail : Need your input   
    I have always thought this to be... strange, to put it this way, but then, since I am registered, it does not matter to me . Other sites where I need a file or three from (mostly bumped into by the grace of Google) I register, grab the stuff, never to return. I will never be a community there just as these people won't be a community here, so what you are left with is basically stuffing in the board database. What good is that for?
  22. Like
    gordon got a reaction from GeekDoc in Ethernet Booster Pack   
    Nah. Solder ain't stupid. Solder flows where it needs to be. Flux, hot iron, flux, good tip, flux, faith, flux, little practice on scrap stuff perhaps, and some more flux.
  23. Like
    gordon reacted to oPossum in AC power usage Booster Pack   
    Here are two design proposals. Up to 6 of each can be stacked to increase channel count.
    The first uses a 12 bit ADC and has 2 channels that can be used for voltage or current and 5 channels that are current only. This could be used for single or split phase applications. Accuracy would be poor at low load due to limited ADC resolution.
    A 2.5 V reference voltage is supplied by the MSP430 and buffered by IC1A. The buffered reference is used by the ADC and also divided by 2 and buffered by IC1B to create a bias for the sensors. The first ADC channel reads the bias voltage so it can be subtracted from the other 7 channels and produce a signed result representing voltages above and below 'zero'.
    Each input has a simple passive first order low pass filter to reduce aliasing. A second or higher order filter would be better, but require many more components.

    The second uses a 24 bit (max) ADC and has 3 channels that can be used for voltage or current and 3 channels that are current only. It could be used for single, split, or 3 phase applications. Accuracy would probably be limited by the voltage and current transformers used. It could approach 'utility grade' precision with careful hardware and firmware design.
    Each input is balanced and ground referenced. TP or STP cable would be used to minimize pickup of unwanted signals in the wiring. Passive first order low pass filter to reduce aliasing.
    The MCP3903 ADC is made for power monitoring applications and has hardware assist for phase lead/lag compensation. This would be a SMD design to ensure maximum performance - ground planes and guarding are critical for high resolution measurement.

  24. Like
    gordon reacted to fj604 in CIR - Infrared remote decoder for NEC protocol   
    A quick demo that can be converted to a library:

    /* Consumer IR receiver demo for the NEC protocol for MSP430G2231 (Launchpad) * Requires a 38kHz IR detector such as Vishay TSOP4838 on Pin 4 (P1.2/TA0.1) * Toggles a LED when a particular IR remote button is pushed * For more details on the NEC protocol, see http://www.sbprojects.com/knowledge/ir/nec.php */ #include // IR pulse timing constants in microseconds #define HP_MIN 8500 // Header pulse minimum duration #define HP_MAX 9500 // Header pulse maximum duration #define HPL_MIN 4100 // Header pulse low minimum duration #define HPL_MAX 4800 // Header pulse low maximum duration #define RPT_MIN 1900 // Repeat pulse minimum duration #define RPT_MAX 2500 // Repeat pulse minimum duration #define BP_MIN 450 // Bit pulse minimum duration #define BP_MAX 650 // Bit pulse maximum duration #define ONE_MIN 2000 // Logical one minumum duration #define ONE_MAX 2500 // Logical one maxumum duration #define ZERO_MIN 1000 // Logical zero minumum duration #define ZERO_MAX 1300 // Logical zero maxumum duration #define FALSE 0 #define TRUE (!FALSE) #define IR_REPEAT 0xFF00 // Special repeat code #define MAX_DATA_BITS 32 // NEC protocol provides for 32 bits of data #define PIN_IR BIT2 // This must be TA0.1 #define PIN_LED1 BIT0 // LED1 on the Launchpad #define BUTTON_POWER 0x00FD00FF // This is a code for the button to toggle the LED static volatile unsigned long data; void ir_init(void) { _disable_interrupts(); BCSCTL1 = CALBC1_1MHZ; // Set DCO to 1MHz to measure pulses in microseconds DCOCTL = CALDCO_1MHZ; P1DIR &= ~PIN_IR; // Set IR detector pin to input P1OUT |= PIN_IR; // Set resistor to pull-up P1REN |= PIN_IR; // Enable resistor P1SEL = PIN_IR; // set IR detector pin to peripheral function TACTL = TASSEL_2 | ID_0 | MC_2; // SMCLK, Continuous mode, Input divider /1 TACCTL1 = CM_3 | CCIS_0 | CAP | CCIE; // Capture on both edges, Capture Input Select CCI0A, Capture mode, Capture interrupt enable _enable_interrupts(); } void main(void) { WDTCTL = WDTPW | WDTHOLD; // Stop the Watchdog timer P1DIR = PIN_LED1; // LED1 to output ir_init(); // Initialize IR detection for (; // Loop forever { _low_power_mode_0(); // Wait in LPM0 until the IR remote code is received // Set a breakpoint on the next line and add a watch for the data variable to see the IR code received if (data == BUTTON_POWER) // If remote power button is pressed P1OUT ^= PIN_LED1; // Toggle LED1 } } #pragma vector=TIMERA1_VECTOR __interrupt void timer_A_interrupt(void) { static unsigned char hp, hr; //header pulse received, header received static unsigned char br; // bits received static unsigned char pulse=FALSE; // pulse in progress static volatile unsigned char ready = FALSE; // data ready static unsigned int pw=0, bw=0; // pulse width, bit width unsigned int i = TAIV; // Read TAIV to clear CCIFG // Is this the beginning or the end of the pulse? if (!pulse) // start of the pulse { bw=TACCR1; // reset Timer TACTL |= TACLR; pulse=TRUE; // Has the header pulse just been received? if (hp) { // Is the header duration in range? if (bw>HPL_MIN && bw { hr=TRUE; br=0; data=0; ready=FALSE; } // is it a repeat code? else if (bw>RPT_MIN && bw { data=IR_REPEAT; hr=FALSE; ready=TRUE; } } // Was there a bit pulse before, and also has the header been received? if(hr && pw>BP_MIN && pw { if (bw>ONE_MIN && bw { data<<=1; data++; br++; } else if (bw>ZERO_MIN && bw { data<<=1; br++; } if (br==MAX_DATA_BITS) { hr=FALSE; ready=TRUE; } } hp=FALSE; } else // end of the pulse { pw=TACCR1; pulse=FALSE; // Is this a header pulse? if (pw>HP_MIN && pw { // set Header Pulse Received flag hp=TRUE; // Reset timer TACTL |= TACLR; } else { hp=FALSE; } } if (ready) { ready = FALSE; _low_power_mode_off_on_exit(); // Return from LPM } }
    (edited - added a pullup resistor setting)
  25. Like
    gordon reacted to GeekDoc in taking a short leave   
    Back from vacation. I'm jumping on this today. Keeping fingers crossed...
    EDIT: Good grief those backups are huge files! WIN7 64-bit (8GB RAM) with MySQL server (32 bit) won't open the file. :x
    Ubuntu to the rescue! Set up an Ubuntu box, added MySQL Server, FINALLY restored one of the backups to work on.
    I can see jsolarski's posts and user file. I'm hoping that's all that's needed to get him back. Now to work up a script... :think:
  • Create New...