Jump to content
43oh

CorB

Members
  • Content Count

    288
  • Joined

  • Last visited

  • Days Won

    5

Reputation Activity

  1. Like
    CorB reacted to cubeberg in TI Deals moves to new time!   
    Looks like they know there's a shipping problem - check their twitter account
  2. Like
    CorB got a reaction from larsie in Remote controlled power socket   
    Hello Larsie,
     
    In the Netherlands an alike design is sold as "klik aan klik uit -KAKU" system which translates into "click on click off". A group of people working on Jeenode (Atmel based) have done a great deal of work to find out the way these modules communicate. You can read more about that overhere :
     
    inside of a unit
    http://forum.jeelabs.net/node/537
    protocols
    http://forum.jeelabs.net/node/348
     
    cheers
    Cor
  3. Like
    CorB got a reaction from dacoffey in Remote controlled power socket   
    Hello Larsie,
     
    In the Netherlands an alike design is sold as "klik aan klik uit -KAKU" system which translates into "click on click off". A group of people working on Jeenode (Atmel based) have done a great deal of work to find out the way these modules communicate. You can read more about that overhere :
     
    inside of a unit
    http://forum.jeelabs.net/node/537
    protocols
    http://forum.jeelabs.net/node/348
     
    cheers
    Cor
  4. Like
    CorB reacted to oPossum in Software Real Time Clock (RTC) - two methods   
    The Launchpad comes with a 32.768 kHz crystal that can be used when timing more precise than the DCO is needed. The crystal frequency is useful for simple timing tasks, such as a RTC, because it is a power of 2. That allows a simple cascade of 15 flip-flops to create a 1 pulse per second time base. It is common for microcontroller timers to have prescalers, postscalers and/or preset divisors that are simply a tap on the flip-flip chain. The watchdog timer in the MSP430 is an example of a timer with power of 2 presets (64, 512, 8192, 32768). TimerA units have a prescaler with power of 2 presets (1, 2, 4, 8).
     
    The sample code in this post uses the watchdog timer to create an interrupt that occurs once per second. TimerA can also be used to do this. One of the advantages of using TimerA is the ability to change the preset +/- 1 every N cycles to allow for calibration and temperature compensation of the crystal. I chose to use the watchdog timer so that TimerA was free to be used for alarm tones or PWM backlight control.
     

     
    Using the C standard library time functions for a RTC
    The C standard library provides several functions for working with real time. The function prototypes are in time.h. The type time_t is typically an integer type that is in units of 1 second. It doesn't have to be that, but usually is. The epoch is usually January 1, 1970 for "unix time." Be aware that CCS uses an epoch of January 1, 1900 and time_t is unsigned rather than signed. I assume GCC uses the more common unix time epoch and time_t is signed.
     
    Since time_t is in units of 1 second, the ISR for timekeeping is trivial...

    #pragma vector = WDT_VECTOR // - Watchdog timer interrupt vector __interrupt void wdt_isr(void) // This interrupt will occur once per second { // ++tt; // Increment time_t } //
     
    To display the time it can be converted to a tm structure that has elements for hours, minutes, day, month, ect. There are two functions to do this: gmtime() and localtime(). gmtime() converts to UTC, and localtime converts to the time zone for the set locale. Both functions take a time_t and return a pointer to a static tm struct.
     
    To set the time the mktime() function will convert a tm struct to a time_t value. It will also determine day of week and day or year for you.
     
    Benefits
    Tivial ISR. Simple and efficient.
    Portable code - the C standard library time functions work on almost any device with a C compiler.
    Easy to calulate time deltas - use ordinary integer math on time_t values.
    Easy to compare times using <, >, ==, etc.
    Compact representation of time (32 bit time_t typically) is good for timestamps of data logs.
    Some file systems (not FAT unfortunately) use time_t as for timestamps.
     
    Concerns
    Converting from time_t to tm struct takes quite a few clock cycles, so not good for low power (battery powered) systems.
    Time functions take up quite a bit of flash - will not fit in G2211 for example.
     
    Software model of a hardware RTC
    Hardware real time clocks typically have counters for seconds, minutes, hours, ect. Each counter will reset at the appropriate
    limit - 60 seconds, 24 hours, ect. This approch can be use for a software RTC. The ISR has more code than the previous version...

    #pragma vector = WDT_VECTOR // - Watchdog timer interrupt vector __interrupt void wdt_isr(void) // This interrupt will occur once per second { // if(++t.tm_sec > 59) { // Increment seconds, check for overflow t.tm_sec = 0; // Reset seconds if(++t.tm_min > 59) { // Increment minutes, check for overflow t.tm_min = 0; // Reset minutes if(++t.tm_hour > 23) { // Increment hours, check for overflow t.tm_hour = 0; // Reset hours ++t.tm_yday; // Increment day of year if(++t.tm_wday > 6) // Increment day of week, check for overflow t.tm_wday = 0; // Reset day of week // Increment day of month, check for overflow if(++t.tm_mday > dim[t.tm_mon][is_leap_year(t.tm_year + 1900)]) { t.tm_mday = 1; // Reset day of month if(++t.tm_mon > 11) { // Increment month, check for overflow t.tm_mon = 0; // Reset month t.tm_yday = 0; // Reset day of year ++t.tm_year; // Increment year } // - year } // - month } // - day } // - hour } // - minute } //
     
    Most of the time the ISR will just increment the seconds member and return. The worst case is at the end of the year when the year is incremented and all other counters are reset to inital values.
     
    There is no need for any conversion for display of the time or setting the time. Be aware that day of week and day of year must be explicity set and can be out-of-sync if not properly set.
     
    Benefits
    No conversion function needed for display of time or setting of time.
    Small code size. Fits in G2211.
    High efficiency is good for battery powered applications.
    Use of tm struct provides some familiarity to those who have used the C standard library functions.
     
    Concerns
    No easy to way calulate time delta.
    No support for time zones / localization.
    Time comparison (for alarms) requires more MCU cycles because several structure members require comparason rather than just a long integer.
     


    This sample code can be configured to use either of the two methods descibed by (un)commenting the "#define USE_STDLIB_TIME" in main.c
     
    main.c

    #include #include #include #include "rtc.h" #include "lcd.h" //#define USE_STDLIB_TIME // Use functions in time.h void show_time(const struct tm *t) // Show time on LCD { static const char *dow[7] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" }; int x, w; const char *d; if(t->tm_hour < 10) { x = -1; lcd_fill(0, 1, 10, 2, 0); } else { x = 4; lcd_fill(0, 1, 4, 2, 0); lcd_pd12(t->tm_hour / 10, x, 1); } lcd_pd12(t->tm_hour % 10, x + 11, 1); lcd_pd12(11, x + 22, 1); lcd_pd12(t->tm_min / 10, x + 27, 1); lcd_pd12(t->tm_min % 10, x + 38, 1); lcd_pd12(11, x + 49, 1); lcd_pd12(t->tm_sec / 10, x + 54, 1); lcd_pd12(t->tm_sec % 10, x + 65, 1); lcd_fill(x + 76, 1, 8 - x, 2, 0); if(t->tm_mon < 9) { x = -4; lcd_fill(0, 3, 7, 2, 0); } else { x = 1; lcd_fill(0, 3, 1, 2, 0); lcd_pd12((t->tm_mon + 1) / 10, x, 3); } lcd_pd12((t->tm_mon + 1) % 10, x + 11, 3); lcd_pd12(13, x + 22, 3); lcd_pd12(t->tm_mday / 10, x + 30, 3); lcd_pd12(t->tm_mday % 10, x + 41, 3); lcd_pd12(13, x + 52, 3); lcd_pd12(t->tm_year %100 / 10, x + 60, 3); lcd_pd12(t->tm_year % 10, x + 71, 3); lcd_fill(x + 82, 3, 2 - x, 2, 0); d = dow[t->tm_wday]; w = strlen(d) * 6; x = (84 - w) >> 1; lcd_fill(0, 5, x, 1, 0); lcd_print(d, x, 5); x += w; lcd_fill(x, 5, 84 - x, 1, 0); } // struct tm ts; // Time structure time_t tt; // Time in seconds since epoch // // #pragma vector = WDT_VECTOR // - Watchdog timer interrupt vector __interrupt void wdt_isr(void) // This interrupt will occur once per second { // #ifdef USE_STDLIB_TIME // ++tt; // Increment time_t #else // rtc_tick(&ts); // Increment tm struct #endif // __bic_SR_register_on_exit(LPM0_bits); // Wakeup main code } // // void main(void) // { // WDTCTL = WDTPW | WDTHOLD; // Disable watchdog reset // lcd_init(); // Init LCD lcd_clear(0); // lcd_print("MSP430 RTC", 12, 0); // // // 32 kHz xtal loading //BCSCTL3 = XCAP_1; // 6 pF (default) BCSCTL3 = XCAP_2; // 10 pF //BCSCTL3 = XCAP_3; // 12.5 pF // WDTCTL = WDTPW | WDTTMSEL | WDTCNTCL | WDTSSEL; // Use WDT as interval timer IE1 |= WDTIE; // Enable WDT interrupt _EINT(); // Enable interrupts // // Set initial time - there is no UI for this ts.tm_hour = 13; // Hour ts.tm_min = 37; // Minute ts.tm_sec = 42; // Second ts.tm_mon = 3; // Month (0 based!) ts.tm_mday = 20; // Day of Month ts.tm_year = 2012 - 1900; // Year ts.tm_wday = 5; // Day of Week - Not used by mktime() ts.tm_yday = 0; // Not used by mktime() ts.tm_isdst = 0; // DST flag - Not used by rtc_tick() // #ifdef USE_STDLIB_TIME // Convert tm struct to time_t tt = mktime(&ts); // #endif // // for(; { // for-ever #ifdef USE_STDLIB_TIME // show_time(localtime(&tt)); // Convert time_t to tm struct and show on LCD #else // show_time(&ts); // Show time on LCD #endif // __bis_SR_register(LPM0_bits + GIE); // Sleep until WDT interrupt } // } //
     
    rtc.h

    void rtc_tick(struct tm *t);
     
    rtc.c - Software model of hardware RTC

    #include static int is_leap_year(const int y) { if(y & 3) return 0; // Not divisible by 4 switch(y % 400) { // Divisible by 100, but not by 400 (1900, 2100, 2200, 2300, 2500, 2600) case 100: case 200: case 300: return 0; } return 1; // Divisible by 4 and !(100 and !400) } void rtc_tick(struct tm *t) { static const signed char dim[12][2] = { // Number of days in month for non-leap year and leap year 31, 31, // January 28, 29, // February 31, 31, // March 30, 30, // April 31, 31, // May 30, 30, // June 31, 31, // July 31, 31, // August 30, 30, // September 31, 31, // October 30, 30, // November 31, 31 // December }; // // if(++t->tm_sec > 59) { // Increment seconds, check for overflow t->tm_sec = 0; // Reset seconds if(++t->tm_min > 59) { // Increment minutes, check for overflow t->tm_min = 0; // Reset minutes if(++t->tm_hour > 23) { // Increment hours, check for overflow t->tm_hour = 0; // Reset hours ++t->tm_yday; // Increment day of year if(++t->tm_wday > 6) // Increment day of week, check for overflow t->tm_wday = 0; // Reset day of week // Increment day of month, check for overflow if(++t->tm_mday > dim[t->tm_mon][is_leap_year(t->tm_year + 1900)]) { t->tm_mday = 1; // Reset day of month if(++t->tm_mon > 11) { // Increment month, check for overflow t->tm_mon = 0; // Reset month t->tm_yday = 0; // Reset day of year ++t->tm_year; // Increment year } // - year } // - month } // - day } // - hour } // - minute } //
     
    lcd.h

    typedef enum { lcd_command = 0, // Array of one or more commands lcd_data = 1, // Array of one or more bytes of data lcd_data_repeat = 2 // One byte of data repeated } lcd_cmd_type; void lcd_send(const unsigned char *cmd, unsigned len, const lcd_cmd_type type); void lcd_home(void); void lcd_pos(unsigned char x, unsigned char y); void lcd_clear(unsigned char x); void lcd_init(void); void lcd_fill(unsigned x, unsigned y, unsigned w, unsigned h, unsigned char z); void lcd_print(const char *s, unsigned x, unsigned y); void lcd_pd12(unsigned n, unsigned x, unsigned y);
     
    lcd.c

    #include #include "lcd.h" //static const unsigned TXD = BIT1; static const unsigned RXD = BIT2; static const unsigned SWITCH = BIT3; static const unsigned LCD_CLK = BIT5; static const unsigned LCD_BACKLIGHT = BIT6; static const unsigned LCD_DATA = BIT7; static const unsigned LCD_DC = BIT0; // PORT2 static const unsigned LCD_CE = BIT1; // PORT2 void lcd_send(const unsigned char *cmd, unsigned len, const lcd_cmd_type type) { register unsigned mask; P2OUT &= ~LCD_CE; do { mask = 0x0080; do { if(*cmd & mask) { P1OUT &= ~LCD_CLK; P1OUT |= LCD_DATA; } else { P1OUT &= ~(LCD_CLK | LCD_DATA); } P1OUT |= LCD_CLK; mask >>= 1; } while(!(mask & 1)); if(!type) P2OUT &= ~LCD_DC; if(*cmd & mask) { P1OUT &= ~LCD_CLK; P1OUT |= LCD_DATA; } else { P1OUT &= ~(LCD_CLK | LCD_DATA); } P1OUT |= LCD_CLK; P2OUT |= LCD_DC; if(!(type & 2)) ++cmd; } while(--len); P2OUT |= LCD_CE; } static const unsigned char home[] = { 0x40, 0x80 }; void lcd_home(void) { lcd_send(home, sizeof(home), lcd_command); } void lcd_pos(unsigned char x, unsigned char y) { unsigned char c[2]; c[0] = 0x80 | x; c[1] = 0x40 | y; lcd_send(c, sizeof(c), lcd_command); } void lcd_clear(unsigned char x) { lcd_home(); lcd_send(&x, 504, lcd_data_repeat); lcd_home(); } void lcd_init(void) { static const unsigned char init[] = { 0x20 + 0x01, // function set - extended instructions enabled 0x80 + 64, // set vop (contrast) 0 - 127 0x04 + 0x02, // temperature control 0x10 + 0x03, // set bias system 0x20 + 0x00, // function set - chip active, horizontal addressing, basic instructions 0x08 + 0x04 // display control - normal mode }; P1REN = RXD | SWITCH; P1DIR = LCD_CLK | LCD_BACKLIGHT | LCD_DATA; P1OUT = LCD_CLK | RXD | SWITCH | LCD_BACKLIGHT; P2REN = 0; P2DIR = LCD_DC | LCD_CE; P2OUT = LCD_CE; __delay_cycles(20000); P2OUT |= LCD_DC; __delay_cycles(20000); lcd_send(init, sizeof(init), lcd_command); } void lcd_fill(unsigned x, unsigned y, unsigned w, unsigned h, unsigned char z) { unsigned yy = y + h; unsigned char c[2]; c[0] = 0x80 | x; for(;y < yy; ++y) { c[1] = 0x40 | y; lcd_send(c, sizeof(c), lcd_command); lcd_send(&z, w, lcd_data_repeat); } } static const unsigned char font6x8[96][5] = { 0x00, 0x00, 0x00, 0x00, 0x00, // 20 32 0x00, 0x00, 0x5F, 0x00, 0x00, // 21 33 ! 0x00, 0x07, 0x00, 0x07, 0x00, // 22 34 " 0x14, 0x7F, 0x14, 0x7F, 0x14, // 23 35 # 0x24, 0x2A, 0x7F, 0x2A, 0x12, // 24 36 $ 0x23, 0x13, 0x08, 0x64, 0x62, // 25 37 % 0x36, 0x49, 0x56, 0x20, 0x50, // 26 38 & 0x00, 0x08, 0x07, 0x03, 0x00, // 27 39 ' 0x00, 0x1C, 0x22, 0x41, 0x00, // 28 40 ( 0x00, 0x41, 0x22, 0x1C, 0x00, // 29 41 ) 0x2A, 0x1C, 0x7F, 0x1C, 0x2A, // 2A 42 * 0x08, 0x08, 0x3E, 0x08, 0x08, // 2B 43 + 0x00, 0x40, 0x38, 0x18, 0x00, // 2C 44 , 0x08, 0x08, 0x08, 0x08, 0x08, // 2D 45 - 0x00, 0x00, 0x60, 0x60, 0x00, // 2E 46 . 0x20, 0x10, 0x08, 0x04, 0x02, // 2F 47 / 0x3E, 0x51, 0x49, 0x45, 0x3E, // 30 48 0 0x00, 0x42, 0x7F, 0x40, 0x00, // 31 49 1 0x42, 0x61, 0x51, 0x49, 0x46, // 32 50 2 0x21, 0x41, 0x49, 0x4D, 0x33, // 33 51 3 0x18, 0x14, 0x12, 0x7F, 0x10, // 34 52 4 0x27, 0x45, 0x45, 0x45, 0x39, // 35 53 5 0x3C, 0x4A, 0x49, 0x49, 0x30, // 36 54 6 0x41, 0x21, 0x11, 0x09, 0x07, // 37 55 7 0x36, 0x49, 0x49, 0x49, 0x36, // 38 56 8 0x06, 0x49, 0x49, 0x29, 0x1E, // 39 57 9 0x00, 0x00, 0x14, 0x00, 0x00, // 3A 58 : 0x00, 0x00, 0x40, 0x34, 0x00, // 3B 59 ; 0x00, 0x08, 0x14, 0x22, 0x41, // 3C 60 < 0x14, 0x14, 0x14, 0x14, 0x14, // 3D 61 = 0x00, 0x41, 0x22, 0x14, 0x08, // 3E 62 > 0x02, 0x01, 0x51, 0x09, 0x06, // 3F 63 ? 0x3E, 0x41, 0x5D, 0x59, 0x4E, // 40 64 @ 0x7C, 0x12, 0x11, 0x12, 0x7C, // 41 65 A 0x7F, 0x49, 0x49, 0x49, 0x36, // 42 66 B 0x3E, 0x41, 0x41, 0x41, 0x22, // 43 67 C 0x7F, 0x41, 0x41, 0x41, 0x3E, // 44 68 D 0x7F, 0x49, 0x49, 0x49, 0x41, // 45 69 E 0x7F, 0x09, 0x09, 0x09, 0x01, // 46 70 F 0x3E, 0x41, 0x49, 0x49, 0x7A, // 47 71 G 0x7F, 0x08, 0x08, 0x08, 0x7F, // 48 72 H 0x00, 0x41, 0x7F, 0x41, 0x00, // 49 73 I 0x20, 0x40, 0x41, 0x3F, 0x01, // 4A 74 J 0x7F, 0x08, 0x14, 0x22, 0x41, // 4B 75 K 0x7F, 0x40, 0x40, 0x40, 0x40, // 4C 76 L 0x7F, 0x02, 0x1C, 0x02, 0x7F, // 4D 77 M 0x7F, 0x04, 0x08, 0x10, 0x7F, // 4E 78 N 0x3E, 0x41, 0x41, 0x41, 0x3E, // 4F 79 O 0x7F, 0x09, 0x09, 0x09, 0x06, // 50 80 P 0x3E, 0x41, 0x51, 0x21, 0x5E, // 51 81 Q 0x7F, 0x09, 0x19, 0x29, 0x46, // 52 82 R 0x26, 0x49, 0x49, 0x49, 0x32, // 53 83 S 0x01, 0x01, 0x7F, 0x01, 0x01, // 54 84 T 0x3F, 0x40, 0x40, 0x40, 0x3F, // 55 85 U 0x1F, 0x20, 0x40, 0x20, 0x1F, // 56 86 V 0x3F, 0x40, 0x38, 0x40, 0x3F, // 57 87 W 0x63, 0x14, 0x08, 0x14, 0x63, // 58 88 X 0x03, 0x04, 0x78, 0x04, 0x03, // 59 89 Y 0x61, 0x51, 0x49, 0x45, 0x43, // 5A 90 Z 0x00, 0x7F, 0x41, 0x41, 0x41, // 5B 91 [ 0x02, 0x04, 0x08, 0x10, 0x20, // 5C 92 '\' 0x00, 0x41, 0x41, 0x41, 0x7F, // 5D 93 ] 0x04, 0x02, 0x01, 0x02, 0x04, // 5E 94 ^ 0x80, 0x80, 0x80, 0x80, 0x80, // 5F 95 _ 0x00, 0x03, 0x07, 0x08, 0x00, // 60 96 ' 0x20, 0x54, 0x54, 0x54, 0x78, // 61 97 a 0x7F, 0x28, 0x44, 0x44, 0x38, // 62 98 b 0x38, 0x44, 0x44, 0x44, 0x28, // 63 99 c 0x38, 0x44, 0x44, 0x28, 0x7F, // 64 100 d 0x38, 0x54, 0x54, 0x54, 0x18, // 65 101 e 0x00, 0x08, 0x7E, 0x09, 0x02, // 66 102 f 0x18, 0xA4, 0xA4, 0xA4, 0x7C, // 67 103 g 0x7F, 0x08, 0x04, 0x04, 0x78, // 68 104 h 0x00, 0x44, 0x7D, 0x40, 0x00, // 69 105 i 0x00, 0x20, 0x40, 0x40, 0x3D, // 6A 106 j 0x00, 0x7F, 0x10, 0x28, 0x44, // 6B 107 k 0x00, 0x41, 0x7F, 0x40, 0x00, // 6C 108 l 0x7C, 0x04, 0x78, 0x04, 0x78, // 6D 109 m 0x7C, 0x08, 0x04, 0x04, 0x78, // 6E 110 n 0x38, 0x44, 0x44, 0x44, 0x38, // 6F 111 o 0xFC, 0x18, 0x24, 0x24, 0x18, // 70 112 p 0x18, 0x24, 0x24, 0x18, 0xFC, // 71 113 q 0x7C, 0x08, 0x04, 0x04, 0x08, // 72 114 r 0x48, 0x54, 0x54, 0x54, 0x24, // 73 115 s 0x04, 0x04, 0x3F, 0x44, 0x24, // 74 116 t 0x3C, 0x40, 0x40, 0x20, 0x7C, // 75 117 u 0x1C, 0x20, 0x40, 0x20, 0x1C, // 76 118 v 0x3C, 0x40, 0x30, 0x40, 0x3C, // 77 119 w 0x44, 0x28, 0x10, 0x28, 0x44, // 78 120 x 0x4C, 0x90, 0x90, 0x90, 0x7C, // 79 121 y 0x44, 0x64, 0x54, 0x4C, 0x44, // 7A 122 z 0x00, 0x08, 0x36, 0x41, 0x00, // 7B 123 { 0x00, 0x00, 0x77, 0x00, 0x00, // 7C 124 | 0x00, 0x41, 0x36, 0x08, 0x00, // 7D 125 } 0x02, 0x01, 0x02, 0x04, 0x02, // 7E 126 ~ 0x00, 0x06, 0x09, 0x09, 0x06, // 7F 127 degrees }; void lcd_print(const char *s, unsigned x, unsigned y) { unsigned char c[2]; c[0] = 0x80 | x; c[1] = 0x40 | y; lcd_send(c, sizeof(c), lcd_command); while(*s) { lcd_send(&font6x8[*s - 32][0], 5, lcd_data); lcd_send(&font6x8[0][0], 1, lcd_data); ++s; } } static const unsigned char num11x16[19][11 * 2] = { 0x00,0xF0,0xFC,0xFE,0x06,0x02,0x06,0xFE,0xFC,0xF0,0x00, // 0 0x00,0x07,0x1F,0x3F,0x30,0x20,0x30,0x3F,0x1F,0x07,0x00, 0x00,0x00,0x08,0x0C,0xFC,0xFE,0xFE,0x00,0x00,0x00,0x00, // 1 0x00,0x20,0x20,0x20,0x3F,0x3F,0x3F,0x20,0x20,0x20,0x00, 0x00,0x0C,0x0E,0x06,0x02,0x02,0x86,0xFE,0x7C,0x38,0x00, // 2 0x00,0x30,0x38,0x3C,0x36,0x33,0x31,0x30,0x30,0x38,0x00, 0x00,0x0C,0x0E,0x86,0x82,0x82,0xC6,0xFE,0x7C,0x38,0x00, // 3 0x00,0x18,0x38,0x30,0x20,0x20,0x31,0x3F,0x1F,0x0E,0x00, 0x00,0x00,0xC0,0x20,0x18,0x04,0xFE,0xFE,0xFE,0x00,0x00, // 4 0x00,0x03,0x02,0x02,0x02,0x22,0x3F,0x3F,0x3F,0x22,0x02, 0x00,0x00,0x7E,0x7E,0x46,0x46,0xC6,0xC6,0x86,0x00,0x00, // 5 0x00,0x18,0x38,0x30,0x20,0x20,0x30,0x3F,0x1F,0x0F,0x00, 0x00,0xC0,0xF0,0xF8,0xFC,0x4C,0xC6,0xC2,0x82,0x00,0x00, // 6 0x00,0x0F,0x1F,0x3F,0x30,0x20,0x30,0x3F,0x1F,0x0F,0x00, 0x00,0x06,0x06,0x06,0x06,0x06,0xC6,0xF6,0x3E,0x0E,0x00, // 7 0x00,0x00,0x00,0x30,0x3C,0x0F,0x03,0x00,0x00,0x00,0x00, 0x00,0x38,0x7C,0xFE,0xC6,0x82,0xC6,0xFE,0x7C,0x38,0x00, // 8 0x00,0x0E,0x1F,0x3F,0x31,0x20,0x31,0x3F,0x1F,0x0E,0x00, 0x00,0x78,0xFC,0xFE,0x86,0x02,0x86,0xFE,0xFC,0xF8,0x00, // 9 0x00,0x00,0x00,0x21,0x21,0x31,0x1D,0x1F,0x0F,0x03,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x70,0x70,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // : 0x00,0x0E,0x0E,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // . 0x00,0x38,0x38,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0xC0,0x30,0x0C,0x00,0x00,0x00,0x00, // / 0x00,0x30,0x0C,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, // - 0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 0x00,0x18,0x3C,0x66,0x66,0x3C,0x18,0x00,0x00,0x00,0x00, // 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0xF0,0xF8,0x0C,0x06,0x02,0x02,0x02,0x02,0x0E,0x0C,0x00, // C 0x03,0x07,0x0C,0x18,0x10,0x10,0x10,0x10,0x1C,0x0C,0x00, 0xFE,0xFE,0x42,0x42,0x42,0x42,0x42,0x42,0x00,0x00,0x00, // F 0x1F,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0xFE,0xFE,0x40,0xE0,0xB0,0x18,0x0C,0x06,0x02,0x00,0x00, // K 0x1F,0x1F,0x00,0x00,0x01,0x03,0x06,0x0C,0x18,0x10,0x00 }; void lcd_pd12(unsigned n, unsigned x, unsigned y) { unsigned char c[2]; c[0] = 0x80 | x; c[1] = 0x40 + y; lcd_send(c, 2, lcd_command); lcd_send(num11x16[n], 11, lcd_data); c[1] = 0x41 + y; lcd_send(c, 2, lcd_command); lcd_send(num11x16[n] + 11, 11, lcd_data); }
  5. Like
    CorB got a reaction from krzyk2 in Anaren TI CC110L RF AIR Booster Pack   
    Hi Cuberg,
     
    I am using the same basic code as Larsie and have had the same issue as you report some time ago. Ive added some additional code (see below) and I dont have any issues anymore. In my test-setup I have currently 3 Sensors (2 on batteries, 2xAAA or CR3025) and 1 Hub, they send data (mainly battery level as I am testing how long a setup can run from batteries) every 10 seconds. All sensors are at sleep most of the time and wake-up every 10 seconds, send a package and go to sleep again. Every 5th package asks for an ACK from the Hub, sensors wait for the ACK to come back (not sleeping). In the ACK-reply from the HUB every sensor learns how strong its signal is when received by the Hub, sensors do self power up/down (paTable) to minimize transmission energy whilst keeping a good connection.
     
    Here;s the modified code for RFSendPacket
     
    void RFSendPacket(char *txBuffer, char size)
    {
     
    // added 20120123 based on ANAREN code
    TI_CC_SPIStrobe(TI_CCxxx0_SIDLE); // set to IDLE
    TI_CC_SPIStrobe(TI_CCxxx0_SFRX); // Flush RX
    TI_CC_SPIStrobe(TI_CCxxx0_SFTX); // Flush TX
    // end new 20120123
     
    TI_CC_SPIWriteBurstReg(TI_CCxxx0_TXFIFO, txBuffer, size); // Write TX packet structure data
     
    TI_CC_SPIStrobe(TI_CCxxx0_STX); // Change state to TX, initiating data transfer
     
    while (!(TI_CC_GDO0_PxIN&TI_CC_GDO0_PIN)); // Wait GDO0 to go hi -> sync TX'ed
    while (TI_CC_GDO0_PxIN&TI_CC_GDO0_PIN); // Wait GDO0 to clear -> end of pkt
     
    TI_CC_SPIStrobe(TI_CCxxx0_SRX); // Change state to RX after sending
     
    TI_CC_GDO0_PxIFG &= ~TI_CC_GDO0_PIN; // After pkt TX, this interrupt flag is set.
    // Has to be cleared before exiting
     
     
    }
     
     
    cheers
    Cor
  6. Like
    CorB reacted to gwdeveloper in Customize Templates in CCS v5.1   
    I don't know if anyone has really noticed, but the default MSP430 template for CCS v5.1 is lacking a few details.
     
    It didn't take much to track down the blank main.c file. In my case, it was located:
    \Texas Instruments\CCSv5\ccsv5\eclipse\plugins\com.ti.ccstudio.project.templates_5.1.0.201110281600\resources\empty
     
    Just edit the main.c file to include any needed information. Most importantly, add:

    #include
  7. Like
    CorB got a reaction from kenilworthkid44 in Anaren TI CC110L RF AIR Booster Pack   
    Hi,
     
    The fact that the units show different temperatures is not a worry, the measured temperatures of the MSP430G2553 need to be cali brated before you can compare them properly. I have decided not to go forward with the Anaren firmware but just go with the far more simple code based on the SLAA325 application note of TI.
     
    regards
    Cor
  8. Like
    CorB got a reaction from noogrub in Anaren TI CC110L RF AIR Booster Pack   
    Hi,
     
    When testing the Air-BoosterStack software from Anaren you need to be sure that you set the devices in the right mode. So one serves as a HUB and another serves as a SENSOR. I had initially problems to get this working but after the firmware revision later in december the steps to setup as HUB and SENSOR did work easier. After that things should work as planned.
    Unfortunately we cannot SEE the AIR-Module working if the HUB and SENSOR are not communicating with each other. A simple Led (with a jumper) on the boosterpack would have been easy.
    Furthermore, I had an issue with one of my launchpads which took me some time to find out. The GND-connection did not reach the boosterpack. Turned out that one this particular launchpad the GND pin from the header wasnt connecting good. It might be wise to check if the AIR_module gets powered up properly.
     
    cheers
     
    Cor
  9. Like
    CorB got a reaction from ADIDAIllini in Anaren TI CC110L RF AIR Booster Pack   
    Hi all,
     
    Anaren has released an update of their firmware and its now also available for CCs
     
    http://www.anaren.com/content/File/AIR/ ... upport.cfm
     
    cheers
     
    Cor
     
    EDIT: just checked the download and most of the code seems to be missing in this update ... contacting ANAREN now.
  10. Like
    CorB got a reaction from bluehash in Anaren TI CC110L RF AIR Booster Pack   
    Hi all,
     
    Anaren has released an update of their firmware and its now also available for CCs
     
    http://www.anaren.com/content/File/AIR/ ... upport.cfm
     
    cheers
     
    Cor
     
    EDIT: just checked the download and most of the code seems to be missing in this update ... contacting ANAREN now.
  11. Like
    CorB reacted to gwdeveloper in Anaren TI CC110L RF AIR Booster Pack   
    Here's an updated CCS project for the Anaren Air Booster Pack. It's quite obvious they're not familiar with CCS. Included directories are very vague and leave header includes looking like "../../../HAL/HAL.h" instead of simply, "HAL.h". The code is a mess as well as the project's documentation lacks notes on how to configure the CCS project.
     
    CCS v5.1 Project
    [attachment=2]Anaren_CCS.zip[/attachment]
    CCS v4.2 Project
    [attachment=0]Anaren_CCS_v4.zip[/attachment]
    Originally, it required you to create a new workspace in the /Firmware folder then import the project. With this project, you can import into any workspace.
     
    2 warnings exist after compiling but don't seem to cause malfunction.
    [attachment=1]warning.JPG[/attachment]
     
    Consider this repair in the BETA stages, there are a few more changes that should be made for all-round usability but it works to get it going and test it.
     
    NOTE: This is a CCS project you need to import. In CCS, click "Project -> Import Existing CCS Project" then browse to the unzipped project folder.
  12. Like
    CorB got a reaction from gwdeveloper in Anaren TI CC110L RF AIR Booster Pack   
    Hi all,
     
    Anaren has released an update of their firmware and its now also available for CCs
     
    http://www.anaren.com/content/File/AIR/ ... upport.cfm
     
    cheers
     
    Cor
     
    EDIT: just checked the download and most of the code seems to be missing in this update ... contacting ANAREN now.
  13. Like
    CorB got a reaction from cubeberg in Anaren TI CC110L RF AIR Booster Pack   
    Hi all,
     
    Anaren has released an update of their firmware and its now also available for CCs
     
    http://www.anaren.com/content/File/AIR/ ... upport.cfm
     
    cheers
     
    Cor
     
    EDIT: just checked the download and most of the code seems to be missing in this update ... contacting ANAREN now.
  14. Like
    CorB got a reaction from legailutin in Anaren TI CC110L RF AIR Booster Pack   
    The link to the TI stuff http://www.ti.com/general/docs/litabsmu ... r=slaa325a
  15. Like
    CorB got a reaction from larsie in Anaren TI CC110L RF AIR Booster Pack   
    The link to the TI stuff http://www.ti.com/general/docs/litabsmu ... r=slaa325a
  16. Like
    CorB reacted to larsie in Anaren TI CC110L RF AIR Booster Pack   
    OK, so I made the library, and it was sort of working, but then CorB told me about this library: slaa325a (I'm not allowed to add a URL as I*m a new user, so google it).
     
    I reverted to using that, ported it to Launchpad (just minor config changes) and made it available on my GitHub repository. It's BSD-licensed. Thanks Texas Instruments for making a great Launchpad product and a great CC1101, which must be the most flexible of all RF chips. And to Anaren for the module!!! (you can tell I'm very happy, right? )
  17. Like
    CorB reacted to larsie in Anaren TI CC110L RF AIR Booster Pack   
    I'm making a very simple open source RF library for the MSP430 RF Booster Pack. It's at https://github.com/mobilars/LarsRF It's not done yet, but I hope to make a functional demo during today. It won't be advanced though. It's just meant for simple demos, prototypes and DIY stuff. For more advanced stuff, I'd recommend using SimpliciTI, now that this has been shown to be portable.
  18. Like
    CorB reacted to ADIDAIllini in Anaren TI CC110L RF AIR Booster Pack   
    The changes need to be made in the your SimpliciTI smartrf_CC1101.h file. For me the file was located in the following path:
    c:\Texas Instruments\SimpliciTI-CCS-1.1.1\Components\mrfi\smartrf\CC1101\smartrf_CC1101.h
    SmartRF Studio will export your register settings and you can copy and paste them in this file after remove the settings that are in there. You need to make sure that you select all the registers and not just the default registers that are selected.
     
     
    These are fairly self explanatory, I believe.
     
    Original code from mrfi_board_defs.h:

    /* ------------------------------------------------------------------------------------------------ * GDO2 Pin Configuration * ------------------------------------------------------------------------------------------------ */ #define __mrfi_GDO2_BIT__ 7 #define MRFI_CONFIG_GDO2_PIN_AS_INPUT() st( P2SEL &= ~BV(__mrfi_GDO2_BIT__); ) /* clear pin special function default */ #define MRFI_GDO2_PIN_IS_HIGH() (P2IN & BV(__mrfi_GDO2_BIT__)) #define MRFI_GDO2_INT_VECTOR PORT2_VECTOR #define MRFI_ENABLE_GDO2_INT() st( P2IE |= BV(__mrfi_GDO2_BIT__); ) /* atomic operation */ #define MRFI_DISABLE_GDO2_INT() st( P2IE &= ~BV(__mrfi_GDO2_BIT__); ) /* atomic operation */ #define MRFI_GDO2_INT_IS_ENABLED() ( P2IE & BV(__mrfi_GDO2_BIT__) ) #define MRFI_CLEAR_GDO2_INT_FLAG() st( P2IFG &= ~BV(__mrfi_GDO2_BIT__); ) /* atomic operation */ #define MRFI_GDO2_INT_FLAG_IS_SET() ( P2IFG & BV(__mrfi_GDO2_BIT__) ) #define MRFI_CONFIG_GDO2_RISING_EDGE_INT() st( P2IES &= ~BV(__mrfi_GDO2_BIT__); ) /* atomic operation */ #define MRFI_CONFIG_GDO2_FALLING_EDGE_INT() st( P2IES |= BV(__mrfi_GDO2_BIT__); ) /* atomic operation */
    New Code for mrfi_board_defs.h:

    /* ------------------------------------------------------------------------------------------------ * GDO2 Pin Configuration * ------------------------------------------------------------------------------------------------ */ #define __mrfi_GDO2_BIT__ 0 #define MRFI_CONFIG_GDO2_PIN_AS_INPUT() st( P1SEL &= ~BV(__mrfi_GDO2_BIT__); ) /* clear pin special function default */ #define MRFI_GDO2_PIN_IS_HIGH() (P1IN & BV(__mrfi_GDO2_BIT__)) #define MRFI_GDO2_INT_VECTOR PORT1_VECTOR #define MRFI_ENABLE_GDO2_INT() st( P1IE |= BV(__mrfi_GDO2_BIT__); ) /* atomic operation */ #define MRFI_DISABLE_GDO2_INT() st( P1IE &= ~BV(__mrfi_GDO2_BIT__); ) /* atomic operation */ #define MRFI_GDO2_INT_IS_ENABLED() ( P1IE & BV(__mrfi_GDO2_BIT__) ) #define MRFI_CLEAR_GDO2_INT_FLAG() st( P1IFG &= ~BV(__mrfi_GDO2_BIT__); ) /* atomic operation */ #define MRFI_GDO2_INT_FLAG_IS_SET() ( P1IFG & BV(__mrfi_GDO2_BIT__) ) #define MRFI_CONFIG_GDO2_RISING_EDGE_INT() st( P1IES &= ~BV(__mrfi_GDO2_BIT__); ) /* atomic operation */ #define MRFI_CONFIG_GDO2_FALLING_EDGE_INT() st( P1IES |= BV(__mrfi_GDO2_BIT__); ) /* atomic operation */
     
    I hope this helps.
×
×
  • Create New...