Jump to content

SirZusa

Members
  • Content Count

    105
  • Joined

  • Last visited


Reputation Activity

  1. Like
    SirZusa got a reaction from dubnet in GSM-Remote-Controlled Car-Heater   
    Hey there,
    it has been a while since my last project - and i didn't finish it till now. Since i got employed there is only a little time left for projects like these :shifty:
     
    Cause it is getting cold here and i don't want to sit in a cold car every morning when driving to work i had the idea for this small project.
    Spontaneously i ordered an Siemens TC35i - GSM - Module on ebay for 25


  2. Like
    SirZusa got a reaction from chandra in How to initialize MSP430F5510 correctly?   
    Hi,
     
    i got RobG's development board some days ago and started playing with it.
    Soon i have discovered some points that i don't understand... I started with RobG's UART-example and modified it a little bit.
     
    The changes that i made so far:
    1. It now runs at 24 MHz (clocked by XT2)
    2. stripped some unneccessary NOP's (no operation)
    3. inlined some functions for initialization and handling
     

    /*** USB-Includes ***/ #include "USB_config/descriptors.h" #include "USB_API/types.h" #include "USB_API/device.h" #include "USB_API/usb.h" #include "USB_API/UsbCdc.h" #include "usbConstructs.h" /*** HAL-Includes ***/ #include "F5510/HAL_UCS.h" #include "F5510/HAL_PMM.h" /*** USB-Variables ***/ // Flag set by event handler to indicate data has been received into USB buffer volatile BYTE bCDCDataReceived_event = false; #define BUFFER_SIZE 32 char dataBuffer[bUFFER_SIZE] = ""; /////////////////////////////////////////////////////////// void main(void) { // Stop watchdog timer WDTCTL = WDTPW + WDTHOLD; // initialize all ports and set them to output-direction P1OUT = 0x00; P1DIR = 0xFF; P2OUT = 0x00; P2DIR = 0xFF; P3OUT = 0x00; P3DIR = 0xFF; P4OUT = 0x00; P4DIR = 0xFF; P5OUT = 0x00; P5DIR = 0xFF; P6OUT = 0x00; P6DIR = 0xFF; PJOUT = 0x00; PJDIR = 0xFF; // Higher V_Core needed for Coreclock at 24 MHz SetVCore(PMMCOREV_3); // Initialization of clock module // enable XT2 pins P5SEL |= 0x0C; // use REFO for FLL and ACLK // ??? UCSCTL3 = (UCSCTL3 & ~(SELREF_7)) | (SELREF__REFOCLK); UCSCTL4 = (UCSCTL4 & ~(SELA_7)) | (SELA__REFOCLK); // MCLK will be driven by the FLL (not by XT2), referenced to the REFO // Start the FLL, at the freq indicated by the config // ??? Init_FLL_Settle(USB_MCLK_FREQ / 1000, USB_MCLK_FREQ / 98361); // Start the "USB crystal" - constant USB_MCLK_FREQ XT2_Start(XT2DRIVE_0); // Initialization of USB module // Init USB USB_init(); // Enable USB event handling routines USB_setEnabledEvents(kUSB_allUsbEvents); // See if we're already attached physically to USB, and if so, connect to it // Normally applications don't invoke the event handlers, but this is an exception. if (USB_connectionInfo() & kUSB_vbusPresent) { if (USB_enable() == kUSB_succeed) { USB_reset(); USB_connect(); } } /////////////////////////////////////////////////////////// // enable interrupts __bis_SR_register(GIE); // MCLK = XT2 SELECT_MCLK(SELM__XT2CLK); // no divisor - full speed MCLK_DIV(1); // main loop while (1) { // generate a clock on P1.0 to measure it toggle(P1OUT, BIT0); // ST_ENUM_ACTIVE if ((USBPWRCTL & USBBGVBV) && (USBCNF & PUR_EN) && (bEnumerationStatus == ENUMERATION_COMPLETE) && (!(bFunctionSuspended == TRUE))) { while (bCDCDataReceived_event) { // Clear flag early -- just in case execution breaks below because of an error bCDCDataReceived_event = false; // Count has the number of bytes received into dataBuffer WORD count = cdcReceiveDataInBuffer((BYTE*) dataBuffer, BUFFER_SIZE, CDC0_INTFNUM); // process incomming data WORD c = 0; while (c < count) { DataHandling(dataBuffer[c]); c++; } } } } } /* * ======== UNMI_ISR ======== */ #pragma vector = UNMI_VECTOR __interrupt void UNMI_ISR(void) { switch (__even_in_range(SYSUNIV, SYSUNIV_BUSIFG)) { case SYSUNIV_NONE: // __no_operation(); break; case SYSUNIV_NMIIFG: // __no_operation(); break; case SYSUNIV_OFIFG: // clear OSC flags UCSCTL7 &= ~(DCOFFG + XT1LFOFFG + XT2OFFG); SFRIFG1 &= ~OFIFG; //Clear OFIFG fault flag break; case SYSUNIV_ACCVIFG: // __no_operation(); break; case SYSUNIV_BUSIFG: // clear bus error flag SYSBERRIV = 0; // disable USB_disable(); break; } }
     
    USB CDC is up and running, if the values for the FLL are wrong Windows won't detect the proper device.
    If everything is fine the speed i tested got over 4.000.000 baud without problems.
     
    So the questions that i have after the first hours working with the MSP430F5510 are:
    - Are there some Interrupt-Routines for handling incomming data? The actual method is really inefficient (Polling in an endless loop)
    - How does the FLL work? How to set proper parameters? Wrong values lead to a lock because it can't settle.
    - What is REF0? Why use it for FLL and ACLK instead of XT2?
     
    Maybe some of you can answer or help me out ... still a lot of things to learn the next days
  3. Like
    SirZusa got a reaction from GeekDoc in Sample code for Rob's f5510 usb dev board   
    Here's my example for communication over USB-CDC based on the TI example:
     

    /*** Standard-Includes ***/ #include "stdbool.h" /*** USB-Includes ***/ #include "USB_config/descriptors.h" #include "USB_API/types.h" #include "USB_API/device.h" #include "USB_API/usb.h" #include "USB_API/UsbCdc.h" #include "usbConstructs.h" /*** HAL-Includes ***/ #include "F5510/HAL_UCS.h" #include "F5510/HAL_PMM.h" /*** USB-Variables ***/ // Flag set by event handler to indicate data has been received into USB buffer volatile BYTE bCDCDataReceived_event = false; #define BUFFER_SIZE 64 char dataBuffer[bUFFER_SIZE] = ""; /*** Send data ***/ void SendData(BYTE output) { WORD x = 0; BYTE out[1] = { output }; // send it over USB if (cdcSendDataWaitTilDone(out, 1, CDC0_INTFNUM, 0)) { // it failed for some reason; abort and leave the USBCDC_abortSend(&x, CDC0_INTFNUM); } } /*** Handling of incomming data ***/ void DataHandling(BYTE input) { // DO SOMETHING } /*** MAIN ***/ void main(void) { // Stop watchdog timer WDTCTL = WDTPW + WDTHOLD; // Higher Vcore needed for 24 MHz SetVCore(PMMCOREV_3); // enable XT2 pins P5SEL |= 0x0C; UCSCTL6 |= XT2DRIVE_2; // Start crystal UCSCTL6 &= ~XT2OFF; // wait at least 2ms for XT2 to settle __delay_cycles(50000); // Clear all OSC fault Flags UCSCTL7 = 0; // MCLK = XT2-Freq. SELECT_MCLK(SELM__XT2CLK); // full speed MCLK_DIV(1); // Initialization of USB module // Init USB USB_init(); // Enable all USB event handling routines USB_setEnabledEvents(kUSB_allUsbEvents); // See if we're already attached physically to USB, and if so, connect to it // Normally applications don't invoke the event handlers, but this is an exception. if (USB_connectionInfo() & kUSB_vbusPresent) { if (USB_enable() == kUSB_succeed) { USB_reset(); USB_connect(); } } // enable interrupts __bis_SR_register(GIE); // main loop while (1) { // ST_ENUM_ACTIVE if ((USBPWRCTL & USBBGVBV) && (USBCNF & PUR_EN) && (bEnumerationStatus == ENUMERATION_COMPLETE) && (!(bFunctionSuspended == TRUE))) { while (bCDCDataReceived_event) { // Clear flag early -- just in case execution breaks below because of an error bCDCDataReceived_event = false; // Count has the number of bytes received into dataBuffer WORD count = cdcReceiveDataInBuffer((BYTE*) dataBuffer, BUFFER_SIZE, CDC0_INTFNUM); // process incomming data WORD c = 0; while (c < count) { DataHandling(dataBuffer[c]); c++; } } } } }
  4. Like
    SirZusa got a reaction from jsolarski in Sample code for Rob's f5510 usb dev board   
    Here's my example for communication over USB-CDC based on the TI example:
     

    /*** Standard-Includes ***/ #include "stdbool.h" /*** USB-Includes ***/ #include "USB_config/descriptors.h" #include "USB_API/types.h" #include "USB_API/device.h" #include "USB_API/usb.h" #include "USB_API/UsbCdc.h" #include "usbConstructs.h" /*** HAL-Includes ***/ #include "F5510/HAL_UCS.h" #include "F5510/HAL_PMM.h" /*** USB-Variables ***/ // Flag set by event handler to indicate data has been received into USB buffer volatile BYTE bCDCDataReceived_event = false; #define BUFFER_SIZE 64 char dataBuffer[bUFFER_SIZE] = ""; /*** Send data ***/ void SendData(BYTE output) { WORD x = 0; BYTE out[1] = { output }; // send it over USB if (cdcSendDataWaitTilDone(out, 1, CDC0_INTFNUM, 0)) { // it failed for some reason; abort and leave the USBCDC_abortSend(&x, CDC0_INTFNUM); } } /*** Handling of incomming data ***/ void DataHandling(BYTE input) { // DO SOMETHING } /*** MAIN ***/ void main(void) { // Stop watchdog timer WDTCTL = WDTPW + WDTHOLD; // Higher Vcore needed for 24 MHz SetVCore(PMMCOREV_3); // enable XT2 pins P5SEL |= 0x0C; UCSCTL6 |= XT2DRIVE_2; // Start crystal UCSCTL6 &= ~XT2OFF; // wait at least 2ms for XT2 to settle __delay_cycles(50000); // Clear all OSC fault Flags UCSCTL7 = 0; // MCLK = XT2-Freq. SELECT_MCLK(SELM__XT2CLK); // full speed MCLK_DIV(1); // Initialization of USB module // Init USB USB_init(); // Enable all USB event handling routines USB_setEnabledEvents(kUSB_allUsbEvents); // See if we're already attached physically to USB, and if so, connect to it // Normally applications don't invoke the event handlers, but this is an exception. if (USB_connectionInfo() & kUSB_vbusPresent) { if (USB_enable() == kUSB_succeed) { USB_reset(); USB_connect(); } } // enable interrupts __bis_SR_register(GIE); // main loop while (1) { // ST_ENUM_ACTIVE if ((USBPWRCTL & USBBGVBV) && (USBCNF & PUR_EN) && (bEnumerationStatus == ENUMERATION_COMPLETE) && (!(bFunctionSuspended == TRUE))) { while (bCDCDataReceived_event) { // Clear flag early -- just in case execution breaks below because of an error bCDCDataReceived_event = false; // Count has the number of bytes received into dataBuffer WORD count = cdcReceiveDataInBuffer((BYTE*) dataBuffer, BUFFER_SIZE, CDC0_INTFNUM); // process incomming data WORD c = 0; while (c < count) { DataHandling(dataBuffer[c]); c++; } } } } }
  5. Like
    SirZusa got a reaction from bluehash in Need a challenge question that a visitor may know, to keep off spam   
    hmm... seems like the bots got intelligent over the last years ...
     
    * another try would be to use the questions - but don't render them as text - provide them as an image - i know many bots use text-recognition but you may confuse them a bit
     
    * to make it even more complicated: give out a fake-question in plain text and lets have it the same color or hide it so the user won't see it ... then give out the correct question you want the user to answer in an image and give it a class, name, alt, title that doesn't allow the bot to conclude it is used as something lika a "captcha"
     
    * maybe a verification by an SMS would be possible - but this could be too expensive over time
  6. Like
    SirZusa got a reaction from bluehash in Need a challenge question that a visitor may know, to keep off spam   
    What about these standard things?
    * is there no AKISMET-Plugin available?
    * normal graphical captcha
    * a small calculation (1 + 2 = ?, 4 * 3 = ?)
    * Colors (Which color has the water, grass, blood, beer, sky, ... )
    * Pictures (show 4 pictures and tell the user to select for example "the apple" out of this set)
    * a simple task for the user ... something like that: http://webdesignledger.com/wp-content/uploads/2010/11/currybet.jpg
  7. Like
    SirZusa got a reaction from zeke in Need a challenge question that a visitor may know, to keep off spam   
    What about these standard things?
    * is there no AKISMET-Plugin available?
    * normal graphical captcha
    * a small calculation (1 + 2 = ?, 4 * 3 = ?)
    * Colors (Which color has the water, grass, blood, beer, sky, ... )
    * Pictures (show 4 pictures and tell the user to select for example "the apple" out of this set)
    * a simple task for the user ... something like that: http://webdesignledger.com/wp-content/uploads/2010/11/currybet.jpg
  8. Like
    SirZusa got a reaction from bluehash in Need some SEO help   
    You should also set some more keywords and a better description:


     
    Some more keywords: Motor, Servo, LED, RX/TX, UART, USB, Ethernet, SPI, ISP, Spy-by-wire, SBW, bluetooth, shop, microcontroller, avr, mega, atmega, compiler, Controller, MCU, Board, JTAG, Debugger, Programmer, Embedded, Hardware, Development ... maybe repeat some category-titles
     
    You use Google Analytics? It should show you where the users come from and what they were looking for (keywords and searchengines they where using - you can use these for building a pool of keywords)
     
    Maybe you also want to use subdomains because Google handles every Subdomain as a own domain (forum.43oh.com, store.43oh.com, etc. )
  9. Like
    SirZusa reacted to gordon in Efficient micro mathematics   
    Tripped over this by accident while watching one of Travis Goodspeed's talks:
     
    Efficient Micro Mathematics
  10. Like
    SirZusa got a reaction from dacoffey in Content driven AmbientLight /// LightPack-Clone   
    Idea and description:
    Inspired by this project (Lightpack: http://code.google.com/p/light-pack/) i started to develop my own solution based on an launchpad equipped with a MSP430G2211, later i had to move on to a MSP430G2553 cause i was runnning out of RAM. Now it makes use of the hardware-UART and can theoretically handle up to 375 frames per second.
     
    How to take control over the
  11. Like
    SirZusa reacted to RobG in MSP430F5510 USB Development Board   
    MSP430F5510 development board, inspired by xpg, with LaunchPad compatible headers.
     




  12. Like
    SirZusa reacted to dacoffey in USB Controllable 8 Outlet AC Relay Box   
    Here is a project built using a 430 to power a USB controllable 8 outlet AC relay box.
     
    http://david-adam-coffey.com/blog/ac-relay-box
     
     


  13. Like
    SirZusa reacted to artifus in diy resistive ribbon sensor   
    stumbled upon this recently, thought it may be of interest:
     
    http://memoir.okno.be/phys_comp_tutorial/ribbon4/ribbon4.htm
  14. Like
    SirZusa got a reaction from Mk_ in Launchpad as a Data Acquisition module   
    How much data do you need to store?
    How much samples per minute (or second or hour)?
     
    Maybe you want to have a look at the FRAM series (Experimenter Board) offering up to 16K inbuild non-volatile memory
  15. Like
    SirZusa got a reaction from spreng37 in Strange breadboarding issue (MSP430G2231 + TLC5940)   
    Where's your capacitor (100nF) between Vcc and GND (Pins 21 and 22) on the TLC5940-side?
     
    Have a look at TLC5940 Datasheet page 21
  16. Like
    SirZusa got a reaction from pillum in TLC5940 - "Full Implementation"   
    hi there, as i already said in another thread i was working on the code for controlling the TLC5940. here it is!
     
    100% working. specification-sheet i used to code this: http://www.ti.com/lit/sw/slvc106/slvc106.pdf
     


    [*:1o0bnvvd]supports DC
    [*:1o0bnvvd]supports Grayscale
    [*:1o0bnvvd]recommendet implementation from the Programming Flow Chart
    [*:1o0bnvvd]does not support EEPROM-programming (cause you will need 22 Volts for this)
    [*:1o0bnvvd]actually does not support "Use DC from EEPROM-mode"
    [*:1o0bnvvd]LOD-Check not implemented for now ... but i think i will do this soon if i find more literature on this
     

    /*** TLC5940 ***/ #include "msp430g2553.h" #include "stdbool.h" // How many TLC's daisy-chained #define n 2 /*** Ports ***/ // STATUS-LED #define PORT_STATUS_LED P1OUT #define PIN_STATUS_LED BIT0 // BLANK - to pin 23 of every TLC5940 #define PORT_BLANK P1OUT #define PIN_BLANK BIT3 // XLAT - to pin 24 of every TLC5940 #define PORT_XLAT P1OUT #define PIN_XLAT BIT4 // SCLK - to pin 25 of every TLC5940 #define PORT_SCLK P1OUT #define PIN_SCLK BIT5 // SIN - to pin 26 of first TLC5940 #define PORT_SIN P1OUT #define PIN_SIN BIT6 // GSCLK - to pin 18 of every TLC5940 #define PORT_GSCLK P1OUT #define PIN_GSCLK BIT7 // DCPRG - to pin 19 of every TLC5940 #define PORT_DCPRG P2OUT #define PIN_DCPRG BIT3 // VPRG - to pin 27 of every TLC5940 #define PORT_VPRG P2OUT #define PIN_VPRG BIT4 /*** DO NOT EDIT BELOW ***/ #define x (n * 16) /*** Brightness-Correction ***/ const int pwm_table[256] = { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,26,28,30,32,34,36,38,40,42, 44,46,48,50,52,55,58,61,64,67,70,73,76,79,82,85,88,91,94,97,100,103,106,110,114,118,122,126,130, 134,138,142,146,150,154,158,162,166,170,174,178,182,186,190,195,200,205,210,215,220,225,230,235, 240,245,250,255,260,265,270,275,280,285,290,297,304,311,318,325,332,339,346,353,360,367,374,381, 388,395,402,409,416,423,430,437,444,451,458,467,476,485,494,503,512,521,530,539,548,557,566,575, 584,593,602,611,626,641,656,671,686,701,716,731,746,761,776,791,806,821,836,851,866,881,896,916, 936,956,976,996,1016,1036,1056,1076,1096,1116,1136,1156,1176,1196,1221,1246,1271,1296,1321,1346, 1371,1396,1421,1446,1471,1496,1526,1556,1586,1616,1646,1676,1706,1736,1766,1796,1826,1856,1886, 1921,1956,1991,2026,2061,2096,2131,2166,2201,2236,2271,2306,2341,2376,2411,2446,2481,2516,2551, 2586,2621,2656,2691,2726,2761,2796,2832,2868,2904,2940,2976,3012,3048,3084,3120,3156,3192,3228, 3266,3304,3342,3380,3418,3456,3494,3532,3572,3612,3652,3692,3737,3782,3827,3872,3917,3962,4007,4095 }; // holds the actual DC-data for each channel char dc_data[x] = {63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63}; /*** Variables ***/ // first PWM-cycle after Dot Correction Data has changed? bool FirstCycleFlag; // holds the actual PWM-data for each channel int gs_data[x]; /*** small userdefined Functions ***/ // useful macros #define setLow(port, pin) { port &= ~pin; } #define setHigh(port, pin) { port |= pin; } #define pulse(port, pin) { setHigh(port, pin); setLow(port, pin); } #define toggle(port, pin) { port ^= pin; } /*** transfer DC-data to our TLC5940's ***/ void send_DC() { // DCPRG - dont use DC-EEPROM setHigh(PORT_DCPRG, PIN_DCPRG); // VPRG - set Dot Correction Input setHigh(PORT_VPRG, PIN_VPRG); // Reset Counter int Counter = 0; // clock in Dot Correction Data for (; { // Counter > n * 96 - 1 // 6 Bits * 16 Channels = 96 if (Counter > (n * 96 - 1)) { pulse(PORT_XLAT, PIN_XLAT); break; } else { // Set SIN to DC Data[Counter] // MSB first if ((dc_data[Counter / 6] >> (5 - (Counter % 6))) & 0x01) { setHigh(PORT_SIN, PIN_SIN); } else { setLow(PORT_SIN, PIN_SIN); } pulse(PORT_SCLK, PIN_SCLK); Counter++; } } // dont save to EEPROM - so we finish here // set FirstCycleFlag to true FirstCycleFlag = true; } /*** transfer PWM-data to our TLC5940's ***/ void send_GS() { if (FirstCycleFlag == true) { setLow(PORT_VPRG, PIN_VPRG); } // Reset Counters int GSCLK_Counter = 0; int Data_Counter = 0; setLow(PORT_BLANK, PIN_BLANK); // clock in PWM Data for (; { if (GSCLK_Counter > 4095) { setHigh(PORT_BLANK, PIN_BLANK); pulse(PORT_XLAT, PIN_XLAT); if (FirstCycleFlag == true) { pulse(PORT_SCLK, PIN_SCLK); } FirstCycleFlag = false; break; } else { // 12 Bit * 16 Channels = 192 if (Data_Counter > (n * 192 - 1)) { pulse(PORT_GSCLK, PIN_GSCLK); GSCLK_Counter++; } else { // Set SIN to GS Data[Counter] // MSB first if ((gs_data[Data_Counter / 12] >> (11 - (Data_Counter % 12))) & 0x01) { setHigh(PORT_SIN, PIN_SIN); } else { setLow(PORT_SIN, PIN_SIN); } pulse(PORT_SCLK, PIN_SCLK); Data_Counter++; pulse(PORT_GSCLK, PIN_GSCLK); GSCLK_Counter++; } } } } /*** Our main program ***/ void main(void) { // stop WDT - WDTPW is the password needed for every write and then tell watchdog to hold WDTCTL = WDTPW | WDTHOLD; BCSCTL1 = CALBC1_16MHZ; DCOCTL = CALDCO_16MHZ; // initialize the ports connected to the TLC's // set ports to output-direction P1DIR |= (PIN_STATUS_LED|PIN_BLANK|PIN_XLAT|PIN_SCLK|PIN_SIN|PIN_GSCLK); P1OUT = 0x00; P2DIR |= (PIN_DCPRG|PIN_VPRG); P2OUT = 0x00; // initialize TLC5940 setLow(PORT_GSCLK, PIN_GSCLK); setLow(PORT_SCLK, PIN_SCLK); setLow(PORT_DCPRG, PIN_DCPRG); setHigh(PORT_VPRG, PIN_VPRG); setLow(PORT_XLAT, PIN_XLAT); setHigh(PORT_BLANK, PIN_BLANK); // force first cycle send_DC(); send_GS(); // enable interrupts __bis_SR_register(GIE); while(1) { // load gs-data here // update PWM-data permanently send_GS(); } }
  17. Like
    SirZusa got a reaction from fj604 in TLC5940 - "Full Implementation"   
    hi there, as i already said in another thread i was working on the code for controlling the TLC5940. here it is!
     
    100% working. specification-sheet i used to code this: http://www.ti.com/lit/sw/slvc106/slvc106.pdf
     


    [*:1o0bnvvd]supports DC
    [*:1o0bnvvd]supports Grayscale
    [*:1o0bnvvd]recommendet implementation from the Programming Flow Chart
    [*:1o0bnvvd]does not support EEPROM-programming (cause you will need 22 Volts for this)
    [*:1o0bnvvd]actually does not support "Use DC from EEPROM-mode"
    [*:1o0bnvvd]LOD-Check not implemented for now ... but i think i will do this soon if i find more literature on this
     

    /*** TLC5940 ***/ #include "msp430g2553.h" #include "stdbool.h" // How many TLC's daisy-chained #define n 2 /*** Ports ***/ // STATUS-LED #define PORT_STATUS_LED P1OUT #define PIN_STATUS_LED BIT0 // BLANK - to pin 23 of every TLC5940 #define PORT_BLANK P1OUT #define PIN_BLANK BIT3 // XLAT - to pin 24 of every TLC5940 #define PORT_XLAT P1OUT #define PIN_XLAT BIT4 // SCLK - to pin 25 of every TLC5940 #define PORT_SCLK P1OUT #define PIN_SCLK BIT5 // SIN - to pin 26 of first TLC5940 #define PORT_SIN P1OUT #define PIN_SIN BIT6 // GSCLK - to pin 18 of every TLC5940 #define PORT_GSCLK P1OUT #define PIN_GSCLK BIT7 // DCPRG - to pin 19 of every TLC5940 #define PORT_DCPRG P2OUT #define PIN_DCPRG BIT3 // VPRG - to pin 27 of every TLC5940 #define PORT_VPRG P2OUT #define PIN_VPRG BIT4 /*** DO NOT EDIT BELOW ***/ #define x (n * 16) /*** Brightness-Correction ***/ const int pwm_table[256] = { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,26,28,30,32,34,36,38,40,42, 44,46,48,50,52,55,58,61,64,67,70,73,76,79,82,85,88,91,94,97,100,103,106,110,114,118,122,126,130, 134,138,142,146,150,154,158,162,166,170,174,178,182,186,190,195,200,205,210,215,220,225,230,235, 240,245,250,255,260,265,270,275,280,285,290,297,304,311,318,325,332,339,346,353,360,367,374,381, 388,395,402,409,416,423,430,437,444,451,458,467,476,485,494,503,512,521,530,539,548,557,566,575, 584,593,602,611,626,641,656,671,686,701,716,731,746,761,776,791,806,821,836,851,866,881,896,916, 936,956,976,996,1016,1036,1056,1076,1096,1116,1136,1156,1176,1196,1221,1246,1271,1296,1321,1346, 1371,1396,1421,1446,1471,1496,1526,1556,1586,1616,1646,1676,1706,1736,1766,1796,1826,1856,1886, 1921,1956,1991,2026,2061,2096,2131,2166,2201,2236,2271,2306,2341,2376,2411,2446,2481,2516,2551, 2586,2621,2656,2691,2726,2761,2796,2832,2868,2904,2940,2976,3012,3048,3084,3120,3156,3192,3228, 3266,3304,3342,3380,3418,3456,3494,3532,3572,3612,3652,3692,3737,3782,3827,3872,3917,3962,4007,4095 }; // holds the actual DC-data for each channel char dc_data[x] = {63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63}; /*** Variables ***/ // first PWM-cycle after Dot Correction Data has changed? bool FirstCycleFlag; // holds the actual PWM-data for each channel int gs_data[x]; /*** small userdefined Functions ***/ // useful macros #define setLow(port, pin) { port &= ~pin; } #define setHigh(port, pin) { port |= pin; } #define pulse(port, pin) { setHigh(port, pin); setLow(port, pin); } #define toggle(port, pin) { port ^= pin; } /*** transfer DC-data to our TLC5940's ***/ void send_DC() { // DCPRG - dont use DC-EEPROM setHigh(PORT_DCPRG, PIN_DCPRG); // VPRG - set Dot Correction Input setHigh(PORT_VPRG, PIN_VPRG); // Reset Counter int Counter = 0; // clock in Dot Correction Data for (; { // Counter > n * 96 - 1 // 6 Bits * 16 Channels = 96 if (Counter > (n * 96 - 1)) { pulse(PORT_XLAT, PIN_XLAT); break; } else { // Set SIN to DC Data[Counter] // MSB first if ((dc_data[Counter / 6] >> (5 - (Counter % 6))) & 0x01) { setHigh(PORT_SIN, PIN_SIN); } else { setLow(PORT_SIN, PIN_SIN); } pulse(PORT_SCLK, PIN_SCLK); Counter++; } } // dont save to EEPROM - so we finish here // set FirstCycleFlag to true FirstCycleFlag = true; } /*** transfer PWM-data to our TLC5940's ***/ void send_GS() { if (FirstCycleFlag == true) { setLow(PORT_VPRG, PIN_VPRG); } // Reset Counters int GSCLK_Counter = 0; int Data_Counter = 0; setLow(PORT_BLANK, PIN_BLANK); // clock in PWM Data for (; { if (GSCLK_Counter > 4095) { setHigh(PORT_BLANK, PIN_BLANK); pulse(PORT_XLAT, PIN_XLAT); if (FirstCycleFlag == true) { pulse(PORT_SCLK, PIN_SCLK); } FirstCycleFlag = false; break; } else { // 12 Bit * 16 Channels = 192 if (Data_Counter > (n * 192 - 1)) { pulse(PORT_GSCLK, PIN_GSCLK); GSCLK_Counter++; } else { // Set SIN to GS Data[Counter] // MSB first if ((gs_data[Data_Counter / 12] >> (11 - (Data_Counter % 12))) & 0x01) { setHigh(PORT_SIN, PIN_SIN); } else { setLow(PORT_SIN, PIN_SIN); } pulse(PORT_SCLK, PIN_SCLK); Data_Counter++; pulse(PORT_GSCLK, PIN_GSCLK); GSCLK_Counter++; } } } } /*** Our main program ***/ void main(void) { // stop WDT - WDTPW is the password needed for every write and then tell watchdog to hold WDTCTL = WDTPW | WDTHOLD; BCSCTL1 = CALBC1_16MHZ; DCOCTL = CALDCO_16MHZ; // initialize the ports connected to the TLC's // set ports to output-direction P1DIR |= (PIN_STATUS_LED|PIN_BLANK|PIN_XLAT|PIN_SCLK|PIN_SIN|PIN_GSCLK); P1OUT = 0x00; P2DIR |= (PIN_DCPRG|PIN_VPRG); P2OUT = 0x00; // initialize TLC5940 setLow(PORT_GSCLK, PIN_GSCLK); setLow(PORT_SCLK, PIN_SCLK); setLow(PORT_DCPRG, PIN_DCPRG); setHigh(PORT_VPRG, PIN_VPRG); setLow(PORT_XLAT, PIN_XLAT); setHigh(PORT_BLANK, PIN_BLANK); // force first cycle send_DC(); send_GS(); // enable interrupts __bis_SR_register(GIE); while(1) { // load gs-data here // update PWM-data permanently send_GS(); } }
  18. Like
    SirZusa got a reaction from gatImmusepete in Would anyone be interested in a MSP430F5510 breakout   
    I also began to do a breakout, but i didn't want to make a msp430f55xx-only breakout. Why? Because it's hard to sell in time (probably no problem over longer period - but i must finance them first). You can only get the best price when buying a higher quantity - but how much can you sell of these breakouts? Just ask the people in this forum. (I got the best discount for a quantity of about 200-250 pieces - depending on the size (~63mm x 23 mm))
     
    1$ / board with tin-finish, solder-mask etc.? Where do you order? (i can't go under 1
  19. Like
    SirZusa got a reaction from SugarAddict in TLC5940 - "Full Implementation"   
    hi there, as i already said in another thread i was working on the code for controlling the TLC5940. here it is!
     
    100% working. specification-sheet i used to code this: http://www.ti.com/lit/sw/slvc106/slvc106.pdf
     


    [*:1o0bnvvd]supports DC
    [*:1o0bnvvd]supports Grayscale
    [*:1o0bnvvd]recommendet implementation from the Programming Flow Chart
    [*:1o0bnvvd]does not support EEPROM-programming (cause you will need 22 Volts for this)
    [*:1o0bnvvd]actually does not support "Use DC from EEPROM-mode"
    [*:1o0bnvvd]LOD-Check not implemented for now ... but i think i will do this soon if i find more literature on this
     

    /*** TLC5940 ***/ #include "msp430g2553.h" #include "stdbool.h" // How many TLC's daisy-chained #define n 2 /*** Ports ***/ // STATUS-LED #define PORT_STATUS_LED P1OUT #define PIN_STATUS_LED BIT0 // BLANK - to pin 23 of every TLC5940 #define PORT_BLANK P1OUT #define PIN_BLANK BIT3 // XLAT - to pin 24 of every TLC5940 #define PORT_XLAT P1OUT #define PIN_XLAT BIT4 // SCLK - to pin 25 of every TLC5940 #define PORT_SCLK P1OUT #define PIN_SCLK BIT5 // SIN - to pin 26 of first TLC5940 #define PORT_SIN P1OUT #define PIN_SIN BIT6 // GSCLK - to pin 18 of every TLC5940 #define PORT_GSCLK P1OUT #define PIN_GSCLK BIT7 // DCPRG - to pin 19 of every TLC5940 #define PORT_DCPRG P2OUT #define PIN_DCPRG BIT3 // VPRG - to pin 27 of every TLC5940 #define PORT_VPRG P2OUT #define PIN_VPRG BIT4 /*** DO NOT EDIT BELOW ***/ #define x (n * 16) /*** Brightness-Correction ***/ const int pwm_table[256] = { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,26,28,30,32,34,36,38,40,42, 44,46,48,50,52,55,58,61,64,67,70,73,76,79,82,85,88,91,94,97,100,103,106,110,114,118,122,126,130, 134,138,142,146,150,154,158,162,166,170,174,178,182,186,190,195,200,205,210,215,220,225,230,235, 240,245,250,255,260,265,270,275,280,285,290,297,304,311,318,325,332,339,346,353,360,367,374,381, 388,395,402,409,416,423,430,437,444,451,458,467,476,485,494,503,512,521,530,539,548,557,566,575, 584,593,602,611,626,641,656,671,686,701,716,731,746,761,776,791,806,821,836,851,866,881,896,916, 936,956,976,996,1016,1036,1056,1076,1096,1116,1136,1156,1176,1196,1221,1246,1271,1296,1321,1346, 1371,1396,1421,1446,1471,1496,1526,1556,1586,1616,1646,1676,1706,1736,1766,1796,1826,1856,1886, 1921,1956,1991,2026,2061,2096,2131,2166,2201,2236,2271,2306,2341,2376,2411,2446,2481,2516,2551, 2586,2621,2656,2691,2726,2761,2796,2832,2868,2904,2940,2976,3012,3048,3084,3120,3156,3192,3228, 3266,3304,3342,3380,3418,3456,3494,3532,3572,3612,3652,3692,3737,3782,3827,3872,3917,3962,4007,4095 }; // holds the actual DC-data for each channel char dc_data[x] = {63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63}; /*** Variables ***/ // first PWM-cycle after Dot Correction Data has changed? bool FirstCycleFlag; // holds the actual PWM-data for each channel int gs_data[x]; /*** small userdefined Functions ***/ // useful macros #define setLow(port, pin) { port &= ~pin; } #define setHigh(port, pin) { port |= pin; } #define pulse(port, pin) { setHigh(port, pin); setLow(port, pin); } #define toggle(port, pin) { port ^= pin; } /*** transfer DC-data to our TLC5940's ***/ void send_DC() { // DCPRG - dont use DC-EEPROM setHigh(PORT_DCPRG, PIN_DCPRG); // VPRG - set Dot Correction Input setHigh(PORT_VPRG, PIN_VPRG); // Reset Counter int Counter = 0; // clock in Dot Correction Data for (; { // Counter > n * 96 - 1 // 6 Bits * 16 Channels = 96 if (Counter > (n * 96 - 1)) { pulse(PORT_XLAT, PIN_XLAT); break; } else { // Set SIN to DC Data[Counter] // MSB first if ((dc_data[Counter / 6] >> (5 - (Counter % 6))) & 0x01) { setHigh(PORT_SIN, PIN_SIN); } else { setLow(PORT_SIN, PIN_SIN); } pulse(PORT_SCLK, PIN_SCLK); Counter++; } } // dont save to EEPROM - so we finish here // set FirstCycleFlag to true FirstCycleFlag = true; } /*** transfer PWM-data to our TLC5940's ***/ void send_GS() { if (FirstCycleFlag == true) { setLow(PORT_VPRG, PIN_VPRG); } // Reset Counters int GSCLK_Counter = 0; int Data_Counter = 0; setLow(PORT_BLANK, PIN_BLANK); // clock in PWM Data for (; { if (GSCLK_Counter > 4095) { setHigh(PORT_BLANK, PIN_BLANK); pulse(PORT_XLAT, PIN_XLAT); if (FirstCycleFlag == true) { pulse(PORT_SCLK, PIN_SCLK); } FirstCycleFlag = false; break; } else { // 12 Bit * 16 Channels = 192 if (Data_Counter > (n * 192 - 1)) { pulse(PORT_GSCLK, PIN_GSCLK); GSCLK_Counter++; } else { // Set SIN to GS Data[Counter] // MSB first if ((gs_data[Data_Counter / 12] >> (11 - (Data_Counter % 12))) & 0x01) { setHigh(PORT_SIN, PIN_SIN); } else { setLow(PORT_SIN, PIN_SIN); } pulse(PORT_SCLK, PIN_SCLK); Data_Counter++; pulse(PORT_GSCLK, PIN_GSCLK); GSCLK_Counter++; } } } } /*** Our main program ***/ void main(void) { // stop WDT - WDTPW is the password needed for every write and then tell watchdog to hold WDTCTL = WDTPW | WDTHOLD; BCSCTL1 = CALBC1_16MHZ; DCOCTL = CALDCO_16MHZ; // initialize the ports connected to the TLC's // set ports to output-direction P1DIR |= (PIN_STATUS_LED|PIN_BLANK|PIN_XLAT|PIN_SCLK|PIN_SIN|PIN_GSCLK); P1OUT = 0x00; P2DIR |= (PIN_DCPRG|PIN_VPRG); P2OUT = 0x00; // initialize TLC5940 setLow(PORT_GSCLK, PIN_GSCLK); setLow(PORT_SCLK, PIN_SCLK); setLow(PORT_DCPRG, PIN_DCPRG); setHigh(PORT_VPRG, PIN_VPRG); setLow(PORT_XLAT, PIN_XLAT); setHigh(PORT_BLANK, PIN_BLANK); // force first cycle send_DC(); send_GS(); // enable interrupts __bis_SR_register(GIE); while(1) { // load gs-data here // update PWM-data permanently send_GS(); } }
  20. Like
    SirZusa got a reaction from larsie in TLC5940 - "Full Implementation"   
    hi there, as i already said in another thread i was working on the code for controlling the TLC5940. here it is!
     
    100% working. specification-sheet i used to code this: http://www.ti.com/lit/sw/slvc106/slvc106.pdf
     


    [*:1o0bnvvd]supports DC
    [*:1o0bnvvd]supports Grayscale
    [*:1o0bnvvd]recommendet implementation from the Programming Flow Chart
    [*:1o0bnvvd]does not support EEPROM-programming (cause you will need 22 Volts for this)
    [*:1o0bnvvd]actually does not support "Use DC from EEPROM-mode"
    [*:1o0bnvvd]LOD-Check not implemented for now ... but i think i will do this soon if i find more literature on this
     

    /*** TLC5940 ***/ #include "msp430g2553.h" #include "stdbool.h" // How many TLC's daisy-chained #define n 2 /*** Ports ***/ // STATUS-LED #define PORT_STATUS_LED P1OUT #define PIN_STATUS_LED BIT0 // BLANK - to pin 23 of every TLC5940 #define PORT_BLANK P1OUT #define PIN_BLANK BIT3 // XLAT - to pin 24 of every TLC5940 #define PORT_XLAT P1OUT #define PIN_XLAT BIT4 // SCLK - to pin 25 of every TLC5940 #define PORT_SCLK P1OUT #define PIN_SCLK BIT5 // SIN - to pin 26 of first TLC5940 #define PORT_SIN P1OUT #define PIN_SIN BIT6 // GSCLK - to pin 18 of every TLC5940 #define PORT_GSCLK P1OUT #define PIN_GSCLK BIT7 // DCPRG - to pin 19 of every TLC5940 #define PORT_DCPRG P2OUT #define PIN_DCPRG BIT3 // VPRG - to pin 27 of every TLC5940 #define PORT_VPRG P2OUT #define PIN_VPRG BIT4 /*** DO NOT EDIT BELOW ***/ #define x (n * 16) /*** Brightness-Correction ***/ const int pwm_table[256] = { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,26,28,30,32,34,36,38,40,42, 44,46,48,50,52,55,58,61,64,67,70,73,76,79,82,85,88,91,94,97,100,103,106,110,114,118,122,126,130, 134,138,142,146,150,154,158,162,166,170,174,178,182,186,190,195,200,205,210,215,220,225,230,235, 240,245,250,255,260,265,270,275,280,285,290,297,304,311,318,325,332,339,346,353,360,367,374,381, 388,395,402,409,416,423,430,437,444,451,458,467,476,485,494,503,512,521,530,539,548,557,566,575, 584,593,602,611,626,641,656,671,686,701,716,731,746,761,776,791,806,821,836,851,866,881,896,916, 936,956,976,996,1016,1036,1056,1076,1096,1116,1136,1156,1176,1196,1221,1246,1271,1296,1321,1346, 1371,1396,1421,1446,1471,1496,1526,1556,1586,1616,1646,1676,1706,1736,1766,1796,1826,1856,1886, 1921,1956,1991,2026,2061,2096,2131,2166,2201,2236,2271,2306,2341,2376,2411,2446,2481,2516,2551, 2586,2621,2656,2691,2726,2761,2796,2832,2868,2904,2940,2976,3012,3048,3084,3120,3156,3192,3228, 3266,3304,3342,3380,3418,3456,3494,3532,3572,3612,3652,3692,3737,3782,3827,3872,3917,3962,4007,4095 }; // holds the actual DC-data for each channel char dc_data[x] = {63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63}; /*** Variables ***/ // first PWM-cycle after Dot Correction Data has changed? bool FirstCycleFlag; // holds the actual PWM-data for each channel int gs_data[x]; /*** small userdefined Functions ***/ // useful macros #define setLow(port, pin) { port &= ~pin; } #define setHigh(port, pin) { port |= pin; } #define pulse(port, pin) { setHigh(port, pin); setLow(port, pin); } #define toggle(port, pin) { port ^= pin; } /*** transfer DC-data to our TLC5940's ***/ void send_DC() { // DCPRG - dont use DC-EEPROM setHigh(PORT_DCPRG, PIN_DCPRG); // VPRG - set Dot Correction Input setHigh(PORT_VPRG, PIN_VPRG); // Reset Counter int Counter = 0; // clock in Dot Correction Data for (; { // Counter > n * 96 - 1 // 6 Bits * 16 Channels = 96 if (Counter > (n * 96 - 1)) { pulse(PORT_XLAT, PIN_XLAT); break; } else { // Set SIN to DC Data[Counter] // MSB first if ((dc_data[Counter / 6] >> (5 - (Counter % 6))) & 0x01) { setHigh(PORT_SIN, PIN_SIN); } else { setLow(PORT_SIN, PIN_SIN); } pulse(PORT_SCLK, PIN_SCLK); Counter++; } } // dont save to EEPROM - so we finish here // set FirstCycleFlag to true FirstCycleFlag = true; } /*** transfer PWM-data to our TLC5940's ***/ void send_GS() { if (FirstCycleFlag == true) { setLow(PORT_VPRG, PIN_VPRG); } // Reset Counters int GSCLK_Counter = 0; int Data_Counter = 0; setLow(PORT_BLANK, PIN_BLANK); // clock in PWM Data for (; { if (GSCLK_Counter > 4095) { setHigh(PORT_BLANK, PIN_BLANK); pulse(PORT_XLAT, PIN_XLAT); if (FirstCycleFlag == true) { pulse(PORT_SCLK, PIN_SCLK); } FirstCycleFlag = false; break; } else { // 12 Bit * 16 Channels = 192 if (Data_Counter > (n * 192 - 1)) { pulse(PORT_GSCLK, PIN_GSCLK); GSCLK_Counter++; } else { // Set SIN to GS Data[Counter] // MSB first if ((gs_data[Data_Counter / 12] >> (11 - (Data_Counter % 12))) & 0x01) { setHigh(PORT_SIN, PIN_SIN); } else { setLow(PORT_SIN, PIN_SIN); } pulse(PORT_SCLK, PIN_SCLK); Data_Counter++; pulse(PORT_GSCLK, PIN_GSCLK); GSCLK_Counter++; } } } } /*** Our main program ***/ void main(void) { // stop WDT - WDTPW is the password needed for every write and then tell watchdog to hold WDTCTL = WDTPW | WDTHOLD; BCSCTL1 = CALBC1_16MHZ; DCOCTL = CALDCO_16MHZ; // initialize the ports connected to the TLC's // set ports to output-direction P1DIR |= (PIN_STATUS_LED|PIN_BLANK|PIN_XLAT|PIN_SCLK|PIN_SIN|PIN_GSCLK); P1OUT = 0x00; P2DIR |= (PIN_DCPRG|PIN_VPRG); P2OUT = 0x00; // initialize TLC5940 setLow(PORT_GSCLK, PIN_GSCLK); setLow(PORT_SCLK, PIN_SCLK); setLow(PORT_DCPRG, PIN_DCPRG); setHigh(PORT_VPRG, PIN_VPRG); setLow(PORT_XLAT, PIN_XLAT); setHigh(PORT_BLANK, PIN_BLANK); // force first cycle send_DC(); send_GS(); // enable interrupts __bis_SR_register(GIE); while(1) { // load gs-data here // update PWM-data permanently send_GS(); } }
  21. Like
    SirZusa reacted to oPossum in Fraunchpad Synth - Still Alive   
    The note envelope is a simple exponential decay. After each cycle of the waveform, the level is multiplied by 65408/65536 (0.99805). Higher frequency notes will decay faster then lower frequency.

    The music data is in an array in FRAM, it is not MIDI driven like the previous version

    Inspired by this project

    main.c
    #include "msp430fr5739.h" #include "alive.h" void set_tick(unsigned); unsigned get_tick(void); void synth_init(void); void set_note(int, int, int); int wave[257] = { 0, 804, 1608, 2410, 3212, 4011, 4808, 5602, 6393, 7179, 7962, 8739, 9512, 10278, 11039, 11793, 12539, 13279, 14010, 14732, 15446, 16151, 16846, 17530, 18204, 18868, 19519, 20159, 20787, 21403, 22005, 22594, 23170, 23731, 24279, 24811, 25329, 25832, 26319, 26790, 27245, 27683, 28105, 28510, 28898, 29268, 29621, 29956, 30273, 30571, 30852, 31113, 31356, 31580, 31785, 31971, 32137, 32285, 32412, 32521, 32609, 32678, 32728, 32757, 32767, 32757, 32728, 32678, 32609, 32521, 32412, 32285, 32137, 31971, 31785, 31580, 31356, 31113, 30852, 30571, 30273, 29956, 29621, 29268, 28898, 28510, 28105, 27683, 27245, 26790, 26319, 25832, 25329, 24811, 24279, 23731, 23170, 22594, 22005, 21403, 20787, 20159, 19519, 18868, 18204, 17530, 16846, 16151, 15446, 14732, 14010, 13279, 12539, 11793, 11039, 10278, 9512, 8739, 7962, 7179, 6393, 5602, 4808, 4011, 3212, 2410, 1608, 804, 0, -804, -1608, -2410, -3212, -4011, -4808, -5602, -6393, -7179, -7962, -8739, -9512, -10278, -11039, -11793, -12539, -13279, -14010, -14732, -15446, -16151, -16846, -17530, -18204, -18868, -19519, -20159, -20787, -21403, -22005, -22594, -23170, -23731, -24279, -24811, -25329, -25832, -26319, -26790, -27245, -27683, -28105, -28510, -28898, -29268, -29621, -29956, -30273, -30571, -30852, -31113, -31356, -31580, -31785, -31971, -32137, -32285, -32412, -32521, -32609, -32678, -32728, -32757, -32767, -32757, -32728, -32678, -32609, -32521, -32412, -32285, -32137, -31971, -31785, -31580, -31356, -31113, -30852, -30571, -30273, -29956, -29621, -29268, -28898, -28510, -28105, -27683, -27245, -26790, -26319, -25832, -25329, -24811, -24279, -23731, -23170, -22594, -22005, -21403, -20787, -20159, -19519, -18868, -18204, -17530, -16846, -16151, -15446, -14732, -14010, -13279, -12539, -11793, -11039, -10278, -9512, -8739, -7962, -7179, -6393, -5602, -4808, -4011, -3212, -2410, -1608, -804, 0 }; void main(void) { unsigned osc; const struct event_t *e; WDTCTL = WDTPW + WDTHOLD; CSCTL0 = 0xA500; // Unlock clock registers CSCTL1 = DCORSEL | DCOFSEL1 | DCOFSEL0; // 24 MHz CSCTL2 = 0x0333; // Use DCO clock for ACLK, SMCLK and MCLK CSCTL3 = 0x0000; // Set all clock divider to 1 //CSCTL4 = //CSCTL5 = P1DIR = 0x01; // PWM audio output on P1.0 P1REN = 0x00; // P1OUT = 0x00; // P1SEL0 = 0x01; // Enable Timer A output P1SEL1 = 0x00; // P2DIR = 0x00; // P2REN = 0x00; // P2OUT = 0x00; // P2SEL0 = 0x00; // P2SEL1 = 0x03; // Enable UART UCA0 P3DIR = 0x10; // P3REN = 0x00; // P3OUT = 0x00; // P3SEL0 = 0x10; // SMCLK output P3SEL1 = 0x10; // SMCLK output P4DIR = 0x00; // P4REN = 0x00; // P4OUT = 0x00; // P4SEL0 = 0x00; // P4SEL1 = 0x00; // PJDIR = 0x0F; // 4 LEDs PJREN = 0x00; // PJOUT = 0x00; // PJSEL0 = 0x00; // PJSEL1 = 0x00; // UCA0MCTLW = 1; // 16x oversampling UCA0BRW = 24000000 / 16 / 9600; // Fraunchpad UART //UCA0BRW = 24000000 / 16/ 31250; // Standard MIDI bit rate UCA0CTLW0 = 0x0080; // Use SMCLK for bit rate generator, release reset synth_init(); for(osc = 0, e = tune_still_alive; e->pitch; ++e) { set_note(osc++ & 7, e->pitch, 9000); ++PJOUT; set_tick((e[1].time - e[0].time) * 150); while(get_tick()); } }

    alive.h

    struct event_t { unsigned time; unsigned pitch; }; static const struct event_t tune_still_alive[] = { 192, 91, 240, 90, 288, 88, 336, 88, 384, 69, 384, 90, 432, 74, 480, 78, 528, 74, 576, 71, 624, 74, 672, 78, 720, 74, 768, 69, 816, 74, 864, 78, 912, 74, 912, 81, 960, 71, 960, 91, 1008, 74, 1008, 90, 1056, 78, 1056, 88, 1104, 74, 1104, 88, 1152, 69, 1200, 74, 1200, 90, 1248, 78, 1296, 74, 1344, 71, 1344, 86, 1392, 74, 1440, 78, 1440, 88, 1488, 74, 1488, 81, 1536, 69, 1584, 74, 1632, 78, 1680, 74, 1728, 71, 1776, 74, 1824, 78, 1872, 74, 1872, 81, 1920, 71, 1920, 88, 1968, 76, 2016, 79, 2016, 90, 2064, 76, 2064, 91, 2112, 71, 2160, 76, 2208, 79, 2208, 88, 2256, 76, 2256, 85, 2304, 69, 2352, 73, 2352, 86, 2400, 79, 2448, 73, 2496, 69, 2496, 88, 2544, 73, 2592, 79, 2592, 81, 2640, 73, 2640, 81, 2688, 69, 2736, 74, 2736, 90, 2784, 78, 2832, 74, 2880, 71, 2928, 74, 2976, 78, 3024, 74, 3072, 69, 3120, 74, 3168, 78, 3216, 74, 3264, 71, 3264, 91, 3312, 74, 3312, 90, 3360, 78, 3360, 88, 3408, 74, 3408, 88, 3456, 69, 3456, 90, 3504, 74, 3552, 78, 3600, 74, 3648, 71, 3696, 74, 3744, 78, 3792, 74, 3840, 69, 3888, 74, 3936, 78, 3984, 74, 3984, 81, 4032, 71, 4032, 91, 4080, 74, 4080, 90, 4128, 78, 4128, 88, 4176, 74, 4176, 88, 4224, 69, 4272, 74, 4320, 78, 4320, 90, 4368, 74, 4368, 86, 4416, 71, 4464, 74, 4512, 78, 4512, 88, 4560, 74, 4560, 81, 4608, 69, 4656, 74, 4704, 78, 4752, 74, 4800, 71, 4848, 74, 4896, 78, 4944, 74, 4992, 71, 4992, 88, 5040, 76, 5088, 79, 5088, 90, 5136, 76, 5136, 91, 5184, 71, 5232, 76, 5280, 79, 5280, 88, 5328, 76, 5328, 85, 5376, 69, 5424, 73, 5472, 79, 5472, 86, 5520, 73, 5520, 88, 5568, 69, 5616, 73, 5616, 81, 5664, 79, 5664, 86, 5712, 73, 5712, 88, 5760, 70, 5760, 89, 5808, 74, 5808, 88, 5856, 77, 5856, 86, 5904, 81, 5904, 84, 6048, 81, 6096, 82, 6141, 89, 6144, 105, 6144, 72, 6144, 77, 6144, 84, 6192, 81, 6192, 96, 6240, 108, 6240, 72, 6240, 77, 6240, 89, 6288, 96, 6336, 103, 6336, 72, 6336, 76, 6336, 88, 6336, 88, 6384, 79, 6384, 86, 6384, 96, 6432, 108, 6432, 72, 6432, 76, 6432, 86, 6480, 84, 6480, 96, 6528, 106, 6528, 70, 6528, 74, 6528, 86, 6528, 86, 6576, 105, 6576, 82, 6576, 84, 6576, 96, 6624, 103, 6624, 70, 6624, 74, 6624, 84, 6672, 76, 6672, 96, 6720, 105, 6720, 72, 6720, 77, 6720, 84, 6720, 89, 6768, 81, 6768, 96, 6816, 101, 6816, 72, 6816, 77, 6816, 81, 6864, 82, 6864, 96, 6909, 89, 6912, 105, 6912, 72, 6912, 77, 6912, 84, 6960, 81, 6960, 96, 7008, 108, 7008, 72, 7008, 77, 7008, 89, 7056, 96, 7104, 103, 7104, 72, 7104, 76, 7104, 88, 7104, 91, 7152, 79, 7152, 89, 7152, 96, 7200, 108, 7200, 72, 7200, 76, 7200, 88, 7248, 86, 7248, 96, 7296, 106, 7296, 70, 7296, 74, 7296, 86, 7296, 86, 7344, 105, 7344, 82, 7344, 88, 7344, 96, 7392, 103, 7392, 70, 7392, 74, 7392, 89, 7440, 76, 7440, 96, 7488, 105, 7488, 72, 7488, 77, 7488, 89, 7488, 89, 7536, 81, 7536, 96, 7584, 101, 7584, 72, 7584, 77, 7584, 91, 7632, 93, 7632, 96, 7680, 103, 7680, 70, 7680, 74, 7680, 91, 7680, 94, 7728, 106, 7728, 79, 7728, 94, 7776, 105, 7776, 70, 7776, 74, 7776, 93, 7824, 103, 7824, 79, 7872, 100, 7872, 72, 7872, 76, 7872, 91, 7872, 91, 7920, 101, 7920, 79, 7968, 103, 7968, 72, 7968, 76, 7968, 89, 8016, 108, 8016, 79, 8016, 91, 8064, 105, 8064, 72, 8064, 77, 8064, 89, 8064, 93, 8112, 108, 8112, 81, 8112, 93, 8160, 103, 8160, 72, 8160, 77, 8160, 88, 8160, 91, 8208, 108, 8208, 81, 8256, 101, 8256, 74, 8256, 77, 8256, 86, 8256, 89, 8304, 81, 8304, 93, 8352, 105, 8352, 74, 8352, 77, 8352, 86, 8400, 81, 8400, 84, 8445, 89, 8448, 106, 8448, 70, 8448, 74, 8448, 86, 8496, 79, 8496, 89, 8496, 98, 8544, 101, 8544, 70, 8544, 74, 8544, 89, 8592, 79, 8592, 88, 8592, 98, 8640, 105, 8640, 69, 8640, 73, 8640, 88, 8688, 79, 8688, 88, 8688, 97, 8736, 103, 8736, 69, 8736, 73, 8736, 74, 8736, 90, 8784, 102, 8784, 79, 8784, 90, 8832, 62, 8832, 69, 8880, 74, 8928, 78, 8976, 62, 8976, 74, 9024, 59, 9024, 71, 9072, 74, 9120, 78, 9168, 59, 9168, 74, 9216, 62, 9216, 69, 9264, 74, 9312, 78, 9360, 62, 9360, 74, 9408, 59, 9408, 71, 9456, 74, 9504, 78, 9552, 59, 9552, 74, 9600, 62, 9600, 69, 9648, 74, 9696, 78, 9744, 62, 9744, 74, 9792, 59, 9792, 71, 9840, 74, 9888, 78, 9936, 59, 9936, 74, 9984, 62, 9984, 69, 10032, 74, 10080, 78, 10128, 62, 10128, 74, 10128, 81, 10176, 71, 10176, 71, 10176, 91, 10224, 74, 10224, 90, 10272, 71, 10272, 78, 10272, 88, 10320, 69, 10320, 74, 10320, 88, 10368, 62, 10368, 69, 10368, 90, 10416, 74, 10464, 78, 10512, 62, 10512, 74, 10560, 59, 10560, 71, 10608, 74, 10656, 78, 10704, 59, 10704, 74, 10752, 62, 10752, 69, 10800, 74, 10848, 78, 10896, 62, 10896, 74, 10944, 59, 10944, 71, 10944, 91, 10992, 74, 10992, 90, 11040, 78, 11040, 88, 11088, 59, 11088, 74, 11088, 88, 11136, 62, 11136, 69, 11184, 74, 11232, 78, 11232, 90, 11280, 62, 11280, 74, 11280, 86, 11328, 59, 11328, 71, 11376, 74, 11376, 88, 11424, 78, 11472, 59, 11472, 74, 11472, 81, 11520, 62, 11520, 69, 11568, 74, 11616, 78, 11664, 62, 11664, 74, 11712, 59, 11712, 71, 11760, 74, 11808, 78, 11856, 59, 11856, 74, 11904, 64, 11904, 71, 11904, 88, 11952, 76, 12000, 79, 12000, 90, 12048, 64, 12048, 76, 12048, 91, 12096, 64, 12096, 71, 12144, 66, 12144, 76, 12192, 67, 12192, 79, 12192, 88, 12240, 76, 12288, 57, 12288, 69, 12288, 85, 12336, 73, 12384, 79, 12384, 86, 12432, 57, 12432, 73, 12432, 88, 12480, 57, 12480, 69, 12528, 59, 12528, 73, 12576, 61, 12576, 79, 12576, 81, 12624, 73, 12624, 81, 12672, 62, 12672, 69, 12720, 74, 12720, 90, 12768, 78, 12816, 62, 12816, 74, 12864, 59, 12864, 71, 12912, 74, 12960, 78, 13008, 59, 13008, 74, 13056, 62, 13056, 69, 13104, 74, 13152, 78, 13200, 62, 13200, 74, 13200, 81, 13200, 86, 13248, 71, 13248, 71, 13248, 91, 13248, 95, 13296, 74, 13296, 90, 13296, 93, 13344, 71, 13344, 78, 13344, 88, 13344, 91, 13392, 69, 13392, 74, 13392, 88, 13392, 91, 13440, 62, 13440, 69, 13440, 90, 13440, 93, 13488, 74, 13536, 78, 13584, 62, 13584, 74, 13632, 59, 13632, 71, 13680, 74, 13728, 78, 13776, 59, 13776, 74, 13824, 62, 13824, 69, 13872, 74, 13920, 78, 13968, 62, 13968, 74, 13968, 81, 13968, 86, 14016, 59, 14016, 71, 14016, 91, 14016, 95, 14064, 74, 14064, 90, 14064, 93, 14112, 78, 14112, 88, 14112, 91, 14160, 59, 14160, 74, 14160, 88, 14160, 91, 14208, 62, 14208, 69, 14256, 74, 14304, 78, 14304, 90, 14304, 93, 14352, 62, 14352, 74, 14352, 86, 14352, 90, 14400, 59, 14400, 71, 14448, 74, 14496, 78, 14496, 88, 14496, 91, 14544, 59, 14544, 74, 14544, 81, 14544, 86, 14592, 62, 14592, 69, 14640, 74, 14688, 78, 14736, 62, 14736, 74, 14784, 59, 14784, 71, 14832, 74, 14880, 78, 14928, 59, 14928, 74, 14976, 64, 14976, 71, 14976, 88, 15024, 76, 15072, 79, 15072, 90, 15120, 64, 15120, 76, 15120, 91, 15168, 64, 15168, 71, 15216, 66, 15216, 76, 15264, 67, 15264, 79, 15264, 88, 15312, 76, 15360, 57, 15360, 69, 15360, 85, 15408, 73, 15456, 79, 15456, 86, 15504, 57, 15504, 73, 15504, 88, 15552, 57, 15552, 69, 15600, 59, 15600, 73, 15600, 81, 15648, 61, 15648, 79, 15648, 86, 15696, 57, 15696, 73, 15696, 88, 15744, 58, 15744, 70, 15744, 89, 15792, 74, 15792, 88, 15840, 81, 15840, 86, 15888, 70, 15888, 77, 15888, 84, 15936, 81, 15984, 77, 16032, 70, 16032, 77, 16032, 81, 16032, 81, 16080, 57, 16080, 77, 16080, 79, 16080, 82, 16128, 65, 16128, 72, 16128, 77, 16128, 81, 16128, 84, 16176, 81, 16224, 72, 16224, 77, 16224, 84, 16224, 89, 16272, 65, 16320, 60, 16320, 72, 16320, 76, 16320, 84, 16320, 88, 16368, 79, 16368, 86, 16416, 72, 16416, 76, 16416, 82, 16416, 86, 16464, 60, 16464, 81, 16464, 84, 16512, 58, 16512, 70, 16512, 74, 16512, 82, 16512, 86, 16560, 81, 16560, 82, 16560, 84, 16608, 70, 16608, 74, 16608, 81, 16608, 84, 16656, 58, 16656, 76, 16704, 65, 16704, 72, 16704, 77, 16704, 81, 16704, 84, 16752, 81, 16800, 72, 16800, 77, 16800, 79, 16800, 81, 16848, 77, 16848, 82, 16896, 65, 16896, 72, 16896, 77, 16896, 77, 16896, 84, 16944, 81, 16992, 72, 16992, 77, 16992, 81, 16992, 89, 17040, 65, 17088, 60, 17088, 72, 17088, 76, 17088, 82, 17088, 91, 17136, 79, 17136, 81, 17136, 89, 17184, 72, 17184, 76, 17184, 79, 17184, 88, 17232, 60, 17232, 77, 17232, 86, 17280, 58, 17280, 70, 17280, 74, 17280, 77, 17280, 86, 17328, 79, 17328, 82, 17328, 88, 17376, 70, 17376, 74, 17376, 81, 17376, 89, 17424, 58, 17424, 76, 17472, 65, 17472, 72, 17472, 77, 17472, 81, 17472, 89, 17520, 81, 17568, 65, 17568, 72, 17568, 77, 17568, 82, 17568, 91, 17616, 60, 17616, 84, 17616, 93, 17664, 58, 17664, 70, 17664, 74, 17664, 86, 17664, 94, 17712, 79, 17712, 86, 17712, 94, 17760, 58, 17760, 70, 17760, 74, 17760, 84, 17760, 93, 17808, 79, 17856, 60, 17856, 72, 17856, 76, 17856, 84, 17856, 91, 17904, 79, 17952, 60, 17952, 72, 17952, 76, 17952, 81, 17952, 89, 18000, 79, 18000, 82, 18000, 91, 18048, 65, 18048, 72, 18048, 77, 18048, 84, 18048, 93, 18096, 81, 18096, 84, 18096, 93, 18144, 64, 18144, 72, 18144, 77, 18144, 82, 18144, 91, 18192, 81, 18192, 89, 18240, 62, 18240, 74, 18240, 77, 18240, 81, 18240, 89, 18288, 81, 18336, 60, 18336, 74, 18336, 77, 18336, 79, 18336, 86, 18384, 77, 18384, 81, 18384, 84, 18432, 58, 18432, 70, 18432, 74, 18432, 77, 18432, 86, 18480, 79, 18480, 79, 18480, 89, 18528, 65, 18528, 70, 18528, 74, 18528, 81, 18528, 89, 18576, 79, 18576, 79, 18576, 88, 18624, 57, 18624, 69, 18624, 73, 18672, 79, 18672, 79, 18672, 88, 18720, 64, 18720, 69, 18720, 73, 18720, 81, 18720, 90, 18768, 79, 18768, 81, 18768, 90, 18816, 62, 18816, 69, 18864, 74, 18912, 78, 18960, 62, 18960, 74, 19008, 59, 19008, 71, 19056, 74, 19104, 78, 19152, 59, 19152, 74, 19200, 62, 19200, 69, 19248, 74, 19296, 78, 19344, 62, 19344, 74, 19392, 59, 19392, 71, 19440, 74, 19488, 78, 19536, 59, 19536, 74, 19584, 62, 19584, 69, 19632, 74, 19680, 78, 19728, 62, 19728, 74, 19776, 59, 19776, 71, 19824, 74, 19872, 78, 19920, 59, 19920, 74, 19968, 62, 19968, 69, 20016, 74, 20064, 78, 20112, 62, 20112, 74, 20160, 71, 20160, 71, 20160, 91, 20184, 91, 20208, 74, 20208, 90, 20256, 71, 20256, 78, 20256, 88, 20304, 69, 20304, 74, 20304, 88, 20352, 69, 20376, 90, 20400, 74, 20448, 78, 20496, 74, 20544, 71, 20592, 74, 20640, 78, 20688, 74, 20736, 69, 20784, 74, 20832, 78, 20880, 74, 20880, 81, 20928, 71, 20928, 91, 20976, 74, 20976, 90, 21024, 78, 21024, 88, 21072, 74, 21072, 88, 21120, 69, 21168, 74, 21216, 78, 21216, 90, 21264, 74, 21264, 86, 21312, 71, 21360, 74, 21408, 78, 21408, 88, 21456, 74, 21456, 81, 21504, 69, 21552, 74, 21600, 78, 21648, 74, 21696, 71, 21744, 74, 21792, 78, 21840, 74, 21888, 71, 21888, 88, 21936, 76, 21984, 79, 21984, 90, 22032, 76, 22032, 91, 22080, 71, 22128, 76, 22176, 79, 22176, 88, 22224, 76, 22272, 69, 22272, 85, 22320, 73, 22368, 79, 22368, 86, 22416, 73, 22416, 88, 22464, 69, 22512, 73, 22560, 79, 22560, 81, 22608, 73, 22608, 81, 22656, 69, 22704, 74, 22704, 90, 22752, 78, 22800, 74, 22848, 71, 22896, 74, 22944, 78, 22992, 74, 23040, 69, 23088, 74, 23136, 78, 23184, 74, 23232, 71, 23232, 91, 23232, 95, 23280, 74, 23280, 90, 23280, 93, 23328, 78, 23328, 88, 23328, 91, 23376, 74, 23376, 88, 23376, 91, 23424, 62, 23424, 69, 23436, 90, 23436, 93, 23472, 74, 23520, 78, 23568, 62, 23568, 74, 23616, 59, 23616, 71, 23664, 74, 23712, 78, 23760, 59, 23760, 74, 23808, 62, 23808, 69, 23856, 74, 23904, 78, 23952, 62, 23952, 74, 24000, 59, 24000, 71, 24000, 91, 24000, 95, 24048, 74, 24048, 90, 24048, 93, 24096, 78, 24096, 88, 24096, 91, 24144, 59, 24144, 74, 24144, 88, 24144, 91, 24192, 62, 24192, 69, 24240, 74, 24288, 78, 24288, 90, 24288, 93, 24336, 62, 24336, 74, 24336, 86, 24336, 90, 24384, 59, 24384, 71, 24432, 74, 24480, 78, 24480, 88, 24480, 91, 24528, 59, 24528, 74, 24528, 81, 24528, 86, 24576, 62, 24576, 69, 24624, 74, 24672, 78, 24720, 62, 24720, 74, 24768, 59, 24768, 71, 24816, 74, 24864, 78, 24912, 59, 24912, 74, 24960, 64, 24960, 71, 24960, 88, 25008, 76, 25056, 79, 25056, 90, 25104, 64, 25104, 76, 25104, 91, 25152, 64, 25152, 71, 25200, 66, 25200, 76, 25248, 67, 25248, 79, 25248, 88, 25296, 76, 25344, 57, 25344, 69, 25344, 85, 25392, 73, 25440, 79, 25440, 86, 25488, 57, 25488, 73, 25488, 88, 25536, 57, 25536, 69, 25584, 59, 25584, 73, 25584, 81, 25632, 61, 25632, 79, 25632, 86, 25680, 57, 25680, 73, 25680, 88, 25728, 58, 25728, 70, 25728, 89, 25776, 74, 25776, 88, 25824, 81, 25824, 86, 25872, 70, 25872, 77, 25872, 84, 25920, 81, 25968, 77, 26016, 70, 26016, 77, 26016, 81, 26016, 81, 26064, 57, 26064, 77, 26064, 79, 26064, 82, 26112, 65, 26112, 72, 26112, 77, 26112, 81, 26112, 84, 26160, 81, 26208, 72, 26208, 77, 26208, 84, 26208, 89, 26256, 65, 26304, 60, 26304, 72, 26304, 76, 26304, 84, 26304, 88, 26352, 79, 26352, 86, 26400, 72, 26400, 76, 26400, 82, 26400, 86, 26448, 60, 26448, 81, 26448, 84, 26496, 58, 26496, 70, 26496, 74, 26496, 82, 26496, 86, 26544, 81, 26544, 82, 26544, 84, 26592, 70, 26592, 74, 26592, 81, 26592, 84, 26640, 58, 26640, 76, 26688, 65, 26688, 72, 26688, 77, 26688, 81, 26688, 84, 26736, 81, 26784, 72, 26784, 77, 26784, 79, 26784, 81, 26832, 65, 26832, 77, 26832, 82, 26880, 65, 26880, 72, 26880, 77, 26880, 77, 26880, 84, 26928, 81, 26976, 72, 26976, 77, 26976, 81, 26976, 89, 27024, 65, 27072, 60, 27072, 72, 27072, 76, 27072, 82, 27072, 91, 27120, 79, 27120, 81, 27120, 89, 27168, 72, 27168, 76, 27168, 79, 27168, 88, 27216, 60, 27216, 77, 27216, 86, 27264, 58, 27264, 70, 27264, 74, 27264, 77, 27264, 86, 27312, 79, 27312, 82, 27312, 88, 27360, 70, 27360, 74, 27360, 81, 27360, 89, 27408, 58, 27408, 76, 27456, 65, 27456, 72, 27456, 77, 27456, 81, 27456, 89, 27504, 81, 27552, 65, 27552, 72, 27552, 77, 27552, 82, 27552, 91, 27600, 60, 27600, 84, 27600, 93, 27648, 58, 27648, 70, 27648, 74, 27648, 86, 27648, 94, 27696, 79, 27696, 86, 27696, 94, 27744, 58, 27744, 70, 27744, 74, 27744, 84, 27744, 93, 27792, 79, 27792, 91, 27840, 60, 27840, 72, 27840, 76, 27840, 84, 27840, 91, 27888, 79, 27936, 60, 27936, 72, 27936, 76, 27936, 81, 27936, 89, 27984, 79, 27984, 82, 27984, 91, 28032, 65, 28032, 72, 28032, 77, 28032, 84, 28032, 93, 28080, 81, 28080, 84, 28080, 93, 28128, 64, 28128, 72, 28128, 77, 28128, 82, 28128, 91, 28176, 81, 28176, 89, 28224, 62, 28224, 74, 28224, 77, 28224, 81, 28224, 89, 28272, 81, 28320, 60, 28320, 74, 28320, 77, 28320, 79, 28320, 86, 28368, 77, 28368, 81, 28368, 84, 28416, 58, 28416, 70, 28416, 74, 28416, 77, 28416, 86, 28464, 79, 28464, 79, 28464, 89, 28512, 65, 28512, 70, 28512, 74, 28512, 81, 28512, 89, 28560, 79, 28560, 79, 28560, 88, 28608, 57, 28608, 69, 28608, 73, 28656, 79, 28656, 79, 28656, 88, 28704, 64, 28704, 69, 28704, 73, 28704, 81, 28704, 90, 28752, 79, 28752, 81, 28752, 90, 28800, 62, 28800, 69, 28848, 74, 28896, 78, 28944, 62, 28944, 74, 28992, 59, 28992, 71, 29040, 74, 29088, 78, 29088, 93, 29136, 59, 29136, 74, 29136, 93, 29184, 62, 29184, 69, 29184, 95, 29232, 74, 29232, 93, 29280, 78, 29280, 90, 29328, 62, 29328, 74, 29328, 86, 29376, 59, 29376, 71, 29424, 74, 29424, 88, 29424, 91, 29472, 78, 29472, 90, 29472, 93, 29520, 59, 29520, 74, 29520, 90, 29520, 93, 29568, 62, 29568, 69, 29616, 74, 29664, 78, 29712, 62, 29712, 74, 29760, 59, 29760, 71, 29808, 74, 29808, 93, 29856, 78, 29856, 93, 29904, 59, 29904, 74, 29904, 93, 29952, 62, 29952, 69, 29952, 95, 30000, 74, 30000, 93, 30048, 78, 30048, 90, 30096, 62, 30096, 74, 30096, 86, 30144, 59, 30144, 71, 30192, 74, 30192, 88, 30192, 91, 30240, 78, 30240, 90, 30240, 93, 30288, 59, 30288, 74, 30288, 90, 30288, 93, 30336, 62, 30336, 69, 30384, 74, 30432, 78, 30480, 62, 30480, 74, 30528, 59, 30528, 71, 30576, 74, 30576, 93, 30624, 78, 30624, 93, 30672, 59, 30672, 74, 30672, 93, 30720, 62, 30720, 69, 30720, 95, 30768, 74, 30768, 93, 30816, 78, 30816, 90, 30864, 62, 30864, 74, 30864, 86, 30912, 59, 30912, 71, 30960, 74, 30960, 88, 30960, 91, 31008, 78, 31008, 90, 31008, 93, 31056, 59, 31056, 74, 31056, 90, 31056, 93, 31104, 62, 31104, 69, 31152, 74, 31200, 78, 31248, 62, 31248, 74, 31296, 59, 31296, 71, 31344, 74, 31392, 78, 31392, 93, 31440, 59, 31440, 74, 31440, 93, 31488, 62, 31488, 69, 31488, 95, 31536, 74, 31536, 93, 31584, 78, 31584, 90, 31632, 62, 31632, 74, 31632, 86, 31680, 59, 31680, 71, 31728, 74, 31728, 88, 31728, 91, 31776, 78, 31776, 90, 31776, 93, 31824, 59, 31824, 74, 31824, 90, 31824, 93, 31872, 62, 31872, 69, 31920, 74, 31968, 78, 32016, 62, 32016, 74, 32064, 59, 32064, 71, 32112, 74, 32112, 93, 32160, 78, 32160, 93, 32208, 59, 32208, 74, 32208, 93, 32256, 62, 32256, 69, 32256, 95, 32304, 74, 32304, 93, 32352, 78, 32352, 90, 32400, 62, 32400, 74, 32400, 86, 32448, 59, 32448, 71, 32496, 74, 32496, 88, 32496, 91, 32544, 78, 32544, 90, 32544, 93, 32592, 59, 32592, 74, 32592, 90, 32592, 93, 32640, 62, 32640, 69, 32688, 74, 32736, 78, 32784, 62, 32784, 74, 32832, 59, 32832, 71, 32880, 74, 32880, 91, 32928, 78, 32928, 93, 32976, 59, 32976, 74, 32976, 93, 33024, 62, 33024, 69, 33072, 74, 33120, 78, 33168, 62, 33168, 74, 33216, 71, 33216, 71, 33264, 74, 33264, 91, 33312, 71, 33312, 78, 33312, 90, 33360, 69, 33360, 74, 33360, 90, 33791, 0 // 176 seconds * 48 * 4 - 1 };

    synth.asm

    .cdecls C, LIST, "msp430fr5739.h" .text .def set_tick .def get_tick .def synth_init .def set_note .ref wave .bss tick, 2 .bss pwm_out, 2 .bss phase_inc, 6 * 8 ; Level ; Phase increment LSW/MSW (from note table) .bss phase_acc, 4 * 8 ; Phase accumulator LSW/MSW .def phase_inc set_tick: mov R12, &tick reta get_tick: mov &tick, R12 reta synth_init: mov #0x0210, &TA0CTL ; Timer A config: SMCLK, count up mov #749, &TA0CCR0 ; Setup Timer A period for 32000 sps mov #375, &TA0CCR1 ; Setup Timer A compare mov #0x00E0, &TA0CCTL1 ; Setup Timer A reset/set output mode ; mov #phase_inc, R12 ; Clear all phase inc and accum mov #5 * 16, R14 ; Word count clr 0(R12) ; Clear word incd R12 ; Next word dec R14 ; Dec word count jne $ - 8 ; Loop until all words done... ; eint ; Enable interupts bis #0x0010, &TA0CCTL0 ; Enable PWM interupt ; reta ; ; synth_isr: ; mov &pwm_out, &TA0CCR1 ; Output sample ; push R4 ; Wavetable pointer push R5 ; Phase increment / level pointer push R6 ; Phase accumulator pointer push R8 ; Wave sample pointer / next sample push R9 ; Wave sample push R10 ; Voice mix accumulator MSW push R11 ; Voice mix accumulator LSW ; mov #wave, R4 ; Setup wavetable pointer mov #phase_inc, R5 ; Setup phase increment and level pointer mov #phase_acc, R6 ; Setup phase accumulator pointer clr R10 ; Clear voice mix clr R11 ; voice_loop: ; .loop 8 mov @R6+, &MPYS32L ; Get phase acc LSW (fraction) to multiplier mov @R6+, R8 ; Get phase acc MSW (wave table index) ; bit #0xFF00, R8 ; Test phase acc MSB mov.b R8, R8 ; Clear MSB ;jeq no_decay ; jeq $ + 22 mov @R5, &MPY ; Get level mov #0xFF00, &OP2 ; Decay factor mov R8, -2(R6) ; Update phase acc mov &RES1, 0(R5) ; Update level ;no_decay: clr &MPYS32H ; add R8, R8 ; Make word index add R4, R8 ; Add wavetable pointer mov @R8+, R9 ; Get wave sample mov @R8, R8 ; Get next wave sample sub R9, R8 ; Calc delta mov R8, &OP2L ; Multiply by delta bit #0x8000, R8 ; Sign extend delta subc R8, R8 ; inv R8 ; mov R8, &OP2H ; add &RES1, R9 ; Add interpolation to sample mov R9, &MPYS ; Multiply by voice level mov @R5+, &OP2 ; add @R5+, -4(R6) ; Update phase acc addc @R5+, -2(R6) ; add &RES0, R11 ; Update mix addc &RES1, R10 ; ; .endloop ; swpb R10 ; Use MSB of R10 mov.b R10, R10 ; sxt R10 ; Sign extend add R10, R10 ; * 2 add #375, R10 ; Bias to center of PWM range mov R10, &pwm_out ; ; dec &tick ; jc $ + 6 ; clr &tick ; ; pop R11 ; pop R10 ; pop R9 ; pop R8 ; pop R6 ; pop R5 ; pop R4 ; reti ; ; set_note: ; mov R12, R15 ; Voice * 6 add R15, R12 ; (+1 = *2) add R15, R12 ; (+1 = *3) rla R12 ; (*2 = *6) add #phase_inc, R12 ; Add phase inc pointer mov R14, 0(R12) ; Set level cmp #128, R13 ; Out of range note values are note off jhs note_off ; clr R14 ; Clear octave count tst_note: ; cmp #116, R13 ; Within note table? jge get_pi ; Yes... inc R14 ; Inc octave count add #12, R13 ; Add octave to note jmp tst_note ; Check again... get_pi: ; Get phase increment sub #116, R13 ; Adjust for first note in table rla R13 ; MIDI note * 4 rla R13 ; add #notes, R13 ; Add note table pointer mov @R13+, R15 ; Get LSW mov @R13, R13 ; Get MSW tst R14 ; Shifting required? jeq set_phase ; No... shift_phase: ; rra R13 ; Shift phase inc rrc R15 ; dec R14 ; Dec octave count jne shift_phase ; Repeat until zero... set_phase: ; mov R15, 2(R12) ; Set phase inc mov R13, 4(R12) ; reta ; Return ; note_off: ; incd SP ; Discard level clr 0(R12) ; Clear phase inc clr 2(R12) ; .if 0 ; Note: Abrupt return to zero causes poping clr 4(R12) ; Clear level add #phase_acc - phase_inc, R12 ; Phase accum pointer clr 0(R12) ; Clear phase accum clr 2(R12) ; .endif ; reta ; Return ; ; notes ; MIDI Note Frequency .long 3483828 ; 116 G#8 6644.87457275391 .long 3690988 ; 117 A8 7040.00091552734 .long 3910465 ; 118 A#8 7458.62007141113 .long 4142993 ; 119 B8 7902.13203430176 .long 4389349 ; 120 C9 8372.01881408691 .long 4650353 ; 121 C#9 8869.84443664551 .long 4926877 ; 122 D9 9397.27210998535 .long 5219845 ; 123 D#9 9956.06422424316 .long 5530233 ; 124 E9 10548.0823516846 .long 5859077 ; 125 F9 11175.3025054932 .long 6207476 ; 126 F#9 11839.8208618164 .long 6576592 ; 127 G9 12543.8537597656 ; Interrupt Vectors .sect ".int53" ; TA0CCR0 CCIFG0 .short synth_isr ; ; .end ;
  22. Like
    SirZusa got a reaction from Kernald in TLC5940 - "Full Implementation"   
    hi there, as i already said in another thread i was working on the code for controlling the TLC5940. here it is!
     
    100% working. specification-sheet i used to code this: http://www.ti.com/lit/sw/slvc106/slvc106.pdf
     


    [*:1o0bnvvd]supports DC
    [*:1o0bnvvd]supports Grayscale
    [*:1o0bnvvd]recommendet implementation from the Programming Flow Chart
    [*:1o0bnvvd]does not support EEPROM-programming (cause you will need 22 Volts for this)
    [*:1o0bnvvd]actually does not support "Use DC from EEPROM-mode"
    [*:1o0bnvvd]LOD-Check not implemented for now ... but i think i will do this soon if i find more literature on this
     

    /*** TLC5940 ***/ #include "msp430g2553.h" #include "stdbool.h" // How many TLC's daisy-chained #define n 2 /*** Ports ***/ // STATUS-LED #define PORT_STATUS_LED P1OUT #define PIN_STATUS_LED BIT0 // BLANK - to pin 23 of every TLC5940 #define PORT_BLANK P1OUT #define PIN_BLANK BIT3 // XLAT - to pin 24 of every TLC5940 #define PORT_XLAT P1OUT #define PIN_XLAT BIT4 // SCLK - to pin 25 of every TLC5940 #define PORT_SCLK P1OUT #define PIN_SCLK BIT5 // SIN - to pin 26 of first TLC5940 #define PORT_SIN P1OUT #define PIN_SIN BIT6 // GSCLK - to pin 18 of every TLC5940 #define PORT_GSCLK P1OUT #define PIN_GSCLK BIT7 // DCPRG - to pin 19 of every TLC5940 #define PORT_DCPRG P2OUT #define PIN_DCPRG BIT3 // VPRG - to pin 27 of every TLC5940 #define PORT_VPRG P2OUT #define PIN_VPRG BIT4 /*** DO NOT EDIT BELOW ***/ #define x (n * 16) /*** Brightness-Correction ***/ const int pwm_table[256] = { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,26,28,30,32,34,36,38,40,42, 44,46,48,50,52,55,58,61,64,67,70,73,76,79,82,85,88,91,94,97,100,103,106,110,114,118,122,126,130, 134,138,142,146,150,154,158,162,166,170,174,178,182,186,190,195,200,205,210,215,220,225,230,235, 240,245,250,255,260,265,270,275,280,285,290,297,304,311,318,325,332,339,346,353,360,367,374,381, 388,395,402,409,416,423,430,437,444,451,458,467,476,485,494,503,512,521,530,539,548,557,566,575, 584,593,602,611,626,641,656,671,686,701,716,731,746,761,776,791,806,821,836,851,866,881,896,916, 936,956,976,996,1016,1036,1056,1076,1096,1116,1136,1156,1176,1196,1221,1246,1271,1296,1321,1346, 1371,1396,1421,1446,1471,1496,1526,1556,1586,1616,1646,1676,1706,1736,1766,1796,1826,1856,1886, 1921,1956,1991,2026,2061,2096,2131,2166,2201,2236,2271,2306,2341,2376,2411,2446,2481,2516,2551, 2586,2621,2656,2691,2726,2761,2796,2832,2868,2904,2940,2976,3012,3048,3084,3120,3156,3192,3228, 3266,3304,3342,3380,3418,3456,3494,3532,3572,3612,3652,3692,3737,3782,3827,3872,3917,3962,4007,4095 }; // holds the actual DC-data for each channel char dc_data[x] = {63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63}; /*** Variables ***/ // first PWM-cycle after Dot Correction Data has changed? bool FirstCycleFlag; // holds the actual PWM-data for each channel int gs_data[x]; /*** small userdefined Functions ***/ // useful macros #define setLow(port, pin) { port &= ~pin; } #define setHigh(port, pin) { port |= pin; } #define pulse(port, pin) { setHigh(port, pin); setLow(port, pin); } #define toggle(port, pin) { port ^= pin; } /*** transfer DC-data to our TLC5940's ***/ void send_DC() { // DCPRG - dont use DC-EEPROM setHigh(PORT_DCPRG, PIN_DCPRG); // VPRG - set Dot Correction Input setHigh(PORT_VPRG, PIN_VPRG); // Reset Counter int Counter = 0; // clock in Dot Correction Data for (; { // Counter > n * 96 - 1 // 6 Bits * 16 Channels = 96 if (Counter > (n * 96 - 1)) { pulse(PORT_XLAT, PIN_XLAT); break; } else { // Set SIN to DC Data[Counter] // MSB first if ((dc_data[Counter / 6] >> (5 - (Counter % 6))) & 0x01) { setHigh(PORT_SIN, PIN_SIN); } else { setLow(PORT_SIN, PIN_SIN); } pulse(PORT_SCLK, PIN_SCLK); Counter++; } } // dont save to EEPROM - so we finish here // set FirstCycleFlag to true FirstCycleFlag = true; } /*** transfer PWM-data to our TLC5940's ***/ void send_GS() { if (FirstCycleFlag == true) { setLow(PORT_VPRG, PIN_VPRG); } // Reset Counters int GSCLK_Counter = 0; int Data_Counter = 0; setLow(PORT_BLANK, PIN_BLANK); // clock in PWM Data for (; { if (GSCLK_Counter > 4095) { setHigh(PORT_BLANK, PIN_BLANK); pulse(PORT_XLAT, PIN_XLAT); if (FirstCycleFlag == true) { pulse(PORT_SCLK, PIN_SCLK); } FirstCycleFlag = false; break; } else { // 12 Bit * 16 Channels = 192 if (Data_Counter > (n * 192 - 1)) { pulse(PORT_GSCLK, PIN_GSCLK); GSCLK_Counter++; } else { // Set SIN to GS Data[Counter] // MSB first if ((gs_data[Data_Counter / 12] >> (11 - (Data_Counter % 12))) & 0x01) { setHigh(PORT_SIN, PIN_SIN); } else { setLow(PORT_SIN, PIN_SIN); } pulse(PORT_SCLK, PIN_SCLK); Data_Counter++; pulse(PORT_GSCLK, PIN_GSCLK); GSCLK_Counter++; } } } } /*** Our main program ***/ void main(void) { // stop WDT - WDTPW is the password needed for every write and then tell watchdog to hold WDTCTL = WDTPW | WDTHOLD; BCSCTL1 = CALBC1_16MHZ; DCOCTL = CALDCO_16MHZ; // initialize the ports connected to the TLC's // set ports to output-direction P1DIR |= (PIN_STATUS_LED|PIN_BLANK|PIN_XLAT|PIN_SCLK|PIN_SIN|PIN_GSCLK); P1OUT = 0x00; P2DIR |= (PIN_DCPRG|PIN_VPRG); P2OUT = 0x00; // initialize TLC5940 setLow(PORT_GSCLK, PIN_GSCLK); setLow(PORT_SCLK, PIN_SCLK); setLow(PORT_DCPRG, PIN_DCPRG); setHigh(PORT_VPRG, PIN_VPRG); setLow(PORT_XLAT, PIN_XLAT); setHigh(PORT_BLANK, PIN_BLANK); // force first cycle send_DC(); send_GS(); // enable interrupts __bis_SR_register(GIE); while(1) { // load gs-data here // update PWM-data permanently send_GS(); } }
  23. Like
    SirZusa got a reaction from bluehash in TSSOP28 / TSSOP38 breakout-board (breadboard-compatible)   
    i finally finished the breakoutboard supporting TSSOP28 to TSSOP38 on the front with bigger solderpads - and i made the backside for LQFP32
     

    Breakout.brd
  24. Like
    SirZusa got a reaction from GeekDoc in TSSOP28 / TSSOP38 breakout-board (breadboard-compatible)   
    i finally finished the breakoutboard supporting TSSOP28 to TSSOP38 on the front with bigger solderpads - and i made the backside for LQFP32
     

    Breakout.brd
  25. Like
    SirZusa got a reaction from lastaid in TLC5940 - "Full Implementation"   
    hi there, as i already said in another thread i was working on the code for controlling the TLC5940. here it is!
     
    100% working. specification-sheet i used to code this: http://www.ti.com/lit/sw/slvc106/slvc106.pdf
     


    [*:1o0bnvvd]supports DC
    [*:1o0bnvvd]supports Grayscale
    [*:1o0bnvvd]recommendet implementation from the Programming Flow Chart
    [*:1o0bnvvd]does not support EEPROM-programming (cause you will need 22 Volts for this)
    [*:1o0bnvvd]actually does not support "Use DC from EEPROM-mode"
    [*:1o0bnvvd]LOD-Check not implemented for now ... but i think i will do this soon if i find more literature on this
     

    /*** TLC5940 ***/ #include "msp430g2553.h" #include "stdbool.h" // How many TLC's daisy-chained #define n 2 /*** Ports ***/ // STATUS-LED #define PORT_STATUS_LED P1OUT #define PIN_STATUS_LED BIT0 // BLANK - to pin 23 of every TLC5940 #define PORT_BLANK P1OUT #define PIN_BLANK BIT3 // XLAT - to pin 24 of every TLC5940 #define PORT_XLAT P1OUT #define PIN_XLAT BIT4 // SCLK - to pin 25 of every TLC5940 #define PORT_SCLK P1OUT #define PIN_SCLK BIT5 // SIN - to pin 26 of first TLC5940 #define PORT_SIN P1OUT #define PIN_SIN BIT6 // GSCLK - to pin 18 of every TLC5940 #define PORT_GSCLK P1OUT #define PIN_GSCLK BIT7 // DCPRG - to pin 19 of every TLC5940 #define PORT_DCPRG P2OUT #define PIN_DCPRG BIT3 // VPRG - to pin 27 of every TLC5940 #define PORT_VPRG P2OUT #define PIN_VPRG BIT4 /*** DO NOT EDIT BELOW ***/ #define x (n * 16) /*** Brightness-Correction ***/ const int pwm_table[256] = { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,26,28,30,32,34,36,38,40,42, 44,46,48,50,52,55,58,61,64,67,70,73,76,79,82,85,88,91,94,97,100,103,106,110,114,118,122,126,130, 134,138,142,146,150,154,158,162,166,170,174,178,182,186,190,195,200,205,210,215,220,225,230,235, 240,245,250,255,260,265,270,275,280,285,290,297,304,311,318,325,332,339,346,353,360,367,374,381, 388,395,402,409,416,423,430,437,444,451,458,467,476,485,494,503,512,521,530,539,548,557,566,575, 584,593,602,611,626,641,656,671,686,701,716,731,746,761,776,791,806,821,836,851,866,881,896,916, 936,956,976,996,1016,1036,1056,1076,1096,1116,1136,1156,1176,1196,1221,1246,1271,1296,1321,1346, 1371,1396,1421,1446,1471,1496,1526,1556,1586,1616,1646,1676,1706,1736,1766,1796,1826,1856,1886, 1921,1956,1991,2026,2061,2096,2131,2166,2201,2236,2271,2306,2341,2376,2411,2446,2481,2516,2551, 2586,2621,2656,2691,2726,2761,2796,2832,2868,2904,2940,2976,3012,3048,3084,3120,3156,3192,3228, 3266,3304,3342,3380,3418,3456,3494,3532,3572,3612,3652,3692,3737,3782,3827,3872,3917,3962,4007,4095 }; // holds the actual DC-data for each channel char dc_data[x] = {63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63}; /*** Variables ***/ // first PWM-cycle after Dot Correction Data has changed? bool FirstCycleFlag; // holds the actual PWM-data for each channel int gs_data[x]; /*** small userdefined Functions ***/ // useful macros #define setLow(port, pin) { port &= ~pin; } #define setHigh(port, pin) { port |= pin; } #define pulse(port, pin) { setHigh(port, pin); setLow(port, pin); } #define toggle(port, pin) { port ^= pin; } /*** transfer DC-data to our TLC5940's ***/ void send_DC() { // DCPRG - dont use DC-EEPROM setHigh(PORT_DCPRG, PIN_DCPRG); // VPRG - set Dot Correction Input setHigh(PORT_VPRG, PIN_VPRG); // Reset Counter int Counter = 0; // clock in Dot Correction Data for (; { // Counter > n * 96 - 1 // 6 Bits * 16 Channels = 96 if (Counter > (n * 96 - 1)) { pulse(PORT_XLAT, PIN_XLAT); break; } else { // Set SIN to DC Data[Counter] // MSB first if ((dc_data[Counter / 6] >> (5 - (Counter % 6))) & 0x01) { setHigh(PORT_SIN, PIN_SIN); } else { setLow(PORT_SIN, PIN_SIN); } pulse(PORT_SCLK, PIN_SCLK); Counter++; } } // dont save to EEPROM - so we finish here // set FirstCycleFlag to true FirstCycleFlag = true; } /*** transfer PWM-data to our TLC5940's ***/ void send_GS() { if (FirstCycleFlag == true) { setLow(PORT_VPRG, PIN_VPRG); } // Reset Counters int GSCLK_Counter = 0; int Data_Counter = 0; setLow(PORT_BLANK, PIN_BLANK); // clock in PWM Data for (; { if (GSCLK_Counter > 4095) { setHigh(PORT_BLANK, PIN_BLANK); pulse(PORT_XLAT, PIN_XLAT); if (FirstCycleFlag == true) { pulse(PORT_SCLK, PIN_SCLK); } FirstCycleFlag = false; break; } else { // 12 Bit * 16 Channels = 192 if (Data_Counter > (n * 192 - 1)) { pulse(PORT_GSCLK, PIN_GSCLK); GSCLK_Counter++; } else { // Set SIN to GS Data[Counter] // MSB first if ((gs_data[Data_Counter / 12] >> (11 - (Data_Counter % 12))) & 0x01) { setHigh(PORT_SIN, PIN_SIN); } else { setLow(PORT_SIN, PIN_SIN); } pulse(PORT_SCLK, PIN_SCLK); Data_Counter++; pulse(PORT_GSCLK, PIN_GSCLK); GSCLK_Counter++; } } } } /*** Our main program ***/ void main(void) { // stop WDT - WDTPW is the password needed for every write and then tell watchdog to hold WDTCTL = WDTPW | WDTHOLD; BCSCTL1 = CALBC1_16MHZ; DCOCTL = CALDCO_16MHZ; // initialize the ports connected to the TLC's // set ports to output-direction P1DIR |= (PIN_STATUS_LED|PIN_BLANK|PIN_XLAT|PIN_SCLK|PIN_SIN|PIN_GSCLK); P1OUT = 0x00; P2DIR |= (PIN_DCPRG|PIN_VPRG); P2OUT = 0x00; // initialize TLC5940 setLow(PORT_GSCLK, PIN_GSCLK); setLow(PORT_SCLK, PIN_SCLK); setLow(PORT_DCPRG, PIN_DCPRG); setHigh(PORT_VPRG, PIN_VPRG); setLow(PORT_XLAT, PIN_XLAT); setHigh(PORT_BLANK, PIN_BLANK); // force first cycle send_DC(); send_GS(); // enable interrupts __bis_SR_register(GIE); while(1) { // load gs-data here // update PWM-data permanently send_GS(); } }
×
×
  • Create New...