Jump to content
43oh

oPossum

Members
  • Content Count

    925
  • Joined

  • Last visited

  • Days Won

    103

Reputation Activity

  1. Like
    oPossum got a reaction from JonnyBoats in How to solder HTSSOP heatsink without reflowing the board?   
    It is possible to do thermal pads without a reflow oven or hot air.
     

  2. Like
    oPossum got a reaction from yyrkoon in SocketCAN help needed   
    Have you ever seen any frames with more than 16 packets? Maybe the lower nibble of the first byte is the packet sequence and the upper nibble can be ignored.
  3. Like
    oPossum got a reaction from yyrkoon in SocketCAN help needed   
    Checking for proper sequence...
    (only changed code shown)
     

    struct Fastpacket { unsigned char *bufferEnd; // End of buffer + 1 unsigned char *bufferPos; // Next char goes here unsigned char seq; // Next char in sequence }; struct Fastpacket *newFastpacket(size_t const size){ // Allocate enough memory for the structure and the buffer struct Fastpacket *retVal = malloc(sizeof(struct Fastpacket) + (size * sizeof(unsigned char))); if(retVal) { // Buffer begins after the structure retVal->bufferPos = (unsigned char *)(retVal + 1); retVal->bufferEnd = retVal->bufferPos + size; retVal->seq = 0x40; } return retVal; } int appendFrame(struct Fastpacket *fastpacket, unsigned char const *msg){ if(msg[0] != fastpacket->seq) { // Check if incorrect sequence fastpacket->seq = 0x40; // Start over return -1; // Return error } ++fastpacket->seq; // Increment sequence unsigned char const * const msgEnd = msg + 8; while((msg < msgEng) && (fastpacket->bufferPos < fastpacket->bufferEnd)) *(fastpacket->bufferPos)++ = *msg++; return 0; }
  4. Like
    oPossum got a reaction from yyrkoon in SocketCAN help needed   
    Nothing wrong with what you have written.
     
    If you want it a little faster and smaller with a little less memory fragmentation, here is some optimized code...
     

    struct Fastpacket { unsigned char *bufferEnd; // End of buffer + 1 unsigned char *bufferPos; // Next char goes here }; struct Fastpacket *newFastpacket(size_t const size){ // Allocate enough memory for the structure and the buffer struct Fastpacket *retVal = malloc(sizeof(struct Fastpacket) + (size * sizeof(unsigned char))); if(retVal) { // Buffer begins after the structure retVal->bufferPos = (unsigned char *)(retVal + 1); retVal->bufferEnd = retVal->bufferPos + size; } return retVal; } void delFastpacket(struct Fastpacket *fastpacket){ if(fastpacket) free(fastpacket); } void appendFrame(struct Fastpacket *fastpacket, unsigned char const *msg){ unsigned char const * const msgEnd = msg + 8; while((msg < msgEng) && (fastpacket->bufferPos < fastpacket->bufferEnd)) *(fastpacket->bufferPos)++ = *msg++; } int main(int argc, char *argv[]) { int i; struct Fastpacket *fastpacket = newFastpacket(88); if(!fastpacket) return -1; appendFrame(fastpacket, msg01); appendFrame(fastpacket, msg02); appendFrame(fastpacket, msg03); appendFrame(fastpacket, msg04); appendFrame(fastpacket, msg05); appendFrame(fastpacket, msg06); appendFrame(fastpacket, msg07); appendFrame(fastpacket, msg08); appendFrame(fastpacket, msg09); appendFrame(fastpacket, msg10); appendFrame(fastpacket, msg11); unsigned char const *b = (unsigned char*)(fastpacket + 1); int const len = fastpacket->bufferPos - b; for(i = 0; i < len; ++i) printf("%02X%s" , *b++, ((i & 7) == 7) ? "\n" : " "); printf("\nBuffer position is currently at: %d\n", len); delFastpacket(fastpacket); return 0; }
  5. Like
    oPossum got a reaction from bluehash in SocketCAN help needed   
    Checking for proper sequence...
    (only changed code shown)
     

    struct Fastpacket { unsigned char *bufferEnd; // End of buffer + 1 unsigned char *bufferPos; // Next char goes here unsigned char seq; // Next char in sequence }; struct Fastpacket *newFastpacket(size_t const size){ // Allocate enough memory for the structure and the buffer struct Fastpacket *retVal = malloc(sizeof(struct Fastpacket) + (size * sizeof(unsigned char))); if(retVal) { // Buffer begins after the structure retVal->bufferPos = (unsigned char *)(retVal + 1); retVal->bufferEnd = retVal->bufferPos + size; retVal->seq = 0x40; } return retVal; } int appendFrame(struct Fastpacket *fastpacket, unsigned char const *msg){ if(msg[0] != fastpacket->seq) { // Check if incorrect sequence fastpacket->seq = 0x40; // Start over return -1; // Return error } ++fastpacket->seq; // Increment sequence unsigned char const * const msgEnd = msg + 8; while((msg < msgEng) && (fastpacket->bufferPos < fastpacket->bufferEnd)) *(fastpacket->bufferPos)++ = *msg++; return 0; }
  6. Like
    oPossum got a reaction from yyrkoon in SocketCAN help needed   
    Looks like this is the code that does the printing in your candump example...
     

    void sprint_long_canframe(char *buf , struct can_frame *cf, int view) { /* documentation see lib.h */ int i, j, dlen, offset; int dlc = (cf->can_dlc > 8)? 8 : cf->can_dlc; if (cf->can_id & CAN_ERR_FLAG) { sprintf(buf, "%8X ", cf->can_id & (CAN_ERR_MASK|CAN_ERR_FLAG)); offset = 10; } else if (cf->can_id & CAN_EFF_FLAG) { sprintf(buf, "%8X ", cf->can_id & CAN_EFF_MASK); offset = 10; } else { sprintf(buf, "%3X ", cf->can_id & CAN_SFF_MASK); offset = 5; } sprintf(buf+offset, "[%d]", dlc); offset += 3; ..... So it does mask off the address bits and also prints 3 or 8 hex digits as needed.
  7. Like
    oPossum got a reaction from yyrkoon in SocketCAN help needed   
    Bit 31 of can_frame.can_id indicates if an 11 or 29 bit address is used. It is probably being masked by the candump program because it is not actually part of the address.
     
    It would be nice if the candump program used 3 or 8 hex digits to indicate the address size in use.
     
    Using a stream (socket) for a block based protocol seems like a bad idea. Much that can go wrong.
  8. Like
    oPossum reacted to maelli01 in Tiny Chip-on-glass LCD with ST7565 controller   
    Connected one of those
     
    http://www.newhavendisplay.com/lcd-chiponglass-128-x-32-c-3_113.html
     
    to the launchpad. These are really tiny chip-on-glass LCD displays. The visible area is 8 x 32mm.
     

     
    More tricky than the software is the hardware: in order to work, I had to connect nine 1uF ceramic caps
    to the display (I guess that with the chip-on-glass display it is not possible to integrate the caps into he display).
     
    Made a small,hand etched, one sided PCB, to accomodate the caps and to change from the weird 1.5mm connector
    pitch to a 2.54 one.
     

     
    6502 for size comparison only ;-)
     
    RobG's Nokia software helped me to get the hardware SPI right. Software-SPI, works as well, advantage is the free choice 
    of the pins, but more processor time is wasted for the display.
     
    I measured 85uA, with the example clock program (Display + MSP in LPM3), without backlight. So power-wise this 
    fits perfectly with the MSP. 
    Official working voltage is 2.7-3.3V. The 3.6V of the LP are the maximum rating for the display. 
     
    The backlight is already bright enough for me with 2mA. So switching the backlight on/offwith an extra pin would be easy.
    #include "msp430g2553.h" const unsigned char font5x8[][5] ={ { 0x00, 0x00, 0x00, 0x00, 0x00 }, // sp { 0x00, 0x00, 0x2f, 0x00, 0x00 }, // ! { 0x00, 0x07, 0x00, 0x07, 0x00 }, // " { 0x14, 0x7f, 0x14, 0x7f, 0x14 }, // # { 0x24, 0x2a, 0x7f, 0x2a, 0x12 }, // $ { 0x62, 0x64, 0x08, 0x13, 0x23 }, // % { 0x36, 0x49, 0x55, 0x22, 0x50 }, // & { 0x00, 0x05, 0x03, 0x00, 0x00 }, // ' { 0x00, 0x1c, 0x22, 0x41, 0x00 }, // ( { 0x00, 0x41, 0x22, 0x1c, 0x00 }, // ) { 0x14, 0x08, 0x3E, 0x08, 0x14 }, // * { 0x08, 0x08, 0x3E, 0x08, 0x08 }, // + { 0x00, 0x00, 0x50, 0x30, 0x00 }, // , { 0x08, 0x08, 0x08, 0x08, 0x08 }, // - { 0x00, 0x60, 0x60, 0x00, 0x00 }, // . { 0x20, 0x10, 0x08, 0x04, 0x02 }, // / { 0x3E, 0x51, 0x49, 0x45, 0x3E }, // 0 { 0x00, 0x42, 0x7F, 0x40, 0x00 }, // 1 { 0x42, 0x61, 0x51, 0x49, 0x46 }, // 2 { 0x21, 0x41, 0x45, 0x4B, 0x31 }, // 3 { 0x18, 0x14, 0x12, 0x7F, 0x10 }, // 4 { 0x27, 0x45, 0x45, 0x45, 0x39 }, // 5 { 0x3C, 0x4A, 0x49, 0x49, 0x30 }, // 6 { 0x01, 0x71, 0x09, 0x05, 0x03 }, // 7 { 0x36, 0x49, 0x49, 0x49, 0x36 }, // 8 { 0x06, 0x49, 0x49, 0x29, 0x1E }, // 9 { 0x00, 0x36, 0x36, 0x00, 0x00 }, // : { 0x00, 0x56, 0x36, 0x00, 0x00 }, // ; { 0x08, 0x14, 0x22, 0x41, 0x00 }, // < { 0x14, 0x14, 0x14, 0x14, 0x14 }, // = { 0x00, 0x41, 0x22, 0x14, 0x08 }, // > { 0x02, 0x01, 0x51, 0x09, 0x06 }, // ? { 0x32, 0x49, 0x59, 0x51, 0x3E }, // @ { 0x7C, 0x12, 0x11, 0x12, 0x7C }, // A { 0x7F, 0x49, 0x49, 0x49, 0x36 }, // B { 0x3E, 0x41, 0x41, 0x41, 0x22 }, // C { 0x7F, 0x41, 0x41, 0x22, 0x1C }, // D { 0x7F, 0x49, 0x49, 0x49, 0x41 }, // E { 0x7F, 0x09, 0x09, 0x09, 0x01 }, // F { 0x3E, 0x41, 0x49, 0x49, 0x7A }, // G { 0x7F, 0x08, 0x08, 0x08, 0x7F }, // H { 0x00, 0x41, 0x7F, 0x41, 0x00 }, // I { 0x20, 0x40, 0x41, 0x3F, 0x01 }, // J { 0x7F, 0x08, 0x14, 0x22, 0x41 }, // K { 0x7F, 0x40, 0x40, 0x40, 0x40 }, // L { 0x7F, 0x02, 0x0C, 0x02, 0x7F }, // M { 0x7F, 0x04, 0x08, 0x10, 0x7F }, // N { 0x3E, 0x41, 0x41, 0x41, 0x3E }, // O { 0x7F, 0x09, 0x09, 0x09, 0x06 }, // P { 0x3E, 0x41, 0x51, 0x21, 0x5E }, // Q { 0x7F, 0x09, 0x19, 0x29, 0x46 }, // R { 0x46, 0x49, 0x49, 0x49, 0x31 }, // S { 0x01, 0x01, 0x7F, 0x01, 0x01 }, // T { 0x3F, 0x40, 0x40, 0x40, 0x3F }, // U { 0x1F, 0x20, 0x40, 0x20, 0x1F }, // V { 0x3F, 0x40, 0x38, 0x40, 0x3F }, // W { 0x63, 0x14, 0x08, 0x14, 0x63 }, // X { 0x07, 0x08, 0x70, 0x08, 0x07 }, // Y { 0x61, 0x51, 0x49, 0x45, 0x43 }, // Z { 0x00, 0x7F, 0x41, 0x41, 0x00 }, // [ { 0x04, 0x08, 0x10, 0x20, 0x40 }, // / { 0x00, 0x41, 0x41, 0x7F, 0x00 }, // ] { 0x04, 0x02, 0x01, 0x02, 0x04 }, // ^ { 0x40, 0x40, 0x40, 0x40, 0x40 }, // _ { 0x00, 0x01, 0x02, 0x04, 0x00 }, // ' { 0x20, 0x54, 0x54, 0x54, 0x78 }, // a { 0x7F, 0x48, 0x44, 0x44, 0x38 }, // b { 0x38, 0x44, 0x44, 0x44, 0x20 }, // c { 0x38, 0x44, 0x44, 0x48, 0x7F }, // d { 0x38, 0x54, 0x54, 0x54, 0x18 }, // e { 0x08, 0x7E, 0x09, 0x01, 0x02 }, // f { 0x18, 0xA4, 0xA4, 0xA4, 0x7C }, // g { 0x7F, 0x08, 0x04, 0x04, 0x78 }, // h { 0x00, 0x44, 0x7D, 0x40, 0x00 }, // i { 0x40, 0x80, 0x84, 0x7D, 0x00 }, // j { 0x7F, 0x10, 0x28, 0x44, 0x00 }, // k { 0x00, 0x41, 0x7F, 0x40, 0x00 }, // l { 0x7C, 0x04, 0x18, 0x04, 0x78 }, // m { 0x7C, 0x08, 0x04, 0x04, 0x78 }, // n { 0x38, 0x44, 0x44, 0x44, 0x38 }, // o { 0xFC, 0x24, 0x24, 0x24, 0x18 }, // p { 0x18, 0x24, 0x24, 0x18, 0xFC }, // q { 0x7C, 0x08, 0x04, 0x04, 0x08 }, // r { 0x48, 0x54, 0x54, 0x54, 0x20 }, // s { 0x04, 0x3F, 0x44, 0x40, 0x20 }, // t { 0x3C, 0x40, 0x40, 0x20, 0x7C }, // u { 0x1C, 0x20, 0x40, 0x20, 0x1C }, // v { 0x3C, 0x40, 0x30, 0x40, 0x3C }, // w { 0x44, 0x28, 0x10, 0x28, 0x44 }, // x { 0x1C, 0xA0, 0xA0, 0xA0, 0x7C }, // y { 0x44, 0x64, 0x54, 0x4C, 0x44 }, // z { 0x08, 0x36, 0x41, 0x41, 0x00 }, // { { 0x00, 0x00, 0x7F, 0x00, 0x00 }, // | { 0x41, 0x41, 0x36, 0x08, 0x00 }, // } { 0x02, 0x04, 0x02, 0x01, 0x02 } // ~ }; unsigned char hour=12, min, sec,j; void clearline(unsigned char); void clearall(void); void print( char* s); void gotoXy(unsigned char , unsigned char); void printc(unsigned char r); void sendData(unsigned char data); void sendCmd(unsigned char cmd); //lcd connected to port 0 #define A0 BIT2 #define CS BIT3 #define SCK BIT5 #define SDA BIT7 #define RST BIT6 void main(void) { WDTCTL = WDT_ADLY_1000; // WDT 1sec, ACLK, interval timer IE1 |= WDTIE; // Enable WDT interrupt BCSCTL1 = CALBC1_1MHZ; DCOCTL = CALDCO_1MHZ; P1DIR = 0b11101100; P1REN = 0b00010011; P2REN = 0b00111111; P1SEL |=SCK + SDA; P1SEL2|=SCK + SDA; UCB0CTL0 |= UCCKPH + UCMSB + UCMST + UCSYNC; // 3-pin, 8-bit SPI master UCB0CTL1 |= UCSSEL_2; // SMCLK UCB0BR0 |= 0x01; // 1:1 UCB0BR1 = 0; UCB0CTL1 &= ~UCSWRST; // clear SW P1OUT &= ~RST; __delay_cycles(1000); P1OUT |= RST; P1OUT &=~A0; P1OUT &=~CS; //Initialize LCD display //see http://www.newhavendisplay.com/specs/NHD-C12832A1Z-FSRGB-FBW-3V.pdf for command set sendCmd(0xA1); //ADC select reverse mode sendCmd(0xA2); // 1/7 bias sendCmd(0x2F); //VC on, VR on, VF on sendCmd(0x21); //resistor ratio 3.5 sendCmd(0x81); //set contrast sendCmd(0x27); //adjust this number to get the best contrast sendCmd(0xAF); //now turn it on! clearall(); gotoXy(0,20); print("MSP430G2553 LCD"); gotoXy(1,35); print("2015-05-22"); while (1){ sec++; if (sec==60){ sec=0; clearline(2); min++; if (min==60){ min=0; hour++; if (hour==24) hour=0; } } gotoXy(3,40); printc((hour/10%10)+48); printc((hour%10)+48); printc(':'); printc((min/10%10)+48); printc((min%10)+48); printc(':'); printc((sec/10%10)+48); printc((sec%10)+48); gotoXy(2,sec); print("Hello World!"); __bis_SR_register(LPM3_bits + GIE); // Enter LPM3 w/interrupt } } // Watchdog Timer interrupt service routine #pragma vector=WDT_VECTOR __interrupt void watchdog_timer(void){ __bic_SR_register_on_exit(CPUOFF); // wake up } void clearall(void){ unsigned char i; for(i = 0; i<4 ; i++) clearline(i); } void clearline(unsigned char line){ unsigned char j; sendCmd(0xB0 | line); //sets page(row) sendCmd(0x10); //sets column address(MSB) to 0 for each page(row) sendCmd(0x04); //sets Column address(LSB) start, for this display 4 for(j=0;j<128;j++) {sendData(0x00);} } void sendData(unsigned char data){ P1OUT |=A0; UCB0TXBUF = data; while(!(IFG2 & UCB0TXIFG)); } void sendCmd(unsigned char cmd){ P1OUT &=~A0; UCB0TXBUF = cmd; while(!(IFG2 & UCB0TXIFG)); } void gotoXy(unsigned char x,unsigned char y){ y+=4; //this display does not show first four lines sendCmd(0xB0|(x & 0x03)); sendCmd(0x10|((y>>4))); sendCmd(0x00|(y & 0x0F)); } void print(char* s){ while(*s) printc(*s++); } void printc(unsigned char r){ unsigned char i; sendData(0); for (i=0;i<5;i++) sendData(font5x8[r-32][i] ); }
  9. Like
    oPossum reacted to austen520 in Self-balancing PID robot w/ code + schematic + UART tool   
    I recently completed a final project for an undergrad circuits class, throughout which this forum was a huge help, and so I just wanted to try and give back a little by presenting our code here. The project was, as you may have guessed, a two-wheeled self-balancing robot via a PID controller:

     
    We used an MSP430G2553 with the EXP430G2 launchpad, although the code should of course be applicable to any similar MCU. We also used the apparently popular MPU6050 IMU to produce angle estimates, and a simple H-bridge using TIP-102 transistors for motor control. The schematic that I've attached is a complete reproduction of our setup (including our pin configuration), and can also be found on the github linked to at the bottom of this post.
     
    The files that describe the primary control sequences are main.c, which of course has the setup and main loop, as well as the PID controller code; and StateEstimate.c, which describes how the raw IMU data is combined into a more accurate estimate of the robot's current angle with the ground (we used the so-called "complementary filter" with reasonable success, which just sums a low-passed accelerometer reading with a high-passed gyroscope reading). Furthermore, the parameters for the PID controller are located in Config.h (the parameters currently in the repo are just toy values), and the parameters for the state estimator are located in StateEstimate.h.
     
    The two biggest frustrations we faced when developing the project was successfully communicating with the MPU6050 over I2C (included in the github is the i2c device library, separately available at http://www.i2cdevlib.com),and getting useful information sent over a UART connection. So, I hope that by releasing this code we can make those tasks at least a little bit smoother for people tackling the same problems. The code is set up, by default, to use pins 1.1 and 1.2 for UART communication over the hardware serial interface. The MSP430 will send the angle estimate and PID control signal over UART, which can be captured and saved as a CSV, or even displayed in an OpenGL gui, using the supplied serialReader.py python utility (instructions are in the repository README). Using the supplied C code as a template, sending and receiving arbitrary data for post-processing should hopefully be trivial. UART is configured in main.c, and the functions for sending data over the connection are located in hwuart.c.
     
    Link to github: https://github.com/austensatterlee/robotbuddy
     
    Anyway, I hope this is helpful or at least interesting to some of you. I'd be happy to answer any questions about how we got this working, or receive any criticisms from more knowledgeable members!

  10. Like
    oPossum reacted to spirilis in MSP-FET for $43+shipping for 4/30 day   
    eStore code "FET43" - https://twitter.com/TXInstruments/status/593792328831279104
     
    Link to product: https://store.ti.com/msp-fet.aspx?DCMP=ep-mcu-msp-mcugen-en&HQS=ep-mcu-msp-mcugen-twit-storeevm-msp-fet-en(discount shows in cart when code is applied)
  11. Like
    oPossum got a reaction from spirilis in MSP-EXP432P401R UART Delay Question   
    In Windows there are several timing parameters for async serial (COM) ports that are configured with the SetCommTimeouts() API call.
     
    https://msdn.microsoft.com/en-us/library/windows/desktop/aa363437
    https://msdn.microsoft.com/en-us/library/windows/desktop/aa363190
     
    These settings in combination with the buffer sizes use for tx/rx can have a significant impact on latency. This latency is in addition to that of the USB to serial hardware.
     
    I suspect that it is not possible to modify this stuff when using LabView. Not sure about C#. It is, of course, possible to adjust all this when using C or C++.
     
    As a practical matter you should probably be using a windowing protocol to limit the impact of latency.
     
    http://en.wikipedia.org/wiki/Sliding_window_protocol
     
    If you really need a low latency async serial connection, you could try a USB to MIDI cable. There is a 14 bit limit on most messages. See Firmata for an example of repurposing the MIDI protocol.
     
    https://github.com/firmata/protocol
  12. Like
    oPossum got a reaction from dubnet in MSP-EXP432P401R UART Delay Question   
    In Windows there are several timing parameters for async serial (COM) ports that are configured with the SetCommTimeouts() API call.
     
    https://msdn.microsoft.com/en-us/library/windows/desktop/aa363437
    https://msdn.microsoft.com/en-us/library/windows/desktop/aa363190
     
    These settings in combination with the buffer sizes use for tx/rx can have a significant impact on latency. This latency is in addition to that of the USB to serial hardware.
     
    I suspect that it is not possible to modify this stuff when using LabView. Not sure about C#. It is, of course, possible to adjust all this when using C or C++.
     
    As a practical matter you should probably be using a windowing protocol to limit the impact of latency.
     
    http://en.wikipedia.org/wiki/Sliding_window_protocol
     
    If you really need a low latency async serial connection, you could try a USB to MIDI cable. There is a 14 bit limit on most messages. See Firmata for an example of repurposing the MIDI protocol.
     
    https://github.com/firmata/protocol
  13. Like
    oPossum reacted to zeke in Easiest way to connect Launchpad to an Arduino?   
    I have helped out a client to connect an msp430g2553 to his arduino. He uses a 3 to 5 volt translator on the I2C bus. He's got it talking to the msp430 just fine. He's using Processing on the arduino side. He's using my code on the msp430.
     
    I echo the sentiment that working with the I2C master on the MSP is challenging. So much so that I wrote my own bit banged I2C master routines. 
     
    I have had a lot of success using the I2C peripheral in interrupt driven slave mode though. That's a relief.
     
    That being said, is it really a voltage mismatch that is causing the problems?
    What does the logic analyzer show when you are having problems?
    Is the slave in polled mode or interrupt I2C mode?
    Do you have a schematic that you can share?
    Are the grounds connected between the two boards?
     
    I agree with @@spirilis that a common voltage on the I2C bus would be best.
     
  14. Like
    oPossum reacted to westfw in (yet again another boring) question about energia / printf   
    OK.   Now I'm feeling a little embarassed, thinking that stdout was more magical than it actually is.  How about just:
    ssize_t myWrite(void *cookie, const char *buf, size_t n) {   return Serial.write((uint8_t*)buf, n); } cookie_io_functions_t myVectors = { 0, myWrite, 0, 0 }; void setup() {                   Serial.begin(115200);   stdout = fopencookie((void *)0, "w", myVectors);   setlinebuf(stdout);   printf( "This is an fprintf demo\n"); } To me, this seems cleaner and more obvious than the mechanations you'd otherwise have to go through to provide a C _write_r() function that called C++ Wiring core functions...  I don't know whether it has "baggage" brought in my calling fopen()...
  15. Like
    oPossum reacted to timb in Adding Serial Port to Logic Supply Case   
    So, as I






  16. Like
    oPossum reacted to fatihinanc in Configuring the f5529lp to run at 25 MHz   
    @@nickn
     
    You just need to set PMM registers and change the core voltage step by step. The code which given below sets the core voltage to correct value and also generates 25 MHz from LFXT1(32.768kHz). It is referenced from TI code examples.(MSP430F55xx_UCS_10.c) Only difference is ACLK = LFXT1, not REFO.
    void set25mhz(void) { P5SEL |= BIT4 + BIT5; // Select XT1 // Increase Vcore setting to level3 to support fsystem=25MHz // NOTE: Change core voltage one level at a time.. SetVcoreUp (0x01); SetVcoreUp (0x02); SetVcoreUp (0x03); UCSCTL6 &= ~(XT1OFF); // XT1 On UCSCTL4 |= SELA_0; // ACLK = LFTX1 (by default) UCSCTL6 |= XCAP_3; // Internal load cap __bis_SR_register(SCG0); // Disable the FLL control loop UCSCTL0 = 0x0000; // Set lowest possible DCOx, MODx UCSCTL1 = DCORSEL_7; // Select DCO range 50MHz operation UCSCTL2 = FLLD_0 | 762; // Set DCO Multiplier for 25MHz // (N + 1) * FLLRef = Fdco // (762 + 1) * 32768 = 25MHz // Set FLL Div = fDCOCLK/2 __bic_SR_register(SCG0); // Enable the FLL control loop // Worst-case settling time for the DCO when the DCO range bits have been // changed is n x 32 x 32 x f_MCLK / f_FLL_reference. See UCS chapter in 5xx // UG for optimization. // 32 x 32 x 25 MHz / 32,768 Hz ~ 780k MCLK cycles for DCO to settle __delay_cycles(782000); // Loop until XT1,XT2 & DCO stabilizes - In this case only DCO has to stabilize do { UCSCTL7 &= ~(XT2OFFG | XT1LFOFFG | DCOFFG); // Clear XT2,XT1,DCO fault flags SFRIFG1 &= ~OFIFG; // Clear fault flags }while (SFRIFG1&OFIFG); // Test oscillator fault flag UCSCTL6 &= ~(XT1DRIVE_3); // Xtal is now stable, reduce drive strength } void SetVcoreUp (unsigned int level) { // Open PMM registers for write PMMCTL0_H = PMMPW_H; // Set SVS/SVM high side new level SVSMHCTL = SVSHE | SVSHRVL0 * level | SVMHE | SVSMHRRL0 * level; // Set SVM low side to new level SVSMLCTL = SVSLE | SVMLE | SVSMLRRL0 * level; // Wait till SVM is settled while ((PMMIFG & SVSMLDLYIFG) == 0); // Clear already set flags PMMIFG &= ~(SVMLVLRIFG | SVMLIFG); // Set VCore to new level PMMCTL0_L = PMMCOREV0 * level; // Wait till new level reached if ((PMMIFG & SVMLIFG)) while ((PMMIFG & SVMLVLRIFG) == 0); // Set SVS/SVM low side to new level SVSMLCTL = SVSLE | SVSLRVL0 * level | SVMLE | SVSMLRRL0 * level; // Lock PMM registers for write access PMMCTL0_H = 0x00; }
  17. Like
    oPossum reacted to spirilis in Updates and going forward   
    C2Kcentral could definitely shut down.  I mean @@TI_Trey might shed a tear .... and I would go ahead and put a sub-forum on one of the sites for the C2000, especially with the new F28069M LaunchPad being released.
     
    I'm personally in favor of collapsing everything into 43oh.com myself.  Once you have SSO, I bet it wouldn't be as difficult to move all the content from the other sites into subforums of 43oh.
  18. Like
    oPossum reacted to Fred in Updates and going forward   
    It'd be more convenient for me with separate forums, especially as I tend to bookmark the "new posts" link and see if there's anything new and interesting to read. There would be no need for SSO is they weren't separate anyway.
     
    Personally, I'd also like to see Energia moved to its own forum. I have zero interest in Energia and I frequently see a question pop up on 43oh. When I go to answer I then find it's about Energia and have nothing to say. (I know the section is shown but I usually miss it.) As it's cross-platform anyway so would be more appropriate in its own forum.
     
    Anyway, that's just my opinion. What I suggest you do is whatever suits you and makes your life easier. We'll cope!
  19. Like
    oPossum reacted to pabigot in Updates and going forward   
    I'm still here, though not doing much with TI chips because I'm now using nRF51 chips (which I'm pretty happy with).  Personally, I concur with @@Fred about putting Energia somewhere else.  It's a fine system with a lot of traction, but programming with Energia is not really relevant to those of us who work on bare metal MCUs, and vice-versa.  Over the past several months I've frequently noticed a topic and though "Looks interesting...oh wait, Energia."  The degree of mixing waters down the value for both communities, in my opinion.
  20. Like
    oPossum reacted to spirilis in 43oh Server Slow Responsiveness.   
    Fwiw I started using Atlantic.net's $0.99/mo tiny VPS option, they seem like a sharp shop, with SSD-backed cloud instances ... prices go up from there: https://www.atlantic.net/vps/vps-hosting/
    Not sure what size VPS this site requires but just wanted to toss their name in.
  21. Like
    oPossum got a reaction from agaelema in Tiny printf() - C version   
    This is a tiny printf() function that can be used with the chips that come with the Launchpad. Code size is about 640 bytes with CCS.
     
    There are 7 format specifiers:
    %c - Character
    %s - String
    %i - signed Integer (16 bit)
    %u - Unsigned integer (16 bit)
    %l - signed Long (32 bit)
    %n - uNsigned loNg (32 bit)
    %x - heXadecimal (16 bit)
     
    Field width, floating point and other standard printf() features are not supported.
     
    printf() code

    #include "msp430g2231.h" #include "stdarg.h" void putc(unsigned); void puts(char *); static const unsigned long dv[] = { // 4294967296 // 32 bit unsigned max 1000000000, // +0 100000000, // +1 10000000, // +2 1000000, // +3 100000, // +4 // 65535 // 16 bit unsigned max 10000, // +5 1000, // +6 100, // +7 10, // +8 1, // +9 }; static void xtoa(unsigned long x, const unsigned long *dp) { char c; unsigned long d; if(x) { while(x < *dp) ++dp; do { d = *dp++; c = '0'; while(x >= d) ++c, x -= d; putc(c); } while(!(d & 1)); } else putc('0'); } static void puth(unsigned n) { static const char hex[16] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; putc(hex[n & 15]); } void printf(char *format, ...) { char c; int i; long n; va_list a; va_start(a, format); while(c = *format++) { if(c == '%') { switch(c = *format++) { case 's': // String puts(va_arg(a, char*)); break; case 'c': // Char putc(va_arg(a, char)); break; case 'i': // 16 bit Integer case 'u': // 16 bit Unsigned i = va_arg(a, int); if(c == 'i' && i < 0) i = -i, putc('-'); xtoa((unsigned)i, dv + 5); break; case 'l': // 32 bit Long case 'n': // 32 bit uNsigned loNg n = va_arg(a, long); if(c == 'l' && n < 0) n = -n, putc('-'); xtoa((unsigned long)n, dv); break; case 'x': // 16 bit heXadecimal i = va_arg(a, int); puth(i >> 12); puth(i >> 8); puth(i >> 4); puth(i); break; case 0: return; default: goto bad_fmt; } } else bad_fmt: putc(c); } va_end(a); }
     
    test code

    #include "msp430g2231.h" void serial_setup(unsigned out_mask, unsigned in_mask, unsigned duration); void printf(char *, ...); void main(void) { char *s; char c; int i; unsigned u; long int l; long unsigned n; unsigned x; // Disable watchdog WDTCTL = WDTPW + WDTHOLD; // Use 1 MHz DCO factory calibration DCOCTL = 0; BCSCTL1 = CALBC1_1MHZ; DCOCTL = CALDCO_1MHZ; // Setup the serial port // Serial out: P1.1 (BIT1) // Serial in: P1.2 (BIT2) // Bit rate: 9600 (CPU freq / bit rate) serial_setup(BIT1, BIT2, 1000000 / 9600); printf("%s", "\r\n*** printf() test ***\r\n"); s = "test"; c = 'X'; i = -12345; u = 12345; l = -1234567890; n = 1234567890; x = 0xABCD; printf("String %s\r\n", s); printf("Char %c\r\n", c); printf("Integer %i\r\n", i); printf("Unsigned %u\r\n", u); printf("Long %l\r\n", l); printf("uNsigned loNg %n\r\n", n); printf("heX %x\r\n", x); printf("multiple args %s %c %i %u %l %n %x\r\n", s, c, i, u, l, n, x); printf("\r\n*** Done ***\r\n"); for(;; }

  22. Like
    oPossum got a reaction from StefanWxx in Is this 38KHz PWM ?   
    It's close. Can be made more accurate...
     
    Set the oscillator to one of the calibrated values.

    DCOCTL = 0; BCSCTL1 = CALBC1_1MHZ; DCOCTL = CALDCO_1MHZ; Set the max count to N - 1
    TA0CCR0 = (1000000 / 38000) - 1; TA0CCR1 = TA0CCR0 >> 1;
  23. Like
    oPossum got a reaction from pabigot in Is this 38KHz PWM ?   
    It's close. Can be made more accurate...
     
    Set the oscillator to one of the calibrated values.

    DCOCTL = 0; BCSCTL1 = CALBC1_1MHZ; DCOCTL = CALDCO_1MHZ; Set the max count to N - 1
    TA0CCR0 = (1000000 / 38000) - 1; TA0CCR1 = TA0CCR0 >> 1;
  24. Like
    oPossum reacted to Lgbeno in ESI Project: Water Usage Monitoring   
    Interesting project, I'm actually doing something similar with cc110l and msp430G2553. I call it "droplet". It runs off of a cr2450 battery, sleeps most of the time then wakes up sends measurements to a Hub that is wall powered and the hub ships the data to data.sparkfun.com. Here's the droplet:
     

     
    And here is a hub prototype (just ordered a real pcb for it)
     

     
    You can see the electric imp that receives data via uart the pushes it to sparkfun.
     
    My web app project imp.guru fetches the data from sparkfun to view, here's the data imp.guru/f1
     
     
    I'm willing to share any/all of this work for your project if interested. My recommendation would be to skip the whole energy harvesting thing and use batteries. With the right design you should last years on a pair of AA's.
     
    I've seen projects on hack a day where people use Hall effect sensors to pick up the spinning magnet in their utility water meter. I think this is it:
     
    http://hackaday.io/project/1460-Remote-Water-Consumption-Display
  25. Like
    oPossum got a reaction from Atas 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.
     


×
×
  • Create New...