Jump to content
43oh

jsolarski

Members
  • Content Count

    568
  • Joined

  • Last visited

  • Days Won

    8

Reputation Activity

  1. Like
    jsolarski reacted to spirilis in Charcoal Grill / Smoker Monitor   
    Ok so this is my inaugural MSP430 project, i.e. the first legitimately useful thing I've built since buying a LaunchPad.
     
    One of my bosses at work asked me, after I babbled on about my Arduino work et al, "So what would it take for me to get text messages when my Big Green Egg is done cooking my pork shoulder roast?"
     
    As it turns out, there are commercial solutions out there which will not only monitor your grill & roast temperatures--but also CONTROL them through some sort of fan mounted on a custom fan shroud that replaces the air inlet draft door. These solutions all cost $300+, usually $400-600 for the automated control ones, so I figured there's room for improvement on the price point and DIY'ability of this.
    These solutions also seem to require AC power (or AC adapter) of some sort, and I didn't look to see if there was much weatherproofing of that.
     
    So I devised a couple requirements of my own:
    1. This solution must be an appliance, permanently installed and able to withstand the elements. Maryland doesn't get anything too extreme, maybe 5F (-15C) temps in the depths of winter and upwards of 105F (40C) temps at the peak of summer. Variable rain, snow, ice. I maintain this requirement because I hate dragging gadgets out to plug in/set up when I already have a zillion small tasks in my head.
    2. This solution needs to come in at under $200 for everything.
    3. There should be an expansion capability built in for adding other stuff--like the ability to control a draft fan, or the ability to show the grill + meat temperatures on some sort of portable display (besides a cellphone)
    4. There needs to be Internet capability, even if it's through a stationary PC or Mac that talks to a base station MSP430.
     
    What I came up with was a solution based on the MSP430 Value Line chips, Nordic Semiconductor nRF24L01+ transceivers and Maxim MAX31855 digital thermocouple readers. A base station composed of a LaunchPad board with Nordic nRF24L01+ boosterpack (bonus also includes FTDI 6-pin pinout for high speed serial) comprises the internal half of the solution, and software running on a PC/Mac (currently a Linux server) does the dirty Internet work.
     
    THERMOCOUPLE SENDER UNIT
    The exterior unit that is hardened to the elements/etc. is a custom PCB (OSHpark.com) with an MSP430G2452 TSSOP chip, two MAX31855's, two screw terminals, a Nordic nRF24L01+ board bought off eBay for $2 and some power regulation hardware to take two AA batteries and generate a fairly clean 3.3V rail (required by the MAX31855's, it can't go down to 1.8-2.0V like the MSP430 and nRF24 can...).
    The board was designed to fit inside an enclosure sold by Polycase -- the WC-22F (http://www.polycase.com/wc-22f) -- with a cable gland installed in the side to feed the thermocouple leads while maintaining the watertightness of the enclosure.
     
    Pic of the external unit installed:

     
    The bottom side of the PCB with the MSP430:

     
    Schematic - DipTrace_Schematic_-_GrillMonitor_draft6.pdf
    Gerber files (OSHpark ready to use) - GrillMon_ExtSenderUnit_43oh.zip
     
    Thermocouples I ended up using - http://www.auberins....e5b2d83c4c4407a
     
     
     
    GRILL MONITOR BASE STATION
    The main requirements for the base station is some way to talk to a PC and some way to receive the RF information from the external sending unit. A $4.30 LaunchPad board works fine for this with a custom boosterpack to attach a nRF24L01+ breakout board. I tossed in an FTDI pinout just in case I was having trouble with the LaunchPad's application UART, which ended up being the case (the Linux driver I found for cdc-acm kernel panics my server after a day or 2 of use).
     
    Pic of the LP + boosterpack (note- I used an nRF24L01+ module with an RP-SMA antenna, it cost around $12 vs the $2 for the PCB trace version).

     
    Schematic of the BoosterPack - DipTrace_Schematic_-_GrillMonitor_BaseStn_draft4.pdf
    Gerber files (OSHpark ready to use) - GrillMon_BaseStation_43oh.zip
     
     
     
    CODE
     
    I went ahead and took a current snapshot of my work (I am using git, but, don't have it up on github yet) and here it is:
    http://spirilis.net/...urce-0.1.tar.gz
     
    Note this includes 2 libraries I wrote, "msprf24" -- http://github.com/spirilis/msprf24 and mspuartcli -- http://github.com/spirilis/mspuartcli
    The latter library I wrote in a hurry, debugged it a bit here and there, but frankly it could use some improvement (e.g. toss the print functions and just use oPossum's printf() implementation). It does work however!
     
    I'll go ahead and include some of the main code for the external sensor unit:
     
    tcsender.h -- header info for tcsender main prog

    /* tcsender.h * * Main program - exported global variables and #define constants */ #ifndef TCSENDER_H #define TCSENDER_H /* Sleep interval between thermocouple reads; in units of 46ms */ // Set to 2 minutes (2608*46ms) #define SLEEP_INTERVAL_BETWEEN_TC_READS 2608 /* RX window after a thermocouple read; a back-window to receive GPIO updates from the base station */ // Set to ~322ms (7*46ms) #define SLEEP_INTERVAL_RX_BACKWINDOW 7 // Interval between LED test polls #define SLEEP_INTERVAL_TEST_POLLS 4 // Number of attempts to send packet (multiply this times 30ms each, which constitutes 15 retries each) #define RETRY_ATTEMPTS 32 // nRF24L01+ RF channel & speed #define RF_CHANNEL 10 #define RF_SPEED RF24_SPEED_MIN // Protocol device IDs (not RFaddr, used to uniquely identify different thermocouple devices) #define DEVICE_ID 0x01 #define DEVICE_ID_TC1 0x01 #define DEVICE_ID_TC2 0x02 // Test LEDs #define LED_RED_PORTOUT P2OUT #define LED_RED_PORT BIT6 #define LED_GREEN_PORTOUT P2OUT #define LED_GREEN_PORT BIT7 // Thermocouple control & SPI #define TC_MOSFET_PORTOUT P2OUT #define TC_MOSFET_PORT BIT0 #define TC1_CS_PORTOUT P1OUT #define TC1_CS_PORT BIT3 #define TC2_CS_PORTOUT P1OUT #define TC2_CS_PORT BIT4 // External GPIO ports #define GPIO_1_PORTOUT P2OUT #define GPIO_1_PORT BIT1 #define GPIO_2_PORTOUT P2OUT #define GPIO_2_PORT BIT3 #define EXTSPI_CS1_PORTOUT P2OUT #define EXTSPI_CS1_PORT BIT2 #define EXTSPI_CS2_PORTOUT P2OUT #define EXTSPI_CS2_PORT BIT4 // Test mode jumper input pin #define TEST_MODE_PORTIN P2IN #define TEST_MODE_PORT BIT5 #endif
     
    TCsender main() function -- main.c:

    /* TCsender * * Grill Monitor/Remote Thermocouple Sensor Unit * Main code * * Provides data from 2 thermocouples over an nRF24L01+ transceiver to * a Base Station which should be listening. Base Station is also * relied upon for RF test data, and in TEST mode this unit will frequently * request Test LED information from the base to reflect on this unit's red LED. * * Designed for the Texas Instruments MSP430 G2452 Value Line microcontroller * with a Nordic Semiconductor nRF24L01+ attached to the USI port. * * Thermocouple data is accessed via a pair of Maxim MAX31855K digital thermocouple * amplifiers accessed over the same USI SPI port; power to the MAX31855's are enabled * or disabled using a MOSFET controlled by one of the MSP430's pins. * * Utilizes VLOCLK as a timer for scheduling thermocouple-read events and Test LED * packet requests during TEST mode. */ #include <msp430.h> #include "tcsender.h" #include "packet_processor.h" #include "nrf_userconfig.h" #include "msprf24.h" #include <sys/cdefs.h> #include <string.h> const char tcsender_rxaddr[] = {0xDE, 0xAD, 0xBE, 0xEF, 0x02}; const char tcsender_dummyaddr[] = {0x00, 0x00, 0x00, 0x00, 0x00}; const char basestation_rxaddr[] = {0xDE, 0xAD, 0xBE, 0xEF, 0x01}; volatile unsigned int sleep_counter, rx_waitack; unsigned int tcread_count, txfail_count; char rfbuf[32]; // Sharing this with test_mode_main // Function prototypes void test_mode_main(); void thermocouple_wakeup(); void thermocouple_sleep(); char thermocouple_read(char tcid, struct packet_task *taskbuf); void debug_packet(struct packet_task *taskbuf); void wdt_suspend(); void wdt_unsuspend(); // Main program int main() { char task_rxwindow_after_txack, txretry_count, txretry_latch; char do_lpm; int i; char pipeid, pktlen; WDTCTL = WDTPW | WDTHOLD; DCOCTL = CALDCO_16MHZ; BCSCTL1 = CALBC1_16MHZ; BCSCTL2 = DIVS_2; // SMCLK = DCOCLK/4, or 4MHz /* nRF24L01+ supports up to 10MHz, but the MAX31855 * only supports 5MHz SPI. */ BCSCTL3 = LFXT1S_2; // ACLK = VLOCLK while (BCSCTL3 & LFXT1OF) ; // Wait until the VLOCLK is up, running & stable /* Initialize/reset all I/O ports */ P1DIR = 0x00; P1OUT = 0x00; P1SEL = 0x00; P1SEL2 = 0x00; P1REN = 0x00; P1IFG = 0x00; P1IE = 0x00; P2DIR = 0x00; P2OUT = 0x00; P2SEL = 0x00; P2SEL2 = 0x00; P2REN = 0x00; P2IFG = 0x00; P2IE = 0x00; /* Init I/O ports for application use */ // Test LEDs P2DIR |= LED_RED_PORT | LED_GREEN_PORT; // Thermocouple Vcc MOSFET & SPI CS lines--turn on initially so nRF24 init can occur P2DIR |= TC_MOSFET_PORT; TC_MOSFET_PORTOUT &= ~TC_MOSFET_PORT; // LOW=on P1DIR |= TC1_CS_PORT | TC2_CS_PORT; TC1_CS_PORTOUT |= TC1_CS_PORT; TC2_CS_PORTOUT |= TC2_CS_PORT; // External GPIO & SPI CS ports P2DIR |= GPIO_1_PORT | GPIO_2_PORT | EXTSPI_CS1_PORT | EXTSPI_CS2_PORT; // Test mode jumper input pin P2OUT |= TEST_MODE_PORT; // Pull-up enabled P2REN |= TEST_MODE_PORT; P2IES |= TEST_MODE_PORT; // Interrupt on falling-edge P2IE |= TEST_MODE_PORT; // nRF24L01+ configuration & initialization rf_crc = RF24_EN_CRC | RF24_CRCO; // CRC enabled, 16-bit rf_addr_width = 5; rf_speed_power = RF_SPEED | RF24_POWER_MAX; // RF_SPEED from tcsender.h rf_channel = RF_CHANNEL; // This #define is located in tcsender.h msprf24_init(); msprf24_open_pipe(0, 1); // Open pipe#0 with Enhanced ShockBurst for receiving Auto-ACKs msprf24_open_pipe(1, 1); // Pipe#1 is the primary receiver for base->slave traffic msprf24_set_pipe_packetsize(0, 0); // Dynamic packet sizes msprf24_set_pipe_packetsize(1, 0); // Dynamic packet sizes w_rx_addr(0, (char*)tcsender_dummyaddr); w_rx_addr(1, (char*)tcsender_rxaddr); // For receiving base->slave packets // Now that the nRF24 module has been initialized, we can shut off the TC amps. thermocouple_sleep(); // Set up WDT interval timer as a scheduler sleep_counter = 0; WDTCTL = WDT_ADLY_16; // 46ms per overflow with VLOCLK IFG1 &= ~WDTIFG; IE1 |= WDTIE; // Main loop task_rxwindow_after_txack = 0; rx_waitack = 0; txretry_count = 0; txretry_latch = 0; tcread_count = 0; txfail_count = 0; while (1) { do_lpm = 1; // Handle RF acknowledgements & RX packets if (rf_irq & RF24_IRQ_FLAGGED) { msprf24_get_irq_reason(); // Handle TX acknowledgements if (rf_irq & RF24_IRQ_TX) { // Acknowledge msprf24_irq_clear(RF24_IRQ_TX); flush_tx(); // Load dummy address into pipe#0 w_rx_addr(0, (char*)tcsender_dummyaddr); // Shut off green LED to indicate we're finished LED_GREEN_PORTOUT &= ~LED_GREEN_PORT; txretry_count = 0; // Reset this txretry_latch = 0; } if (rf_irq & RF24_IRQ_TXFAILED) { // Acknowledge msprf24_irq_clear(RF24_IRQ_TXFAILED); // If we have not exhausted our txretry_count's, resubmit the packet. if (txretry_count) { txretry_count--; if (!txretry_latch) { txretry_latch = 1; tx_reuse_lastpayload(); } pulse_ce(); } else { flush_tx(); w_rx_addr(0, (char*)tcsender_dummyaddr); LED_GREEN_PORTOUT &= ~LED_GREEN_PORT; txretry_latch = 0; } txfail_count++; } // Handle RX packets if (rf_irq & RF24_IRQ_RX) { pktlen = r_rx_peek_payload_size(); pipeid = r_rx_payload(pktlen, rfbuf); msprf24_irq_clear(RF24_IRQ_RX); /* Ignore any 0-byte receives, and we only care * about packets coming for pipe#1 */ if (pktlen && pipeid == 1) { for (i=0; i<pktlen; i++) { if (rfbuf[i]) { // Only process this packet if the length does not send us past the buffer! // (otherwise this would make an easy buffer overflow attack vector) if ((i + (unsigned char)rfbuf[i+1] + 1) < pktlen) { packet_processor((unsigned char)rfbuf[i], (unsigned char)rfbuf[i+1], &rfbuf[i+2]); i += (unsigned char)rfbuf[i+1] + 1; } } } } rx_waitack = 1; } /* If a TX acknowledgement occurred and we just sent thermocouple data, enable * a short RX backwindow */ if (task_rxwindow_after_txack && (rf_irq & (RF24_IRQ_TX|RF24_IRQ_TXFAILED)) && !txretry_count) { sleep_counter = SLEEP_INTERVAL_RX_BACKWINDOW; msprf24_activate_rx(); // Switch on green LED to indicate we're actively using RF LED_GREEN_PORTOUT |= LED_GREEN_PORT; } do_lpm = 0; // Prefer to always loop once more after handling nRF24 events } // Check for TEST mode (active=LOW) if ( !(TEST_MODE_PORTIN & TEST_MODE_PORT) ) { // Mandatory 92ms debounce period int old_sleep_counter = sleep_counter - 2; sleep_counter = 2; while(sleep_counter) LPM3; if ( !(TEST_MODE_PORTIN & TEST_MODE_PORT) ) { flush_tx(); flush_rx(); thermocouple_wakeup(); test_mode_main(); sleep_counter = 0; // Force an immediate thermocouple read upon leaving Test Mode } else { if (old_sleep_counter > 0) /* Restore deep-sleep counter in case the TEST line gets flappy so we don't * waste too much power with this crap */ sleep_counter = old_sleep_counter; } } // Did we just finish a long sleep-between-TC-read? if (!sleep_counter) { // Is this the end of the RX-backwindow-after-TX? if (task_rxwindow_after_txack) { msprf24_powerdown(); flush_tx(); flush_rx(); msprf24_irq_clear(RF24_IRQ_MASK); LED_GREEN_PORTOUT &= ~LED_GREEN_PORT; // Shut off green LED to indicate we're not listening anymore thermocouple_sleep(); /* This is the safest time to shut off the TC amplifiers, since we're * done all SPI I/O now. */ task_rxwindow_after_txack = 0; sleep_counter = SLEEP_INTERVAL_BETWEEN_TC_READS; } else { // Wake everyone up and perform a TC read! thermocouple_wakeup(); msprf24_standby(); tcread_count++; // Perform TC read, append TX packet tasks struct packet_task tcpkt; if (thermocouple_read(DEVICE_ID_TC1, &tcpkt)) packet_task_append(&tcpkt); if (thermocouple_read(DEVICE_ID_TC2, &tcpkt)) packet_task_append(&tcpkt); debug_packet(&tcpkt); packet_task_append(&tcpkt); // TC packet will be sent shortly after this with packet_process_txqueue() /* Flag the nRF24 IRQ handler that we should enable a 322ms RX window * once this transmission has acknowledged. */ task_rxwindow_after_txack = 1; // Attempt to retransmit for at least 1/2 second before giving up txretry_count = RETRY_ATTEMPTS; } } if (packet_task_next() != NULL) { if (!rx_waitack) { if (packet_process_txqueue()) // Switch on Green LED to indicate we have a transmission in progress LED_GREEN_PORTOUT |= LED_GREEN_PORT; } } if (do_lpm) { LPM3; } } return 0; // This should cause a reset, but it should never be reached. } volatile unsigned int tx_count; void test_mode_main() { char do_lpm; int i; struct packet_task txpkt, *pt; char pipeid, pktlen; LED_RED_PORTOUT &= ~LED_RED_PORT; LED_GREEN_PORTOUT &= ~LED_GREEN_PORT; tx_count = 0; sleep_counter = 0; // Alternative main loop for when the TEST jumper is active. (active=LOW) while ( !(TEST_MODE_PORTIN & TEST_MODE_PORT) ) { do_lpm = 1; if (rf_irq & RF24_IRQ_FLAGGED) { msprf24_get_irq_reason(); if (rf_irq & (RF24_IRQ_TX|RF24_IRQ_TXFAILED)) { msprf24_irq_clear(RF24_IRQ_TX|RF24_IRQ_TXFAILED); flush_tx(); w_rx_addr(0, (char*)tcsender_dummyaddr); msprf24_activate_rx(); LED_GREEN_PORTOUT &= ~LED_GREEN_PORT; tx_count++; // just used for debugging } if (rf_irq & RF24_IRQ_RX) { // Read packet & process pktlen = r_rx_peek_payload_size(); pipeid = r_rx_payload(pktlen, rfbuf); msprf24_irq_clear(RF24_IRQ_RX); /* Ignore any 0-byte receives, and we only care * about packets coming for pipe#1 */ i = 0; if (pktlen && pipeid == 1) { for (i=0; i<pktlen; i++) { if (rfbuf[i]) { // Only process this packet if the length does not send us past the buffer! // (otherwise this would make an easy buffer overflow attack vector) if ((i + (unsigned char)rfbuf[i+1] + 1) < pktlen) { packet_processor((unsigned char)rfbuf[i], (unsigned char)rfbuf[i+1], &rfbuf[i+2]); i += (unsigned char)rfbuf[i+1] + 1; } } } } } do_lpm = 0; } if (!sleep_counter) { // Send Test LED Request packet txpkt.program = 0x02; txpkt.size = 6; memcpy(&(txpkt.rfaddr[0]), basestation_rxaddr, 5); txpkt.data[0] = DEVICE_ID; memcpy(&(txpkt.data[1]), tcsender_rxaddr, 5); packet_task_append(&txpkt); sleep_counter = SLEEP_INTERVAL_TEST_POLLS; } if (!(rf_irq & RF24_IRQ_FLAGGED) && (pt = packet_task_next()) != NULL) { if (packet_process_txqueue()) LED_GREEN_PORTOUT |= LED_GREEN_PORT; } if (do_lpm) LPM3; } msprf24_standby(); // Leave the calling function in a powered-on standby state msprf24_irq_clear(RF24_IRQ_MASK); // Clear any outstanding TX packets, queues or IRQs flush_tx(); flush_rx(); packet_init_tasklist(); LED_RED_PORTOUT &= ~LED_RED_PORT; LED_GREEN_PORTOUT &= ~LED_GREEN_PORT; } void thermocouple_wakeup() { // Activate Thermocouple Amplifiers TC_MOSFET_PORTOUT &= ~TC_MOSFET_PORT; TC1_CS_PORTOUT |= TC1_CS_PORT; TC2_CS_PORTOUT |= TC2_CS_PORT; // Wait over 200ms for the first valid results to come in (BLOCKING SLEEP) sleep_counter = 6; while (sleep_counter) LPM3; } void thermocouple_sleep() { // Deactivate thermocouple amplifiers TC_MOSFET_PORTOUT |= TC_MOSFET_PORT; // Shut off SPI CS lines to avoid parasitic power TC1_CS_PORTOUT &= ~TC1_CS_PORT; TC2_CS_PORTOUT &= ~TC2_CS_PORT; /* Note that the SPI SCLK pin will still provide some parasitic power so long as we're * doing SPI communication. Cleanest way to resolve this is to avoid calling this function * until we're done all SPI I/O and are ready to go into deep sleep for a while. */ } char thermocouple_read(char tcid, struct packet_task *taskbuf) { unsigned int tcread[2]; int temp; unsigned char portbit; switch (tcid) { case DEVICE_ID_TC1: portbit = TC1_CS_PORT; break; case DEVICE_ID_TC2: portbit = TC2_CS_PORT; break; default: return 0; } taskbuf->program = 0x10; taskbuf->size = 6; taskbuf->data[0] = tcid; memcpy(&taskbuf->rfaddr[0], basestation_rxaddr, 5); // SPI I/O TC1_CS_PORTOUT &= ~portbit; tcread[0] = spi_transfer16(0xFFFF); tcread[1] = spi_transfer16(0xFFFF); TC1_CS_PORTOUT |= portbit; // Interpret numbers into degrees C for TC temp temp = (int) ((tcread[0] & 0xFFF0) >> 4); if (temp & 0x0800) temp |= 0xF000; // Properly sign-extend negative values memcpy(&(taskbuf->data[1]), &temp, sizeof(int)); // Interpret numbers into degrees C for Ambient temp temp = (int) ((tcread[1] & 0xFF00) >> 8); if (temp & 0x0080) temp |= 0xFF00; // Properly sign-extend negative values memcpy(&(taskbuf->data[3]), &temp, sizeof(int)); // Interpret fault codes taskbuf->data[5] = 0; if (tcread[1] & 0x0001) // Open circuit taskbuf->data[5] = 1; if (tcread[1] & 0x0002) // Short to GND taskbuf->data[5] = 3; if (tcread[1] & 0x0004) // Short to +Vcc taskbuf->data[5] = 2; return 1; } void debug_packet(struct packet_task *taskbuf) { unsigned char *devidptr = (unsigned char *) &(taskbuf->data[0]); /* making sure the (unsigned) DEVID isn't clobbered by the * signed char nature of the data[] array */ *devidptr = DEVICE_ID; memcpy(&(taskbuf->data[1]), &tcread_count, 2); // # times we've woken up to read/xmit the thermocouple data memcpy(&(taskbuf->data[3]), &txfail_count, 2); // # times we've seen a TXFAILED IRQ memcpy(&(taskbuf->data[5]), &devidptr, 2); // Stack address of the devidptr variable created here, to watch/detect memory leaks taskbuf->program = 0xFE; taskbuf->size = 7; memcpy(&taskbuf->rfaddr[0], basestation_rxaddr, 5); } void wdt_suspend() { IE1 &= ~WDTIE; } void wdt_unsuspend() { IE1 |= WDTIE; } // WDT overflow/timer #pragma vector=WDT_VECTOR __interrupt void WDT_ISR(void) { IFG1 &= ~WDTIFG; if (rx_waitack) { rx_waitack--; if (!rx_waitack) __bic_SR_register_on_exit(LPM3_bits); } if (sleep_counter) sleep_counter--; else __bic_SR_register_on_exit(LPM3_bits); } // PORT2 interrupt ISR // Note that our nRF24L01+ IRQ is attached to PORT1, so the msprf24 library is not providing // this ISR, thus we should provide our own. #pragma vector=PORT2_VECTOR __interrupt void P2_ISR(void) { if (P2IFG & TEST_MODE_PORT) { P2IFG &= ~TEST_MODE_PORT; __bic_SR_register_on_exit(LPM3_bits); } }
     
    One interesting thing to note here is how I handled the MAX31855's power consumption during idle--there's a small signal FET gating Vcc on both chips controlled by one of the G2452's I/O pins, however turning off Vcc doesn't solve the problem since it can grab parasitic current from the SPI lines as well as the Chip Select lines. So I have to make sure that any time the chip is in a state where SPI I/O may occur, the thermocouple chips are up and running, and only right before I go into extended low-power LPM3 sleep should I shut off the Vcc (and SPI CS lines for the chips).
     
     
    As for the OTA binary protocol, I came up with my own little scheme which is detailed in the code tarball under PROTOCOL.txt. From the G2452 side though, here's the code that interprets/processes incoming packets:
     
    packet_processor.h

    /* packet_processor.h * * Handle slave node packets (TX or RX) * * Headers & reference documentation * Struct for managing packet task list */ /* Command/packet reference: * +---------+-----------+----------------+ * | PROGRAM | PACKETLEN | PACKETCONTENTS | * +---------+-----------+----------------+ * * Programs: * 0x01 : Hello (slave->base) * 0x02 : LEDtest request (slave->base) * 0x03 : LEDtest reply (base->slave) * 0x04 : GPIO set (base->slave) * 0x05 : GPIO get request (base->slave) * 0x06 : GPIO get reply (slave->base) * 0x10 : Thermocouple status (slave->base) */ #define PACKET_TASKLIST_DEPTH 3 // Packet TX task; a single-linked list struct packet_task { unsigned char active; unsigned char program; unsigned char size; char rfaddr[5]; char data[16]; }; extern struct packet_task txtasks[PACKET_TASKLIST_DEPTH]; // Task list void packet_init_tasklist(); char packet_task_append(struct packet_task *task); struct packet_task *packet_task_next(); char packet_processor(unsigned char program, unsigned char size, char *data); // Processes an RX packet, one at a time, returning 1 if successful char packet_process_txqueue(); /* Submits a TX packet stuffing as many packets with the same RF address as can fit * inside a 32-byte packet; returns 1 if successful or 0 if no packets found in the task * queue. * This function runs msprf24_activate_tx() and the MCU should enter LPM sleep shortly after * successful completion of this function, handling IRQ upon wakeup. After waking up it's * prudent to clear RX pipe#0's address (w_rx_addr(0, <some_dummy_array_of_zeroes>)) to avoid * inadvertently capturing other traffic destined to that remote module if we enter RX mode later. */
     
    packet_processor.c

    /* packet_processor.c * Handle slave node packets (TX or RX) */ #include <msp430.h> #include "tcsender.h" #include "packet_processor.h" #include "msprf24.h" #include <sys/cdefs.h> #include <string.h> #include <stdlib.h> struct packet_task txtasks[PACKET_TASKLIST_DEPTH]; char packet_task_append(struct packet_task *task) { int i=0; if (task == NULL) return 0; // Invalid request while (txtasks[i].active && i < PACKET_TASKLIST_DEPTH) i++; if (i == PACKET_TASKLIST_DEPTH) return 0; // No free slots in the tasklist queue memcpy(&(txtasks[i]), task, sizeof(struct packet_task)); txtasks[i].active = 1; return 1; } struct packet_task *packet_task_next() { int i; for (i=0; i < PACKET_TASKLIST_DEPTH; i++) { if (txtasks[i].active) return &txtasks[i]; } return NULL; } void packet_init_tasklist() { int i; for (i=0; i < PACKET_TASKLIST_DEPTH; i++) { txtasks[i].active = 0; txtasks[i].program = 0; txtasks[i].size = 0; } } /* Process RX packet payloads * * Some commands may result in TX replies, which are appended to the * packet task list. */ char packet_processor(unsigned char program, unsigned char size, char *data) { unsigned char *udata = (unsigned char*)data; switch (program) { case 0x03: // LED test reply // Data: ID(1), LED_EN(1) if (size != 2) return 0; // Packet length invalid if (udata[0] != DEVICE_ID) return 0; // Packet was sent to the wrong device if (udata[1]) LED_RED_PORTOUT |= LED_RED_PORT; else LED_RED_PORTOUT &= ~LED_RED_PORT; return 1; default: return 0; } return 1; } /* Process all outstanding TX packet payloads of a similar RF address */ char packet_process_txqueue() { char packet[32], *curaddr; int plen=0; struct packet_task *ct; // No point in sending a packet until the TX queue is empty if ( msprf24_queue_state() & RF24_QUEUE_TXFULL ) return 0; if ((ct = packet_task_next()) == NULL) return 0; curaddr = ct->rfaddr; do { if (ct->active && !memcmp(ct->rfaddr, curaddr, 5)) { if ( (ct->size + 2 + plen) < 32 ) { packet[plen++] = ct->program; packet[plen++] = ct->size; memcpy(&packet[plen], ct->data, ct->size); plen += ct->size; ct->active = 0; // Delete task; it's handled } if (ct->size > 16) // Cull any invalid/faulty-sized packets ct->active = 0; } ct = packet_task_next(); } while (ct != NULL); if (!plen) return 0; w_tx_addr(curaddr); w_rx_addr(0, curaddr); w_tx_payload(plen, packet); // Let'er rip msprf24_activate_tx(); return 1; }
     
    That is all for now (no idea if this post is exceeding any limits for that matter...) but I'll post more details as questions come!
  2. Like
    jsolarski got a reaction from abecedarian in Acrylic dragon   
    I just watched the video, looks very nice.
     
    I love the how fast it cycles, and how the dragon lights up. Cant wait to see your finished piece.
     
    Very Cool and Great work!!
     
    As for the code, that was one of my first msp430 projects I took on, and I used an antiquated version of mspgcc that was not compatible with CCS or IAR or even the newer mspgcc. But it does show a simple way to create SW PWM.
    I am very happy that it is being reused
     
    Keep up the good work.
  3. Like
    jsolarski reacted to jpnorair in [ ENDED ] Nov-Dec 2012 - 43oh Project of the Month Contest   
    I'm finishing an MSP430 + CC430 dev kit that does wireless, Energia, USB, and all kinds of other stuff that should knock the AVR Arduino folks on their butts. I will throw in 3-pack of these modules for the prize! (kit is called "OMG" for Opentag Module+Gadget) I would submit the project itself, but it doesn't seem right -- this is a long term project that just happens to be finishing-up during Nov/Dec.
  4. Like
    jsolarski reacted to abecedarian in [ ENDED ] Nov-Dec 2012 - 43oh Project of the Month Contest   
    I'll offer up (mostly) the same thing I did on stellarisiti.com:
     
    1) I will contribute $10 US to the prize, be it a gift certificate to whichever online source or cash prize, at a minimum, assuming the winner uses an MSP430 Launchpad.
    ... OR ...
    2) I will contribute $20 US to the prize, if the project also includes a C2000, Stellaris Launchpad or a 2nd MSP430.
    ... OR ...
    3) I will contribute $40 US to the prize, if the project includes an MSP430 Launchpad and at least two of the following: MSP430, C2000 or Stellaris processor.
     
    The criteria are mutually exclusive- if the winner meets the criteria for [3], the winner can't claim [2] and [1], for example.
     
     
    I will entertain, pending community opinion of course, the idea of "runner ups", provided those meet certain other standards. A runner up cannot get a prize above the winner: for instance if the winner doesn't meet the [3] criteria, neither can the runner up, right? Therefore the runner up(s) would win the prize(s) below the winner... catch my drift? Anyone could hook up a few MCU's and make some lights blink, but it's more about doing the most with the hardware and software than just hooking things up and making lights blink.
     
    I will stipulate that if you enter the same project here, on 43oh.com as well on stellarisiti.com, you cannot claim a prize from both, should you win.
     
     
    (My wife is going to hate me for doing this... :grin:)
  5. Like
    jsolarski reacted to MattTheGeek in Better Documentation for Store BoosterPacks   
    I'd be willing to write user manuals for boosterpacks, if anyone is interested...
  6. Like
    jsolarski reacted to bluehash in Single sign-on coming soon   
    43oh runs on IPB 3.3
    In a blog post yesterday,, IPB announced that SSO will be available in the next release v3.4. This will allow user integration of Stellarisiti and C2KCentral with 43oh while keeping them separate.
     
    Just an update.
  7. Like
    jsolarski reacted to spirilis in MSP430F5172 LaunchPad XL   
    Buy @ The 43oh Store.
     
    So I got a couple samples of the F5172 (has 5V-tolerant I/Os, 32KB flash + 2KB SRAM, Timer_D can run up to 256MHz with FLL) this past summer and had nothing to do with them. Original idea was to make an Arduino-variant since it has around 12 5V-tolerant I/Os, but I decided against that when I first read about TI's 40-pin XL standard.
     
    EDIT: Link to newest revision of this design: http://forum.43oh.com/topic/2828-msp430f5172-launchpad-xl/page-4#entry31194
     
     


    Between last night and this morning I did some marathon CAD, and came up with my F5172 LaunchPad. Let me know what you think:

    (OSHpark mockup images, I'll most likely use Seeed and make them red.)


    Bottom:


    Notes:
    1. The board includes "mount" headers (female headers pointing down) to plug into the Emulation layer on the MSP430 LaunchPad rev 1.5. As I understand it, TI does *not* support the use of the LP's SBW for programming or debugging F5xxx devices but I've heard it does in fact work, maybe with some limitations (on the E2E forums someone was complaining step-by-step execution didn't work).

    2. The board includes the MSP-FET430UIF 14-pin header, SBW-only (and wired in accordance with slau278k's recommendations for SBW on F5xxx and F6xxx devices). A 3-pin jumper is there to select VCC TOOL (sourced from the FET tool) or external power.

    3. To align with TI's recommendations for the 40-pin XL pin functions, some ports have been duplicated to more than one LP pin. There is a vertical bar next to the pin label if it's also used elsewhere in the 40-pin layout.

    4. The device includes an FTDI FT232RL chip for the serial port. TXD and RXD LEDs are attached to CBUS0/CBUS1 and CBUS2-4 from the FTDI are broken out to a header. I now have headers in place to disable the TX/RX circuit from the chip.

    5. An LDO TPS77333 regulator (similar to MSP430 LaunchPad) is included for providing 3.3V power off the 5V USB feed. LDO_EN lets you enable/disable this and LDO_RST connects the RESET line to the F5172's RESET so the LDO can keep the chip halted until the LDO has built up its output voltage.

    6. LEDs on P1.7 and P3.6 (both PWM-able) have been included, I was thinking of using a white LED with P1.7 and blue LED with P3.6.

    7. P2.7 is not broken out to any of the LP pins, so it's specially designated for the SW1 button which also has a hardware debounce circuit. Should be idle-high, active-low (low when pressed).

    8. The 5V tolerant pins are enabled by switching the "VIO" header to 5V.

    9. XTALs are on the bottom, there are footprints for a tuning fork crystal and a HF through-hole crystal with its load capacitors nearby.

    10. AVcc exists on these chips so I set up an LC filter for it, L1 (10uH SMD) and C9 (10nF SMD).

    11. The F5172 datasheet, page 33, note 3 has not been adhered to--if VIO jumper is set to 5V it will probably get power before the LDO has spun up the 3V3 rail. We'll see if that matters (I doubt it)...
  8. Like
    jsolarski reacted to larsie in Garage door opener   
    On the garage-end of my garage-door-opener, I need a relay that
  9. Like
    jsolarski reacted to larsie in Garage door opener   
    I'm trying to make a garage door opener using some cheap CC2500 boards bought through a group-buy at 43oh.com (2 USD each) and a really nice board designed by RobG. I've made a prototype first, and it seems to work, but is not very pretty. I need to maybe make it more compact and make a case for it. Here's a picture:



    The code is definitely not finished, but you can download it here if you want to look at it. It's based on the TI CC2500 library (not SimpliciTI, which would probably have been a natural choice). I'm using the bitbanging version, as I didn't have any surface mount MSP430G2553.

    I guess maybe I should put the battery beneath.
  10. Like
    jsolarski reacted to jazz in MSP430 USB Benchmark   
    Firmware size is under 1.5 KB (from $E000) and it is tested with MSP430F5508. I guess it will work with any MSP430F550x family member. Firmware is in TI txt format, and It can be flashed by USB BSL. "MSP430_USB_Firmware_Upgrade_Example-1.2.1-Setup.exe" can be download from here:
    http://software-dl.t.../index_FDS.html
     
    uC is powered by USB, and it is running by internal DCO at 25MHz.When is connected to PC, it will be enumeration process. When device is enumerated P1.0 LED will turn on, and uC is ready for benchmark. Any error during benchmark on uC side will be marked with turning P1.0 led OFF. In this case uC needs to be reseted.
     
    Here is attached firmware for XT2 at 12MHz and 24MHz. "usbbmgb*.txt " is firmware for generic bulk, and "usbbmcdc*.txt" is firmware for CDC. "*d.txt" is firmware for dummy transfer.
     
    usbbm12MHz.rar
    usbbm24MHz.rar
     
    All my benchmark results are posted in this topic. Now, you have everything if you want to do it by yourself. You are doing it on your own risk, and don't complain here if you as benchmark results have destroyed MSP430 board or dead cat. It's not my problem.
  11. Like
    jsolarski reacted to scompo in Stellaris launchpad gcc makefile, startup file and linker script BSD   
    Hi, I've never noticed that the license for the examples of the stellaris launchpad were closed, they say explicitly that:
     

    # Texas Instruments (TI) is supplying this software for use solely and # exclusively on TI’s microcontroller products. The software is owned by # TI and/or its suppliers, and is protected under applicable copyright # laws. You may not combine this software with “viral” open-source # software in order to form a larger program.
     
    I wasn't very comfortable with this and I finally decided to write the needed linker script, startup file and the useful Makefile from scratch and license them with a BSD license.
     
    You can find my impressions here and the code in this github repository.
     
    Right now it doesn't support Stellarisware (It's basically the first working version) but I'm planning to add support for libraries in the Makefile as soon as I have time! I don't think it would be so difficult!
     
    Of course the sofware it's opened, so: every help, suggestion, bug issue it's welcome!
     
    I hope this would be useful in any way!
  12. Like
    jsolarski reacted to bluehash in Butterfly BASIC for the MSP430   
    Thanks for this. I've uploaded it to the Forum below for future use.
    basic.zip
  13. Like
    jsolarski reacted to RobG in MSP430F5510 USB Development Board   
    Here it is.
     

  14. Like
    jsolarski reacted to RobG in TLC5940 examples   
    Here are some 2231 examples
     

    #include <msp430g2231.h> #include "pattern.h" #define SCLK_PIN BIT5 #define MOSI_PIN BIT7 #define GSCLK_PIN BIT4 #define BLANK_PIN BIT2 #define XLAT_PIN BIT1 #define DCPRG_PIN BIT7 //P2 #define VPRG_PIN BIT0 typedef unsigned char u_char; typedef unsigned int u_int; #define NUMBER_OF_LEDS 16 u_char timerCounter = 0; // 16 levels of brightness const u_int lut[16] = { 0, 30, 60, 100, 200, 300, 400, 600, 800, 1000, 1200, 1500, 1800, 2100, 2400, 2550 }; // range is 0-4095 (12bit) u_char patternIndex = 0; u_char patternCounter = 0; void updateTLC(); void sendData(u_int data); void main(void) { WDTCTL = WDTPW + WDTHOLD; // disable WDT DCOCTL |= DCO0 + DCO1; // DCO = 15.25MHz BCSCTL1 |= RSEL0 + RSEL1 + RSEL2 + RSEL3; // as above BCSCTL2 |= DIVS_3; // divide clock by 8 P1OUT &= ~(VPRG_PIN + BLANK_PIN + XLAT_PIN + SCLK_PIN + MOSI_PIN); P1DIR |= VPRG_PIN + BLANK_PIN + XLAT_PIN + SCLK_PIN + MOSI_PIN; P1DIR |= GSCLK_PIN; // port 1.4 configured as SMCLK out P1SEL |= GSCLK_PIN; P2SEL &= ~(BIT6 | BIT7); P2OUT &= ~DCPRG_PIN; P2DIR |= DCPRG_PIN; // setup timer CCR0 = 0xFFF; TACTL = TASSEL_2 + MC_1 + ID_0; // SMCLK, up mode, 1:1 CCTL0 = CCIE; // CCR0 interrupt enabled updateTLC(); P1OUT |= XLAT_PIN; P1OUT &= ~XLAT_PIN; _bis_SR_register(GIE); while (1) { // // logic goes here // patternIndex is used for pattern selection // patternCounter is used for timeline if(patternCounter < 16) { patternIndex++; patternCounter++; } else { patternIndex--; patternCounter++; } // sleep _bis_SR_register(LPM0_bits); } } void updateTLC() { u_char ledCounter = NUMBER_OF_LEDS >> 1; while (ledCounter-- > 0) { u_char i = ledCounter << 1; sendData(lut[pattern[patternIndex][i + 1]]); sendData(lut[pattern[patternIndex][i]]); } } #pragma vector = TIMER0_A0_VECTOR __interrupt void Timer_A0(void) { P1OUT |= BLANK_PIN; P1OUT |= XLAT_PIN; P1OUT &= ~XLAT_PIN; P1OUT &= ~BLANK_PIN; patternIndex &= 0x0F; // mask patternCounter to get 0-15 range timerCounter++; if (timerCounter == 0x08) { // 0x08 - 2ms * 8 = 16.384ms, ~61Hz updateTLC(); timerCounter = 0; _bic_SR_register_on_exit(LPM0_bits); } } void sendData(u_int data) { u_char c = 0; while (c < 12) { (data & 0x0800) ? (P1OUT |= MOSI_PIN) : (P1OUT &= ~MOSI_PIN); P1OUT |= SCLK_PIN; P1OUT &= ~SCLK_PIN; data <<= 1; c++; } }
     
    Pattern.h

    #ifndef PATTERN_H_ #define PATTERN_H_ // 16 patterns, 16 LEDs, 16 brightness levels const char pattern[16][16] = { // { 1, 3, 5, 7, 9, 11, 13, 15, 14, 12, 10, 8, 6, 4, 2, 0 }, // { 0, 1, 3, 5, 7, 9, 11, 13, 15, 14, 12, 10, 8, 6, 4, 2 }, // { 2, 0, 1, 3, 5, 7, 9, 11, 13, 15, 14, 12, 10, 8, 6, 4 }, // { 4, 2, 0, 1, 3, 5, 7, 9, 11, 13, 15, 14, 12, 10, 8, 6 }, // { 6, 4, 2, 0, 1, 3, 5, 7, 9, 11, 13, 15, 14, 12, 10, 8 }, // { 8, 6, 4, 2, 0, 1, 3, 5, 7, 9, 11, 13, 15, 14, 12, 10 }, // { 10, 8, 6, 4, 2, 0, 1, 3, 5, 7, 9, 11, 13, 15, 14, 12 }, // { 12, 10, 8, 6, 4, 2, 0, 1, 3, 5, 7, 9, 11, 13, 15, 14 }, // { 14, 12, 10, 8, 6, 4, 2, 0, 1, 3, 5, 7, 9, 11, 13, 15 }, // { 15, 14, 12, 10, 8, 6, 4, 2, 0, 1, 3, 5, 7, 9, 11, 13 }, // { 13, 15, 14, 12, 10, 8, 6, 4, 2, 0, 1, 3, 5, 7, 9, 11 }, // { 11, 13, 15, 14, 12, 10, 8, 6, 4, 2, 0, 1, 3, 5, 7, 9 }, // { 9, 11, 13, 15, 14, 12, 10, 8, 6, 4, 2, 0, 1, 3, 5, 7 }, // { 7, 9, 11, 13, 15, 14, 12, 10, 8, 6, 4, 2, 0, 1, 3, 5 }, // { 5, 7, 9, 11, 13, 15, 14, 12, 10, 8, 6, 4, 2, 0, 1, 3 }, // { 3, 5, 7, 9, 11, 13, 15, 14, 12, 10, 8, 6, 4, 2, 0, 1 }, // }; #endif /* PATTERN_H_ */
     
    Another example

    #include <msp430g2231.h> #define SCLK_PIN BIT5 #define MOSI_PIN BIT7 #define GSCLK_PIN BIT4 #define BLANK_PIN BIT2 #define XLAT_PIN BIT1 #define DCPRG_PIN BIT7 //P2 #define VPRG_PIN BIT0 typedef unsigned char u_char; typedef unsigned int u_int; #define NUMBER_OF_LEDS 16 u_int leds[NUMBER_OF_LEDS] = { 0, }; u_char timerCounter = 0; void updateTLC(); void sendData(u_int data); void main(void) { WDTCTL = WDTPW + WDTHOLD; // disable WDT DCOCTL |= DCO0 + DCO1; // DCO = 15.25MHz BCSCTL1 |= RSEL0 + RSEL1 + RSEL2 + RSEL3; // as above BCSCTL2 |= DIVS_3; // divide clock by 8 P1OUT &= ~(VPRG_PIN + BLANK_PIN + XLAT_PIN + SCLK_PIN + MOSI_PIN); P1DIR |= VPRG_PIN + BLANK_PIN + XLAT_PIN + SCLK_PIN + MOSI_PIN; P1DIR |= GSCLK_PIN; // port 1.4 configured as SMCLK out P1SEL |= GSCLK_PIN; P2SEL &= ~(BIT6 | BIT7); P2OUT &= ~DCPRG_PIN; P2DIR |= DCPRG_PIN; // setup timer CCR0 = 0xFFF; TACTL = TASSEL_2 + MC_1 + ID_0; // SMCLK, up mode, 1:1 CCTL0 = CCIE; // CCR0 interrupt enabled updateTLC(); P1OUT |= XLAT_PIN; P1OUT &= ~XLAT_PIN; _bis_SR_register(GIE); leds[0] = 0x0F; u_char counter = 0; u_char direction = 0; u_char first = 0; u_char firstDirection = 0; u_int brightness = 0xFFF; while (1) { // if (direction) { counter--; leds[counter] = brightness; leds[counter + 1] = 0; if (counter == first) { direction = 0; // first if (firstDirection) { first--; if (first == 0) firstDirection = 0; } else { leds[first - 1] = brightness; first++; if (first == (NUMBER_OF_LEDS - 2)) firstDirection = 1; } } } else { counter++; leds[counter] = brightness; leds[counter - 1] = 0; if (counter == (NUMBER_OF_LEDS - 1)) { direction = 1; } } //update all leds u_char c = 0; while(c < NUMBER_OF_LEDS) { if(leds[c] > 0) leds[c] = brightness; c++; } //update brightness brightness -= 0x02; // sleep _bis_SR_register(LPM0_bits); } } void updateTLC() { u_char ledCounter = NUMBER_OF_LEDS >> 1; while (ledCounter-- > 0) { u_char i = ledCounter << 1; sendData(leds[i + 1]); sendData(leds[i]); } } #pragma vector = TIMER0_A0_VECTOR __interrupt void Timer_A0(void) { P1OUT |= BLANK_PIN; P1OUT |= XLAT_PIN; P1OUT &= ~XLAT_PIN; P1OUT &= ~BLANK_PIN; timerCounter++; if (timerCounter == 0x08) { // 0x08 - 2ms * 8 = 16.384ms, ~61Hz updateTLC(); timerCounter = 0; _bic_SR_register_on_exit(LPM0_bits); } } void sendData(u_int data) { u_char c = 0; while (c < 12) { (data & 0x0800) ? (P1OUT |= MOSI_PIN) : (P1OUT &= ~MOSI_PIN); P1OUT |= SCLK_PIN; P1OUT &= ~SCLK_PIN; data <<= 1; c++; } }
  15. Like
    jsolarski reacted to RobG in Automated LED stairs   
    You should try shift registers, There are many code and hardware examples.
  16. Like
    jsolarski reacted to SirPatrick in Automated LED stairs   
    Alright so you are on the right track currently but we definitely can improve. Before I go into showing you how to fade an LED let me first give you some tips on your code.
     
    First lets take a look at your main function. It looks like you are going through each LED and turning it on for a certain amount and then back off. It also looks like your are doing pretty much the same thing for several lines. To clean that up a bit you should think about using some type of loop. I am going to pseudocode the loop and let you try to attempt it.
     

    for every LED: set LED high delay N seconds set LED low delay N seconds continue on to next LED
     
     
    So you need to look into "For Loops" and figure out how you can iterate through each LED. Think about trying to store each LED in some type of structure and then loop through that structure. I would look into "Arrays" as well in C. Another note, TI has explicit declarations for the pins on the launchpad so you don't have to know the hex representation of each. For example pin 0 is BIT0, pin1 is BIT, etc. You can specify which port by doing PxOUT, where x is 1 or 2.
     
    Okay so now lets take a look at fading an LED. To do that we are going to need to learn about the launchpad timers and about pulse width modulation (PWM). Check out this tutorial on timers. After that you can find more info by a general google search like this. If you have any specific problems just update this post and we will go from there!
  17. Like
    jsolarski reacted to gordon in Welcome!   
    Just remember... no killy jsolarski... no killy jsolarski... again...
  18. Like
    jsolarski reacted to pramode in Stellaris launchpad development using Linux/gcc/lm4tools   
    If you are a Linux enthusiasts, you will love this! You can develop for the stellaris launchpad
    using command-line tools on Linux; check out:
     
    http://recursive-lab...etting-started/
  19. Like
    jsolarski got a reaction from bluehash in Need a challenge question that a visitor may know, to keep off spam   
    i would suggest something off the launchpad site, or what is included in the box. maybe a register name for one of the base chips, or settings.
     
    just some ideas
  20. Like
    jsolarski reacted to bluehash in E.M.I.'s PERF-ect Board Starter Kit   
    This was in this week's TI news flash.
    PERF-ect Board Header Assembly Kit
     
     
    PCB has the following features: (1) 2X4 inch perfboard area, detachable SMT mounts for (4) SOT23-6, (16) 0805 LED, Resistor, or Capacitor pads, (1) SOIC8, (1) TSSOP8, (1) TSSOP16, (1) SSOP16, (1) TSSOP20, (1) PLCC20, (1) Cap Sensor - Slider, and (1) Cap Sensor - button

  21. Like
    jsolarski reacted to squalyl in Linux Tool Chain Options   
    I just did like the github project.
     
    TARGET=arm-none-eabi
     
    the prefix is /opt/stella
    Do you have a preference for $PREFIX?
     
    the binaries have "natural" names, do arm-none-eabi-gcc et al.
     
    I know one can create a relocatable toolchain so that it does not depend on the prefix and can be installed elsewhere, I don't remember how to do this at the moment.
     
    I also cross-built binutils for mingw, working on gcc now.
  22. Like
    jsolarski reacted to ntfreak in ICDI support in OpenOCD   
    ok i have uploaded support for the ICDI to the OpenOCD review system (gerrit) - http://openocd.zylin.com/922
     
    This is really only for devs, as it requires you to build OpenoCD from src.
    But if you are happy building then feel free to test.
     
    Once we iron out any issues it will be commited to OpenOCD master ready for a release.
     
    Also for those who wish to discuss join us on ##stellaris over on freenode.
     
    Cheers
    Spen
  23. Like
    jsolarski reacted to Rickta59 in ICDI support in OpenOCD   
    Thanks, we all really appreciate your efforts!
     
    I used this as my cfg file:
     

    # # TI Stellaris Launchpad ek-lm4f120xl Evaluation Kits # # http://www.ti.com/tool/ek-lm4f120xl # # # NOTE: using the bundled ICDI interface is optional! # This interface is not ftdi based as previous board were # source [find interface/ti-icdi.cfg] set WORKAREASIZE 0x4000 set CHIPNAME lm4f120h5qr source [find target/stellaris_icdi.cfg]
     
    Flashing code, setting breakpoints, triggering breakpoints, 'step', 'finish', and 'next' all seemed to work great. I wasn't able to get watchpoints working. Should watchpoints work OK?
     
    -rick
  24. Like
    jsolarski got a reaction from bluehash in ICDI support in OpenOCD   
    I can confirm that l4flash will program the stellaris launchpad and that lmicdi will connect to it as well, and will connect to gdb, I have not tried to debug yet, but it looks promising.
  25. Like
    jsolarski reacted to squalyl in Stellaris gcc compile on linux.   
    Okay, I'm building one now. I expected some patches to be required. thanks!
×
×
  • Create New...