Jump to content

Clavier

Members
  • Content Count

    52
  • Joined

  • Last visited

  • Days Won

    8

Reputation Activity

  1. Thanks
    Clavier got a reaction from mph in Implementing an I2C slave device.   
    Clavier's Short Guide to I²C Slaves on the MSP430x2xx Family
    Read section 17.3.4.1 of the User's Guide, and the example code.
    Slave mode is somewhat easier than master mode because you do not have to care about getting the transaction sequence correct; you just react to the master's requests.
    The slave address is an arbitrary but unique 7-bit number. Just put it into the I2COA ("own address") register; the USCI module will automatically handle transactions to this address.
    You do not need to configure a clock source; the clock signal is supplied by the master.
    When the master has written a byte, you get an RXIFG interrupt. Your interrupt handler must read that byte from RXBUF. (You can set the TXNACK bit after reading RXBUF, this will tell the master to stop after the following byte.)
    When the master wants to read a byte, you get a TXIFG interrupt. Your interrupt handler must write a byte to TXBUF.
    If your code is slow, the USCI module will automatically stop the bus via clock stretching until you have reacted.
    You can get notifications when start and stop conditions happen (STTIFG and STPIFG), but that is not always necessary.
    The I²C protocol itself defines only byte reads and writes. If you have registers, you have to handle the register address yourself. Typically, the first write after a start condition is the register address, and all following writes (and all reads) are from/to the specified register (and often the register address automatically increments).
    As a slave, you have no control over what the master does; you must react to any write and read requests at any time. (If you really have nothing to read, just send the last byte again, or some garbage byte.)
  2. Like
    Clavier got a reaction from energia in Advice for proper chip selection   
    In general, the G2xx chips have 16 interrupt-capable pins (if they have that many pins at all).
    For development, I'd suggest the G2553 on the LaunchPad.

  3. Like
    Clavier got a reaction from tripwire in Delay() and sleep() have different timing cycles.   
    The delay() function is part of the official Arduino API. It is implemented with a busy loop, based on the CPU clock.

    The sleep() function is not part of the official Arduino API. It powers down the CPU, and measures time based on the VLO, which doesn't have a accurately specified frequency to begin with and has much higher temperature and voltage coefficients than other clock sources.
  4. Like
    Clavier got a reaction from energia in Delay() and sleep() have different timing cycles.   
    The delay() function is part of the official Arduino API. It is implemented with a busy loop, based on the CPU clock.

    The sleep() function is not part of the official Arduino API. It powers down the CPU, and measures time based on the VLO, which doesn't have a accurately specified frequency to begin with and has much higher temperature and voltage coefficients than other clock sources.
  5. Like
    Clavier got a reaction from Fmilburn in Delay() and sleep() have different timing cycles.   
    The delay() function is part of the official Arduino API. It is implemented with a busy loop, based on the CPU clock.

    The sleep() function is not part of the official Arduino API. It powers down the CPU, and measures time based on the VLO, which doesn't have a accurately specified frequency to begin with and has much higher temperature and voltage coefficients than other clock sources.
  6. Like
    Clavier got a reaction from dubnet in Delay() and sleep() have different timing cycles.   
    The delay() function is part of the official Arduino API. It is implemented with a busy loop, based on the CPU clock.

    The sleep() function is not part of the official Arduino API. It powers down the CPU, and measures time based on the VLO, which doesn't have a accurately specified frequency to begin with and has much higher temperature and voltage coefficients than other clock sources.
  7. Like
    Clavier got a reaction from bluehash in MOSFET Power Circuitry Fails if I2C Pins Initialized First.   
    Please see table 9 of the LIS3DH datasheet; you are not allowed to apply voltages greater than 0.3 V to the SDA/SCL pins when VACC = 0 V.
    You must disconnect these signals before powering down the chip. (And when it's powered down, ACC_INT1 might be floating; you have to deal with that.)
    I'd guess VACC gets powered through R8/R9, or through the chip's ESD protection diodes (which go from any I/O to VDD).
  8. Like
    Clavier got a reaction from bluehash in Sending data via USB to another USB   
    The G2553 chip itself does not have USB support. You can go through the LaunchPad's "application"/"backchannel" UART; you firmware then just needs to write/read the UART. You also need an application on the host PC to read from one COM port and write to another.
    But why use USB? Why can't you control the solenoid directly from the LaunchPad?
  9. Like
    Clavier got a reaction from Dortol in Sending data via USB to another USB   
    The G2553 chip itself does not have USB support. You can go through the LaunchPad's "application"/"backchannel" UART; you firmware then just needs to write/read the UART. You also need an application on the host PC to read from one COM port and write to another.
    But why use USB? Why can't you control the solenoid directly from the LaunchPad?
  10. Like
    Clavier got a reaction from NurseBob in Sending data via USB to another USB   
    The G2553 chip itself does not have USB support. You can go through the LaunchPad's "application"/"backchannel" UART; you firmware then just needs to write/read the UART. You also need an application on the host PC to read from one COM port and write to another.
    But why use USB? Why can't you control the solenoid directly from the LaunchPad?
  11. Like
    Clavier got a reaction from yyrkoon in Implementing an I2C slave device.   
    Clavier's Short Guide to I²C Slaves on the MSP430x2xx Family
    Read section 17.3.4.1 of the User's Guide, and the example code.
    Slave mode is somewhat easier than master mode because you do not have to care about getting the transaction sequence correct; you just react to the master's requests.
    The slave address is an arbitrary but unique 7-bit number. Just put it into the I2COA ("own address") register; the USCI module will automatically handle transactions to this address.
    You do not need to configure a clock source; the clock signal is supplied by the master.
    When the master has written a byte, you get an RXIFG interrupt. Your interrupt handler must read that byte from RXBUF. (You can set the TXNACK bit after reading RXBUF, this will tell the master to stop after the following byte.)
    When the master wants to read a byte, you get a TXIFG interrupt. Your interrupt handler must write a byte to TXBUF.
    If your code is slow, the USCI module will automatically stop the bus via clock stretching until you have reacted.
    You can get notifications when start and stop conditions happen (STTIFG and STPIFG), but that is not always necessary.
    The I²C protocol itself defines only byte reads and writes. If you have registers, you have to handle the register address yourself. Typically, the first write after a start condition is the register address, and all following writes (and all reads) are from/to the specified register (and often the register address automatically increments).
    As a slave, you have no control over what the master does; you must react to any write and read requests at any time. (If you really have nothing to read, just send the last byte again, or some garbage byte.)
  12. Like
    Clavier got a reaction from Fmilburn in Implementing an I2C slave device.   
    Clavier's Short Guide to I²C Slaves on the MSP430x2xx Family
    Read section 17.3.4.1 of the User's Guide, and the example code.
    Slave mode is somewhat easier than master mode because you do not have to care about getting the transaction sequence correct; you just react to the master's requests.
    The slave address is an arbitrary but unique 7-bit number. Just put it into the I2COA ("own address") register; the USCI module will automatically handle transactions to this address.
    You do not need to configure a clock source; the clock signal is supplied by the master.
    When the master has written a byte, you get an RXIFG interrupt. Your interrupt handler must read that byte from RXBUF. (You can set the TXNACK bit after reading RXBUF, this will tell the master to stop after the following byte.)
    When the master wants to read a byte, you get a TXIFG interrupt. Your interrupt handler must write a byte to TXBUF.
    If your code is slow, the USCI module will automatically stop the bus via clock stretching until you have reacted.
    You can get notifications when start and stop conditions happen (STTIFG and STPIFG), but that is not always necessary.
    The I²C protocol itself defines only byte reads and writes. If you have registers, you have to handle the register address yourself. Typically, the first write after a start condition is the register address, and all following writes (and all reads) are from/to the specified register (and often the register address automatically increments).
    As a slave, you have no control over what the master does; you must react to any write and read requests at any time. (If you really have nothing to read, just send the last byte again, or some garbage byte.)
  13. Like
    Clavier got a reaction from bluehash in Implementing an I2C slave device.   
    Clavier's Short Guide to I²C Slaves on the MSP430x2xx Family
    Read section 17.3.4.1 of the User's Guide, and the example code.
    Slave mode is somewhat easier than master mode because you do not have to care about getting the transaction sequence correct; you just react to the master's requests.
    The slave address is an arbitrary but unique 7-bit number. Just put it into the I2COA ("own address") register; the USCI module will automatically handle transactions to this address.
    You do not need to configure a clock source; the clock signal is supplied by the master.
    When the master has written a byte, you get an RXIFG interrupt. Your interrupt handler must read that byte from RXBUF. (You can set the TXNACK bit after reading RXBUF, this will tell the master to stop after the following byte.)
    When the master wants to read a byte, you get a TXIFG interrupt. Your interrupt handler must write a byte to TXBUF.
    If your code is slow, the USCI module will automatically stop the bus via clock stretching until you have reacted.
    You can get notifications when start and stop conditions happen (STTIFG and STPIFG), but that is not always necessary.
    The I²C protocol itself defines only byte reads and writes. If you have registers, you have to handle the register address yourself. Typically, the first write after a start condition is the register address, and all following writes (and all reads) are from/to the specified register (and often the register address automatically increments).
    As a slave, you have no control over what the master does; you must react to any write and read requests at any time. (If you really have nothing to read, just send the last byte again, or some garbage byte.)
  14. Like
    Clavier got a reaction from Fmilburn in Basic MSP430 GPIO Macros   
    This is how I do my GPIO initialization. It doesn't handle any later GPIO accesses, but it's a nice table, and smaller and faster than configuring the bits one by one.
    /* use 0 or 1 to set the output level */ #define OUTPUT        0x00    /* default */ #define INPUT         0x02 #define PULL_DOWN     0x04 #define PULL_UP       0x05 #define REDUCED_DRIVE 0x00    /* default */ #define FULL_DRIVE    0x08 #define GPIO         0x00    /* default */ #define PERIPHERAL    0x10 struct digital_io_init_f5529 {     u8 P1[8];     u8 P2[8];     u8 P3[8];     u8 P4[8];     u8 P5[8];     u8 P6[8];     u8 P7[8];     u8 P8[3];     u8 PJ[4]; }; static void init_port(const u8 *init, unsigned int count, uint16_t int base_address) {     uint16_t out = 0, dir = 0, ren = 0, ds = 0, sel = 0;     uint16_t bit;     for (bit = 1; count > 0; init++, bit <<= 1, count--) {         if (*init & 1)          out |= bit;         if (!(*init & INPUT))   dir |= bit;         if (*init & PULL_DOWN)  ren |= bit;         if (*init & FULL_DRIVE) ds  |= bit;         if (*init & PERIPHERAL) sel |= bit;     }     HWREG16(base_address + OFS_PAOUT) = out;     HWREG16(base_address + OFS_PADIR) = dir;     HWREG16(base_address + OFS_PAREN) = ren;     HWREG16(base_address + OFS_PADS ) = ds;     HWREG16(base_address + OFS_PASEL) = sel; } static void init_ports(const struct digital_io_init_f5529 *init) {     init_port(init->P1, 8 + 8, PA_BASE);     init_port(init->P3, 8 + 8, PB_BASE);     init_port(init->P5, 8 + 8, PC_BASE);     init_port(init->P7, 8 + 3, PD_BASE);     init_port(init->PJ, 4,     PJ_BASE); } void init() {     init_ports(&(const struct digital_io_init_f5529){            .P4[4] = PERIPHERAL | OUTPUT,            .P4[5] = PERIPHERAL | INPUT,            .P7[0] = GPIO | INPUT | PULL_UP,            .P7[1] = GPIO | OUTPUT | FULL_DRIVE,            /* ... */     }); }
  15. Like
    Clavier got a reaction from pokmo in Analog comparator   
    Huh? All MSP430 comparator modules are able to raise an interrupt for this.
  16. Like
    Clavier got a reaction from tripwire in Analog comparator   
    Huh? All MSP430 comparator modules are able to raise an interrupt for this.
  17. Like
    Clavier got a reaction from yyrkoon in GPIO interrupts in both directions   
    Toggling the PxIES bit once has a race condition, when the signal switches again before the interrupt has run. You also have to check the current state of the PxIN bit to ensure that PxIES catches the next edge.
     
    But the easiest way to get interrupts for both edges is to route the signal to two pins.
  18. Like
    Clavier got a reaction from oPossum in GPIO interrupts in both directions   
    Toggling the PxIES bit once has a race condition, when the signal switches again before the interrupt has run. You also have to check the current state of the PxIN bit to ensure that PxIES catches the next edge.
     
    But the easiest way to get interrupts for both edges is to route the signal to two pins.
  19. Like
    Clavier got a reaction from Fred in MOSFET choice for relay switching   
    There is no flyback diode in this device.
     
    All MOSFETS have a parasitic body diode, but it is no help for you because it is across the source/drain channel, not across the relay.
     
    The NXP's BSS138 model has ESD diodes that protect the gate insulation, but again, these does not help you.
     
    You cannot avoid putting a separate diode across the relay.
  20. Like
    Clavier got a reaction from Fred in MOSFET choice for relay switching   
    The 2N7000 would require 5 V to switch on completely, so it is not suitable for the Tiva.
     
    Why do you want to avoid the flyback diode? This would require a high-voltage transistor, and those typically have higher gate threshold voltages.
  21. Like
    Clavier got a reaction from tripwire in Have feedback for TI? Please share here.   
    No; the driverlib does not abstract away the differences between the peripherals. For example, you don't have a single SPI API, you have functions for USCI_A_SPI, USCI_B_SPI, EUSCI_A_SPI, and EUSCI_B_SPI. Similarly for Timer_A, Timer_B.
     
    The TI documentation says that the drivers "provide a mechanism that makes it easy to use the device
  22. Like
    Clavier got a reaction from Fmilburn in Have feedback for TI? Please share here.   
    No; the driverlib does not abstract away the differences between the peripherals. For example, you don't have a single SPI API, you have functions for USCI_A_SPI, USCI_B_SPI, EUSCI_A_SPI, and EUSCI_B_SPI. Similarly for Timer_A, Timer_B.
     
    The TI documentation says that the drivers "provide a mechanism that makes it easy to use the device
  23. Like
    Clavier got a reaction from tripwire in Have feedback for TI? Please share here.   
    Of all the components in an MCU, only the CPU itself is hidden by the compiler; changing anything else would not be portable.
     
    By combining an ARM CPU with the MSP430 peripherals, they allow existing MSP430 program(mer)s to use a faster CPU, without having to do much porting.
    The MSP432 is useful for somebody coming from MSP430, not from any other ARM.
  24. Like
    Clavier got a reaction from zeke in MIDI Booster Pack   
    And it links to this thread!
     
    And the schematic is capable of improvement: the output connector's pin 2 must be grounded; the unused inverters' inputs must not float; the optocoupler needs a resistor of about 10 k? between pins 5 and 7; and it needs a decoupling capacitor between pins 5 and 8.
  25. Like
    Clavier got a reaction from Shiv in Parsing "strings" in C - Attempting to parse MQTT payload   
    If a byte and a char have the same size, casting is no problem.
     
    To avoid modifying the data, don't use zero-terminated strings; just use pointer+length everywhere:
    static void parseParameter(const char *param, size_t length); static void handleNameValue(const char *name, size_t nameLength, const char *value, size_t valueLength); static void handleCmd(const char *value, size_t length); static void handleColor(const char *value, size_t length); // etc. void parsePayload(const char *payload, size_t length) { size_t i, paramStartIndex = 0; for (i = 0; i < length; i++) { if (payload[i] == '&') { parseParameter(paramStartIndex, i - paramStartIndex); paramStartIndex = i + 1; } } parseParameter(paramStartIndex, length - paramStartIndex); } static void parseParameter(const char *param, size_t length) { size_t i; for (i = 0; i < length; i++) if (param[i] == '=') { handleNameValue(param, i, &param[i + 1], length - (i + 1)); break; } } #define memeq(a,b,sz) (!memcmp(a,b,sz)) #define isString(value, length, literal) (length == sizeof(literal) - 1 && memeq(value, literal, length)) static void handleNameValue(const char *name, size_t nameLength, const char *value, size_t valueLength) { if (isString(name, nameLength, "cmd")) { handleCmd(value, valueLength); } else if (isString(name, nameLength, "color")) { handleColor(value, valueLength); } else if (isString(name, nameLength, "state")) { handleState(value, valueLength); } } static void handleCmd(const char *value, size_t length) { if (isString(value, length, "led")) { remoteCommand.command = Command::Led; } } static void handleColor(const char *value, size_t length) { if (isString(value, length, "red")) { remoteCommand.ledColor = LedColor::red; } else if (isString(value, length, "green")) { remoteCommand.ledColor = LedColor::green; } else if (isString(value, length, "blue")) { remoteCommand.ledColor = LedColor::blue; } } // etc.
×
×
  • Create New...