Jump to content


  • Content count

  • Joined

  • Last visited

  • Days Won


terjeio last won the day on June 7

terjeio had the most liked content!

About terjeio

  • Rank
    Level 1

Profile Information

  • Gender
  • Location
  • Interests
    Electronic design, motion control, programming
  • Github

Recent Profile Visitors

778 profile views
  1. Did you debounce the switch signal with some kind of circuit first? If not I believe you need add a debouncer, possibly in code. MAX6816 is an easy to use chip but adds parts and cost to the design, doing it by code only needs some programming effort to make it work.
  2. terjeio

    IRremote Library Not Working

    Protocol mismatch? Wrong modulation frequency? Hardware problem? Use a mobile phone camera to see if there is any activity out of the IR diode, assuming you are using one for transmission.
  3. terjeio

    UCAxCTL0 Register

    The information can be found in the device datasheet and it depends on which pins you are connecting to, from figure 4.1: P3.3/UCA0TXD/UCA0SIMO P3.4/UCA0RXD/UCA0SOMI and P4.5/PM_UCA1RXD/PM_UCA1SOMI P4.4/PM_UCA1TXD/PM_UCA1SIMO It can also be inferred from table 3.1 - number of USCI channels. Channel A is listed with 2 instances, meaning x = 0 and x = 1 is available.
  4. terjeio

    RFC: CNC BoosterPack

    Design is now published on Github, driver code to follow when completed - some new features needs to be verified first. A Youtube video showing off the PCB and some additional parts is here: GRBL DRO & MPG Terje
  5. terjeio

    MSP432P401R LaunchPad Black EEPROM

    As a part of my grbl port I added support for a Microchip 24LC16B 2K EEPROM a few days ago - the code is pure CMSIS and uses I2C polling so I do not know if it can be used with Energia. I did not get ACK-polling to work so I resorted to a delay for writing, maybe I will look into that later. The code is a bit "raw", there is no real support for handling abnormal conditions. /* eeprom.c - driver code for Texas Instruments MSP432 ARM processor for 2K EEPROM on CNC Boosterpack (Microchip 24LC16B) Part of Grbl Copyright (c) 2017-2018 Terje Io Grbl is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Grbl is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Grbl. If not, see <http://www.gnu.org/licenses/>. */ #include <msp.h> #include <stdint.h> #include <stdbool.h> #include "driver.h" #include "GRBL/grbl.h" #define EEPROM_I2C_ADDRESS (0xA0 >> 1) #define EEPROM_ADDR_BITS_LO 8 #define EEPROM_BLOCK_SIZE (2 ^ EEPROM_LO_ADDR_BITS) #define EEPROM_PAGE_SIZE 16 typedef struct { uint8_t addr; volatile int16_t count; uint8_t *data; uint8_t word_addr; } i2c_trans_t; static i2c_trans_t i2c; void eepromInit (void) { P6->SEL0 |= BIT4|BIT5; // Assign I2C pins to USCI_B0 // NVIC_EnableIRQ(EUSCIB1_IRQn); EUSCI_B1->CTLW0 |= EUSCI_B_CTLW0_SWRST; // Put EUSCI_B1 in reset state EUSCI_B1->CTLW0 |= EUSCI_B_CTLW0_MODE_3|EUSCI_B_CTLW0_MST| EUSCI_B_CTLW0_SYNC; // I2C master mode, SMCLK EUSCI_B1->BRW = 240; // baudrate 100 KHZ (SMCLK = 48MHz) EUSCI_B1->CTLW0 &=~ EUSCI_B_CTLW0_SWRST; // clear reset register // EUSCI_B1->IE = EUSCI_B_IE_NACKIE; // NACK interrupt enable } /* could not get ACK polling to work... static void WaitForACK (void) { while(EUSCI_B1->STATW & EUSCI_B_STATW_BBUSY); do { EUSCI_B1->IFG &= ~(EUSCI_B_IFG_TXIFG0|EUSCI_B_IFG_RXIFG0); EUSCI_B1->CTLW0 |= EUSCI_B_CTLW0_TR|EUSCI_B_CTLW0_TXSTT; // I2C TX, start condition while (EUSCI_B1->CTLW0 & EUSCI_B_CTLW0_TXSTT) { // Ensure stop condition got sent if(!(EUSCI_B1->IFG & EUSCI_B_IFG_NACKIFG)) // Break out if ACK received break; } // EUSCI_B1->CTLW0 |= EUSCI_B_CTLW0_TXSTP; // while (EUSCI_B1->CTLW0 & EUSCI_B_CTLW0_TXSTP); // Ensure stop condition got sent __delay_cycles(5000); } while(EUSCI_B1->IFG & EUSCI_B_IFG_NACKIFG); // EUSCI_B1->CTLW0 |= EUSCI_B_CTLW0_TXSTP; // while (EUSCI_B1->CTLW0 & EUSCI_B_CTLW0_TXSTP); // Ensure stop condition got sent } */ static void StartI2C (bool read) { bool single = i2c.count == 1; EUSCI_B1->I2CSA = i2c.addr; // Set EEPROM address and MSB part of data address EUSCI_B1->IFG &= ~(EUSCI_B_IFG_TXIFG0|EUSCI_B_IFG_RXIFG0); // Clear interrupt flags EUSCI_B1->CTLW0 |= EUSCI_B_CTLW0_TR|EUSCI_B_CTLW0_TXSTT; // Transmit start condition and address while(!(EUSCI_B1->IFG & EUSCI_B_IFG_TXIFG0)); // Wait for TX EUSCI_B1->TXBUF = i2c.word_addr; // Transmit data address LSB // EUSCI_B1->IFG &= ~EUSCI_B_IFG_TXIFG0; // Clear TX interrupt flag and while(!(EUSCI_B1->IFG & EUSCI_B_IFG_TXIFG0)); // wait for transmit complete if(read) { // Read data from EEPROM: EUSCI_B1->CTLW0 |= EUSCI_B_CTLW0_TXSTP; // Transmit STOP condtition while (EUSCI_B1->CTLW0 & EUSCI_B_CTLW0_TXSTP); // and wait for it to complete EUSCI_B1->CTLW0 &= ~EUSCI_B_CTLW0_TR; // Set read mode if(single) // and issue EUSCI_B1->CTLW0 |= EUSCI_B_CTLW0_TXSTT|EUSCI_B_CTLW0_TXSTP; // restart and stop condition if single byte read else // else EUSCI_B1->CTLW0 |= EUSCI_B_CTLW0_TXSTT; // restart condition only while(i2c.count) { // Read data... if(!single && i2c.count == 1) { EUSCI_B1->CTLW0 |= EUSCI_B_CTLW0_TXSTP; while (EUSCI_B1->CTLW0 & EUSCI_B_CTLW0_TXSTP) { while(!(EUSCI_B1->IFG & EUSCI_B_IFG_RXIFG0)); } } else while(!(EUSCI_B1->IFG & EUSCI_B_IFG_RXIFG0)); i2c.count--; *i2c.data++ = EUSCI_B1->RXBUF; } } else { // Write data to EEPROM: while (i2c.count--) { EUSCI_B1->TXBUF = *i2c.data++; while(!(EUSCI_B1->IFG & EUSCI_B_IFG_TXIFG0)); } EUSCI_B1->CTLW0 |= EUSCI_B_CTLW0_TXSTP; // I2C stop condition // WaitForACK(); hal.delay_ms(5, 0); // Wait a bit for the write cycle to complete } while (EUSCI_B1->CTLW0 & EUSCI_B_CTLW0_TXSTP); // Ensure stop condition got sent } uint8_t eepromGetByte (uint32_t addr) { uint8_t value = 0; i2c.addr = EEPROM_I2C_ADDRESS | (addr >> 8); i2c.word_addr = addr & 0xFF; i2c.data = &value; i2c.count = 1; StartI2C(true); return value; } void eepromPutByte (uint32_t addr, uint8_t new_value) { i2c.addr = EEPROM_I2C_ADDRESS | (addr >> 8); i2c.word_addr = addr & 0xFF; i2c.data = &new_value; i2c.count = 1; StartI2C(false); } void eepromWriteBlockWithChecksum (uint32_t destination, uint8_t *source, uint32_t size) { uint32_t bytes = size; i2c.word_addr = destination & 0xFF; i2c.data = source; while(bytes > 0) { i2c.count = EEPROM_PAGE_SIZE - (destination & (EEPROM_PAGE_SIZE - 1)); i2c.count = bytes < i2c.count ? bytes : i2c.count; i2c.addr = EEPROM_I2C_ADDRESS | (destination >> EEPROM_ADDR_BITS_LO); bytes -= i2c.count; destination += i2c.count; StartI2C(false); i2c.word_addr = destination & 0xFF; } eepromPutByte(destination, calc_checksum(source, size)); } bool eepromReadBlockWithChecksum (uint8_t *destination, uint32_t source, uint32_t size) { i2c.addr = EEPROM_I2C_ADDRESS | (source >> 8); i2c.word_addr = source & 0xFF; i2c.count = size; i2c.data = destination; StartI2C(true); return calc_checksum(destination, size) == eepromGetByte(source + size); }
  6. terjeio

    Raw ECG Signal Processing with MSP430

    I think you first need to assess the signal quality at the output of the amplifier with an oscilloscope, to me it looks like that electrode contact may be bad or the electrodes may be misplaced (assuming the signal is not from a simulator). I would not expect this much noise in the output from the amplifier - IMO you need a far cleaner signal to start with before any analysis can be done, except perhaps be able to extract the heart rate.
  7. terjeio

    MSP430F5529 and RFM12b used together

    Not always so, e.g.: 2 + 1 + 1 = 4, 2 | 1 | 1 = 3 I prefer to OR bitwise constants, adding them is not logical...
  8. terjeio

    IR remote library

    I have wirtten code for RC5 and NEC/Samsung decoding that may be of use. It is not written as an Energia library though - I am using CCS and DriverLib. I use it for my multimedia center so originally only for RC5 commands, I added Samsung (nearly same as NEC) decoding so I could use my TV remote for volume control as well as my dedicated RC5 based remote. The Samsung commands are translated to their RC5 equivalents. remote.zip
  9. terjeio

    MSP432P401R Remapping Pins

    @fmilburn It is brought out to JP4.1 as RTS for the backchannel UART so it is accessible if a jumper is removed (it is not in place on my LaunchPad and I cannot remember if I removed it earlier, I believe not). I have a black edition if that matters. Terje
  10. From assembler it can be seen as 16 or 20bit depending on the instruction set used - MSP430 or MSP430X, it has a 16/20bit ALU. I would guess a C-compiler will mix 16/20bit style instructions for speed if memory requirement is > 64K. The OP never mentioned if using C or assembler and what the value is needed for - printing? a calculation? store somewhere else (in a "variable")?. To load a 64bit value from consecutive words in memory into registers from assembler code register indirect adressing mode with auto increment is the easiest. Move the stack pointer into a register and add (or subtract?) the offset needed to reach the data and use it as the base (assuming the data lives in a stack frame with a fixed offset from the current stack pointer value). From C code use the * dereference operator to read from an address into a variable. It may be possible to read the data into separate registers from C as 16 bit values, but then you are at the mercy of the compiler. I have not looked into how to get at the stack pointer from C, doable? Use a global variable instead of picking it off the stack? A final note: I do not understand why loading into register(s) is required...
  11. terjeio

    MSP430F5529 and RFM12b used together

    I think I have spotted at least three mistakes when reading back the result: 1 . You shift the contents of P6IN the wrong way and do not mask the unwanted bits before or'ing with the result (assuming MSB is sent first). 2. You shift the result after adding a new bit, the shift should be done before adding it. 3. You deselect the device after reading the first bit (MSB) of the result. Move setting nSel high out of the loop. result <<= 1; result |= (P6IN >> 6) & 0x01; The code above migth work for reading the result. However, why not use one of the USCI modules for SPI instead of bitbanging? From a quick glance at the datasheet it seems you can use a fairly high data rate.
  12. terjeio

    RFC: CNC BoosterPack

    @bluehash Thanks. This is not a commercial project, only a small batch of boards will be made and my plan is to make a few available at cost. @jazz I am not sure I understand your point, the ICs will be run well below their max power rating and output transistors are placed close to the connectors so that the connector pins acts as heat sinks. The motor drivers will be the only components with significant power draw/dissipation, this may cause a bit of heating above ambient for the pcb tracks going to the motor connectors. Shorter tracks would be better but (IMO) lead to a more messy design. Also, when routing, I was a bit surprised that I ended up with relatively few vias and fairly clean ground planes. I could have dropped support for the MSP430F2955 launchpad to allow more flexible pin assignments and thus made routing easier. However, since I was able to make a driver for GRBL I wanted to add it. This also means the design follows the BoosterPack design guidelines more closely (but still not 100% compliant). Terje
  13. terjeio

    RFC: CNC BoosterPack

    I have recently been working on a CNC BoosterPack that I will make available on Github when completed later in the spring. Current specifications: Support for my HALified version of GRBL (based on 1.1), currently drivers has been made for MSP432 (black version), Tiva C and MSP430F2955. NOTE: firmware is built with CCS 6.1, MSP432 driver is 100% CMSIS based. Opto-coupled inputs, NC switches recommended. Opto-coupled outputs with 200mA open drain drive for spindle on, spindle direction, flood and mist. Can drive most relays and solenoids directly. Output section can be powered from internal 3V3 or 5V source, or from external source. If powered from external source outputs can be made opto-isolated via jumper setting. PWM-output for spindle speed currently directly connected to MCU pin (could be changed to open drain). I2C (IIC) interface with selectable voltage level (3V3 or 5V) via level shifter, dedicated interrupt input. I2C pinout compatible with my 4x4 keyboard project, supports jogging etc. Optional EEPROM for configuration settings for MCUs with no internal EEPROM. Polulu 8825 motor driver breakout board compatible. Fault signal routed to GPIO input. Considered for later revision: Break out SPI interface and add full support for Trinamic motor drivers. Optional (SPI) DAC for motor speed (laser power) control. This might require a 4-layer PCB and also solving the pinout cabal... --- Anything you want changed? Terje