Jump to content

gordon

Members
  • Content Count

    536
  • Joined

  • Last visited

  • Days Won

    13

Reputation Activity

  1. Like
    gordon reacted to RobG in Activating Relays from Resistance   
    Here's the schematic for you. The code will follow.
    If your sensor is connected to GND and 12V and outputs voltage rather than resistance, use the bottom schematic to connect to P1.0 (R6/R7 is a sensor in that case, R8/R9/C4/D1/D2 replace R2/C2.)
    R4 is a trimmer to set the on/off temp.
     

  2. Like
    gordon reacted to RobG in "Smart" dual H-bridge booster pack   
    Another iteration of my dual H-bridge booster pack (original one is here.)
    Both bridges are totally isolated from the logic and from each other.
    The on board MSP430G2203 acts as a "smart" bridge controller.
    LDO will make it easier to use the board as a stand alone.
     
    The total cost of the board including terminals and headers: ~$6 (opto darlingtons are the most expensive, ~$0.50 a piece.)
    Higher currents (>1A) will require some sort of heat sink.
     

  3. Like
    gordon reacted to pabigot in Favorite scientific calculator   
    The HP-41CV (with the extended functions and memory modules) got me through undergrad, but the HP-28C was what I carried through grad school. I still have both of those, though whatever I used in high school seems to be long gone: it didn't have continuous memory, and I got really fast at typing the code sequence to program in "Lunar Lander" during calculus class. Digging through the HP Museum, I think it was a HP-33E.
     
    Ah, memories.
     
    Now I keep a HP-32SII on my desk for the 10% of the time I want to use a dedicated calculator. It cost more than I'd wanted to spend since I wasn't using a calculator much by that time, so I first purchased a HP-20S. That got about five minutes of use before I truly understood that I could no longer operate an algebraic calculator, so I had to upgrade.
     
    Most of the time now what I use is bc, with occasional recourse to either RealCalc or some Windows widget that's on the other desktop. If the 32SII ever dies, I'll probably just stick with RealCalc or whatever app replaces it.
     
    I still use gdb to convert anything more than 6 bits between hex and decimal though.
  4. Like
    gordon got a reaction from Nytblade in CCS 5: How to Program Two MSPs at Once?   
    ... or (I guess) you could use MSPDebug (the Cygwin version), which can be told what device to program, based on their unique USB serial numbers. Dunno how it would integrate with CCS, though, but here's your start.
  5. Like
    gordon got a reaction from pine in Launchpad driver for ubuntu on beagleboard   
    Comes standard with the distro. Just watch your kernel log while plugging the LP in.
  6. Like
    gordon reacted to oPossum in web site / blog like 43oh for STM32?   
    I would be very interested in a ARM forum like this MSP430 forum. Maybe include other popular brands like NXP and TI, and unique products like Energy Micro. I have 3 STM boards and a Energy Micro EFM32 board, but haven't done anything with them mostly due to lack of a good forum.
     
    I find the 'thumbs up' feature here to be very valuable and it is the reason I post here more then any PIC forum or mailing list. Knowing what people find interesting helps me decide what to share. Most of what I do never makes it on to the Internet, some due to contracts, but most due to lack of time. It is quite common for a post here to get no immediate replies but several likes - that is good to know and motivates me to share more.
  7. Like
    gordon reacted to oPossum in Time & Temperature on Nokia 7110   
    Sorry about the confusion over the license. Anything I post here is for others to learn from and use in any way they want. I don't really care much if I get credit for it. Any exceptions to this would be clearly noted. I have not put a copyright and GPLv3 notice in most of the code I have posted here because the presence of a copyright can give the impression that the code may not be copied and used by others. I certainly don't want to give that impression. Any code I have posted here without specific license is GPLv3 - Copyright 201x Kevin Timmerman
  8. Like
    gordon got a reaction from RobG in Ham Radio Repeater   
    You could also just chicken out and -- at a cost of a couple of pins -- use a dedicated DTMF decoder IC, as I did here: viewtopic.php?f=9&t=1125. Futurlec has them in both DIP and SOP for about $0.50 a pop (plus xtal plus some passives). Less satisfaction but instant results .
  9. Like
    gordon got a reaction from thomasss in Convert 2 analog signals into 1 with the msp430   
    (I faintly remember I did, and it worked indeed.)
  10. Like
    gordon got a reaction from Fe2o3Fish in Police lights... in Forth   
    Rockets4kids dug this up, see 4E4th for details on the interpreter itself. The following code implements a sort of a police light with the two LEDs. As with most everything, there are more than one ways to skin a cat -- this is a very naive and verbose implementation, just for the fun factor.
     

    : blink ( mask addr -- ) over over cset 100 ms cclr 100 ms ; : blink-red ( -- ) red blink ; : blink-green ( -- ) green blink ; : blink-red-twice ( -- ) red blink red blink ; : blink-green-twice ( -- ) green blink green blink ; : police ( -- ) begin blink-red-twice 100 ms blink-green-twice 100 ms s2? until ;
     
    The blinky goes on until one presses S2 (tested at the end of a blinky cycle, no interrupts or instant action or any such thing).
     


  11. Like
    gordon got a reaction from bluehash in Police lights... in Forth   
    Rockets4kids dug this up, see 4E4th for details on the interpreter itself. The following code implements a sort of a police light with the two LEDs. As with most everything, there are more than one ways to skin a cat -- this is a very naive and verbose implementation, just for the fun factor.
     

    : blink ( mask addr -- ) over over cset 100 ms cclr 100 ms ; : blink-red ( -- ) red blink ; : blink-green ( -- ) green blink ; : blink-red-twice ( -- ) red blink red blink ; : blink-green-twice ( -- ) green blink green blink ; : police ( -- ) begin blink-red-twice 100 ms blink-green-twice 100 ms s2? until ;
     
    The blinky goes on until one presses S2 (tested at the end of a blinky cycle, no interrupts or instant action or any such thing).
     


  12. Like
    gordon reacted to RobG in Ethernet Booster Pack   
    If all goes well with the booster pack, a standalone version will follow.
    The one below is 2" x 1", has MSP430G2553, LDO, 8 GPIOs, and a programming header.
     

  13. Like
    gordon reacted to V0JT4 in Universal Ripple Control Receiver   
    This week I got PCBs from my tutor and had time to populate and do some test. Boards were produced by local company so the price was quite high. I'm glad there are also services like Seed.
     

     

     

     

  14. Like
    gordon reacted to rockets4kids in Software async serial tx/rx without timer   
    [ EDIT: be sure to see updated post below ]
     
    Many thanks to Rick and oPossum for helping me get this up and running with gcc 4.6.3. In the process we found a few problems in the original code where word access is made to port registers rather than byte mode.
     
    Here is what I have:
     
    sw_serial.S

    ;------------------------------------------------------------------------ ; File: sw_serial.S - msp430-gcc software only async serial routines ; ; Copyright (C) 2011 Kevin Timmerman ; ; This program is free software: you can redistribute it and/or modify ; it under the terms of the GNU General Public License as published by ; the Free Software Foundation, either version 3 of the License, or ; (at your option) any later version. ; ; This program is distributed in the hope that it will be useful, ; but WITHOUT ANY WARRANTY; without even the implied warranty of ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ; GNU General Public License for more details. ; ; You should have received a copy of the GNU General Public License ; along with this program. If not, see . ; ; ; Desc: blocking versions of putchar(), getchar(), and puts() that ; use cycle counting for accurate sampling and sending. Features ; very small code size, allows use of any pin, and doesn't interfere ; with the use of timers. ; ; Change Log: ; 2012-Jan-04 rick@kimballsoftware.com ; Changes for gcc, renamed function names to ; allow gcc printf() to work, conditional defines to allow ; for smaller code, disabled puts() by default so not to ; conflict with libc version. renamed jump labels to ; reduce symbol table pollution. ; ; 2011-Oct-23 rick@kimballsoftware.com ; Initial port to msp430-gcc ; ; 2012-Apr-28 rockets4kids@gmail.com ; rolled in include file ; fixed I/O ops to byte (. mode ; ; See Also: ; Detailed information about original code here: ; http://www.43oh.com/forum/viewtopic.php?f=10&t=1727 ; ;------------------------------------------------------------------------ ; TODO: Add optional sleep mode in getchar() which will disable MCU until ; incoming pin edge detect triggers interrupt. ; TODO: Allow for mulitple serial ports ;------------------------------------------------------------------------ #include //------------------------------------------------------------------------------ // define PC,SP,SR as gcc only uses the register names // #define PC r0 #define SP r1 #define SR r2 //------------------------------------------------------------------------------ // define argument registers // C function arguments are passed in R15-R12 // // Note: these registers can be used without preservation // #define ARG1 R15 #define ARG2 R14 #define ARG3 R13 #define ARG4 R12 #define ENABLE_GETCHAR /* enable getchar() */ #define ENABLE_PUTCHAR /* enable putchar() */ #undef ENABLE_PUTS /* disable puts() as it isn't ISO conforming */ #define ENABLE_AUTO_GIE /* call __dint() .. __eint() on getchar() putchar() */ .file "sw_serial.S" ;------------------------------------------------------------------------ ; Unitialized SRAM local variables ;------------------------------------------------------------------------ .lcomm rx_bit_mask, 2 ; Serial in pin mask .lcomm tx_bit_mask, 2 ; Serial out pin mask .lcomm bit_dur, 2 ; Bit duration in cycles .lcomm half_dur, 2 ; Half bit duration in cycles ;------------------------------------------------------------------------ ; Exposed Function Symbols ;------------------------------------------------------------------------ .text ; use the "text" section for all code below .global init_serial ; void init_serial(unsigned out_mask, unsigned in_mask, unsigned bit_duration); .global init_serial1 ; void init_serial(_serial_ios *ios); #ifdef ENABLE_GETCHAR .global getchar ; int getchar(void); #endif #ifdef ENABLE_PUTCHAR .global putchar ; int putchar(uint8_t c); #endif #ifdef ENABLE_PUTS .global puts ; int puts(const char *s); NOTE: no appended newline #endif ;------------------------------------------------------------------------ ; Serial Function Implementations ;------------------------------------------------------------------------ .p2align 1,0 ; align on a word boundary ;-------------------------------------------------------------------------------- ; void init_serial(int txPinMask, int rxPinMask, int bitDuration) ;-------------------------------------------------------------------------------- .type init_serial,@function init_serial: ; Setup serial I/O bitmasks and bit duration (minimum of 32) mov ARG1, &tx_bit_mask ; Save serial output bitmask mov ARG2, &rx_bit_mask ; Save serial input bitmask bis.b ARG1, &P1DIR ; set output pin bis.b ARG1, &P1OUT bic.b ARG2, &P1DIR ; clear input pin bis ARG2, ARG1 #ifdef __MSP430FR5739__ bic.b ARG1, &P1SEL0 ; force output pin to digial I/O no pullups bic.b ARG1, &P1SEL1 ; force output pin to digial I/O no pullups #else bic.b ARG1, &P1SEL ; force output pin to digial I/O no pullups #endif mov ARG3, ARG1 ; Compute bit duration sub #16, ARG3 ; Adjust count for loop overhead rla ARG3 ; Multiply by 2 because NOP is two bytes mov ARG3, &bit_dur ; Save bit duration sub #32, ARG1 ; Adjust count for loop overhead mov ARG1, &half_dur ; Save half bit duration ret ; ready to rx/tx .Lfe1: .size init_serial,.Lfe1-init_serial #ifdef ENABLE_GETCHAR ;-------------------------------------------------------------------------------- ; int getchar(void) - read one character (blocking) ;-------------------------------------------------------------------------------- .p2align 1,0 ; align on a word boundary .type getchar,@function getchar: bic #GIE, SR ; disable global interrupts mov &bit_dur, R14 ; Bit duration mov &rx_bit_mask, R13 ; Input bitmask mov #0x01FF, ARG1 ; 9 bits - 8 data + stop .rx_start: ; Wait for start bit mov.b &P1IN, R12 ; Get serial input and R13, R12 ; Mask and test bit jc .rx_start ; Wait for low... mov &half_dur, R13 ; Wait for 1/2 bit time .rx_delay: nop ; Bit delay sub #8, R13 jc .rx_delay subc R13, PC ; 0 to 3 cycle delay nop ; 3 nop ; 2 nop ; 1 mov.b &P1IN, R12 ; Get serial input and &rx_bit_mask, R12 rrc ARG1 ; Shift in a bit mov R14, R13 ; Setup bit timer jc .rx_delay ; Next bit... rla ARG1 ; Move stop bit to carry swpb ARG1 ; Move rx byte to lower byte, start bit in msb bis #GIE, SR ; enable global interrupts ret ; Return with rx char and start bit in R15, stop bit in carry .Lfe3: .size getchar,.Lfe3-getchar #endif #ifdef ENABLE_PUTCHAR ;-------------------------------------------------------------------------------- ; int putchar(uint8_t c) - writes the character c to serial out ;-------------------------------------------------------------------------------- .p2align 1,0 ; align on a word boundary .type putchar,@function putchar: ; Char to tx in R15, R12, R13, R14, R15 trashed bic #GIE, SR ; disable global interrupts mov &tx_bit_mask, R12 ; Serial output bitmask mov &bit_dur, R14 ; Bit duration bis #0x0300, ARG1 ; Add Stop bit(s) to tx char jmp .bit_low ; Send start bit... .tx_bit: mov R14, R13 ; Get bit duration .tx_delay: nop ; 4 cycle loop sub #8, R13 jc .tx_delay subc R13, PC ; 0 to 3 cycle delay nop ; 3 nop ; 2 nop ; 1 rra ARG1 ; Get bit to tx, test for zero jc .bit_high ; If high... .bit_low: bic.b R12, &P1OUT ; Send zero bit jmp .tx_bit ; Next bit... .bit_high: bis.b R12, &P1OUT ; Send one bit jnz .tx_bit ; If tx data is not zero, then there are more bits to send... bis #GIE, SR ; enable global interrupts ret ; Return when all bits sent .Lfe2: .size putchar,.Lfe2-putchar #endif #ifdef ENABLE_PUTS ;-------------------------------------------------------------------------------- ; int puts(const char *s) - writes the string s to serial out. ;-------------------------------------------------------------------------------- .p2align 1,0 ; align on a word boundary .type puts,@function puts: push R11 ; TX string using putchar mov ARG1, R11 ; String pointer in R15, copy to R11 (temp reg) .putsloop: mov.b @R11+, ARG1 ; Get a byte, inc pointer tst.b ARG1 ; Test if end of string jz .putsx ; Yes, exit... call #putchar ; Call putchar jmp .putsloop .putsx: pop R11 ; restore original R11 ret ; .Lfe4: .size puts,.Lfe4-puts #endif
     
    sw_serial.h

    void init_serial(unsigned txPinMask, unsigned rxPinMask, unsigned bitDuration); int getchar(void); int putchar(int c); int puts(const char *s);
     
    main.c

    #include #include #include "sw_serial.h" void main(void) { int c; // 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) init_serial (BIT1, BIT2, 1000000 / 9600); // Send a string puts ("\r\nRunning...\r\n"); for (; { // Do forever c = getchar(); // Get a char putchar (c); // Echo it back } }
     
    Makefile

    lazy.elf: sw_serial.S main.c msp430-gcc -Os sw_serial.S main.c -o lazy.elf -mmcu=msp430g2211 install: lazy.elf mspdebug rf2500 "prog lazy.elf" clean: rm -f *~ *.elf
  15. Like
    gordon reacted to oPossum in Software async serial tx/rx without timer   
    Had some requests for this in IRC so here it is. This is an improved version of the serial tx previously posted and new serial rx code. Both tx and rx are blocking and interrupts should be disabled before calling.
     
    C code to show how to use the serial_setup(), putc(), puts(), and getc() functions.
    This will receive a character, increment it and echo it back. So if you type 'A', then 'B' will be echoed.

    // test.c #include "msp430g2211.h" // Functions in serial.asm (this really should be in a header file) void serial_setup(unsigned out_mask, unsigned in_mask, unsigned duration); void putc(unsigned); void puts(char *); unsigned getc(void); void main(void) { char c; // 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); // Send a string puts("\r\nRunning...\r\n"); for(; { // Do forever c = getc(); // Get a char ++c; // Increment it putc(c); // Echo it back } }
     
    The serial tx/rx code. Just add this as a new source file in your CCS project and it will be callable from your C code.

    ; serial.asm .cdecls C, LIST, "msp430g2231.h" .bss in_bit_mask, 2 ; Serial in pin .bss out_bit_mask, 2 ; Serial out pin .bss bit_dur, 2 ; Bit duration in cycles .bss half_dur, 2 ; Half bit duration in cycles ; .text ; .def serial_setup ; void serial_setup(unsigned out_mask, unsigned in_mask, unsigned bit_duration); .def putc ; void putc(unsigned c); .def puts ; void puts(char *s); .def getc ; unsigned getc(void); ; ; serial_setup ; - Setup serial I/O bitmasks and bit duration (32 minimum) mov R12, &out_bit_mask ; Save serial output bitmask mov R13, &in_bit_mask ; Save serial input bitmask bis.b R12, &P1DIR ; Setup output pin bis.b R12, &P1OUT ; bic.b R13, &P1DIR ; Setup input pin or R13, R12 ; bic.b R12, &P1SEL ; Setup peripheral select mov R14, R12 ; sub #16, R14 ; Adjust count for loop overhead rla R14 ; Multiply by 2 because NOP is two bytes mov R14, &bit_dur ; Save bit duration sub #32, R12 ; Adjust count for loop overhead mov R12, &half_dur ; Save half bit duration ret ; Return ; ; - Send a single char putc ; Char to tx in R12 ; R12, R13, R14, R15 trashed mov &out_bit_mask, R15 ; Serial output bitmask mov &bit_dur, R14 ; Bit duration or #0x0300, R12 ; Stop bit(s) jmp bit_low ; Send start bit... ; tx_bit mov R14, R13 ; Get bit duration tx_delay nop ; 4 cycle loop sub #8, R13 ; jc tx_delay ; subc R13, PC ; 0 to 3 cycle delay nop ; 3 nop ; 2 nop ; 1 ; rra R12 ; Get bit to tx, test for zero jc bit_high ; If high... bit_low bic.b R15, &P1OUT ; Send zero bit jmp tx_bit ; Next bit... bit_high bis.b R15, &P1OUT ; Send one bit jnz tx_bit ; If tx data is not zero, then there are more bits to send... ; ret ; Return when all bits sent ; ; ; - Send a NULL terminated string puts ; Tx string using putc push R11 ; mov R12, R11 ; String pointer in R12, copy to R11 putsloop ; mov.b @R11+, R12 ; Get a byte, inc pointer tst.b R12 ; Test if end of string jz putsx ; Yes, exit... call #putc ; Call putc jmp putsloop ; putsx pop R11 ; ret ; ; getc ; - Get a char mov &bit_dur, R14 ; Bit duration mov &in_bit_mask, R13 ; Input bitmask mov #0x01FF, R12 ; 9 bits - 8 data + stop ; rx_start ; Wait for start bit mov.b &P1IN, R15 ; Get serial input and R13, R15 ; Mask and test bit jc rx_start ; Wait for low... ; mov &half_dur, R13 ; Wait for 1/2 bit time ; rx_delay nop ; Bit delay sub #8, R13 ; jc rx_delay ; subc R13, PC ; 0 to 3 cycle delay nop ; 3 nop ; 2 nop ; 1 ; mov.b &P1IN, R15 ; Get serial input and &in_bit_mask, R15 ; rrc R12 ; Shift in a bit ; mov R14, R13 ; Setup bit timer jc rx_delay ; Next bit... ; rla R12 ; Move stop bit to carry swpb R12 ; Move rx byte to lower byte, start bit in msb ret ; Return with rx char and start bit in R12, stop bit in carry ; .end ;
  16. Like
    gordon got a reaction from Dougster in MSP430 with USB support?   
    Clean solder tip, clean board, and copious amounts of flux. Watch a couple of videos (I like John Gammell's stuff, but there are plenty) to get the feeling, it really is that easy.
  17. Like
    gordon reacted to kff2 in Time & Temperature on Nokia 7110   
    Some notes on compiling this with msp430-gcc.
     
    1) To handle C++ templates in nokia7110tl.h, you need to a version of msp430-gcc with C++ support. If building from sources, configure with --enable_languages=c,c++. The packaged msp430-gcc in recent versions of Ubuntu should already be C++ enabled.
     
    To compile C++ code, use msp430-g++ instead of msp430-gcc. You will likely get the error
     
    ld: cannot find -lstdc++
     
    This is because msp430-g++ links against the C++ standard library by default, which is not included with msp430-gcc. To work around, run msp430-g++ as follows:
     
    msp430-g++ -mmcu=msp430g2452 -o time.elf main.cpp -nodefaultlibs -fno-rtti -fno-exceptions -lc -lgcc
     
    This tells msp430-g++ not to use default libraries. You then need to explicitly list the default libraries that you need (-lc and -lgcc). -fno-rtti -fno-exceptions eliminates some C++ bloat and reduces code size.
     
    2) time.h is not included with msp430-gcc. I used this version which I found somewhere on the internet:
     

    typedef long time_t; /* for representing times in seconds */ struct tm { int tm_sec; int tm_min; int tm_hour; int tm_mday; int tm_mon; int tm_year; int tm_wday; int tm_yday; int tm_isdst; }; const unsigned char moninit[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; static unsigned dylen(unsigned yr) { if(yr%4 || (yr % 100) == 0 && ((yr+300)%400) != 0) return(365); return(366); } struct tm * gmtime(time_t * tp) { time_t t; static struct tm tim; t = *tp; tim.tm_sec = t % 60L; t /= 60L; tim.tm_min = t % 60L; t /= 60L; tim.tm_hour = t % 24L; tim.tm_mday = t / 24L; tim.tm_wday = (tim.tm_mday + 4) % 7; tim.tm_year = 70; while(tim.tm_mday >= dylen(tim.tm_year)) { tim.tm_mday -= dylen(tim.tm_year); tim.tm_year++; } tim.tm_yday = tim.tm_mday; if(tim.tm_mday >= 59 && dylen(tim.tm_year) == 366) tim.tm_mday--; tim.tm_mon = 0; while(tim.tm_mday >= moninit[tim.tm_mon]) { tim.tm_mday -= moninit[tim.tm_mon]; tim.tm_mon++; } tim.tm_mday++; return &tim; } struct tm * localtime(time_t * tp) { time_t t; t = *tp - 7 * 3600L; return gmtime(&t); }
     
    Notice that there is no mktime function here. Instead, in main.cpp, I set tt to the current unix timestamp (obtained with "date +%s" in Linux). Also, the localtime function here hardcodes my timezone. Change accordingly.
     
    3) This original code causes the LCD to go berserk when compiled under msp430-gcc:
     

    for(c = 32; c < 128; ++c) { lcd.print(c); if(++x >= 16) x = 0, lcd.pos(x, ++y); }
     
    That's because c is a signed byte value, and the compiler treats 128 as -1, causing an infinite loop. What you want instead is
     

    for(c = 32; c < 128U; ++c) { lcd.print(c); if(++x >= 16) x = 0, lcd.pos(x, ++y); }
     
    Hope this will be useful to somebody.
  18. Like
    gordon reacted to oPossum in Time & Temperature on Nokia 7110   
    This uses code from Software RTC, Using the internal temperature sensor and Nokia 5110 template class. The code has been modified and refined a bit for this project.
     



     
    main.cpp

    #include #include #include #include #include "nokia7110tl.h" using namespace nokia7110; static const unsigned char ti[] = { 48, 48 / 8, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC, 0xFC,0xFC,0xFC,0xFC,0x00,0x00,0x00,0x00,0x00,0xF0, 0xF0,0xF0,0xF0,0xF0,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFC,0xFC,0x3C,0x80,0xFC,0xFD, 0xFD,0xFD,0x3D,0x81,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC, 0xFC,0xFC,0xFC,0xFC,0x00,0x00,0x00,0x00, 0x00,0x1C,0x7C,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC, 0xFC,0xFC,0xFC,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xF7,0xF0,0xF0,0x00,0xF0,0xFF,0xFF,0xFF, 0xFF,0x0F,0xF0,0xF0,0xF0,0xF0,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xF8,0xF0,0x00,0x00, 0x00,0x00,0x00,0x00,0x01,0x03,0x07,0x3F,0x7F,0xFF, 0xFF,0xFF,0xFF,0xFF,0x7F,0x3F,0x3F,0x7F,0xFF,0xFF, 0xFF,0xFF,0xFF,0x1F,0x00,0x1E,0x1F,0x1F,0x1F,0x1F, 0x01,0x1E,0x1F,0xDF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0x7F,0x7F,0x3F,0x3F,0x3F,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x03, 0x0F,0x3F,0xFF,0xFE,0xFE,0xFE,0xFC,0xFC,0xFC,0xFC, 0xFC,0xFC,0xFC,0x7F,0x1F,0x07,0x03,0x03,0x01,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x01,0x07,0x0F,0x0F,0x1F,0x1F,0x3F, 0x3F,0x3F,0x3F,0x1C,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; /* P1.0 Reset P1.3 Temp Sensor (Not used) P2.0 Serial Data P2.1 Backlight P2.2 Chip Select P2.3 Data/Command P2.4 Serial Clock P2.5 Pushbutton */ // P1 static const unsigned LCD_RESET = BIT0; static const unsigned RXD = BIT2; static const unsigned SWITCH = BIT3; // P2 static const unsigned LCD_DATA = BIT0; static const unsigned LCD_BACKLIGHT = BIT1; static const unsigned LCD_CE = BIT2; static const unsigned LCD_DC = BIT3; static const unsigned LCD_CLK = BIT4; static const unsigned LCD_BTN = BIT5; Nokia7110 lcd; 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 *s; div_t d; if(t->tm_hour < 10) { x = -2; lcd.fill(0, 0, 9, 2, 0); d.rem = t->tm_hour; } else { x = 3; lcd.fill(0, 0, 3, 2, 0); d = div(t->tm_hour, 10); lcd.pd12(d.quot, x, 0); } lcd.pd12(d.rem, x + 11, 0); lcd.pd12(11, x + 22, 0); d = div(t->tm_min, 10); lcd.pd12(d.quot, x + 27, 0); lcd.pd12(d.rem, x + 38, 0); lcd.pd12(11, x + 49, 0); d = div(t->tm_sec, 10); lcd.pd12(d.quot, x + 54, 0); lcd.pd12(d.rem, x + 65, 0); lcd.fill(x + 76, 0, 7 - x, 2, 0); if(t->tm_mon < 9) { x = -5; lcd.fill(0, 2, 6, 2, 0); d.rem = t->tm_mon + 1; } else { x = 0; d = div(t->tm_mon + 1, 10); lcd.pd12(d.quot, x, 2); } lcd.pd12(d.rem, x + 11, 2); lcd.pd12(13, x + 22, 2); d = div(t->tm_mday, 10); lcd.pd12(d.quot, x + 30, 2); lcd.pd12(d.rem, x + 41, 2); lcd.pd12(13, x + 52, 2); d = div(t->tm_year % 100, 10); lcd.pd12(d.quot, x + 60, 2); lcd.pd12(d.rem, x + 71, 2); if(x) lcd.fill(x + 82, 2, 1 - x, 2, 0); s = dow[t->tm_wday]; w = strlen(s) * 6; x = (83 - w) >> 1; lcd.fill(0, 4, x, 1, 0); lcd.print((unsigned char)x, (unsigned char)4, s); x += w; lcd.fill(x, 4, 83 - x, 1, 0); } // Print integer from -999 to 9999 using 12 x 16 font void print_int(int i, const unsigned y) { if(i < -999 || i > 9999) return; const unsigned neg = i < 0; if(neg) i = -i; div_t d; d.quot = i; unsigned x = 48; do { d = div(d.quot, 10); lcd.pd12(d.rem, x -= 12, y); } while(d.quot); if(neg) lcd.pd12(14, x -= 12, y); while(x) lcd.pd12(10, x -= 12, y); } // Print integer from -999 to 9999 using 6 x 8 font void print_int(int i, unsigned x, const unsigned y) { if(i < -999 || i > 9999) return; const unsigned e = x; x += 24; const unsigned neg = i < 0; if(neg) i = -i; div_t d; d.quot = i; do { d = div(d.quot, 10); lcd.print(x -= 6, y, '0' + d.rem); } while(d.quot); if(neg) lcd.print(x -= 6, y, '-'); while(x > e) lcd.print(x -= 6, y, ' '); } void draw_bargraph(int f) { int x, y, bg; char c; unsigned char bgc[9] = { 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE, 0xFF, 0 }; char *bgl[8] = { "90", "80", "70", "60", "50", "40", "30", "20" }; x = 20; // bg = (f - (x - 5)) * 4 / 5; // for(y = 7; y >= 0; --y) { // lcd.pos(83, y); // if(bg < 0) { c = bgc[8]; } else if (bg > 7) { c = bgc[7]; } else { c = bgc[bg]; } lcd.write((unsigned char *)&c, 1, lcd_data); lcd.print(bgl[y], c); bg -= 8; } // } time_t tt; // Time in seconds since epoch unsigned adc; // ADC value #pragma vector = WDT_VECTOR // - Watchdog timer interrupt vector __interrupt void wdt_isr(void) // This interrupt will occur once per second { // ++tt; // Increment time_t __bic_SR_register_on_exit(LPM0_bits); // Wakeup main code } // // #pragma vector = ADC10_VECTOR // ADC conversion complete interrupt __interrupt void ADC10_ISR(void) // { // adc = ADC10MEM; // Read ADC __bic_SR_register_on_exit(LPM0_bits); // Wakeup main code } // int main(void) { int x, y; char c; struct tm ts; int dc, dk, df; // Temperature in degrees C, K, and F WDTCTL = WDTPW | WDTHOLD; P1REN = RXD | SWITCH; P1DIR = LCD_RESET; P1OUT = RXD | SWITCH | LCD_RESET; P2DIR = LCD_DC | LCD_CE | LCD_CLK | LCD_BACKLIGHT | LCD_DATA; P2REN = LCD_BTN; P2OUT = LCD_CLK | LCD_DC | LCD_CE | LCD_BACKLIGHT | LCD_BTN; ADC10CTL0 = 0; // Configure ADC ADC10CTL1 = INCH_10 | ADC10DIV_3; // ADC10CTL0 = SREF_1 | ADC10SHT_3 | REFON | ADC10ON | ADC10IE; ADC10CTL0 |= ADC10IE; // Enable ADC conversion complete interrupt // // 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() // tt = mktime(&ts); // Convert tm struct to time_t // lcd.reset(); lcd.init(); lcd.clear(); lcd.print(30, 6, "MSP430"); lcd.print(18, 7, "Nokia 7110"); for(x = -47; x < 24; ++x) { lcd.bitmap(ti, x, 0); __delay_cycles(20000); } __delay_cycles(2000000); for(; x < 96; ++x) { lcd.bitmap(ti, x, 0); __delay_cycles(20000); } lcd.clear(); lcd.print(9, 7, "Character Set"); x = y = 0; lcd.pos(x, y); for(c = 32; c < 128; ++c) { lcd.print(c); if(++x >= 16) x = 0, lcd.pos(x, ++y); } __delay_cycles(3000000); lcd.clear(); ts.tm_hour = ts.tm_min = ts.tm_sec = 88; ts.tm_mon = 87; ts.tm_mday = ts.tm_year = 88; ts.tm_wday = 5; show_time(&ts); lcd.pd12(15, 48, 5); lcd.pd12(17, 59, 5); lcd.print(24, 7, "\x7F""C"); lcd.print(66, 7, "\x7F""K"); print_int(8888, 5); print_int(8888, 0, 7); print_int(8888, 42, 7); for(x = 15; x < 96; ++x) draw_bargraph(x); __delay_cycles(3000000); lcd.clear(); // lcd.pd12(15, 48, 5); // Degrees lcd.pd12(17, 59, 5); // F lcd.print(24, 7, "\x7F""C"); // C lcd.print(66, 7, "\x7F""K"); // K // for(; { // for-ever show_time(localtime(&tt)); // Convert time_t to tm struct and show on LCD __bis_SR_register(LPM0_bits + GIE); // Sleep until WDT interrupt ADC10CTL0 |= (ENC | ADC10SC); // Begin ADC conversion __bis_SR_register(LPM0_bits + GIE); // Sleep until conversion complete // // Convert to temperature dc = ((27069L * adc) - 18169625L) >> 16; // Vref = 1.5V dk = ((27069L * adc) - 268467L) >> 16; // Vref = 1.5V df = ((48724L * adc) - 30634388L) >> 16; // Vref = 1.5V // // Display on LCD print_int(df, 5); // Degrees F print_int(dc, 0, 7); // Degrees C print_int(dk, 42, 7); // Degrees K draw_bargraph(df); // Deg F Bargraph } // return 0; }
     
    nokia7110tl.h - C++ template class for Nokia 7110 (SED1565)

    namespace nokia7110 { unsigned char PNONE; 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; template volatile unsigned char &_EP, unsigned char _CE, volatile unsigned char &_RP, unsigned char _RST, unsigned _RD> struct Nokia7110 { void write(const unsigned char *cmd, unsigned len, const lcd_cmd_type type = lcd_data); void reset(void); void init(void); void home(void); void pos(unsigned char x, unsigned char y); void clear(unsigned char x = 0); void fill(unsigned x, unsigned y, unsigned w, unsigned h, unsigned char z); void bitmap(const unsigned char *bmp, signed char x, signed char y, unsigned char w, unsigned char h); inline void bitmap(const unsigned char *bmp, signed char x, signed char y) { bitmap(bmp + 2, x, y, bmp[0], bmp[1]); }; void print(char c); inline void print(unsigned char x, unsigned char y, char c) { pos(x, y); print(c); }; void print(const char *s); inline void print(unsigned char x, unsigned char y, const char *s) { pos(x, y); print(s); }; void print(const char *s, unsigned char m); void printv(unsigned char x, unsigned char y, char *s); void pd12(unsigned n, unsigned x, unsigned y); }; template volatile unsigned char &_EP, unsigned char _CE, volatile unsigned char &_RP, unsigned char _RST, unsigned _RD> void Nokia7110<_SP, _CLK, _DATA, _CP, _DC, _EP, _CE, _RP, _RST, _RD>::write(const unsigned char *cmd, unsigned len, const lcd_cmd_type type) { register unsigned mask; if(&_EP != &PNONE) _EP &= ~_CE; do { mask = 0x0080; do { if(*cmd & mask) { _SP |= _DATA; _SP &= ~_CLK; } else { _SP &= ~(_CLK | _DATA); } _SP |= _CLK; mask >>= 1; } while(!(mask & 1)); if(&_CP == &PNONE) { __delay_cycles(_DC); } else { if(!type) _CP &= ~_DC; } if(*cmd & mask) { _SP |= _DATA; _SP &= ~_CLK; } else { _SP &= ~(_CLK | _DATA); } _SP |= _CLK; if(&_CP != &PNONE) _CP |= _DC; if(!(type & 2)) ++cmd; } while(--len); if(&_EP != &PNONE) _EP |= _CE; } template volatile unsigned char &_EP, unsigned char _CE, volatile unsigned char &_RP, unsigned char _RST, unsigned _RD> void Nokia7110<_SP, _CLK, _DATA, _CP, _DC, _EP, _CE, _RP, _RST, _RD>::reset(void) { if(&_RP == &PNONE) { // --- Set initial state of CLK, DC and CE as needed // * = output used for reset if(&_CP == &PNONE) { if(&_EP != &PNONE) { // CLK*, DATA, CE _EP |= _CE; } // else // CLK*, DATA } else { if(&_EP != &PNONE) { // CLK, DATA, DC*, CE if(&_SP == &_EP) { _SP |= (_CLK | _CE); } else { _SP |= _CLK; _EP |= _CE; } } else { // CLK, DATA, DC* _SP |= _CLK; } } // --- Reset pulse on CLK or DC as needed if(&_CP == &PNONE) { // No DC port, use CLK to reset _SP &= ~_CLK; __delay_cycles(_RD); _SP |= _CLK; } else { // Use DC to reset _CP &= ~_DC; __delay_cycles(_RD); _CP |= _DC; } } else { _RP &= ~_RST; if(&_EP != &PNONE) { if(&_SP == &_EP) { _SP |= (_CLK | _CE); } else { _SP |= _CLK; _EP |= _CE; } } else { _SP |= _CLK; } __delay_cycles(_RD); _RP |= _RST; } __delay_cycles(_RD); } template volatile unsigned char &_EP, unsigned char _CE, volatile unsigned char &_RP, unsigned char _RST, unsigned _RD> void Nokia7110<_SP, _CLK, _DATA, _CP, _DC, _EP, _CE, _RP, _RST, _RD>::init(void) { static const unsigned char init[] = { 0xA6, //Display: Normal 0xA3, //LCD Bias Settings: 1/7 0xA1, //ADC Selection: Reverse 0xC0, //Common Output: Normal Direction //0xC8, //Common Output: Upside Down 0x22, //Set the V5 output Voltage 0x81, //Set Electronic Volume Register 0x2E, //Power Controller Set // Booster circuit: ON // Voltage regulator circuit: ON // Voltage follower circuit: OFF 0x2F, //Power Controller Set // Voltage follower circuit: ON 0xE3, //Non-OPeration Command 0x40, //Set the start line 0xAF, //LCD On //0xA5, //Display All Points: ON 0xA4, //Display All Points: NORMAL }; write(init, sizeof(init), lcd_command); } template volatile unsigned char &_EP, unsigned char _CE, volatile unsigned char &_RP, unsigned char _RST, unsigned _RD> void Nokia7110<_SP, _CLK, _DATA, _CP, _DC, _EP, _CE, _RP, _RST, _RD>::home(void) { static const unsigned char home[] = { 0xB0, 0x11, 0x02 }; write(home, sizeof(home), lcd_command); } template volatile unsigned char &_EP, unsigned char _CE, volatile unsigned char &_RP, unsigned char _RST, unsigned _RD> void Nokia7110<_SP, _CLK, _DATA, _CP, _DC, _EP, _CE, _RP, _RST, _RD>::pos(unsigned char x, unsigned char y) { unsigned char c[3]; x += 18; c[0] = 0xB0 | y; c[1] = 0x10 | (x >> 4); c[2] = x & 0x0F; write(c, sizeof(c), lcd_command); } template volatile unsigned char &_EP, unsigned char _CE, volatile unsigned char &_RP, unsigned char _RST, unsigned _RD> void Nokia7110<_SP, _CLK, _DATA, _CP, _DC, _EP, _CE, _RP, _RST, _RD>::clear(unsigned char x) { for(unsigned y = 0; y < 9; ++y) { pos(0, y); write(&x, 96, lcd_data_repeat); } } template volatile unsigned char &_EP, unsigned char _CE, volatile unsigned char &_RP, unsigned char _RST, unsigned _RD> void Nokia7110<_SP, _CLK, _DATA, _CP, _DC, _EP, _CE, _RP, _RST, _RD>::fill(unsigned x, unsigned y, unsigned w, unsigned h, unsigned char z) { unsigned yy = y + h; unsigned char c[3]; x += 18; c[1] = 0x10 | (x >> 4); c[2] = (x & 0x0F); for(;y < yy; ++y) { c[0] = 0xB0 | y; write(c, sizeof(c), lcd_command); write(&z, w, lcd_data_repeat); } } template volatile unsigned char &_EP, unsigned char _CE, volatile unsigned char &_RP, unsigned char _RST, unsigned _RD> void Nokia7110<_SP, _CLK, _DATA, _CP, _DC, _EP, _CE, _RP, _RST, _RD>::bitmap(const unsigned char *bmp, signed char x, signed char y, unsigned char w, unsigned char h) { unsigned char c[3]; unsigned char ww; if(x < 0) { ww = w + x; bmp -= x; x = 0; } else if(x + w >= 96) { ww = (96 - x); } else { ww = w; } x += 18; c[0] = 0xB0 | y; c[1] = 0x10 | (x >> 4); c[2] = x & 0x0F; while(h--) { write(c, sizeof(c), lcd_command); write(bmp, ww); bmp += w; ++c[0]; } } static const unsigned char font[96][5] = { 0x00, 0x00, 0x00, 0x00, 0x00, // 0x00, 0x00, 0x5F, 0x00, 0x00, // ! 0x00, 0x07, 0x00, 0x07, 0x00, // " 0x14, 0x7F, 0x14, 0x7F, 0x14, // # 0x24, 0x2A, 0x7F, 0x2A, 0x12, // $ 0x23, 0x13, 0x08, 0x64, 0x62, // % 0x36, 0x49, 0x56, 0x20, 0x50, // & 0x00, 0x08, 0x07, 0x03, 0x00, // ' 0x00, 0x1C, 0x22, 0x41, 0x00, // ( 0x00, 0x41, 0x22, 0x1C, 0x00, // ) 0x2A, 0x1C, 0x7F, 0x1C, 0x2A, // * 0x08, 0x08, 0x3E, 0x08, 0x08, // + 0x00, 0x40, 0x38, 0x18, 0x00, // , 0x08, 0x08, 0x08, 0x08, 0x08, // - 0x00, 0x00, 0x60, 0x60, 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, 0x49, 0x4D, 0x33, // 3 0x18, 0x14, 0x12, 0x7F, 0x10, // 4 0x27, 0x45, 0x45, 0x45, 0x39, // 5 0x3C, 0x4A, 0x49, 0x49, 0x30, // 6 0x41, 0x21, 0x11, 0x09, 0x07, // 7 0x36, 0x49, 0x49, 0x49, 0x36, // 8 0x06, 0x49, 0x49, 0x29, 0x1E, // 9 0x00, 0x00, 0x14, 0x00, 0x00, // : 0x00, 0x00, 0x40, 0x34, 0x00, // ; 0x00, 0x08, 0x14, 0x22, 0x41, // < 0x14, 0x14, 0x14, 0x14, 0x14, // = 0x00, 0x41, 0x22, 0x14, 0x08, // > 0x02, 0x01, 0x51, 0x09, 0x06, // ? 0x3E, 0x41, 0x5D, 0x59, 0x4E, // @ 0x7C, 0x12, 0x11, 0x12, 0x7C, // A 0x7F, 0x49, 0x49, 0x49, 0x36, // B 0x3E, 0x41, 0x41, 0x41, 0x22, // C 0x7F, 0x41, 0x41, 0x41, 0x3E, // 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, 0x1C, 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 0x26, 0x49, 0x49, 0x49, 0x32, // 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 0x03, 0x04, 0x78, 0x04, 0x03, // Y 0x61, 0x51, 0x49, 0x45, 0x43, // Z 0x00, 0x7F, 0x41, 0x41, 0x41, // [ 0x02, 0x04, 0x08, 0x10, 0x20, // '\' 0x00, 0x41, 0x41, 0x41, 0x7F, // ] 0x04, 0x02, 0x01, 0x02, 0x04, // ^ 0x80, 0x80, 0x80, 0x80, 0x80, // _ 0x00, 0x03, 0x07, 0x08, 0x00, // ' 0x20, 0x54, 0x54, 0x54, 0x78, // a 0x7F, 0x28, 0x44, 0x44, 0x38, // b 0x38, 0x44, 0x44, 0x44, 0x28, // c 0x38, 0x44, 0x44, 0x28, 0x7F, // d 0x38, 0x54, 0x54, 0x54, 0x18, // e 0x00, 0x08, 0x7E, 0x09, 0x02, // f 0x18, 0xA4, 0xA4, 0xA4, 0x7C, // g 0x7F, 0x08, 0x04, 0x04, 0x78, // h 0x00, 0x44, 0x7D, 0x40, 0x00, // i 0x00, 0x20, 0x40, 0x40, 0x3D, // j 0x00, 0x7F, 0x10, 0x28, 0x44, // k 0x00, 0x41, 0x7F, 0x40, 0x00, // l 0x7C, 0x04, 0x78, 0x04, 0x78, // m 0x7C, 0x08, 0x04, 0x04, 0x78, // n 0x38, 0x44, 0x44, 0x44, 0x38, // o 0xFC, 0x18, 0x24, 0x24, 0x18, // p 0x18, 0x24, 0x24, 0x18, 0xFC, // q 0x7C, 0x08, 0x04, 0x04, 0x08, // r 0x48, 0x54, 0x54, 0x54, 0x24, // s 0x04, 0x04, 0x3F, 0x44, 0x24, // 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 0x4C, 0x90, 0x90, 0x90, 0x7C, // y 0x44, 0x64, 0x54, 0x4C, 0x44, // z 0x00, 0x08, 0x36, 0x41, 0x00, // { 0x00, 0x00, 0x77, 0x00, 0x00, // | 0x00, 0x41, 0x36, 0x08, 0x00, // } 0x02, 0x01, 0x02, 0x04, 0x02, // ~ 0x00, 0x06, 0x09, 0x09, 0x06, // degrees }; template volatile unsigned char &_EP, unsigned char _CE, volatile unsigned char &_RP, unsigned char _RST, unsigned _RD> void Nokia7110<_SP, _CLK, _DATA, _CP, _DC, _EP, _CE, _RP, _RST, _RD>::print(char c) { write(&font[c - 32][0], 5); write(&font[0][0], 1); } template volatile unsigned char &_EP, unsigned char _CE, volatile unsigned char &_RP, unsigned char _RST, unsigned _RD> void Nokia7110<_SP, _CLK, _DATA, _CP, _DC, _EP, _CE, _RP, _RST, _RD>::print(const char *s) { while(*s) { write(&font[*s - 32][0], 5); write(&font[0][0], 1); ++s; } } template volatile unsigned char &_EP, unsigned char _CE, volatile unsigned char &_RP, unsigned char _RST, unsigned _RD> void Nokia7110<_SP, _CLK, _DATA, _CP, _DC, _EP, _CE, _RP, _RST, _RD>::print(const char *s, unsigned char m) { unsigned char c; while(*s) { c = font[*s - 32][0] ^ m; write(&c, 1); c = font[*s - 32][1] ^ m; write(&c, 1); c = font[*s - 32][2] ^ m; write(&c, 1); c = font[*s - 32][3] ^ m; write(&c, 1); c = font[*s - 32][4] ^ m; write(&c, 1); write(&m, 1); ++s; } } template volatile unsigned char &_EP, unsigned char _CE, volatile unsigned char &_RP, unsigned char _RST, unsigned _RD> void Nokia7110<_SP, _CLK, _DATA, _CP, _DC, _EP, _CE, _RP, _RST, _RD>::printv(unsigned char x, unsigned char y, char *s) { while(*s) { pos(x, y); ++y; write(&font[*s - 32][0], 5); write(&font[0][0], 1); ++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 }; template volatile unsigned char &_EP, unsigned char _CE, volatile unsigned char &_RP, unsigned char _RST, unsigned _RD> void Nokia7110<_SP, _CLK, _DATA, _CP, _DC, _EP, _CE, _RP, _RST, _RD>::pd12(unsigned n, unsigned x, unsigned y) { pos(x, y); write(num11x16[n], 11, lcd_data); pos(x, ++y); write(num11x16[n] + 11, 11, lcd_data); } } // namespace
  19. Like
    gordon got a reaction from jp430bb in Dead LaunchPad? Possible to re-flash the emulator?   
    IIRC the zip posted by OppaErich contains a zero-length ti_5052.fw .
     
    Actually, so do I (on 2.6.32, Ubuntu 10.04), works flawlessly, for values of "flawless" you could otherwise expect from a TUSB.
  20. Like
    gordon reacted to Rickta59 in Petit FatFs sound player   
    I've been experimenting with playing sound. I'm using the code below to read raw 8bit unsigned PCM files
    from the SDCard booster pack. I've attached the main routine. It is heavily commented so I'm not going
    to say much more than here it is. The Petit Fat Filesystem code can be found on the documents tab
    of the SDCard booster on the 43oh.com store.
     
    I also want to thank oPossum and woodgrainn with their help creating a decent low pass RC filter. I ended up
    using an LM386 as an amplifier on the P1.2 PWM output. Here is the schematic for that:
     
    http://compendiumarcana.com/forumpics/pwm_amp.png
     
    -rick
     

    /* * pcmplayer.cpp - play a 15.625kHz 8bit mono sound file using PWM. * * This snippet plays raw PCM audio files from an SDcard. It looks * for files named 0.raw, 1.raw ... 9.raw and attempts to play them * in a loop. To create these files, use the Audacity program to * sample sound files, convert stereo to mono, then export them * as 8bit unsigned data 15625Hz without a header. * * The SDcard I/O is handled using Petit FatFs and works with both FAT16 * and FAT32 formatted cards. PetitFS has a streaming read feature which * allows you process each byte from the file without buffering using * its callback feature. * * * Inspired from various sources: * * http://www.arduino.cc/playground/Code/PCMAudio * http://elm-chan.org/fsw/ff/00index_p.html * http://en.wikipedia.org/wiki/Pulse-code_modulation * http://en.wikipedia.org/wiki/Pulse-width_modulation * http://en.wikipedia.org/wiki/Low-pass_filter * http://sim.okawa-denshi.jp/en/CRtool.php * http://www.ti.com/lit/an/slaa497/slaa497.pdf * http://www.proaxis.com/~wagnerj/PWMfil/PWM%20Filters.pdf * * help on low pass filtering from oPossum and woodgrainn * * 3920 bytes on a msp430g2553 with msp430-gcc 4.6.3 -Os */ /** * pins used on msp430g2553 * * +-- --+ * | V | * | | * P1.2 TA0.1<<< | * | | * | | * | >>>> MOSI P1.7 * P1.5 SCK <<<< <<<< MISO P1.6 * P2.0 CS <<<< | * | | * | | * +-----+ * * P1.2 - PWM output, run through a low pass RC filter. I'm using * a 470ohm resistor, and 100nF cap played back on cheap airline * headphones. Don't use these values with PC audio card mic or * line in. * * P1.5, P1.6, P1.7 SCLK, MISO, MOSI (USCI SPI) connect to SD card * P2.0 CS connect to SD card * */ #include #include extern "C" { #include "spi.h" #include "diskio.h" #include "pff.h" } #include "mmc.h" #include "ringbuffer.h" static const uint32_t TIMERA_CLK = 16000000; // SMCLK_FREQ/1 static const uint32_t SAMPLE_RATE = 15625; // nice power of 2 friendly value sample rate RingBuffer sample_buffer = {{0}, 0,0}; // structure to buffer our samples /* * on_streaming_data() - called when pf_read completes a read * * pf_read in streaming mode calls this function after each byte * is read. When we get a new value we stuff it into a ring buffer. * The ISR reads from this ring_buffer. This function is the * producer, the ISR is the consumer. */ void on_streaming_data(uint8_t sample) { register int16_t rc, scaled_sample; scaled_sample = sample < 24 ? 24 : sample; // avoid low range glitches scaled_sample <<= 2; // scale it up from 0-255 to 0-1023 do { /* * stuff this at the end of our circular queue * if rc == -1 then it would overflow, wait for * ISR to read a byte */ rc = sample_buffer.push_back(scaled_sample); } while (rc == -1); } /** * Timer0 CCR0 overflow handler * * This method is called each time the CCR0 value counts up to 1023. * We grab the next sample from the circular buffer and scale it * up from the 8 bit unsigned value read from the disk to match * the CCR0 scale. */ #pragma vector = TIMER0_A0_VECTOR void __interrupt TIMER0_OVERFLOW_VECTOR_ISR(void) { // P1OUT ^= BIT0; TACCR1 = sample_buffer.pop_front(); // P1OUT ^= BIT0; } int main(void) { FRESULT res; // PetitFS variables DRESULT dres; FATFS fs; WDTCTL = WDTPW + WDTHOLD; // Stop WDT DCOCTL = 0; // Run at 16 MHz BCSCTL1 = CALBC1_16MHZ; DCOCTL = CALDCO_16MHZ; //DCOCTL += 3; // fine tune 15.9MHz to 16.0MHz on my chip __delay_cycles(0xffff); // delay for power up and stabilization spi_initialize(); // configure SPI for Petit FatFs 8MHz // P1OUT &= ~BIT0; P1DIR |= BIT2 /*| BIT0*/; // P1.2 output P1SEL |= BIT2; // P1.2 use TA0.1 //P1DIR |= BIT4; P1SEL |= BIT4; // output SMCLK, useful for measuring /** * configure TimerA0 with a 15.625k frequency, * setup TA0.1 (P1.2) for the PWM output. */ TACCR0 = (TIMERA_CLK/SAMPLE_RATE)-1; // PWM Period 15.625k (64 us) TACCR1 = TACCR0/2; // Set initial PWM duty cycle to 50% TACCTL0 = CCIE; // Enable CCRO CCIFG interrupt. The TACCR0 CCIFG // interrupt flag is set when the timer counts to // the TACCR0 value. TACCTL1 = OUTMOD_7; // Output is reset (0) when timer counts // to TACCR1, It is set (1) when timer counts // to TACCR0 value TACTL = TASSEL_2 | ID_0 | MC_1; // use SMCLK / 1, in UP MODE to CCR0 // value 1024-1 cycles((16MHz/1)/15.625kHz) __enable_interrupt(); /** * play the same songs in a loop */ while(1) { dres = disk_initialize(); if ( dres == RES_OK ) { res = pf_mount(&fs); if ( res == FR_OK ) { int n; char fileName[] = "0.raw"; for ( n=0; n < 10; n++ ) { fileName[0] = n+'0'; res = pf_open(fileName); if ( res == FR_OK ) { WORD bytes_read; do { res = pf_read(0, 32768, &bytes_read); /* pf_read calls on_streaming_data() for each byte read */ if (res != FR_OK) { break; } } while (bytes_read == 32768); /* read a cluster at a time */ } } } } } return 0; }
  21. Like
    gordon reacted to 4jochen in Ethernet Booster Pack   
    I like to add some information regarding the PCB design.
    On the PHY (inside W5200) the connection to the transformer (inside the RJ45 'MagJack') some critical signals exist and some features of the PHY makes life more easy.
     
    Most important is to have the signals the same length inside the RX signal pair and the TX signal pair, and hold this signals as close together as possible. You can see very good in RobG's new picture compared to the older one.
     
    Some advice:
    a) There is no polarity on the 100mbps PHY signals - means you can turn around the TX+ and TX- signals and also you can exchange the RX+ and RX- with each other. ! dont mix TX.. and RX.. !
    Yes, the 10mbps signals have a polarity but PHY automaticaly turns them internally 'auto polarity' feature. => no polarity.
    the RX and TX pair can be exchanged the same way, because the PHY knows 'auto-cross-over, MDIX' function. So you don't care about standard or cross patch-cable.
    For PCB design this means:
    => it's easy to avoid vias in PHY signals - easy straight forward to the MagJack.
    c) more tricky ! you need the 50ohm (49 is OK) resistors as close to the PHY as possible.
    I did that using vias and put the 50ohm R's on the bottom side of PCB.
    d) inside the transformer is a center connection 'CT' = 'center tab' that must be connected to analog Vcc here 3.3V.
    This voltage must be as stable and noise free as possible. Therefor we added C's right under the MagJack on bottom side.
    Normally this CT voltage is only needed for the TX pair, but because of auto crossover, also needed for RX pair.
    Sometimes (like here) this two CT are connected internally already so there is only one CT at this MagJack.
    e) every PHY has an external R for 'Bandgap' or 'Bias' adjustment. This must be perfectly match the manufactureres recomendation better 1% ! we used two R's in series so you can select cheap R's just out of standard E12 or E24.
     
    Now, it's on you to give live into it. Have fun with coding.
     
    BR, Joachim
  22. Like
    gordon got a reaction from bluehash in How to use GDB with MSPDebug on Linux?   
    I do it like this:
     
    In your project directory (where your sources and binary are), have a file called .gdbinit with the following contents:

    target remote localhost:2000 monitor reset halt load
     
    On one terminal, start MSPDebug like so:

    mspdebug rf2500 gdb
    This starts up MSPDebug in GDB proxy mode -- on one end, there is a GDB server (by default on port 2000, see help gdb); on the other end, it is attached to your FET (change rf2500 to the actual FET driver you are using).
     
    On an other terminal, assuming you are in your project's directory and your binary is called main.elf, start up msp430-gdb like so:

    msp430-gdb main.elf
    I like CGDB as a friont-end to GDB, so I do

    cgdb -d msp430-gdb main.elf
     
    Much of this can be automated from your Makefiles (I have not yet figured out how to reliable handle starting and killing the GDB proxy, then again, it doesn't bother me enough to spend time on it...).
  23. Like
    gordon reacted to oPossum in RTTTL (Ring Tone Text Transfer Language) Player   
    Plays ringtones in the RTTTL format. That is a text string for simple monophonic music.
     
    The parser is very simple and does not attempt strict compliance with the specification. It should properly play strings that are written to spec.
     
    The output is a sine wave constructed using 48 kHz PWM on P1.6 that should be low pass filtered by a simple R/C filter.
     
    Code was tested on G2553 - not sure if this will fit in the 2K chips - it should work if it fits.
     


     

    #include #include // // RTTTL spec: http://www.mobilefish.com/tutorials/rtttl/rtttl_quickguide_specification.html // static const long int phase_limit = 48048 * 1000; // Phase accumulator limit, sample rate * 1/resolution static volatile long int pi = 0; // Phase increment (frequency in millihertz) static volatile unsigned note_timer = 0; // Note timer, decrements 48048 times per second static int isnote(char c) // Get note index, or 128 for pause { // // A B C D E F G H( static const int note_map[8] = { 9, 11, 0, 2, 4, 5, 7, 11 }; // MIDI note value if(c >= 'a' && c <= 'h') return note_map[c - 'a']; // Lower case note if(c >= 'A' && c <= 'H') return note_map[c - 'A']; // Upper case note if(c == 'p' || c == 'P') return 128; // Pause return -1; // Invalid, return -1 } static void play_note(unsigned n, unsigned d) // Play note { // n: MIDI note value // d: duration in units of 1/48048 second // static const unsigned note_spacing = 480; // 10 ms between notes static const unsigned long midi_notes[12] = { // MIDI upper 12 notes 6644875L, // 116 G# 9 7040000L, // 117 A 9 7458620L, // 118 A# 9 7902133L, // 119 B 9 8372018L, // 120 C 10 8869844L, // 121 C# 10 9397273L, // 122 D 10 9956063L, // 123 D# 10 10548082L, // 124 E 10 11175303L, // 125 F 10 11839822L, // 126 F# 10 12543854L // 127 G 10 }; // long f; // if(n > 127) { // Invalid note value is pause f = 0; // Frequency = 0 } else { // unsigned o = 10; n += 4; // Init octave, adjust note while(n >= 12) n -= 12, --o; // Normalize note, adjust octave f = midi_notes[n]; // Get frequency while(o) f >>= 1, --o; // Adjust frequency for octave } // while(note_timer); // Wait for current note to finish // pi = 0; // Silence between notes note_timer = note_spacing; // while(note_timer); // // if(d > note_spacing) d -= note_spacing; // Adjust note duration for note spacing note_timer = d; // Setup note time pi = f - phase_limit; // Play note } void play(const char *s) // Play RTTTL string { // unsigned state = 0; // Initial state char c, d; // Char from string, default specifier unsigned bpm = 63; // Beats (quarter notes) per minute unsigned default_duration = 4; // Default note duration (fraction of a whole note) unsigned default_octave = 5; // Default octave long unsigned dot; // Numerator for note clock count calculation, adjusted for dot notation unsigned duration = 0; // Note duration int note; // Note index 0 to 11 int octave; // Octave 0 to 9 // do { // c = *s++; // Get a char from RTTTL string if(c > 0 && c <= 32) continue; // Ingore whitespace and control chars switch(state) { // case 0: // - Skip name if(c == ':') ++state; // Toss chars until ':' break; // case 1: // - Parse defaults state1: // if(c == ':') { // End of default section, begin parsing notes state = 4; // } else if(isalpha(c)) { // Default designator - allow any alpha d = c; // Save it state = 2; // Verify assignment character } else { // state = 1; // Invalid char, stay in this state } // break; // case 2: // - Default assignment char, must be '=' if(c == '=') { // note = 0; // Init default ++state; // Parse default value } else goto state1; // Invalid char, start over break; // case 3: // - Parse and assign default value if(isdigit(c)) { // Update default note = note * 10 + (c - '0'); // } else if(c == ',' || c == ':') { // End of default, assign to variable switch(d) { // case 'b': // Default BPM case 'B': // bpm = note; // break; // case 'o': // Default octave case 'O': // default_octave = note; // break; // case 'd': // Default note duration case 'D': // default_duration = note;// break; // } // state = (c == ':') ? 4 : 1; // Get next default or begin parsing notes } else goto state1; // Invalid char, start over break; // case 4: // - Parse note dot = 48048L * 60 * 4; // Setup defaults for this note duration = default_duration; // octave = default_octave; // note = 0; // if(isdigit(c)) { // May begin with duration duration = c - '0'; // Init duration ++state; // May be more than one digit, continue in next state } else if((note = isnote(c)) >= 0) {// May begin with note state = 6; // Got note, parse modifiers and octave } // break; // case 5: // - Parse duration if(isdigit(c)) { // Numeric digit, update duration duration = duration * 10 + (c -'0'); } else if((note = isnote(c)) >= 0) {// Got note, parse modifiers and octave ++state; // } else { // Invlid char, start over state = 4; // } // break; // case 6: // - Parse modifiers and octave if(c == ',' || c == 0) { // End of note, play it play_note((octave + 1) * 12 + note, dot / (duration * bpm)); state = 4; // Next note } else if(c == '#') { // Sharp, increment note value ++note; // } else if(c == 'b') { // Flat, decrement note value --note; // } else if(c == '.') { // Dotted note, extend length by 50% dot += (dot >> 1); // } else if(isdigit(c)) { // Octave, 0 to 9 allowed, should be 4 to 7 octave = c - '0'; // } // break; // // } // } while(c); // End of string while(note_timer); // Wait for last note to finish pi = 0; // Silence } static const signed char sine[734] = { // 8 bit signed sine wave samples 0, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 73, 74, 75, 76, 77, 78, 79, 80, 80, 81, 82, 83, 84, 85, 85, 86, 87, 88, 89, 89, 90, 91, 92, 92, 93, 94, 95, 95, 96, 97, 97, 98, 99, 99, 100, 101, 101, 102, 103, 103, 104, 105, 105, 106, 106, 107, 108, 108, 109, 109, 110, 110, 111, 111, 112, 113, 113, 114, 114, 114, 115, 115, 116, 116, 117, 117, 118, 118, 118, 119, 119, 120, 120, 120, 121, 121, 121, 122, 122, 122, 122, 123, 123, 123, 124, 124, 124, 124, 124, 125, 125, 125, 125, 125, 126, 126, 126, 126, 126, 126, 126, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 126, 126, 126, 126, 126, 126, 126, 126, 125, 125, 125, 125, 125, 124, 124, 124, 124, 123, 123, 123, 123, 122, 122, 122, 121, 121, 121, 120, 120, 120, 119, 119, 119, 118, 118, 117, 117, 117, 116, 116, 115, 115, 114, 114, 113, 113, 112, 112, 111, 111, 110, 110, 109, 109, 108, 107, 107, 106, 106, 105, 104, 104, 103, 102, 102, 101, 101, 100, 99, 99, 98, 97, 96, 96, 95, 94, 94, 93, 92, 91, 91, 90, 89, 88, 87, 87, 86, 85, 84, 83, 83, 82, 81, 80, 79, 78, 77, 77, 76, 75, 74, 73, 72, 71, 70, 70, 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, -2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, -15, -16, -17, -18, -19, -20, -21, -22, -23, -24, -25, -26, -27, -29, -30, -31, -32, -33, -34, -35, -36, -37, -38, -39, -40, -41, -42, -43, -44, -45, -46, -47, -48, -49, -50, -51, -52, -53, -54, -55, -56, -57, -58, -59, -60, -61, -62, -63, -64, -65, -66, -67, -68, -68, -69, -70, -71, -72, -73, -74, -75, -76, -76, -77, -78, -79, -80, -81, -82, -82, -83, -84, -85, -86, -86, -87, -88, -89, -90, -90, -91, -92, -93, -93, -94, -95, -96, -96, -97, -98, -98, -99, -100, -100, -101, -102, -102, -103, -104, -104, -105, -106, -106, -107, -107, -108, -108, -109, -110, -110, -111, -111, -112, -112, -113, -113, -114, -114, -115, -115, -116, -116, -116, -117, -117, -118, -118, -119, -119, -119, -120, -120, -120, -121, -121, -121, -122, -122, -122, -123, -123, -123, -123, -124, -124, -124, -124, -125, -125, -125, -125, -125, -126, -126, -126, -126, -126, -126, -126, -126, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -126, -126, -126, -126, -126, -126, -126, -125, -125, -125, -125, -125, -125, -124, -124, -124, -124, -123, -123, -123, -123, -122, -122, -122, -121, -121, -121, -120, -120, -120, -119, -119, -118, -118, -118, -117, -117, -116, -116, -115, -115, -115, -114, -114, -113, -113, -112, -112, -111, -111, -110, -109, -109, -108, -108, -107, -107, -106, -105, -105, -104, -103, -103, -102, -102, -101, -100, -100, -99, -98, -98, -97, -96, -95, -95, -94, -93, -92, -92, -91, -90, -89, -89, -88, -87, -86, -85, -85, -84, -83, -82, -81, -81, -80, -79, -78, -77, -76, -75, -75, -74, -73, -72, -71, -70, -69, -68, -67, -66, -65, -64, -64, -63, -62, -61, -60, -59, -58, -57, -56, -55, -54, -53, -52, -51, -50, -49, -48, -47, -46, -45, -44, -43, -42, -41, -40, -39, -38, -37, -36, -35, -34, -32, -31, -30, -29, -28, -27, -26, -25, -24, -23, -22, -21, -20, -19, -18, -16, -15, -14, -13, -12, -11, -10, -9, -8, -7, -6, -5, -3, -2, -1, 0 }; #pragma vector = TIMER0_A1_VECTOR // Timer A0 Overflow interrupt __interrupt void timer0_a1_isr(void) // { // static long int pa = 0; // Phase accumulator static unsigned sample = 200; // PWM sample // TACCR1 = sample; // Output previous PWM sample // volatile unsigned z = TAIV; // Clear interrupt flag // sample = 200 - sine[pa >> 16]; // Get next PWM value // if((pa += pi) < 0) pa += phase_limit; // Update phase accumulator // if(note_timer) --note_timer; // Decrement note timer } // static const char * const tunes[] = { "StWars:d=4,o=5,b=180:8f,8f,8f,2a#.,2f.6,8d#6,8d6,8c6,2a#.6,f.6,8d#6,8d6,8c6,2a#.6,f.6,8d#6,8d6,8d#6,2c6,p,8f,8f,8f,2a#.,2f.6,8d#6,8d6,8c6,2a#.6,f.6,8d#6,8d6,8c6,2a#.6,f.6,8d#6,8d6,8d#6,2c6", "axelf:d=4,o=5,b=160:f#,8a.,8f#,16f#,8a#,8f#,8e,f#,8c.6,8f#,16f#,8d6,8c#6,8a,8f#,8c#6,8f#6,16f#,8e,16e,8c#,8g#,f#.", "Muppets:d=4,o=5,b=250:c6,c6,a,b,8a,b,g,p,c6,c6,a,8b,8a,8p,g.,p,e,e,g,f,8e,f,8c6,8c,8d,e,8e,8e,8p,8e,g,2p,c6,c6,a,b,8a,b,g,p,c6,c6,a,8b,a,g.,p,e,e,g,f,8e,f,8c6,8c,8d,e,8e,d,8d,c", "Mission:d=4,o=6,b=100:32d,32d#,32d,32d#,32d,32d#,32d,32d#,32d,32d,32d#,32e,32f,32f#,32g,16g,8p,16g,8p,16a#,16p,16c,16p,16g,8p,16g,8p,16f,16p,16f#,16p,16g,8p,16g,8p,16a#,16p,16c,16p,16g,8p,16g,8p,16f,16p,16f#,16p,16a#,16g,2d,32p,16a#,16g,2c#,32p,16a#,16g,2c,16p,16a#5,16c", "TakeOnMe:d=4,o=4,b=160:8f#5,8f#5,8f#5,8d5,8p,8b,8p,8e5,8p,8e5,8p,8e5,8g#5,8g#5,8a5,8b5,8a5,8a5,8a5,8e5,8p,8d5,8p,8f#5,8p,8f#5,8p,8f#5,8e5,8e5,8f#5,8e5,8f#5,8f#5,8f#5,8d5,8p,8b,8p,8e5,8p,8e5,8p,8e5,8g#5,8g#5,8a5,8b5,8a5,8a5,8a5,8e5,8p,8d5,8p,8f#5,8p,8f#5,8p,8f#5,8e5,8e5", "Greensleaves:d=4,o=5,b=140:g,2a#,c6,d.6,8d#6,d6,2c6,a,f.,8g,a,2a#,g,g.,8f,g,2a,f,2d,g,2a#,c6,d.6,8e6,d6,2c6,a,f.,8g,a,a#.,8a,g,f#.,8e,f#,2g", 0 }; void main(void) { WDTCTL = WDTPW | WDTHOLD; // Disable watchdog reset DCOCTL = 0; // Run at 16 MHz BCSCTL1 = CALBC1_16MHZ; // DCOCTL = CALDCO_16MHZ; // // P1DIR = BIT6; // Enable PWM output on P1.6 P1SEL = BIT6; // // TACTL = TASSEL_2 | MC_1 | TAIE; // Timer A config: SMCLK, count up, ovrflow int enabled TACCR0 = 332; // Setup Timer A period for 48.048 kHz TACCR1 = 200; // Setup Timer A compare to "DAC" zero value TACCTL1 = OUTMOD_7; // Setup Timer A reset/set output mode // _EINT(); // Enable interrupts // const char * const *t; // for(; for(t = tunes; *t; ++t) { // Iterate all ring tones play(*t); // Play it note_timer = 48048; // Wait a second before next while(note_timer); // } // }
  24. Like
    gordon reacted to Rickta59 in Energia (Arduino for msp430)   
    I came across the port of the Arduino IDE for the msp430 (it is called Energia) reading another post.
    Robert Wessels has made a great first stab at supporting the Arduino API for the launchpad boards. It already
    works on the MacOSX and Windows platforms. Edit: [i checked in the changes to git for the linux version
    [Linux isn't up to snuff yet, but I'll be helping him getting that working properly.] . It should be good to go.
    If you are running linux and have a working java, msp430-gcc and mspdebug. For a limited time you can try
    out an early snapshot by downloading this linux32 distribution.
     
    http://xxxxxxx It is large (~15MB) and will be changing so it will only
    available at that URL for a limited time.
     
    Download the tar file and unpack it. To launch, just run the energia shell script. In the Energia IDE, select the Tools menu
    pick one of the Launchpad boards. Set the Programmer to rf2500 and then pick your serial port. The picture below
    is a snapshot of the ASCIITable example found in the Communications section. The example uses the Hardware serial
    port of the msp430g2553 so make sure your TX/RX jumpers are set correctly. You can also find some msp430
    specific examples. I haven't tested all the examples so don't expect everything to work. This is a very early
    version of Energia.
     
    If you are a java weenie and want to checkout the source code, you can find it up on github:
     
    https://github.com/energia/Energia
     
    -rick

  25. Like
    gordon reacted to pabigot in TLV data (calibration) parse and display   
    And two underscores for a symbolic name for the corresponding function, e.g.:

    #define TASSEL1 (0x0200) /* Timer A clock source select 1 */ #define TASSEL0 (0x0100) /* Timer A clock source select 0 */ #define TASSEL_0 (0x0000) /* Timer A clock source select: 0 - TACLK */ #define TASSEL_1 (0x0100) /* Timer A clock source select: 1 - ACLK */ #define TASSEL_2 (0x0200) /* Timer A clock source select: 2 - SMCLK */ #define TASSEL_3 (0x0300) /* Timer A clock source select: 3 - INCLK */ #define TASSEL__TACLK (0x0000) /* Timer A clock source select: 0 - TACLK */ #define TASSEL__ACLK (0x0100) /* Timer A clock source select: 1 - ACLK */ #define TASSEL__SMCLK (0x0200) /* Timer A clock source select: 2 - SMCLK */ #define TASSEL__INCLK (0x0300) /* Timer A clock source select: 3 - INCLK */
     
    Though that's not available for all headers. You could file a bug to that effect on the mspgcc project and I'll push the enhancement upstream to TI; that might get it into all toolkits since they supply CCS and IAR as well. They were receptive to the request that TIMER0_A0_VECTOR be available on MCUs that formerly spelled it only asTIMERA0_VECTOR, which helps with portability across MCUs.
×
×
  • Create New...