Jump to content
43oh

tripwire

Members
  • Content Count

    193
  • Joined

  • Last visited

  • Days Won

    14

Posts posted by tripwire

  1. I don't know which USB connector is stronger. My gut instinct is that smaller == more fragile so I imagine that the miniB is stronger.

     

    In theory it's supposed to be the other way around. The micro USB connectors were designed after mini USB, and fixed some flaws in the physical design.

     

    Mini USB was originally designed for up to 1000 connect/disconnect cycles, which is not a lot. Micro USB was designed for up to 10000 cycles (still not a lot, but probably good enough for most uses). One of the changes was to move the parts that are likely to fail from the socket to the plug. That generally makes replacement easier.

     

    That said, mini USB does feel nicer to use due to the extra bulk. I've never broken a micro USB, but the plugs do feel liable to snap off whenever you use them.

  2. Have you made a declaration (aka prototype) of the GetData function in any of the header files included before your main function? If not, and you're compiling as C rather than C++ you'll run into this:

     

    "If the expression that precedes the parenthesized argument list in a function call consists solely of an identifier, and if no declaration is visible for this identifier, the identifier is implicitly declared exactly as if, in the innermost block containing the function call, the declaration

     

    extern int identifier();

     

    appeared." (ANSI C standard)

     

    In that case, as far as main is concerned the GetData function returns an int rather than a float.

  3. I am trying to interface an  msp430f169 with a miniSD and i have this errors:

    #10010 errors encountered during linking; " project  " not built

    #10234-D unresolved symbols remain 
    unresolved symbol main, first referenced in C:\ti\ccsv6\tools\compiler\msp430_4.3.1\lib\rts430_eabi.lib<boot.obj>

     

    The highlighted part means that the compiler can't find your main function (ie it doesn't know where the program starts). Do you have another file in the project that defines main?

     

    Edit: By the way, if you're going to post code it's best to use the syntax highlighter (the button that looks like this: <>). Sometimes the forum software messes up the formatting or turns your punctuation into emoticons if you don't :)

  4. This turned out to be an interesting one, and you're probably going to kick yourself when you see why fgets wasn't working for you...
     
    Initially my gut feeling was that there was no support for reading from the console window on the target*. Having dug a little further I found that the CIO system does support reading from the target side, so I set up a test program to try it out. It didn't work. I noticed that you'd mentioned setting the heap size, so I set mine. That fixed printf but not fgets.
     
    Stepping into the library code revealed that the problem was with allocating the stream buffer for stdin. I'd set the heap to 512 bytes, and each stream requires 256 bytes buffer space plus 32 bytes of header. The printf call was allocating a buffer for stdout and then the heap had insufficient space to allocate a buffer for stdin. While printf causes the program to exit when it fails to initialise the buffer, fgets and getc just return immediately.
     
    Setting the heap size greater than 576 bytes fixed the issue for me.
     



    * Mainly because I've never seen anyone else even try it - stdio.h is commonly regarded as being a bit "heavyweight" for MSP430. The default stream buffer size is bigger than the ram on the msp430g2553! Most example code I've seen uses the UART backchannel instead, or at least a very cut-down printf implementation with a much smaller buffer.
  5. Further to wasson65's reply, I'd suggest it's not helped by the move to higher-level languages in Computer Science courses.

     

    Embedded programming's emphasis on runtime performance, safety/reliability and minimal footprint encourages the use of lower-level languages. There's a gradual shift from assembly to C and C++ for embedded work, but it's behind the curve of programming in general.

     

    Although CS courses tend to focus on the theoretical side of Computer Science, specific languages are usually taught in the first year. For a lot of students these languages become their default choice when completing practical assignments. If you've spent 3 or 4 years of your life programming in Java or C# then the switch to assembly or even C can come as quite a culture shock.

     

    When I was at university the programming tuition had just switched from C to C++ with STL. The migration path back from C++ down through C and assembly is pretty clear; you just stop using the higher level features of C/C++/STL and treat the compiler like a more advanced assembler. Then you start reading the disassembly of your programs to see what's going on under the hood. I wouldn't even know where to begin that process if I had to start with a language that runs bytecode in a virtual machine.

     

    Something that may help to reverse the trend is the easy availability of cheap embedded development platforms (eg MSP430 Launchpad :smile:). The information you need to get started is much more easily available these days, and there's better visibility of hobbyist embedded developers who can act as role models.

  6. Here are a few things I noticed:

     

    P1IN is a read-only register that gives the current state of the port 1 pins. Writing to it has no effect. That said, assuming you want P1.2 to be treated as input all should be well - P1DIR bit 2 is set to zero by the next line.

     

    The globals datareceived, Rxbuff, Rxdatalen, Rxtoutcnt should be volatile, since they're accessed in various ISRs as well as from the main loop. If this isn't done there's a risk that the compiler might treat them as having constant values (it doesn't account for interrupts changing the flow of execution).

     

    The code looks susceptible to problems caused by interrupts firing during transmit. The data being processed by serialmsg could end up in an inconsistent state.

     

    Finally, you said that you're not getting the output. Do you mean that it's not received by the other device (whatever that might be), or that the serialmsg function isn't even being called? You appear to be using P1.3 as a debug output pin, so have you tried setting that at different points in the code to see what's actually being executed?

  7. KickSat is currently due to launch this weekend, on 30th March. Assuming all goes to plan there should be over a hundred MSP430s in low earth orbit, for a few days at least :)

     

    http://forum.43oh.com/topic/1249-kicksat-your-personal-spacecraft-in-space/

    http://en.wikipedia.org/wiki/KickSat

    https://www.kickstarter.com/projects/zacinaction/kicksat-your-personal-spacecraft-in-space/

     

    EDIT: Launch delayed again :(

     

    EDIT2: KickSat is in orbit! The individual sprites aren't deployed from the cubesat yet. I think the plan is to do that on April 30th (430 day :))

  8. I don't think you want to select tertiary function for P1.6 and P1.7 - take a look at page 74 of the datasheet.

     

    UCB0SDA on P1.6 and UCB0SCL on P1.7 are selected when bits 6 and 7 of P1SEL1 are set to one and the corresponding bits of P1SEL0 are zero.

     

    The USCI module will automatically send the R/W bit along with the address. That's something to be wary of, as some I2C peripherals give an 8 bit address which includes the R/W bit already.

  9. You're right about not needing to hold the USCI module in reset between the initialisation and master transmitter mode initiation. The module will just wait for UCTXSTT to be set before starting to do anything.

     

    The updated interrupt looks ok, but you need to use UCB0CTLW0 & UCTXSTT rather than UCB0CTLW0 && UCTXSTT as the condition ("bitwise and" rather than "logical and").

     

    There's something else I totally forgot to mention - you'll need to set up the port registers appropriately to connect the USCI to the outside world. The pinouts vary per chip and package, so the information on that is in the datasheet for the MSP430FR5739 rather than the family user guide.

  10. The MSP430FR5739 has the enhanced eUSCI_B module, which is slightly different to the USCI_B on the g2xx series chips. The eUSCI_B doesn't have UCBxCTL0 and UCBxCTL1 registers (they've been merged into UCBxCTLW0). Interestingly the example initialization sequence in section 20.3.1 of the MSP430FR57xx Family User's Guide hasn't been updated to account for the change. Unless the FR57 headers have some backward compatibility support for USCI_B register names the guide needs to be corrected.

     

    EDIT: Looking at the User's Guide again I see that UCBxCTL0 and UCBxCTL1 are available on FR57 parts. They just alias the appropriate bytes of UCBxCTLW0. When using UCBxCTL0 or UCBxCTL1 it looks like you need to append _L or _H (respectively) onto the names of any bit constants to get the correct value.

     

    I think the initialization sequence needs to look like this:

    UCB0CTLW0 = UCSWRST; // put eUSCI_B in reset state
    UCB0CTLW0 = UCMODE_3 | UCMST | UCSSEL__SMCLK | UCSWRST; // I2C master mode, SMCLK, retain reset flag state
    UCB0BRW = 0x0008; //clock scaler
    
    UCB0CTLW0 &= ~UCSWRST; // eUSCI_B in operational state (clear reset flag)
    UCB0IE |= UCTXIE0; // Enable TX interrupt for address 0
    

    The "get things going" block looks ok (apart from a couple more uses of UCB0CTL1). You might have issues due to taking the module out of reset before setting the slave address. I'm not sure on that though, the fact that UCTR is clear at that time might mean it's safe.

     

    In the interrupt I think you're clearing UCTR and setting UCTXSTT too early. According to the timeline diagrams in the user guide you should wait for UCTXIFG0 to go high again after you set UCB0TXBUF to the command value.

     
    The receive looks ok, though I've not used USCI_B interrupts before so can't be sure.

  11.  

    [...] but what I would like to do is something more like this

    *read bytes*
    if (Line == '[start config]'){
    printf("it matches");
    }

    but this fails because "Line" is a 64 byte long buffer and I only read 14 bytes into it, so the rest of the garbage space is still there.

     

    If Line is an array of char, then the reason this won't work is a bit more subtle than that.

     

    C and C++ don't support equality comparison of native arrays. That means that (Line == "[start config]") doesn't compare each element of Line with the corresponding elements of the "[start config]" string literal. Instead, Line and "[start config]" both decay to pointers to their first elements. Then the values of those pointers are compared. The two arrays are at different locations in memory, so the two pointers will never match.

  12. I've not tried it myself, but I hear some players have been comparing msp430 simulators against the game's emulation to see where it doesn't match the spec. There's been at least one difference found that can save a cycle in some cases. The one I stumbled upon was the opposite; according to the spec it should have saved a cycle, but the incorrect emulation made it a no-go :angry:

  13. I've been quite enjoying* this. At first I didn't think they'd be able to come up with enough inventive ways for the lock designers to foul up, but so far they're keeping it fairly fresh. Hopefully the BitLock team haven't made any of these mistakes!

     

    One nice feature that's not immediately obvious is the Hall of Fame, which has per level stats for every player (date completed, shortest input length, fewest cycles used). There's also an assembler/disassembler page which is handy, though unfortunately it doesn't give instruction cycle counts.

     

    Also, I liked this gem from the game's about page:

    • Zero bottles of beer on the wall, zero bottles of beer; take one down, pass it around, 65535 bottles of beer on the wall.

     

    * Well, I say enjoying, but I spend most of my time cursing the guys who've solved the levels in fewer cycles or less input bytes than I can manage :)

  14. It looks like your flag_RPSTART gets cleared too soon.

     

    The call to TI_USCI_I2C_transmitre(1, whoamireg) sets byteCtr to 1. When the USCI is ready for the first (and only) byte of the transmission it triggers USCIAB0TX_ISR which sets UCB0TXBUF to the value of whoamireg and decrements byteCtr. Unfortunately it also clears flag_RPSTART. Once the UCB0TXBUF is ready for the next byte the USCIAB0TX_ISR gets triggered again, but this time byteCtr == 0 and flag_RPSTART == 0, so the stop condition is sent.

  15. It sounds similar to the Digilent Analog Discovery (specs), but with separate extension boards for logic analyser and oscilloscope functionality. The sample rates are the same, but the sample buffer is a lot larger.

     

    Also, it's good that they're making the software open source. I've found a few minor annoyances in Digilent's software (specifically the protocol decoders) that I wish I could fix.

     

    Unfortunately it doesn't appear to have an AWG or pattern generator, which is disappointing as they're really useful on the AD. Nor does it have a case, which looks cool but is a bit inconvenient!

  16. I have assumed basing on the observation with the uart_puts() added to Timer0 and ADC12 ISRs. For Timer0 one it works, for ADC12's doesn't.

     

    Ok, it's most likely not getting into the ADC12 ISR then (unless something weird's going on with the uart_puts call from inside ADC12 ISR).

     

    Looking at whether the example code works correctly is probably the best thing to try next.

     

    Additionally if it would go into ADC12_ISR then it would wake up the CPU just like it does when entering Timer0_ISR.

     

    It would wake the CPU up, but if the ADC12IFG0 flag is never cleared and GIE is set execution would be stuck in an infinite loop. As soon as the return from the ISR executes it would immediately retrigger. The code after __bis_status_register(LPM0_bits + GIE) in get_adc_data() wouldn't get chance to run, so it would appear as if the CPU was still asleep.

  17. I'm not familiar with ADC12, but am a bit suspicious of that ADC ISR. It never clears ADC12IFG0 and leaves GIE set on exit. I think that means it's possible for the ISR to trigger repeatedly, blocking execution from reaching the line that reads ADC12MEM0 (and clears ADC12IFG0 as a side effect).

     

    EDIT: Looking back at the 2-series ADC10 docs, ADC10IFG gets cleared automatically on entry to the ISR as it's a single-source interrupt vector. That fits in with your observation that the equivalent code worked on msp430g2553.

     

    That said, I'm not sure why the Timer ISR would unblock execution after 5s if this is what's happening.

  18.  

    That's a nice way to calibrate without needing external components (other than a PC, which you kind of need anyway :))

     

    I was going to suggest a rather more hands-on approach.

     

    1) Write a program to toggle the red LED every second and the green one every minute (assuming a DCO frequency of 1MHz)

    2) Start the program, and compare the blink rate with a stopwatch

    3) Tweak the DCO settings up or down as appropriate to get the green LED flash frequency to match the minutes on the stopwatch.

    4) Write down the DCO settings that produce the desired frequency

    5) Repeat for 8, 12 and 16MHz

    6) Write another program to flash the various calibration values to the information memory

     

    Simple! ;)

×
×
  • Create New...