Jump to content
43oh

veryalive

Members
  • Content Count

    140
  • Joined

  • Last visited

  • Days Won

    4

Reputation Activity

  1. Like
    veryalive reacted to maelli01 in lpm 4.5 current measurement, fun with low current   
    The example msp430fr5994x_lpm4-5_02.c is supposed to show how little current is used in this mode.
    In the file it says:
    //   MSP430FR5x9x Demo - Entering and waking up from LPM4.5 via P1.3 interrupt
    //                       with SVS disabled
    //
    //   Description: Download and run the program. When entered LPM4.5, no LEDs
    //                should be on. Use a multimeter to measure current on JP1 and
    //                compare to the datasheet. When a positive voltage is applied
    //                to P1.3 the device should wake up from LPM4.5. This will enable
    //                the LFXT oscillator and blink the LED (on P1.0).
    Even for a high-end multimeter this current is too low to be accurately measured. 
    So I helped myself this way: 
    - power the processor from the supercap
    - a 10k resistor with two antiparallel diodes act as a shunt,  
    - connect the volt meter across the supercap, not across the processor
    0.43mV over a 10k resistor gives 43 Nanoamps. (!)   Yes, the datasheet (page 32) is right, typical value at 25°C is 45nA.  
    A  CR2032 (200mAh) cell would allow the processor to wait for an interrupt  for 530 years. 


  2. Like
    veryalive reacted to dutyfree in Nrf24l01+ Pipe Addressingad   
    I have figured out the problem the array named addr which actually represents the 5 byte of the address of the pipe#0. So in order to use the second or the third pipe for instance some other array which consist some other pipe address must be initialized and used. I am posting the code I'm now using for piping so that anyone can benefit, the library I use is the spirilis as I mentioned. 
    //TRANSMITTER// #include <msp430.h> #include "msprf24.h" #include "nrf_userconfig.h" #include "stdint.h" int scan[5]; volatile unsigned int user; unsigned char isalive; int i = 0; unsigned int chan; unsigned char buf[32] = {'h','e','l','l','o'}; unsigned char *ptrbuf = "hello"; int pipe_test; void main() { uint8_t addr0[5]; uint8_t addr1[5]; uint8_t addr2[5]; WDTCTL = WDTHOLD | WDTPW; DCOCTL = CALDCO_16MHZ; BCSCTL1 = CALBC1_16MHZ; BCSCTL2 = DIVS_1; P1DIR |= 0x41; P1OUT &= ~0x41; user = 0xFE; rf_crc = RF24_EN_CRC | RF24_CRCO; // CRC enabled, 16-bit rf_addr_width = 5; rf_speed_power = RF24_SPEED_1MBPS | RF24_POWER_0DBM; rf_channel = 120; msprf24_init(); msprf24_set_pipe_packetsize(2, 32); msprf24_open_pipe(2, 0); msprf24_standby(); user = msprf24_current_state(); addr0[0] = 0xE7; addr0[1] = 0xD3; addr0[2] = 0xF0; addr0[3] = 0x35; addr0[4] = 0x77; addr1[0] = 0xC2; addr1[1] = 0xC2; addr1[2] = 0xC2; addr1[3] = 0xC2; addr1[4] = 0xA1; addr2[0] = 0xC2; addr2[1] = 0xC2; addr2[2] = 0xC2; addr2[3] = 0xC2; addr2[4] = 0xF1; w_tx_addr(addr2); w_rx_addr(2, addr2); isalive = msprf24_is_alive(); pipe_test = msprf24_pipe_isopen(2); while(1){ __delay_cycles(800000); w_tx_payload(32, buf); msprf24_activate_tx(); LPM4; if (rf_irq & RF24_IRQ_FLAGGED) { rf_irq &= ~RF24_IRQ_FLAGGED; msprf24_get_irq_reason(); if (rf_irq & RF24_IRQ_TX){ P1OUT &= ~BIT0; // Red LED off P1OUT |= 0x40; // Green LED on } if (rf_irq & RF24_IRQ_TXFAILED){ P1OUT &= ~BIT6; // Green LED off P1OUT |= BIT0; // Red LED on } msprf24_irq_clear(rf_irq); user = msprf24_get_last_retransmits(); } } } #include <msp430.h> #include "msprf24.h" #include "nrf_userconfig.h" #include "stdint.h" unsigned char isalive; volatile unsigned int user; unsigned int scan,scan1; int pipe_test; unsigned char buf[32]; int main() { uint8_t addr0[5]; uint8_t addr1[5]; uint8_t addr2[5]; WDTCTL = WDTHOLD | WDTPW; DCOCTL = CALDCO_16MHZ; BCSCTL1 = CALBC1_16MHZ; BCSCTL2 = DIVS_1; P1DIR |= BIT0+BIT6; P1OUT &= ~(BIT0+BIT6); user = 0xFE; rf_crc = RF24_EN_CRC | RF24_CRCO; // CRC enabled, 16-bit rf_addr_width = 5; rf_speed_power = RF24_SPEED_1MBPS | RF24_POWER_0DBM ; rf_channel = 120; msprf24_set_channel(); msprf24_init(); msprf24_set_pipe_packetsize(2, 32); msprf24_open_pipe(2, 0); addr0[0] = 0xE7; addr0[1] = 0xD3; addr0[2] = 0xF0; addr0[3] = 0x35; addr0[4] = 0x77; addr1[0] = 0xC2; addr1[1] = 0xC2; addr1[2] = 0xC2; addr1[3] = 0xC2; addr1[4] = 0xA1; addr2[0] = 0xC2; addr2[1] = 0xC2; addr2[2] = 0xC2; addr2[3] = 0xC2; addr2[4] = 0xF1; w_rx_addr(2, addr2); if (!(RF24_QUEUE_RXEMPTY & msprf24_queue_state())) { flush_rx(); } msprf24_activate_rx(); LPM4; isalive = msprf24_is_alive(); pipe_test = msprf24_pipe_isopen(2); while (1) { if (rf_irq & RF24_IRQ_FLAGGED) { rf_irq &= ~RF24_IRQ_FLAGGED; msprf24_get_irq_reason(); } if (rf_irq & RF24_IRQ_RX || msprf24_rx_pending()) { r_rx_payload(32, buf); msprf24_irq_clear(RF24_IRQ_RX); user = buf[0]; if (buf[0] == '0') P1OUT &= ~BIT0; if (buf[0] == '1') P1OUT |= BIT0; if (buf[1] == '0') P1OUT &= ~BIT6; if (buf[1] == '1') P1OUT |= BIT6; } else { user = 0xFF; } LPM4; } return 0; }
  3. Like
    veryalive reacted to maelli01 in micropower microvoltmeter with MSP430FR4133 and MCP3422 ADC   
    Weekend-project:
    Autoranging microvoltmeter based on the MSP430FR4133 launchpad.
    ADC used: MIcrochip MCP3422, an 18bit, 3.75 sample/second Sigma Delta with 2 differential inputs. I2C interface
    This nice little chip contains a programmable amplifier (x2,x4,x8) and a not-too-bad internal reference of 2.048V.
    Max input range is +/-2.048V, resolution (8x amplified) is 2uV.
     
    Hand-etched a single layer PCB which goes on top of Launchpad.
     
     

    Type K cable in hot water: 2.93mV, 73Kelvin temp difference to ambient
     
     

    compare with my Fluke 289, 0.06% (datasheet says 0.05% typical, 0.35% max)
    Not too shabby for a chip that costs 3 bucks.
     
     

    Current consumption: on average <40uA, the whole setup would run 5000hours from a CR2032
    The ADC does 1 sample/second and sleeps the rest of the time, the MSP430 does what it likes the most: sleep in LPM3
     
     
    Code is not a big deal, quick hack based on the FR4133 examples, for the LCD and for the I2C interface 
    //microvolt meter with MCP3422 and MSP430FR413 //****************************************************************************** #include <msp430.h> #define LCDMEMW ((int*)LCDMEM) #define pos1 4 // Digit A1 - L4 #define pos2 6 // Digit A2 - L6 #define pos3 8 // Digit A3 - L8 #define pos4 10 // Digit A4 - L10 #define pos5 2 // Digit A5 - L2 #define pos6 18 // Digit A6 - L18 const char digit[10] ={ 0xFC, // "0" 0x60, // "1" 0xDB, // "2" 0xF3, // "3" 0x67, // "4" 0xB7, // "5" 0xBF, // "6" 0xE0, // "7" 0xFF, // "8" 0xF7 // "9" }; volatile long voltage; unsigned long dvoltage; unsigned char TXByteCtr; unsigned char TXData; unsigned char newgain,gain; void Clear_LCD(){ int i; for(i=5;i;i--) LCDMEMW[i]=0; LCDMEMW[9]=0; } int main( void ) { WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer P1OUT = 0x00;P2OUT = 0x00;P3OUT = 0x00;P4OUT = 0x00; P5OUT = 0x00;P6OUT = 0x00;P7OUT = 0x00;P8OUT = 0x00; P1DIR = 0xFF;P2DIR = 0xFF;P3DIR = 0xFF;P4DIR = 0xFF; P5DIR = 0xFF;P6DIR = 0xFF;P7DIR = 0xFF;P8DIR = 0xFF; P5SEL0 |= BIT2 | BIT3; // I2C pins // Configure XT1 oscillator P4SEL0 |= BIT1 | BIT2; // P4.2~P4.1: crystal pins do { CSCTL7 &= ~(XT1OFFG | DCOFFG); // Clear XT1 and DCO fault flag SFRIFG1 &= ~OFIFG; } while (SFRIFG1 & OFIFG); // Test oscillator fault flag // Disable the GPIO power-on default high-impedance mode // to activate previously configured port settings PM5CTL0 &= ~LOCKLPM5; CSCTL4 = SELMS__DCOCLKDIV + SELA__XT1CLK; // MCLK=SMCLK=DCO; ACLK=XT1 // Configure RTC RTCCTL |= RTCSS__XT1CLK | RTCIE; // Initialize RTC to use XT1 and enable RTC interrupt RTCMOD = 16384; // Set RTC modulo to 16384 to trigger interrupt twice a second // Configure LCD pins SYSCFG2 |= LCDPCTL; // R13/R23/R33/LCDCAP0/LCDCAP1 pins selected LCDPCTL0 = 0xFFFF; LCDPCTL1 = 0x07FF; LCDPCTL2 = 0x00F0; // L0~L26 & L36~L39 pins selected LCDCTL0 = LCDSSEL_0 | LCDDIV_7; // flcd ref freq is xtclk // LCD Operation - Mode 3, internal 3.08v, charge pump 256Hz LCDVCTL = LCDCPEN | LCDREFEN | VLCD_5 | (LCDCPFSEL0 | LCDCPFSEL1 | LCDCPFSEL2 | LCDCPFSEL3); LCDMEMCTL |= LCDCLRM; // Clear LCD memory LCDCSSEL0 = 0x000F; // Configure COMs and SEGs LCDCSSEL1 = 0x0000; // L0, L1, L2, L3: COM pins LCDCSSEL2 = 0x0000; LCDM0 = 0x21; // L0 = COM0, L1 = COM1 LCDM1 = 0x84; // L2 = COM2, L3 = COM3 LCDCTL0 |= LCD4MUX | LCDON; // Turn on LCD, 4-mux selected (LCD4MUX also includes LCDSON) Clear_LCD(); // Configure USCI_B0 for I2C mode UCB0CTLW0 |= UCSWRST; // Software reset enabled UCB0CTLW0 |= UCMODE_3 | UCMST | UCSYNC; // I2C mode, Master mode, sync UCB0CTLW1 |= UCASTP_2; // Automatic stop generated // after UCB0TBCNT is reached UCB0BRW = 0x0008; // baudrate = SMCLK / 8 UCB0I2CSA = 0x0068; // Slave address UCB0CTL1 &= ~UCSWRST; UCB0IE |= UCRXIE | UCNACKIE | UCBCNTIE | UCTXIE0; while(1){ // P1OUT |= BIT0; TXByteCtr = 1; // Load TX byte counter TXData = 0x8C+gain; while (UCB0CTLW0 & UCTXSTP); // Ensure stop condition got sent UCB0CTLW0 |= UCTR | UCTXSTT; // I2C TX, start condition // P1OUT &= ~BIT0; __bis_SR_register(LPM3_bits | GIE); // timer will wake me up // P1OUT |= BIT0; UCB0TBCNT = 0x0003; // 3 bytes to be received voltage=0; UCB0CTLW0 &= ~UCTR; while (UCB0CTL1 & UCTXSTP); // Ensure stop condition got sent UCB0CTL1 |= UCTXSTT; // I2C start condition __bis_SR_register(LPM3_bits | GIE); // I2C irq will wake me up voltage<<=8; // shift to left corner to do the sign correctly voltage/=32; // calibration is done here: 2048 in an ideal world if ((voltage<400000)&&(voltage>(-400000))){ // autoranging, downshift if (newgain<3) newgain++; } if ((voltage>1000000)||(voltage<-1000000)){ // autoranging, upshift if (newgain) newgain--; } voltage>>=gain; gain=newgain; if ((voltage<500000)&&(voltage>-500000)){ voltage*=10; //low range LCDMEM[11]&=~1; //adjust decimal point LCDMEM[9]|=1; } else{ //high range LCDMEM[9]&=~1; //adjust decimal point LCDMEM[11]|=1; } voltage*=25; voltage/=128; if (voltage<0) {dvoltage=-voltage; LCDMEM[5]|=4 ;} //negative else {dvoltage= voltage; LCDMEM[5]&=~4;} //positive LCDMEM[pos1] = digit[(dvoltage / 100000)%10]; LCDMEM[pos2] = digit[(dvoltage / 10000)%10]; LCDMEM[pos3] = digit[(dvoltage / 1000)%10]; LCDMEM[pos4] = digit[(dvoltage / 100)%10]; LCDMEM[pos5] = digit[(dvoltage / 10)%10]; LCDMEM[pos6] = digit[dvoltage % 10]; // P1OUT &= ~BIT0; __bis_SR_register(LPM3_bits | GIE); // timer will wake me up } } #pragma vector = RTC_VECTOR __interrupt void RTC_ISR(void){ switch(__even_in_range(RTCIV, RTCIV_RTCIF)){ case RTCIV_NONE: break; // No interrupt case RTCIV_RTCIF: // RTC Overflow __bic_SR_register_on_exit(LPM3_bits); break; default: break; } } #pragma vector = USCI_B0_VECTOR __interrupt void USCIB0_ISR(void){ switch(__even_in_range(UCB0IV, USCI_I2C_UCBIT9IFG)){ case USCI_NONE: break; // Vector 0: No interrupts case USCI_I2C_UCALIFG: break; // Vector 2: ALIFG case USCI_I2C_UCNACKIFG: // Vector 4: NACKIFG UCB0CTL1 |= UCTXSTT; // I2C start condition break; case USCI_I2C_UCSTTIFG: break; // Vector 6: STTIFG case USCI_I2C_UCSTPIFG: break; // Vector 8: STPIFG case USCI_I2C_UCRXIFG3: break; // Vector 10: RXIFG3 case USCI_I2C_UCTXIFG3: break; // Vector 14: TXIFG3 case USCI_I2C_UCRXIFG2: break; // Vector 16: RXIFG2 case USCI_I2C_UCTXIFG2: break; // Vector 18: TXIFG2 case USCI_I2C_UCRXIFG1: break; // Vector 20: RXIFG1 case USCI_I2C_UCTXIFG1: break; // Vector 22: TXIFG1 case USCI_I2C_UCRXIFG0: // Vector 24: RXIFG0 voltage=(voltage<<8)+UCB0RXBUF; break; case USCI_I2C_UCTXIFG0: // Vector 26: TXIFG0 if (TXByteCtr){ // Check TX byte counter UCB0TXBUF = TXData; // Load TX buffer TXByteCtr--; // Decrement TX byte counter } else{ UCB0CTLW0 |= UCTXSTP; // I2C stop condition UCB0IFG &= ~UCTXIFG; // Clear USCI_B0 TX int flag } break; case USCI_I2C_UCBCNTIFG: // Vector 28: BCNTIFG __bic_SR_register_on_exit(LPM3_bits); break; case USCI_I2C_UCCLTOIFG: break; // Vector 30: clock low timeout case USCI_I2C_UCBIT9IFG: break; // Vector 32: 9th bit default: break; } }
  4. Like
    veryalive got a reaction from energia in Set PinMode on 2 pins simultaneously   
    Hi,
     
    I've been following your bit-bang I2C efforts.
    If you are making a custom version, perhaps using direct port I/O would be useful?
     
    As follows:
     
    P1DIR |= BIT7 + BIT6;       // make these outputs
    P1OUT |= BIT7 + BIT6;     // make them simultaneously go hi
    P1OUT &= ~(BIT7+BIT6);  //  ditto, but go low
     
    The only thing is that it departs from energia statements.
     
    I suspect you must have a scope / logic analyser or you wouldn't have known / measured the delay between the two PinMode statements you tried? 
     
    Is this OK for your app?
     
    Cheers,
  5. Like
    veryalive reacted to zeke in Open Source Books that teach C Programming   
    I stumbled across a list of nine open source books on Hacker News today that will help people learn how to program in C.
     
    YMMV
  6. Like
    veryalive reacted to chicken in Implementing a simple Menu   
    PS: If you want to get fancy/generic, you could implement the state/menu system with a structure. Something along these lines:
    struct {   int menu_id, // continuous but not functional, helps to keep track of the menu id's   int next_menu, // entry when pressing next   void (*action) (void),  // action when pressing select   const char* label  // displayed text } menu_t; int current_menu = 0; void do_select0(void) {   current_menu = 2; // set to sub menu } void do_ select1(void) {   // do main action 1 } void do_subaction1(void) {   // do sub action 1 } void do_subaction2(void) {   // do sub action 2 } void do_gotop(void) {   current_menu = 0; // set to top menu } menu_t menu[] = {   // Top level     { 0, 1,"Sub Menu", do_select0 },     { 1, 0, "Action", do_select1 },   // Sub menu     { 2, 3, "Sub action 1", do_subaction1 },     { 3, 4, "Sub action 2", do_subaction2 },     { 4, 2, "Up", do_gotop } }; and in the main loop / event handler:
    switch(event) { case next:   current_menu = menu[current_menu].next_menu;   write_text(menu[current_menu].label);   break; case select:   menu[current_menu].action();   write_text(menu[current_menu].label);   break; default;   // do nothing   break; } event = none;  // reset event variable
  7. Like
    veryalive reacted to Fmilburn in Using SPI and Energia with WS2812 LEDs   
    I needed to use this for another project that did not use Energia.  Here it is rewritten with direct register access in C using Code Composer Studio:  https://github.com/fmilburn3/WS2812/blob/master/WS2812_CCS
  8. Like
    veryalive reacted to zeke in Saving flash space, by making use of infomem   
    While reading this thread, I noticed that the answers did not comment on a solution for CCS. 
     
    So here are my observations and code samples to make that work in CCS.
     
    First, I trimmed down the font sample code from @@greeeg just to see if it will work.
    #pragma DATA_SECTION(font_data, ".infoB") const unsigned int font_data[] = { 0x0000,0xC101,0x0110,0x3B89,0x9BD9,0x5BDA,0x0F6D,0x4000, 0x4400,0x0022,0x55AA,0x1188,0x0002,0x1008,0x0001,0x4002, 0xEA57,0x6800,0xB24D,0xDA41,0x3818,0x8659,0x9A5D,0xA840, 0xBA5D,0xBA59,0x0041,0x0042,0x4203,0x1209,0x0621,0xB0C0, }; Good! This is just the right size to fill up 64 bytes - the size of INFOB. Any bigger and the compiler fails out with an error message about memory size is over filled or something.
     
    Next, figure out what special names you can use in the DATA_SECTION declaration.
     
    Open up the linker file for your project. In my case, it's called lnk_msp430g2553.cmd. 
     
    You will see this inside of it:
    .infoA : {} > INFOA /* MSP430 INFO FLASH MEMORY SEGMENTS */ .infoB : {} > INFOB .infoC : {} > INFOC .infoD : {} > INFOD so, use the lowercase name in your declaration.
     
     
    And here is my test program that I used to test drive the flash on an MSP43G2553:
    #include <msp430.h> /* "Compressed" font data, in form 0b ABCD EFGH IJKL MNOP {A-P} represent segment bits in each character __J_ _A__ |\ | /| | K H B | L \ | / C | \|/ | >-M--*--D-< | /|\ | N / | \ E | O I F | |/ | \| ~~P~ ~G~~ */ #pragma DATA_SECTION(font_data, ".infoB") const unsigned int font_data[] = { 0x0000,0xC101,0x0110,0x3B89,0x9BD9,0x5BDA,0x0F6D,0x4000, 0x4400,0x0022,0x55AA,0x1188,0x0002,0x1008,0x0001,0x4002, 0xEA57,0x6800,0xB24D,0xDA41,0x3818,0x8659,0x9A5D,0xA840, 0xBA5D,0xBA59,0x0041,0x0042,0x4203,0x1209,0x0621,0xB0C0, }; //const unsigned int font_data[] //__attribute__((section(".infob"))) = //{ //0x0000,0xC101,0x0110,0x3B89,0x9BD9,0x5BDA,0x0F6D,0x4000, //0x4400,0x0022,0x55AA,0x1188,0x0002,0x1008,0x0001,0x4002, //0xEA57,0x6800,0xB24D,0xDA41,0x3818,0x8659,0x9A5D,0xA840, //0xBA5D,0xBA59,0x0041,0x0042,0x4203,0x1209,0x0621,0xB0C0, //0xAACD,0xB85C,0xBBC1,0x8255,0xABC1,0x825D,0x805C,0x9A55, //0x381C,0x83C1,0x81C5,0x441C,0x0215,0x6834,0x2C34,0xAA55, //0xB05C,0xAE55,0xB45C,0x9A59,0x81C0,0x2A15,0x4016,0x2C16, //0x4422,0x40A0,0xC243,0x0055,0x0420,0xAA00,0x0402,0x0201, //0x0020,0x028D,0x009D,0x000D,0x018D,0x000F,0x9188,0x1E01, //0x009C,0x0080,0x0081,0x1580,0x03C0,0x188C,0x008C,0x008D, //0x015C,0x03D8,0x000C,0x1081,0x1388,0x0085,0x0006,0x0A85, //0x4182,0x0E01,0x000B,0x8388,0x0180,0x11C1,0x3150,0x0000, //}; char value; // 8-bit value to write to segment A // Function prototypes void write_SegC (char value); void copy_C2D (void); int main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer if (CALBC1_1MHZ==0xFF) // If calibration constant erased { while(1); // do not load, trap CPU!! } DCOCTL = 0; // Select lowest DCOx and MODx settings BCSCTL1 = CALBC1_1MHZ; // Set DCO to 1MHz DCOCTL = CALDCO_1MHZ; FCTL2 = FWKEY + FSSEL0 + FN1; // MCLK/3 for Flash Timing Generator value = 0; // initialize value while(1) // Repeat forever { write_SegC(value++); // Write segment C, increment value copy_C2D(); // Copy segment C to D __no_operation(); // SET BREAKPOINT HERE } } void write_SegC (char value) { char *Flash_ptr; // Flash pointer unsigned int i; Flash_ptr = (char *) 0x1040; // Initialize Flash pointer FCTL1 = FWKEY + ERASE; // Set Erase bit FCTL3 = FWKEY; // Clear Lock bit *Flash_ptr = 0; // Dummy write to erase Flash segment FCTL1 = FWKEY + WRT; // Set WRT bit for write operation for (i=0; i<64; i++) { *Flash_ptr++ = value; // Write value to flash } FCTL1 = FWKEY; // Clear WRT bit FCTL3 = FWKEY + LOCK; // Set LOCK bit } void copy_C2D (void) { char *Flash_ptrC; // Segment C pointer char *Flash_ptrD; // Segment D pointer unsigned int i; Flash_ptrC = (char *) 0x1040; // Initialize Flash segment C pointer Flash_ptrD = (char *) 0x1000; // Initialize Flash segment D pointer FCTL1 = FWKEY + ERASE; // Set Erase bit FCTL3 = FWKEY; // Clear Lock bit *Flash_ptrD = 0; // Dummy write to erase Flash segment D FCTL1 = FWKEY + WRT; // Set WRT bit for write operation for (i=0; i<64; i++) { *Flash_ptrD++ = *Flash_ptrC++; // copy value segment C to segment D } FCTL1 = FWKEY; // Clear WRT bit FCTL3 = FWKEY + LOCK; // Set LOCK bit } Here is a screen shot of CCS as I inspected the information memory section.  
     
    The way I have the screen stretched out causes each memory section to be all on one line ie:
    INFOD (0x1000), INFOC (0x1040), INFOB (0x1080) and INFOA (0x10C0).  

     
     
    Footnote: For reference, here's TI's take on this topic: 
  9. Like
    veryalive reacted to Fmilburn in DriverLib Examples for the MSP430F5529   
    Energia and Arduino users eventually get to the point where they need more direct access to the hardware if they take on more complicated projects.  In addition to the direct access of registers using the provided header files, TI offers DriverLib which contains abstractions for accessing the peripherals.
     
    To better understand the peripherals, and to check out DriverLib, I recently created 20+ short examples for my own edification.  All of them were written for the MSP430F5529 LaunchPad and most of the peripherals are covered.  In some cases pushbuttons, LEDs, resistors, potentiometer, etc. are required that you probably have on hand.  A multimeter is required, and in some cases an oscilloscope and logic analyzer are instructive but not necessary.
     

    DriverLib SPI Example 13A_USCI_B_SPI_MCP41010_digiPot
     
    All of the examples are located here:  https://github.com/fmilburn3/MSP430F5529_driverlib_examples
     
    It is necessary to have some understanding of the registers before using DriverLib because the DriverLib documentation doesn't describe how the peripherals and their registers work.  The documentation for registers is located in the User
  10. Like
    veryalive got a reaction from yyrkoon in UART - Sending 3 bytes per start/stop bit sets.   
    You're clearly deep into this, so I don't know if this fits.....
    What about programming an MSP to do that protocol in real time, then have it communicate up to the Linux box as required?
    As I've never heard of that 16/24 bit scheme you mentioned, I'd be absolutely no use progressing this idea further!
    Cheers,
  11. Like
    veryalive reacted to Fmilburn in Problem Sampling Rate MSP430F5529 in Energia   
    A bit off topic but I have been looking into driverlib and decided to rewrite Robert's code in CCS with driverlib using the TI compiler.  It is not apples to apples but I tried to get close.  It runs slower than Robert's code - it was actually faster when polled for the conversion to complete than with the interrupt as shown.  MCLK is  set to 24 MHz rather than 25 MHz.  Anyway, it was an interesting exercise.
     
    EDIT:  Use energia's code - not mine
    #include "driverlib.h" #include <stdio.h> // increase heap size to 320 in linker for printf() #define MCLK_FREQ_KHZ 24000 #define FLLREF_KHZ 32 #define UCS_MCLK_FLLREF_RATIO MCLK_FREQ_KHZ/FLLREF_KHZ #define NUM_READS 10000 #define ADC_PIN GPIO_PORT_P6,GPIO_PIN0 void setupPMM(); void setupUCS(); void setupWDT(); unsigned long milliSecs(); void setupADC(void); unsigned long readADC(void); volatile unsigned long oneThirdMillis = 0; // counter - 1/3 of a millisecond //-------------------------------- m a i n ----------------------------------- int main(void) { WDT_A_hold(WDT_A_BASE); setupPMM(); setupUCS(); setupWDT(); setupADC(); __bis_SR_register(GIE); int i; unsigned long analogValue; unsigned long mark = milliSecs(); for(i = 0; i < NUM_READS; i++){ analogValue = readADC(); } unsigned long finished = milliSecs(); printf("Time = %d ms\n", finished - mark); printf("Last value = %d mV\n", (analogValue * 3230) / 4096); // Vcc = 3.23V while(1); } //----------------------------- s e t u p A D C ------------------------------- void setupADC(void){ GPIO_setAsPeripheralModuleFunctionOutputPin(ADC_PIN); ADC12_A_init(ADC12_A_BASE, ADC12_A_SAMPLEHOLDSOURCE_SC, ADC12_A_CLOCKSOURCE_ADC12OSC, ADC12_A_CLOCKDIVIDER_1); ADC12_A_enable(ADC12_A_BASE); ADC12_A_setupSamplingTimer(ADC12_A_BASE, ADC12_A_CYCLEHOLD_4_CYCLES, ADC12_A_CYCLEHOLD_4_CYCLES, ADC12_A_MULTIPLESAMPLESDISABLE); ADC12_A_configureMemoryParam param = {0}; param.memoryBufferControlIndex = ADC12_A_MEMORY_0; param.inputSourceSelect = ADC12_A_INPUT_A0; param.positiveRefVoltageSourceSelect = ADC12_A_VREFPOS_AVCC; param.negativeRefVoltageSourceSelect = ADC12_A_VREFNEG_AVSS; param.endOfSequence = ADC12_A_NOTENDOFSEQUENCE; ADC12_A_configureMemory(ADC12_A_BASE,&param); ADC12_A_enableInterrupt(ADC12_A_BASE, ADC12_A_IE0); } //----------------------------- r e a d A D C -------------------------------- unsigned long readADC(void){ ADC12_A_startConversion(ADC12_A_BASE, ADC12_A_MEMORY_0, ADC12_A_SINGLECHANNEL); __bis_SR_register(LPM3_bits); // sleep until converted return ADC12_A_getResults(ADC12_A_BASE, ADC12_A_MEMORY_0); } //---------------------------- s e t u p P M M ------------------------------- void setupPMM(void){ // set VCore = 0 for 8 MHz and below // = 1 for 12 MHz // = 2 for 20 MHz // = 3 for 25 MHz PMM_setVCore(PMM_CORE_LEVEL_3); } //---------------------------- s e t u p U C S ------------------------------- void setupUCS(void){ UCS_initClockSignal( // use REFO for ACLK (32768 Hz) UCS_ACLK, UCS_REFOCLK_SELECT, UCS_CLOCK_DIVIDER_1); UCS_initClockSignal( // set DCO FLL ref to DFOCLK UCS_FLLREF, UCS_DCOCLK_SELECT, UCS_CLOCK_DIVIDER_1); UCS_initClockSignal( // use DFOCLK for SMCLK UCS_SMCLK, UCS_DCOCLK_SELECT, UCS_CLOCK_DIVIDER_1); UCS_initFLLSettle( // set MCLK frequency and ratio MCLK_FREQ_KHZ, UCS_MCLK_FLLREF_RATIO); } //---------------------------- s e t u p W D T ------------------------------- void setupWDT(void){ WDT_A_initIntervalTimer(WDT_A_BASE, WDT_A_CLOCKSOURCE_SMCLK, WDT_A_CLOCKDIVIDER_8192); WDT_A_start(WDT_A_BASE); //Place WDT in timer interrupt mode SFR_clearInterrupt(SFR_WATCHDOG_INTERVAL_TIMER_INTERRUPT); SFR_enableInterrupt(SFR_WATCHDOG_INTERVAL_TIMER_INTERRUPT); } //--------------------------- m i l l i S e c s ---------------------------- unsigned long milliSecs(){ return oneThirdMillis / 3; // return millis } //--------------------------- W D T _ A _ I S R ---------------------------- #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__) #pragma vector=WDT_VECTOR __interrupt #elif defined(__GNUC__) __attribute__((interrupt(WDT_VECTOR))) #endif void WDT_A_ISR(void) { oneThirdMillis++; // count thirds of a millisecond } //------------------------- A D C 1 2 _ A _ I S R -------------------------- #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__) #pragma vector=ADC12_VECTOR __interrupt #elif defined(__GNUC__) __attribute__((interrupt(ADC12_VECTOR))) #endif void ADC12_A_ISR(void) { switch(__even_in_range(ADC12IV,34)) { case 0: break; //Vector 0: No interrupt case 2: break; //Vector 2: ADC overflow case 4: break; //Vector 4: ADC timing overflow case 6: //Vector 6: ADC12IFG0 ADC12_A_clearInterrupt(ADC12_A_BASE, ADC12_A_IE0); __bic_SR_register_on_exit(LPM0_bits); case 8: break; //Vector 8: ADC12IFG1 case 10: break; //Vector 10: ADC12IFG2 case 12: break; //Vector 12: ADC12IFG3 case 14: break; //Vector 14: ADC12IFG4 case 16: break; //Vector 16: ADC12IFG5 case 18: break; //Vector 18: ADC12IFG6 case 20: break; //Vector 20: ADC12IFG7 case 22: break; //Vector 22: ADC12IFG8 case 24: break; //Vector 24: ADC12IFG9 case 26: break; //Vector 26: ADC12IFG10 case 28: break; //Vector 28: ADC12IFG11 case 30: break; //Vector 30: ADC12IFG12 case 32: break; //Vector 32: ADC12IFG13 case 34: break; //Vector 34: ADC12IFG14 default: break; } }
  12. Like
    veryalive reacted to oPossum in CCS for $9.99   
    Free shipping until 9/18/2016.
  13. Like
    veryalive got a reaction from Rickta59 in CCS for $9.99   
    @blankname    --   and others interested in the 16KB code limit of the 'free' CS compiler.
     
    Yes, I too found I could compile a file with more than 16KB code loaded into an MSP device. (Using the 'free version' on Windows, CCS v 6.1.3)
     
    As I have a licence now (yet to be implemented on this machine), I'm not too worried about future changes TI may make in counting / restricting compiled code size.
    For my part, I sort of assumed it was a TI CCS bug as the compiler version number (v15 etc)  looks much different than pervious ones (v4.x).
     
    Attached is a text file with my test code and results in a short report format I made for my notes.
     
    Cheers.
     
     
    edit   ....     (note ........   trying to find out how to add a file to this post)  (have to select 'use full editor')Code size GT 16KB CCSv6.1.3.txt
  14. Like
    veryalive got a reaction from spirilis in CCS for $9.99   
    @blankname    --   and others interested in the 16KB code limit of the 'free' CS compiler.
     
    Yes, I too found I could compile a file with more than 16KB code loaded into an MSP device. (Using the 'free version' on Windows, CCS v 6.1.3)
     
    As I have a licence now (yet to be implemented on this machine), I'm not too worried about future changes TI may make in counting / restricting compiled code size.
    For my part, I sort of assumed it was a TI CCS bug as the compiler version number (v15 etc)  looks much different than pervious ones (v4.x).
     
    Attached is a text file with my test code and results in a short report format I made for my notes.
     
    Cheers.
     
     
    edit   ....     (note ........   trying to find out how to add a file to this post)  (have to select 'use full editor')Code size GT 16KB CCSv6.1.3.txt
  15. Like
    veryalive reacted to Rickta59 in CCS for $9.99   
    [NOTE]
    Before you bother trying to find this deal,  read this post:
    http://forum.43oh.com/topic/10050-ccs-70-will-be-available-without-license-requiremens/
     
    and this TI web page:
    http://processors.wiki.ti.com/index.php/CCSv7_Changes
    "Licensing
    With the release of Code Composer Studio v7 TI is no longer charging for licenses. You can simply download the tool and start using it. Along with this the end user license agreement has changed to a simple TSPA compatible license."
     
    [/NOTE]
     
    I didn't see anyone else mention this offer so here it is. Use the link below to buy the promo version of a G2 launchpad bundled with a node locked full version of CCS for only *$9.99:

    https://store.ti.com/MSP430G2-LaunchPad-Development-Kit-With-Code-Composer-Studio-Promotion-P50861.aspx

    -rick
     
    [Edit]
    * price is $9.99 + plus shipping
    [/Edit]
  16. Like
    veryalive reacted to spirilis in RANT: Cloud of this, IoT of that . . .   
    Money is essentially power when you simplify the concepts a bit.  Finite amounts of money usually beget finite amounts of resources, but humans require a steady stream of resources over time to achieve life, indeed death is the cessation of the continual resource train we require.
     
    Thus, those who control the money flow, control life.  That is true "power".
     
    And the companies vying for control over the IoT technologies know that their influence could give them structural insight & control over the development of this technology in the future, and they are betting this tech will be disruptive enough that it will become desirable-and eventually necessary for modern society (much as the cellphone has crossed this threshold I would argue), so it's a competition to see who can capture the most converts and followers and convince them to use their products.  Beware the embodied marketing behind most connected technology these days, it's all laced with puppet strings from competing companies just waiting for the right time to "pull" and orchestrate their self-serving surreptitous agenda (that is, of course, not so secret - it's the continual maximization of margin, of having the true structural capability to charge you more money for less so their rich shareholders receive ever more increasing levels of profit).
     
    The value of open standards, and of open source, in this arena lies in the power of choice- when technology is based on open standards agreed upon by most, each provider and player can be kept honest by the manner in which their customers can "choose" another vendor without significant pain.  The "IoT" crap we've seen so far is anything BUT open, and open standards may still be a long ways out... initiatives like OpenThread sound promising but, when backed by a zillion companies, beware the politics of sharks when you are nothing but a clownfish.
     
    However all this scary capitalism overshadows the real value of connecting things - the "emergent sum" concept, when interconnected and interrelated processes (the promise of IoT, I think?) can create qualities not otherwise intuitive or obvious.  https://en.wikipedia.org/wiki/Emergence
    Base the tech on open standards, and we may all benefit in some form that might not be totally obvious to us until 10-20 years into the future.
  17. Like
    veryalive reacted to will in Temperature & Humidity sensor -with LCD & RF   
    Hi everyone, this is my credit card size wireless sensor node,
    with a 7-seg LCD display showing temperature & humidity, update every second.
    using MSP430FR4133 with HDC1080,BMP180 and OPT3002, 
    transmit by nRF24l01, which sends out temp,humid,pressure,luminosity and also battery voltage per minute.
     

     
    It is all power by a CR2032, and thanks to MSP430FR4133, I can manage to have half an year battery life.

    also thanks to MSP430RF4133 Launchpad with build-in energyTrace, I can estimate battery life with a click(no more oscilloscope  )

    note that I've actually put an RF430 on the down left ot the board(there is an antenna for that),
    which will act as a NFC tag, but it draws too much current (~15uA), so I took it off
    and at the down right is the battery voltage measurement with a mosfet to cut the power,
    but I found out that I can just measure internal voltage reference to calculate its supply voltage, so I've also remove that. 

     
    although I'm pretty much satisfy with this power consumption, but I still think that 16.5uA is a little bit too far from estimating from datasheet
    and I am still trying to figure that out
  18. Like
    veryalive got a reaction from pokmo in Porting Arduino code to MSP   
    Here's a BLDC project that I learned quite a bit from.....    see the cut / paste at the bottom of this message .....
    (author = @lgbeno)
     
    The project uses CCS, a '2553 at 16MHz, and the code is very modular, the documentation (including use of the async port to annotate the scope traces) is cool.
     
    Regarding your questions, though :
     
    My own view is that CCS is a great IDE, has a solid compiler and the memory / HW register / variables mods one can do while the test processor is halted can really save a lot of time during debugging.  
    CCS, along with Energia is a formidable tool for me for doing small projects and actually finishing them.
     
    Best of luck, 
     
     
    ======  search the forum on BLDC  ========
     
     
    Posted 10 July 2013 - 05:18 AM
    Cool project, I did something very similar as well!

    https://github.com/lgbeno/BLDC-Booster   ======
  19. Like
    veryalive got a reaction from Fred in MOSFET choice for relay switching   
    2N7000
  20. Like
    veryalive reacted to Rickta59 in Program won't fit weirdness   
    cdecl.org is your friend here:
    http://cdecl.ridiculousfish.com/?q=const+char+*+const+command%5B%5D
  21. Like
    veryalive reacted to Rickta59 in Initializing flash segment from CCS compiler/linker ?   
    http://forum.43oh.com/topic/1220-saving-flash-space-by-making-use-of-infomem/?p=54004
  22. Like
    veryalive reacted to RobG in T6963 Graphical LCD libraries   
    Still rough and slow. Some borrowed code that needs to be improved and optimized.
    Here you can find cubeberg's version of T6963 library.




    t6963.hpg128128a.h
    UPDATED 1/22/2012
    msp430_t6963.h
     
    Reuploaded on 11/26/2014 (looks like files were corrupt during 43oh migration)
    msp430_t6963.c
    main.c
  23. Like
    veryalive reacted to Rickta59 in msp432 - run code from ram using arm-none-eabi-gcc in CCS   
    I noticed that if you use the TI arm compiler in CCS 6.x you can easily run code from ram.  Unfortunately, it doesn't seem like they have implemented that for the arm-none-eabi-gcc compiler. Attached is a zip file project you can import into CCS.  It is configured to run the msp432 at 48MHz using the high frequency crystal.   It is also configured to generate small code using the nano.specs newlib configuration.
     
    In the default linker script, the data segment uses all the available ram starting at the base address of 0x20000000.  The msp432 provides another bus address for SRAM at the base address of 0x01000000.  This alias address is used to provide single cycle access to code in ram. I modified the the linker script in this project (msp432p401r.lds) so that the first 512 bytes of ram are reserved for code. 
    /* adjust based address for fixed size of 512 bytes (0x200) for code in ram */ /* NOTE: if you change this size, make sure you adjust .vtable offset also */ SRAM_DATA  (RW) : ORIGIN = 0x20000000+0x200, LENGTH = 0x00010000-0x200 Additonally, a new section called .ramfunc is used to collect any code put into the ".ramfunc" section. You do this using the gcc specific _attribute__((section(".ramfunc"))) directive.  When the chip resets, code has been added to copy the instruction code from flash to ram.
    extern uint32_t __ramfunc_load__; extern uint32_t __ramfunc_start__; extern uint32_t __ramfunc_end__; void resetISR(void) {     /* Copy .ramfunc code and data segment initializers from flash to SRAM. */     volatile uint32_t *pui32Src, *pui32Dest;     pui32Src = &__ramfunc_load__;     for(pui32Dest = &__ramfunc_start__; pui32Dest < &__ramfunc_end__; )     {         *pui32Dest++ = *pui32Src++;     } ... Attachment blink_cmsis_gcc.zip:
    blink_cmsis_gcc.zip
     
    In CCS, go to Project Menu and select the "Import CCS Projects ..." and select the archive file button. Use the file dialog to select the location where you downloaded the attached blink_cmsis_gcc.zip file.
     
    BTW: This is using the new CMSIS headers.
     
    Running in the debugger (note the address 0x10000FC of the code in the disassembly window)

  24. Like
    veryalive reacted to RobG in Nokia 5110 display   
    @@veryalive, not sure what's going on, but I copy/pasted that code to new project in ccs6.1.3 and go the same exception (can't see any hidden chars, so it can't be it.)
    I then formatted code in main (shift-control-f) and all is good now.
    Attaching files just in case.
     
    main.cPCD8544.h
  25. Like
    veryalive got a reaction from Fmilburn in TI Store Happy Geek Pride Day! Celebrate with discounted shipping.   
    About the  'off topic' 16 / 25 MHz thing for MSP's:
    =======================================
     
    Its likely more about marketing and silicon economics than physics or architectures, imho.
    And likely no EE degree is needed on this one.
     
    A possible scenario could be:
     
    - MSPs are used in a defined market area of small machines, low cost, low performance demands, and likely high volume.
         (and there are a few other key drivers for the product certainly)
     
    - 16MHz would cover a very large majority of the applications that an MSP would likely face in its market
     
    - and 16 MHz is a pretty low speed for a modern CMOS chip process.....    This speed means, among other things, that the actual silicon chip size for an MSP is pretty small.     A higher speed would mean, again among other things, a bigger chip size in square millimeters.
     
    - and that the process rules (line widths / parasitics) across the MSP line are reasonably fixed - ---   more variants = more differences from design to design  === a more difficult to control development environment for the TI MSP chip designers.  (thus, a 'bad' thing).
    etcetera.   etcetera.  etcetera.
     
    And finally - the point of it all - is that TI, or its fab partner, can make a huge number of MSP's per silicon wafer - a bigger number than for instance a faster / larger / higher-featured product.   A small chip, like the MSP, can have thousands per wafer, each wafer raw cost being 100's or so USD.     So, they strive for:  minimum chip die area / maximum yield thru conservative design / maximum working chips off a wafer.
     
     
    So much of the chip industry is economics and it can become complex with lots of variables rather quickly.
     
     
    Does that get close to the open / off-topic query?
     
    Cheers.
×
×
  • Create New...