Jump to content

V0JT4

Members
  • Content Count

    32
  • Joined

  • Last visited

  • Days Won

    2

Reputation Activity

  1. Like
    V0JT4 got a reaction from pine in IR remote controlled LED segment display   
    Hello,
     
    I needed a large 3 digit display with remote control. All available didn't fit my needs, were quite expensive or not flexible enough. So I decided to create my own inspired by products I found.
     
    IR remote control looked simple and cheap enough, Seeedstudio sells some nice large 7 segment LED displays and prototype PCB manufacture in China doesn't cost much.
     
    First I LaunchPad prototyped the design with 8 channel serial LED driver, like SCT2168, and generic 3 pin IR receiver. I implemented NEC IR protocol with TimerA and bit banged serial display data output. All worked nicely so I ordered 5" 7 segment LED digits from Seedstudio. I highly recommend to order one extra digit. From my batch 2 horizontal segments had visibly couple LEDs busted. Also provided datasheet doesn't match what I received. Instead of 2x6 mine are 3x7 LEDs per segment. I tore one apart to see what's inside. Dot segment doesn't even have a polarity mark and only one seemed to work, but I didn't plan to use them anyway.

     
    I designed 2 boards, one large for individual segments of 5" digit, MCU and voltage regulator and small one for various sizes of common anode LED displays. I can extend the display by daisy chaining digits or run multiple displays in parallel depending on which side I connect next digit. MCU and power supply part is placed only on 1st digit. Currently I have ordered 2.3" digits from ebay for secondary display. Boards were made by Elecrow, I fit 1 large and 2 small designs on one 10x10 PCB.



     
    Code runs on small MSP430G2 MCU and only 4 pins are needed, board is designed for MSP430G2210 SO-8 package but with little leg bending and pin reassignment TSSOP-14 may be used. I use small remote I got with DVB-T tuner I use for SDR. It has just few buttons and fairly large labels. Current code implements 4 memory slots to switch between numbers.
     
    Everything is placed in plastic box covered by gray acrylic.

    Code:
    main.ctools.htools.c
    Eagle files:
    large.schlarge.brdsmall.schsmall.brd
     
  2. Like
    V0JT4 got a reaction from oPossum in IR remote controlled LED segment display   
    Hello,
     
    I needed a large 3 digit display with remote control. All available didn't fit my needs, were quite expensive or not flexible enough. So I decided to create my own inspired by products I found.
     
    IR remote control looked simple and cheap enough, Seeedstudio sells some nice large 7 segment LED displays and prototype PCB manufacture in China doesn't cost much.
     
    First I LaunchPad prototyped the design with 8 channel serial LED driver, like SCT2168, and generic 3 pin IR receiver. I implemented NEC IR protocol with TimerA and bit banged serial display data output. All worked nicely so I ordered 5" 7 segment LED digits from Seedstudio. I highly recommend to order one extra digit. From my batch 2 horizontal segments had visibly couple LEDs busted. Also provided datasheet doesn't match what I received. Instead of 2x6 mine are 3x7 LEDs per segment. I tore one apart to see what's inside. Dot segment doesn't even have a polarity mark and only one seemed to work, but I didn't plan to use them anyway.

     
    I designed 2 boards, one large for individual segments of 5" digit, MCU and voltage regulator and small one for various sizes of common anode LED displays. I can extend the display by daisy chaining digits or run multiple displays in parallel depending on which side I connect next digit. MCU and power supply part is placed only on 1st digit. Currently I have ordered 2.3" digits from ebay for secondary display. Boards were made by Elecrow, I fit 1 large and 2 small designs on one 10x10 PCB.



     
    Code runs on small MSP430G2 MCU and only 4 pins are needed, board is designed for MSP430G2210 SO-8 package but with little leg bending and pin reassignment TSSOP-14 may be used. I use small remote I got with DVB-T tuner I use for SDR. It has just few buttons and fairly large labels. Current code implements 4 memory slots to switch between numbers.
     
    Everything is placed in plastic box covered by gray acrylic.

    Code:
    main.ctools.htools.c
    Eagle files:
    large.schlarge.brdsmall.schsmall.brd
     
  3. Like
    V0JT4 got a reaction from Rickta59 in IR remote controlled LED segment display   
    Hello,
     
    I needed a large 3 digit display with remote control. All available didn't fit my needs, were quite expensive or not flexible enough. So I decided to create my own inspired by products I found.
     
    IR remote control looked simple and cheap enough, Seeedstudio sells some nice large 7 segment LED displays and prototype PCB manufacture in China doesn't cost much.
     
    First I LaunchPad prototyped the design with 8 channel serial LED driver, like SCT2168, and generic 3 pin IR receiver. I implemented NEC IR protocol with TimerA and bit banged serial display data output. All worked nicely so I ordered 5" 7 segment LED digits from Seedstudio. I highly recommend to order one extra digit. From my batch 2 horizontal segments had visibly couple LEDs busted. Also provided datasheet doesn't match what I received. Instead of 2x6 mine are 3x7 LEDs per segment. I tore one apart to see what's inside. Dot segment doesn't even have a polarity mark and only one seemed to work, but I didn't plan to use them anyway.

     
    I designed 2 boards, one large for individual segments of 5" digit, MCU and voltage regulator and small one for various sizes of common anode LED displays. I can extend the display by daisy chaining digits or run multiple displays in parallel depending on which side I connect next digit. MCU and power supply part is placed only on 1st digit. Currently I have ordered 2.3" digits from ebay for secondary display. Boards were made by Elecrow, I fit 1 large and 2 small designs on one 10x10 PCB.



     
    Code runs on small MSP430G2 MCU and only 4 pins are needed, board is designed for MSP430G2210 SO-8 package but with little leg bending and pin reassignment TSSOP-14 may be used. I use small remote I got with DVB-T tuner I use for SDR. It has just few buttons and fairly large labels. Current code implements 4 memory slots to switch between numbers.
     
    Everything is placed in plastic box covered by gray acrylic.

    Code:
    main.ctools.htools.c
    Eagle files:
    large.schlarge.brdsmall.schsmall.brd
     
  4. Like
    V0JT4 reacted to Jaspreet@DTU in MSP430 ControlWare Project   
    Hi all!  This is my first post on 43oh forum. I am currently working on a project which i think the 43oh community members will like.   :grin: 
     
    Project Description: The main aim of the project was to create a Simple, Easy to control Graphic User Interface (GUI) to control various pins on MSP430 Launchpad (MSP430g2553 uC). The GUI for this purpose was created using Visual C# and can be used on any Windows based System.
     
    (GUI in action)
                                                                                                                                                                             
     


    Features:
    The GUI allows the user to test and develop hardware without having to write any code for the device. Pins configured GPIO can be turned "LOW" or "HIGH". The present version of the GUI enables real time data acquisition and plotting. The data obtained from the pins configured as "ADC" can also be stored in an Excel Sheet. Data from Internal Temperature Sensor of the uC can be obtained and plotted as well. The GUI enables the user to Generate three independent PWM Signals and vary the Duty Cycle. Instructions:  You need to upload a code to the MSP430g2553 microcontroller for working with the GUI. The code and the application GUI can be downloaded from the link given below. Extract the contents of the download file and load the MSP430_ControlWare project in Code Composer Studio and upload the code to the MSP430 Launchpad (MSP430g2553 uC). You can also view the video for the demonstration of the GUI. 
     
    Future Upgrades:  First thing that i will do this weekend is to implement a scheme for making the serial communication more efficient. There are way too many comparisons in the current code and i would definitely like to reduce that by a significant amount. Secondly, i will improve the PWM part to allow user to select the frequency as well. I would like to have suggestions on what more i should do with the User Interface.
     
    For any queries and suggestions, feel free to drop me a mail or reply to this post.
     
    MSP430 ControlWare.rar 
  5. Like
    V0JT4 got a reaction from pimmel in Universal Ripple Control Receiver   
    I'm using I2C in my project with USCI. Here is code for write and read with repeated start, 8 or 16 bit EEPROM data address is possible. It was inspired by Anderson's code. May be useful for someone else.
     
    i2c.h

    #ifndef I2C_H_ #define I2C_H_ typedef unsigned char u8; typedef signed char s8; typedef unsigned int u16; typedef signed int s16; typedef struct { u8 count; u8 state; u16 address; u8 *buffer; } i2c_data_t; #define size_tr(size, addr16) ((size-1)<<1)|(addr16 & 0x01) // number of bytes to transfer(1 to 128, 2+ for RX), device ID, buffer pointer, is 16bit addressing, memory address #define i2c_tx(size, id, buffer, addr16, address) i2c_trans(size_tr(size,addr16), id, buffer, address) #define i2c_rx(size, id, buffer, addr16, address) i2c_trans(size_tr(size,addr16), id|0x01, buffer, address) // number of bytes to transfer|16 bit addressing, device ID|dirrection, buffer pointer, memory address void i2c_trans(u8 size, u8 id, u8 buffer[], u16 address); void i2c_init(void); // setup u8 i2c_int(void); // data transfer interrupt u8 i2c_eint(void); // NACK interrupt #endif /*I2C_H_*/
     
    i2c.c

    #include "msp430g2553.h" #include "i2c.h" // i2c states #define WRITE 0x00 #define READ 0x01 #define ADDR16 0x02 #define ADDRTR 0x04 #define REPSTT 0x08 i2c_data_t i2c_data = {0, 0, 0, 0}; void i2c_init(void) { P1SEL |= BIT6 + BIT7; //Set I2C pins P1SEL2 |= BIT6 + BIT7; UCB0CTL1 |= UCSWRST; //Enable SW reset UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; //I2C Master, synchronous mode UCB0CTL1 = UCSSEL_2 + UCSWRST; //Use SMCLK, keep SW reset UCB0BR0 = 12; //fSCL = SMCLK/12 = ~100kHz UCB0BR1 = 0; UCB0CTL1 &= ~UCSWRST; //Clear SW reset, resume operation IE2 |= UCB0TXIE | UCB0RXIE; //Enable TX, RX interrupt UCB0I2CIE = UCNACKIE; // NACK interrups } void i2c_trans(u8 size, u8 id, u8 *buffer, u16 address) { i2c_data.state = (id & READ) | ADDRTR; // byte counter if (size & 0x01) i2c_data.state |= ADDR16; i2c_data.count = (size >> 1) + 1; // byte counter i2c_data.address = address; // byte counter i2c_data.buffer = buffer; // byte counter UCB0I2CSA = id >> 1; // Slave Address 01101000 0x68 RTC //Slave Address 01010000 0x50 EEPROM UCB0CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition __bis_SR_register(CPUOFF + GIE); // Enter LPM0 w/ interrupts // Remain in LPM0 until all data is transferred } u8 i2c_int(void) { if (i2c_data.state == WRITE) { if (i2c_data.count > 0) { //Check TX byte counter UCB0TXBUF = *i2c_data.buffer++; // Load TX buffer i2c_data.count--; //Decrement TX byte counter } else if (i2c_data.count == 0) { //last byte transferred UCB0CTL1 |= UCTXSTP; //I2C stop condition while (UCB0CTL1 & UCTXSTP); //Ensure stop condition got sent IFG2 &= ~UCB0TXIFG; //Clear USCI_B0 TX int flag return 1; //Exit LPM0 } } else if (i2c_data.state == READ) { *i2c_data.buffer++ = UCB0RXBUF; i2c_data.count--; //Decrement RX byte counter if (i2c_data.count == 1) { //Check RX byte counter, 1 byte remaining UCB0CTL1 |= UCTXSTP; // I2C stop condition } if (i2c_data.count == 0) { //Check RX byte counter, last byte received while (UCB0CTL1 & UCTXSTP); // Ensure stop condition got sent return 1; // Exit LPM0 } } else if (i2c_data.state & ADDR16) { // high byte address transmit UCB0TXBUF = _swap_bytes(i2c_data.address); i2c_data.state &= ~ADDR16; } else if (i2c_data.state & ADDRTR) { // low byte address transmit UCB0TXBUF = i2c_data.address; i2c_data.state &= ~ADDRTR; if (i2c_data.state) { // repeated Start for RX i2c_data.state |= REPSTT; } } else if (i2c_data.state & REPSTT) { // repeated start required i2c_data.state &= ~REPSTT; UCB0CTL1 &= ~UCTR; // I2C RX UCB0CTL1 |= UCTXSTT; // I2C repeated Start condition for RX IFG2 &= ~UCB0TXIFG; //Clear USCI_B0 TX int flag } return 0; } u8 i2c_eint(void) { if (UCB0STAT & UCNACKIFG) { // send STOP if slave sends NACK UCB0CTL1 |= UCTXSTP; UCB0STAT &= ~UCNACKIFG; return 1; } return 0; }
     
    example main.c

    #include "msp430g2553.h" #include "i2c.h" u8 txdata[] = {'H', 'E', 'L', 'L', 'O', ' ', 'W', 'O', 'R', 'L', 'D'}; u8 rxdata[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; void main(void) { WDTCTL = WDTPW + WDTHOLD; //Stop WDT BCSCTL1 = CALBC1_1MHZ; //Set DCO to 1MHz DCOCTL = CALDCO_1MHZ; // UART setup P1SEL = BIT1 + BIT2; //Set RXD and TXD P1SEL2 = BIT1 + BIT2; UCA0CTL1 |= UCSSEL_2 | UCSWRST; //Have USCI use SMCLK AKA 1MHz main CLK UCA0BR0 = 104; //Baud = 9600 UCA0BR1 = 0; UCA0MCTL = UCBRS_1; //Modulation UCA0CTL1 &= ~UCSWRST; //Start USCI i2c_init(); // init I2C __delay_cycles(20000); //Just a start up delay i2c_rx(11, 0xA0, rxdata, 0, 0); //i2c RX data u8 i = 0; while (i < 11) { while (!(IFG2 & UCA0TXIFG)); UCA0TXBUF = rxdata[i]; //UART TX data i++; } i2c_tx(11, 0xA0, txdata, 0, 0); //i2c TX 11 bytes("HELLO WORLD") __delay_cycles(20000); //Allow EEPROM to write data i2c_rx(11, 0xA0, rxdata, 0, 0); //i2c RX data i = 0; while (i < 11) { while (!(IFG2 & UCA0TXIFG)); UCA0TXBUF = rxdata[i]; //UART TX data i++; } __bis_SR_register(CPUOFF + GIE); //Wait for a reset } // I2C data transfer vector #pragma vector = USCIAB0TX_VECTOR __interrupt void USCIAB0TX_ISR(void) { if (i2c_int()) __bic_SR_register_on_exit(CPUOFF); //Exit LPM0; } // I2C status vector #pragma vector = USCIAB0RX_VECTOR __interrupt void USCIAB0RX_ISR(void) { if (i2c_eint()) { while (!(IFG2 & UCA0TXIFG)); // send error via UART UCA0TXBUF = '#'; } }
  6. Like
    V0JT4 got a reaction from roadrunner84 in Universal Ripple Control Receiver   
    So far I have built two versions of simple message logger based on LaunchPad, first uses almost unmodified FMX-100 and the next one dropped top board and required some wire cutting on bottom board. I needed to use capacitor to smoothen the signal, 10uF with 2kOhm resistor to LED and opto coupler works just fine. So far I have around 100 hours recorded. Now it's time to concentrate on software part.
     
    Old receiver ZPA FMX-100:

    Inside:

    Message format, time is in secconds:

    Message recorded on scope:

    Logger V1:

    Logger V2:

    Receiver schema V0.8:

    Receiver board V0.8:

    Log sample, time is counted from system start just to get picture how often messages come:

    A1000B00000100P___0____________ +314:11 m:s A1000B01000000P_____1__________ +320:9 m:s A1001B10000000P___1____1_____1_ +324:12 m:s A1000B00110010P_______1_1___1__ +325:32 m:s A1000B00000100P_________0______ +326:52 m:s A0001B11000000P_______1_1___1__ +328:11 m:s A0010B10000000P______00________ +336:9 m:s A1010B11000100P00____00____0__0 +337:28 m:s A1000B00100000P____000_________ +338:47 m:s A1000B00001001P_0___010________ +340:8 m:s A1000B00010000P____0_______0__0 +341:27 m:s
  7. Like
    V0JT4 got a reaction from roadrunner84 in Universal Ripple Control Receiver   
    The goal of my project is to build ripple control receiver with some additional functions, main request was to receive massages and sent them via UART but current plan includes many more functions:
    - receive and decode messages
    - 4 relays triggered by certain message content
    - message logging to EEPROM with date and time from RTC
    - configuration will be stored on RTC DS1338 user memory
    - simple CLI via UART
    - 4 buttons and 20x4 character LCD interface
    - listing recorded messages with filtering
     
    Ripple control messages are transmitted to electricity distribution network, usually at 110kV or 22kV level and pass transformers down to end user 230V mains line. It is used to signal low and high tariff to electricity meters and high non-critical loads to optimize power distribution. The signal uses low modulation frequency, most common in Czech Republic is 216.7Hz. One message takes about 63 seconds to transmit. This allows one transmitter to cover large area. So far I'm getting around 200 messages a day with first receiver prototype.
     
    I plan to use these components:
    - MSP430G2553
    - modified old receiver ZPA FMX-100 for signal extraction from mains, opto-coupled connection
    - AT24C512 I2C EEPROM, 64Kx8 bit
    - DS1338 I2C RTC
    - 20x4 character LCD HD44780 with shift register 74HCT164
    - ULN2803 for relay switching with shift register 74HC595
    - USB to UART module with FTDI or CP2102 chip, opto-coupled UART
     
    Does someone have good experience with DS1338 or would you recommend other RTC? I need 3.3V operation and battery backup, square wave output is welcomed.
  8. Like
    V0JT4 got a reaction from bluehash in Products using MSP430   
    Another device with MSP430 on EEVblog, Atten PPS3205T-3S Triple Output Power Supply uses MSP430F2013 (29:45).

  9. Like
    V0JT4 got a reaction from RobG in New (soon to be) valueline chip. MSP430G2955 56kb Flash 4kb Ram!   
    There is also news on E2E forum about new devices support by MSP-GANG programmer.
    Listed also on http://www.ti.com/gang430
  10. Like
    V0JT4 got a reaction from waic in Universal Ripple Control Receiver   
    I'm using I2C in my project with USCI. Here is code for write and read with repeated start, 8 or 16 bit EEPROM data address is possible. It was inspired by Anderson's code. May be useful for someone else.
     
    i2c.h

    #ifndef I2C_H_ #define I2C_H_ typedef unsigned char u8; typedef signed char s8; typedef unsigned int u16; typedef signed int s16; typedef struct { u8 count; u8 state; u16 address; u8 *buffer; } i2c_data_t; #define size_tr(size, addr16) ((size-1)<<1)|(addr16 & 0x01) // number of bytes to transfer(1 to 128, 2+ for RX), device ID, buffer pointer, is 16bit addressing, memory address #define i2c_tx(size, id, buffer, addr16, address) i2c_trans(size_tr(size,addr16), id, buffer, address) #define i2c_rx(size, id, buffer, addr16, address) i2c_trans(size_tr(size,addr16), id|0x01, buffer, address) // number of bytes to transfer|16 bit addressing, device ID|dirrection, buffer pointer, memory address void i2c_trans(u8 size, u8 id, u8 buffer[], u16 address); void i2c_init(void); // setup u8 i2c_int(void); // data transfer interrupt u8 i2c_eint(void); // NACK interrupt #endif /*I2C_H_*/
     
    i2c.c

    #include "msp430g2553.h" #include "i2c.h" // i2c states #define WRITE 0x00 #define READ 0x01 #define ADDR16 0x02 #define ADDRTR 0x04 #define REPSTT 0x08 i2c_data_t i2c_data = {0, 0, 0, 0}; void i2c_init(void) { P1SEL |= BIT6 + BIT7; //Set I2C pins P1SEL2 |= BIT6 + BIT7; UCB0CTL1 |= UCSWRST; //Enable SW reset UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; //I2C Master, synchronous mode UCB0CTL1 = UCSSEL_2 + UCSWRST; //Use SMCLK, keep SW reset UCB0BR0 = 12; //fSCL = SMCLK/12 = ~100kHz UCB0BR1 = 0; UCB0CTL1 &= ~UCSWRST; //Clear SW reset, resume operation IE2 |= UCB0TXIE | UCB0RXIE; //Enable TX, RX interrupt UCB0I2CIE = UCNACKIE; // NACK interrups } void i2c_trans(u8 size, u8 id, u8 *buffer, u16 address) { i2c_data.state = (id & READ) | ADDRTR; // byte counter if (size & 0x01) i2c_data.state |= ADDR16; i2c_data.count = (size >> 1) + 1; // byte counter i2c_data.address = address; // byte counter i2c_data.buffer = buffer; // byte counter UCB0I2CSA = id >> 1; // Slave Address 01101000 0x68 RTC //Slave Address 01010000 0x50 EEPROM UCB0CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition __bis_SR_register(CPUOFF + GIE); // Enter LPM0 w/ interrupts // Remain in LPM0 until all data is transferred } u8 i2c_int(void) { if (i2c_data.state == WRITE) { if (i2c_data.count > 0) { //Check TX byte counter UCB0TXBUF = *i2c_data.buffer++; // Load TX buffer i2c_data.count--; //Decrement TX byte counter } else if (i2c_data.count == 0) { //last byte transferred UCB0CTL1 |= UCTXSTP; //I2C stop condition while (UCB0CTL1 & UCTXSTP); //Ensure stop condition got sent IFG2 &= ~UCB0TXIFG; //Clear USCI_B0 TX int flag return 1; //Exit LPM0 } } else if (i2c_data.state == READ) { *i2c_data.buffer++ = UCB0RXBUF; i2c_data.count--; //Decrement RX byte counter if (i2c_data.count == 1) { //Check RX byte counter, 1 byte remaining UCB0CTL1 |= UCTXSTP; // I2C stop condition } if (i2c_data.count == 0) { //Check RX byte counter, last byte received while (UCB0CTL1 & UCTXSTP); // Ensure stop condition got sent return 1; // Exit LPM0 } } else if (i2c_data.state & ADDR16) { // high byte address transmit UCB0TXBUF = _swap_bytes(i2c_data.address); i2c_data.state &= ~ADDR16; } else if (i2c_data.state & ADDRTR) { // low byte address transmit UCB0TXBUF = i2c_data.address; i2c_data.state &= ~ADDRTR; if (i2c_data.state) { // repeated Start for RX i2c_data.state |= REPSTT; } } else if (i2c_data.state & REPSTT) { // repeated start required i2c_data.state &= ~REPSTT; UCB0CTL1 &= ~UCTR; // I2C RX UCB0CTL1 |= UCTXSTT; // I2C repeated Start condition for RX IFG2 &= ~UCB0TXIFG; //Clear USCI_B0 TX int flag } return 0; } u8 i2c_eint(void) { if (UCB0STAT & UCNACKIFG) { // send STOP if slave sends NACK UCB0CTL1 |= UCTXSTP; UCB0STAT &= ~UCNACKIFG; return 1; } return 0; }
     
    example main.c

    #include "msp430g2553.h" #include "i2c.h" u8 txdata[] = {'H', 'E', 'L', 'L', 'O', ' ', 'W', 'O', 'R', 'L', 'D'}; u8 rxdata[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; void main(void) { WDTCTL = WDTPW + WDTHOLD; //Stop WDT BCSCTL1 = CALBC1_1MHZ; //Set DCO to 1MHz DCOCTL = CALDCO_1MHZ; // UART setup P1SEL = BIT1 + BIT2; //Set RXD and TXD P1SEL2 = BIT1 + BIT2; UCA0CTL1 |= UCSSEL_2 | UCSWRST; //Have USCI use SMCLK AKA 1MHz main CLK UCA0BR0 = 104; //Baud = 9600 UCA0BR1 = 0; UCA0MCTL = UCBRS_1; //Modulation UCA0CTL1 &= ~UCSWRST; //Start USCI i2c_init(); // init I2C __delay_cycles(20000); //Just a start up delay i2c_rx(11, 0xA0, rxdata, 0, 0); //i2c RX data u8 i = 0; while (i < 11) { while (!(IFG2 & UCA0TXIFG)); UCA0TXBUF = rxdata[i]; //UART TX data i++; } i2c_tx(11, 0xA0, txdata, 0, 0); //i2c TX 11 bytes("HELLO WORLD") __delay_cycles(20000); //Allow EEPROM to write data i2c_rx(11, 0xA0, rxdata, 0, 0); //i2c RX data i = 0; while (i < 11) { while (!(IFG2 & UCA0TXIFG)); UCA0TXBUF = rxdata[i]; //UART TX data i++; } __bis_SR_register(CPUOFF + GIE); //Wait for a reset } // I2C data transfer vector #pragma vector = USCIAB0TX_VECTOR __interrupt void USCIAB0TX_ISR(void) { if (i2c_int()) __bic_SR_register_on_exit(CPUOFF); //Exit LPM0; } // I2C status vector #pragma vector = USCIAB0RX_VECTOR __interrupt void USCIAB0RX_ISR(void) { if (i2c_eint()) { while (!(IFG2 & UCA0TXIFG)); // send error via UART UCA0TXBUF = '#'; } }
  11. Like
    V0JT4 reacted to oPossum in 6 channel logic analyzer   
    Sure - P2.6 and P2.7 can be used as GPIO instead of for a xtal. Some minor firmware changes would be required to properly setup port 2 and use the additional 2 bits. Search the source code for 0x3F to find where most of the changes need to be made.
  12. Like
    V0JT4 got a reaction from majeddotcom in Universal Ripple Control Receiver   
    I'm not sure how functional it may be without interrupts as its written to depend on them and as is described in MSP430 2xxx User's Guide. You would need to check some ready/busy flags of USCI_B module.
     
    However if you get to tx function you can verify functionality:
    Run upto tx count=0
    Reset
    Run to rx count=0 and examine the memory in debug mode
    rxdata buffer should contain same data as txdata
     
    You can also test Anderson's code for I2C USCI, it is for 16bit addressing.
  13. Like
    V0JT4 reacted to oPossum in 6 channel logic analyzer   
    The LogicBoost is a 6 channel 16 MHz 256 ksample logic anlyzer booster for the MSP430 launchpad. It works with 3 to 5 volt logic levels.

    Many common communication protocols can be observed, such as:
    - Async serial ("UART", "RS-232")
    - SPI
    - IIC
    - Dallas/Maxim one wire
    - Low speed USB (1.5 Mbps)
    - DHT11/22 sensors
    - Consumer infrared and IRDA
    It is also useful for PWM and other applications.
     
    SPI RAM chips are used for the acquisition buffer. This greatly simplifies the design relative to using parallel SRAM chips. The SPI RAM have and internal address counter that eliminates the need for an external address bus and counter. The MSP430 sets up an address and write mode, and then data is clocked into the RAM on every SPI clock.
     

     
    The PCB is 50 x 50 mm for low cost and uses thru-hole components so anyone can build it. An optional FTDI board can be used for faster host communication.

     
    It can be stacked with the Launchpad Mini - also 50 x 50 mm. An FTDI board is required for host communication and power in this configuration.


  14. Like
    V0JT4 got a reaction from majeddotcom in Universal Ripple Control Receiver   
    First thing that pops my mind is to set 16bit addressing bit because your EEPROM chip uses it.

    replace i2c_rx(11, 0xA0, rxdata, 0, 0); with i2c_rx(11, 0xA0, rxdata, 1, 0);
    In test example I was using small EEPROM that uses only 8bit addressing, STMicro 24C16. I think all devices up to 256B and some up to 2KB (from outside they behave like 8 I2C devices in one pack) use it. In final design I used 64KB chip that requires 16bit addressing.
     
    You may also check if WP, A0, A1 and A2 are connected to GND. Another option is to place break point into I2C status interrupt that is hit when slave sends NACK or does not respond at all. Best way is to have scope or logic analyzer to see the waveform. You can watch transaction progress if you place break point at the beginning of "u8 i2c_int(void)" in i2c.c.
  15. Like
    V0JT4 got a reaction from zeke in Universal Ripple Control Receiver   
    This week I got PCBs from my tutor and had time to populate and do some test. Boards were produced by local company so the price was quite high. I'm glad there are also services like Seed.
     

     

     

     

  16. Like
    V0JT4 reacted to RobG in LaunchPad Web Server - control your LP over the network   
    Here's the web server software for my Ethernet booster pack.
    The software is 95% ready, still few bugs and some cleanup left, I will post the code when complete.

    The whole thing takes up just under 4.5KB and uses ~400 bytes of RAM, so you still have ~11KB and ~100 bytes of RAM left for whatever you need.

    BTW, I really need to get a tripod for my iPhone



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

     

     

     

  18. Like
    V0JT4 got a reaction from timotet in Universal Ripple Control Receiver   
    I'm using I2C in my project with USCI. Here is code for write and read with repeated start, 8 or 16 bit EEPROM data address is possible. It was inspired by Anderson's code. May be useful for someone else.
     
    i2c.h

    #ifndef I2C_H_ #define I2C_H_ typedef unsigned char u8; typedef signed char s8; typedef unsigned int u16; typedef signed int s16; typedef struct { u8 count; u8 state; u16 address; u8 *buffer; } i2c_data_t; #define size_tr(size, addr16) ((size-1)<<1)|(addr16 & 0x01) // number of bytes to transfer(1 to 128, 2+ for RX), device ID, buffer pointer, is 16bit addressing, memory address #define i2c_tx(size, id, buffer, addr16, address) i2c_trans(size_tr(size,addr16), id, buffer, address) #define i2c_rx(size, id, buffer, addr16, address) i2c_trans(size_tr(size,addr16), id|0x01, buffer, address) // number of bytes to transfer|16 bit addressing, device ID|dirrection, buffer pointer, memory address void i2c_trans(u8 size, u8 id, u8 buffer[], u16 address); void i2c_init(void); // setup u8 i2c_int(void); // data transfer interrupt u8 i2c_eint(void); // NACK interrupt #endif /*I2C_H_*/
     
    i2c.c

    #include "msp430g2553.h" #include "i2c.h" // i2c states #define WRITE 0x00 #define READ 0x01 #define ADDR16 0x02 #define ADDRTR 0x04 #define REPSTT 0x08 i2c_data_t i2c_data = {0, 0, 0, 0}; void i2c_init(void) { P1SEL |= BIT6 + BIT7; //Set I2C pins P1SEL2 |= BIT6 + BIT7; UCB0CTL1 |= UCSWRST; //Enable SW reset UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; //I2C Master, synchronous mode UCB0CTL1 = UCSSEL_2 + UCSWRST; //Use SMCLK, keep SW reset UCB0BR0 = 12; //fSCL = SMCLK/12 = ~100kHz UCB0BR1 = 0; UCB0CTL1 &= ~UCSWRST; //Clear SW reset, resume operation IE2 |= UCB0TXIE | UCB0RXIE; //Enable TX, RX interrupt UCB0I2CIE = UCNACKIE; // NACK interrups } void i2c_trans(u8 size, u8 id, u8 *buffer, u16 address) { i2c_data.state = (id & READ) | ADDRTR; // byte counter if (size & 0x01) i2c_data.state |= ADDR16; i2c_data.count = (size >> 1) + 1; // byte counter i2c_data.address = address; // byte counter i2c_data.buffer = buffer; // byte counter UCB0I2CSA = id >> 1; // Slave Address 01101000 0x68 RTC //Slave Address 01010000 0x50 EEPROM UCB0CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition __bis_SR_register(CPUOFF + GIE); // Enter LPM0 w/ interrupts // Remain in LPM0 until all data is transferred } u8 i2c_int(void) { if (i2c_data.state == WRITE) { if (i2c_data.count > 0) { //Check TX byte counter UCB0TXBUF = *i2c_data.buffer++; // Load TX buffer i2c_data.count--; //Decrement TX byte counter } else if (i2c_data.count == 0) { //last byte transferred UCB0CTL1 |= UCTXSTP; //I2C stop condition while (UCB0CTL1 & UCTXSTP); //Ensure stop condition got sent IFG2 &= ~UCB0TXIFG; //Clear USCI_B0 TX int flag return 1; //Exit LPM0 } } else if (i2c_data.state == READ) { *i2c_data.buffer++ = UCB0RXBUF; i2c_data.count--; //Decrement RX byte counter if (i2c_data.count == 1) { //Check RX byte counter, 1 byte remaining UCB0CTL1 |= UCTXSTP; // I2C stop condition } if (i2c_data.count == 0) { //Check RX byte counter, last byte received while (UCB0CTL1 & UCTXSTP); // Ensure stop condition got sent return 1; // Exit LPM0 } } else if (i2c_data.state & ADDR16) { // high byte address transmit UCB0TXBUF = _swap_bytes(i2c_data.address); i2c_data.state &= ~ADDR16; } else if (i2c_data.state & ADDRTR) { // low byte address transmit UCB0TXBUF = i2c_data.address; i2c_data.state &= ~ADDRTR; if (i2c_data.state) { // repeated Start for RX i2c_data.state |= REPSTT; } } else if (i2c_data.state & REPSTT) { // repeated start required i2c_data.state &= ~REPSTT; UCB0CTL1 &= ~UCTR; // I2C RX UCB0CTL1 |= UCTXSTT; // I2C repeated Start condition for RX IFG2 &= ~UCB0TXIFG; //Clear USCI_B0 TX int flag } return 0; } u8 i2c_eint(void) { if (UCB0STAT & UCNACKIFG) { // send STOP if slave sends NACK UCB0CTL1 |= UCTXSTP; UCB0STAT &= ~UCNACKIFG; return 1; } return 0; }
     
    example main.c

    #include "msp430g2553.h" #include "i2c.h" u8 txdata[] = {'H', 'E', 'L', 'L', 'O', ' ', 'W', 'O', 'R', 'L', 'D'}; u8 rxdata[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; void main(void) { WDTCTL = WDTPW + WDTHOLD; //Stop WDT BCSCTL1 = CALBC1_1MHZ; //Set DCO to 1MHz DCOCTL = CALDCO_1MHZ; // UART setup P1SEL = BIT1 + BIT2; //Set RXD and TXD P1SEL2 = BIT1 + BIT2; UCA0CTL1 |= UCSSEL_2 | UCSWRST; //Have USCI use SMCLK AKA 1MHz main CLK UCA0BR0 = 104; //Baud = 9600 UCA0BR1 = 0; UCA0MCTL = UCBRS_1; //Modulation UCA0CTL1 &= ~UCSWRST; //Start USCI i2c_init(); // init I2C __delay_cycles(20000); //Just a start up delay i2c_rx(11, 0xA0, rxdata, 0, 0); //i2c RX data u8 i = 0; while (i < 11) { while (!(IFG2 & UCA0TXIFG)); UCA0TXBUF = rxdata[i]; //UART TX data i++; } i2c_tx(11, 0xA0, txdata, 0, 0); //i2c TX 11 bytes("HELLO WORLD") __delay_cycles(20000); //Allow EEPROM to write data i2c_rx(11, 0xA0, rxdata, 0, 0); //i2c RX data i = 0; while (i < 11) { while (!(IFG2 & UCA0TXIFG)); UCA0TXBUF = rxdata[i]; //UART TX data i++; } __bis_SR_register(CPUOFF + GIE); //Wait for a reset } // I2C data transfer vector #pragma vector = USCIAB0TX_VECTOR __interrupt void USCIAB0TX_ISR(void) { if (i2c_int()) __bic_SR_register_on_exit(CPUOFF); //Exit LPM0; } // I2C status vector #pragma vector = USCIAB0RX_VECTOR __interrupt void USCIAB0RX_ISR(void) { if (i2c_eint()) { while (!(IFG2 & UCA0TXIFG)); // send error via UART UCA0TXBUF = '#'; } }
  19. Like
    V0JT4 got a reaction from timotet in Universal Ripple Control Receiver   
    So far I have built two versions of simple message logger based on LaunchPad, first uses almost unmodified FMX-100 and the next one dropped top board and required some wire cutting on bottom board. I needed to use capacitor to smoothen the signal, 10uF with 2kOhm resistor to LED and opto coupler works just fine. So far I have around 100 hours recorded. Now it's time to concentrate on software part.
     
    Old receiver ZPA FMX-100:

    Inside:

    Message format, time is in secconds:

    Message recorded on scope:

    Logger V1:

    Logger V2:

    Receiver schema V0.8:

    Receiver board V0.8:

    Log sample, time is counted from system start just to get picture how often messages come:

    A1000B00000100P___0____________ +314:11 m:s A1000B01000000P_____1__________ +320:9 m:s A1001B10000000P___1____1_____1_ +324:12 m:s A1000B00110010P_______1_1___1__ +325:32 m:s A1000B00000100P_________0______ +326:52 m:s A0001B11000000P_______1_1___1__ +328:11 m:s A0010B10000000P______00________ +336:9 m:s A1010B11000100P00____00____0__0 +337:28 m:s A1000B00100000P____000_________ +338:47 m:s A1000B00001001P_0___010________ +340:8 m:s A1000B00010000P____0_______0__0 +341:27 m:s
  20. Like
    V0JT4 got a reaction from gordon in Universal Ripple Control Receiver   
    This week I got PCBs from my tutor and had time to populate and do some test. Boards were produced by local company so the price was quite high. I'm glad there are also services like Seed.
     

     

     

     

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

     

     

     

  22. Like
    V0JT4 reacted to rockets4kids in Software debouncing   
    Jack Ganssle has a *great* article on debouncing, both hardware and software:
     
    http://www.eng.utah.edu/~cs5780/debouncing.pdf
     
    Definitely worth reading even if you already have a working debounce routine.
  23. Like
    V0JT4 got a reaction from turd in Universal Ripple Control Receiver   
    I'm using I2C in my project with USCI. Here is code for write and read with repeated start, 8 or 16 bit EEPROM data address is possible. It was inspired by Anderson's code. May be useful for someone else.
     
    i2c.h

    #ifndef I2C_H_ #define I2C_H_ typedef unsigned char u8; typedef signed char s8; typedef unsigned int u16; typedef signed int s16; typedef struct { u8 count; u8 state; u16 address; u8 *buffer; } i2c_data_t; #define size_tr(size, addr16) ((size-1)<<1)|(addr16 & 0x01) // number of bytes to transfer(1 to 128, 2+ for RX), device ID, buffer pointer, is 16bit addressing, memory address #define i2c_tx(size, id, buffer, addr16, address) i2c_trans(size_tr(size,addr16), id, buffer, address) #define i2c_rx(size, id, buffer, addr16, address) i2c_trans(size_tr(size,addr16), id|0x01, buffer, address) // number of bytes to transfer|16 bit addressing, device ID|dirrection, buffer pointer, memory address void i2c_trans(u8 size, u8 id, u8 buffer[], u16 address); void i2c_init(void); // setup u8 i2c_int(void); // data transfer interrupt u8 i2c_eint(void); // NACK interrupt #endif /*I2C_H_*/
     
    i2c.c

    #include "msp430g2553.h" #include "i2c.h" // i2c states #define WRITE 0x00 #define READ 0x01 #define ADDR16 0x02 #define ADDRTR 0x04 #define REPSTT 0x08 i2c_data_t i2c_data = {0, 0, 0, 0}; void i2c_init(void) { P1SEL |= BIT6 + BIT7; //Set I2C pins P1SEL2 |= BIT6 + BIT7; UCB0CTL1 |= UCSWRST; //Enable SW reset UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; //I2C Master, synchronous mode UCB0CTL1 = UCSSEL_2 + UCSWRST; //Use SMCLK, keep SW reset UCB0BR0 = 12; //fSCL = SMCLK/12 = ~100kHz UCB0BR1 = 0; UCB0CTL1 &= ~UCSWRST; //Clear SW reset, resume operation IE2 |= UCB0TXIE | UCB0RXIE; //Enable TX, RX interrupt UCB0I2CIE = UCNACKIE; // NACK interrups } void i2c_trans(u8 size, u8 id, u8 *buffer, u16 address) { i2c_data.state = (id & READ) | ADDRTR; // byte counter if (size & 0x01) i2c_data.state |= ADDR16; i2c_data.count = (size >> 1) + 1; // byte counter i2c_data.address = address; // byte counter i2c_data.buffer = buffer; // byte counter UCB0I2CSA = id >> 1; // Slave Address 01101000 0x68 RTC //Slave Address 01010000 0x50 EEPROM UCB0CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition __bis_SR_register(CPUOFF + GIE); // Enter LPM0 w/ interrupts // Remain in LPM0 until all data is transferred } u8 i2c_int(void) { if (i2c_data.state == WRITE) { if (i2c_data.count > 0) { //Check TX byte counter UCB0TXBUF = *i2c_data.buffer++; // Load TX buffer i2c_data.count--; //Decrement TX byte counter } else if (i2c_data.count == 0) { //last byte transferred UCB0CTL1 |= UCTXSTP; //I2C stop condition while (UCB0CTL1 & UCTXSTP); //Ensure stop condition got sent IFG2 &= ~UCB0TXIFG; //Clear USCI_B0 TX int flag return 1; //Exit LPM0 } } else if (i2c_data.state == READ) { *i2c_data.buffer++ = UCB0RXBUF; i2c_data.count--; //Decrement RX byte counter if (i2c_data.count == 1) { //Check RX byte counter, 1 byte remaining UCB0CTL1 |= UCTXSTP; // I2C stop condition } if (i2c_data.count == 0) { //Check RX byte counter, last byte received while (UCB0CTL1 & UCTXSTP); // Ensure stop condition got sent return 1; // Exit LPM0 } } else if (i2c_data.state & ADDR16) { // high byte address transmit UCB0TXBUF = _swap_bytes(i2c_data.address); i2c_data.state &= ~ADDR16; } else if (i2c_data.state & ADDRTR) { // low byte address transmit UCB0TXBUF = i2c_data.address; i2c_data.state &= ~ADDRTR; if (i2c_data.state) { // repeated Start for RX i2c_data.state |= REPSTT; } } else if (i2c_data.state & REPSTT) { // repeated start required i2c_data.state &= ~REPSTT; UCB0CTL1 &= ~UCTR; // I2C RX UCB0CTL1 |= UCTXSTT; // I2C repeated Start condition for RX IFG2 &= ~UCB0TXIFG; //Clear USCI_B0 TX int flag } return 0; } u8 i2c_eint(void) { if (UCB0STAT & UCNACKIFG) { // send STOP if slave sends NACK UCB0CTL1 |= UCTXSTP; UCB0STAT &= ~UCNACKIFG; return 1; } return 0; }
     
    example main.c

    #include "msp430g2553.h" #include "i2c.h" u8 txdata[] = {'H', 'E', 'L', 'L', 'O', ' ', 'W', 'O', 'R', 'L', 'D'}; u8 rxdata[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; void main(void) { WDTCTL = WDTPW + WDTHOLD; //Stop WDT BCSCTL1 = CALBC1_1MHZ; //Set DCO to 1MHz DCOCTL = CALDCO_1MHZ; // UART setup P1SEL = BIT1 + BIT2; //Set RXD and TXD P1SEL2 = BIT1 + BIT2; UCA0CTL1 |= UCSSEL_2 | UCSWRST; //Have USCI use SMCLK AKA 1MHz main CLK UCA0BR0 = 104; //Baud = 9600 UCA0BR1 = 0; UCA0MCTL = UCBRS_1; //Modulation UCA0CTL1 &= ~UCSWRST; //Start USCI i2c_init(); // init I2C __delay_cycles(20000); //Just a start up delay i2c_rx(11, 0xA0, rxdata, 0, 0); //i2c RX data u8 i = 0; while (i < 11) { while (!(IFG2 & UCA0TXIFG)); UCA0TXBUF = rxdata[i]; //UART TX data i++; } i2c_tx(11, 0xA0, txdata, 0, 0); //i2c TX 11 bytes("HELLO WORLD") __delay_cycles(20000); //Allow EEPROM to write data i2c_rx(11, 0xA0, rxdata, 0, 0); //i2c RX data i = 0; while (i < 11) { while (!(IFG2 & UCA0TXIFG)); UCA0TXBUF = rxdata[i]; //UART TX data i++; } __bis_SR_register(CPUOFF + GIE); //Wait for a reset } // I2C data transfer vector #pragma vector = USCIAB0TX_VECTOR __interrupt void USCIAB0TX_ISR(void) { if (i2c_int()) __bic_SR_register_on_exit(CPUOFF); //Exit LPM0; } // I2C status vector #pragma vector = USCIAB0RX_VECTOR __interrupt void USCIAB0RX_ISR(void) { if (i2c_eint()) { while (!(IFG2 & UCA0TXIFG)); // send error via UART UCA0TXBUF = '#'; } }
  24. Like
    V0JT4 got a reaction from oPossum in Universal Ripple Control Receiver   
    I'm using I2C in my project with USCI. Here is code for write and read with repeated start, 8 or 16 bit EEPROM data address is possible. It was inspired by Anderson's code. May be useful for someone else.
     
    i2c.h

    #ifndef I2C_H_ #define I2C_H_ typedef unsigned char u8; typedef signed char s8; typedef unsigned int u16; typedef signed int s16; typedef struct { u8 count; u8 state; u16 address; u8 *buffer; } i2c_data_t; #define size_tr(size, addr16) ((size-1)<<1)|(addr16 & 0x01) // number of bytes to transfer(1 to 128, 2+ for RX), device ID, buffer pointer, is 16bit addressing, memory address #define i2c_tx(size, id, buffer, addr16, address) i2c_trans(size_tr(size,addr16), id, buffer, address) #define i2c_rx(size, id, buffer, addr16, address) i2c_trans(size_tr(size,addr16), id|0x01, buffer, address) // number of bytes to transfer|16 bit addressing, device ID|dirrection, buffer pointer, memory address void i2c_trans(u8 size, u8 id, u8 buffer[], u16 address); void i2c_init(void); // setup u8 i2c_int(void); // data transfer interrupt u8 i2c_eint(void); // NACK interrupt #endif /*I2C_H_*/
     
    i2c.c

    #include "msp430g2553.h" #include "i2c.h" // i2c states #define WRITE 0x00 #define READ 0x01 #define ADDR16 0x02 #define ADDRTR 0x04 #define REPSTT 0x08 i2c_data_t i2c_data = {0, 0, 0, 0}; void i2c_init(void) { P1SEL |= BIT6 + BIT7; //Set I2C pins P1SEL2 |= BIT6 + BIT7; UCB0CTL1 |= UCSWRST; //Enable SW reset UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; //I2C Master, synchronous mode UCB0CTL1 = UCSSEL_2 + UCSWRST; //Use SMCLK, keep SW reset UCB0BR0 = 12; //fSCL = SMCLK/12 = ~100kHz UCB0BR1 = 0; UCB0CTL1 &= ~UCSWRST; //Clear SW reset, resume operation IE2 |= UCB0TXIE | UCB0RXIE; //Enable TX, RX interrupt UCB0I2CIE = UCNACKIE; // NACK interrups } void i2c_trans(u8 size, u8 id, u8 *buffer, u16 address) { i2c_data.state = (id & READ) | ADDRTR; // byte counter if (size & 0x01) i2c_data.state |= ADDR16; i2c_data.count = (size >> 1) + 1; // byte counter i2c_data.address = address; // byte counter i2c_data.buffer = buffer; // byte counter UCB0I2CSA = id >> 1; // Slave Address 01101000 0x68 RTC //Slave Address 01010000 0x50 EEPROM UCB0CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition __bis_SR_register(CPUOFF + GIE); // Enter LPM0 w/ interrupts // Remain in LPM0 until all data is transferred } u8 i2c_int(void) { if (i2c_data.state == WRITE) { if (i2c_data.count > 0) { //Check TX byte counter UCB0TXBUF = *i2c_data.buffer++; // Load TX buffer i2c_data.count--; //Decrement TX byte counter } else if (i2c_data.count == 0) { //last byte transferred UCB0CTL1 |= UCTXSTP; //I2C stop condition while (UCB0CTL1 & UCTXSTP); //Ensure stop condition got sent IFG2 &= ~UCB0TXIFG; //Clear USCI_B0 TX int flag return 1; //Exit LPM0 } } else if (i2c_data.state == READ) { *i2c_data.buffer++ = UCB0RXBUF; i2c_data.count--; //Decrement RX byte counter if (i2c_data.count == 1) { //Check RX byte counter, 1 byte remaining UCB0CTL1 |= UCTXSTP; // I2C stop condition } if (i2c_data.count == 0) { //Check RX byte counter, last byte received while (UCB0CTL1 & UCTXSTP); // Ensure stop condition got sent return 1; // Exit LPM0 } } else if (i2c_data.state & ADDR16) { // high byte address transmit UCB0TXBUF = _swap_bytes(i2c_data.address); i2c_data.state &= ~ADDR16; } else if (i2c_data.state & ADDRTR) { // low byte address transmit UCB0TXBUF = i2c_data.address; i2c_data.state &= ~ADDRTR; if (i2c_data.state) { // repeated Start for RX i2c_data.state |= REPSTT; } } else if (i2c_data.state & REPSTT) { // repeated start required i2c_data.state &= ~REPSTT; UCB0CTL1 &= ~UCTR; // I2C RX UCB0CTL1 |= UCTXSTT; // I2C repeated Start condition for RX IFG2 &= ~UCB0TXIFG; //Clear USCI_B0 TX int flag } return 0; } u8 i2c_eint(void) { if (UCB0STAT & UCNACKIFG) { // send STOP if slave sends NACK UCB0CTL1 |= UCTXSTP; UCB0STAT &= ~UCNACKIFG; return 1; } return 0; }
     
    example main.c

    #include "msp430g2553.h" #include "i2c.h" u8 txdata[] = {'H', 'E', 'L', 'L', 'O', ' ', 'W', 'O', 'R', 'L', 'D'}; u8 rxdata[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; void main(void) { WDTCTL = WDTPW + WDTHOLD; //Stop WDT BCSCTL1 = CALBC1_1MHZ; //Set DCO to 1MHz DCOCTL = CALDCO_1MHZ; // UART setup P1SEL = BIT1 + BIT2; //Set RXD and TXD P1SEL2 = BIT1 + BIT2; UCA0CTL1 |= UCSSEL_2 | UCSWRST; //Have USCI use SMCLK AKA 1MHz main CLK UCA0BR0 = 104; //Baud = 9600 UCA0BR1 = 0; UCA0MCTL = UCBRS_1; //Modulation UCA0CTL1 &= ~UCSWRST; //Start USCI i2c_init(); // init I2C __delay_cycles(20000); //Just a start up delay i2c_rx(11, 0xA0, rxdata, 0, 0); //i2c RX data u8 i = 0; while (i < 11) { while (!(IFG2 & UCA0TXIFG)); UCA0TXBUF = rxdata[i]; //UART TX data i++; } i2c_tx(11, 0xA0, txdata, 0, 0); //i2c TX 11 bytes("HELLO WORLD") __delay_cycles(20000); //Allow EEPROM to write data i2c_rx(11, 0xA0, rxdata, 0, 0); //i2c RX data i = 0; while (i < 11) { while (!(IFG2 & UCA0TXIFG)); UCA0TXBUF = rxdata[i]; //UART TX data i++; } __bis_SR_register(CPUOFF + GIE); //Wait for a reset } // I2C data transfer vector #pragma vector = USCIAB0TX_VECTOR __interrupt void USCIAB0TX_ISR(void) { if (i2c_int()) __bic_SR_register_on_exit(CPUOFF); //Exit LPM0; } // I2C status vector #pragma vector = USCIAB0RX_VECTOR __interrupt void USCIAB0RX_ISR(void) { if (i2c_eint()) { while (!(IFG2 & UCA0TXIFG)); // send error via UART UCA0TXBUF = '#'; } }
  25. Like
    V0JT4 got a reaction from zeke in I2C USCI_B0 Slave?   
    Check out USCI I2C documentation, you have to shift device ID >>1, it takes only 7 low bits unlike what you see on the bus. That's the reason why your slave doesn't send ACK.
×
×
  • Create New...