Teensy 4.0 First Beta Test

Status
Not open for further replies.
This one is also easy. I believe it's already been covered, but just in case the answer hasn't been clear...

This is absolutely the correct expected behavior. The ON/OFF state is maintained as long as the low-power (or "SNVS") portion of the chip has at least 1 volt.

Yes, the only surprising thing is that the 'unplugged' Teensy has live MCU circuits powered by the UARTS so it can respond to the Power button when ( if not for the dim glow of the breakout LED ) the T4 would otherwise be assumed to be Unpowered and in no condition to maintain state.

User case: Teensy goes Off while on USB power - without UART or vBat power unplugging and replugging would result in the T4 running normal setup() - like any Teensy.

That just shows that UARTS on pins keep alive - there is at least one variant in those posts where USB gets ODD with current stack - those would be the important ones to make sure the code can restart/reconnect

This one does that - when externally powered with cut traces:: From 5/19 post #2889 when using external power with VIN<>VUSB trace cut
 
Yes, the only surprising thing is that the 'unplugged' Teensy has live MCU circuits powered by the UARTS so it can respond to the Power button when ( if not for the dim glow of the breakout LED ) the T4 would otherwise be assumed to be Unpowered and in no condition to maintain state.

User case: Teensy goes Off while on USB power - without UART or vBat power unplugging and replugging would result in the T4 running normal setup() - like any Teensy.

Yes, this will be "fixed" by documentation.

You may recall I talked about being a bit reluctant to make the on/off feature available to Arduino users... months ago in the transition from 1052 (where I wired the 3.3V regulator always on) and 1062 (where all have supported on/off). It can be confusing when the hardware is "off", for whatever reason. It can be confusing when you believe you've shut off the power, but the caps don't fully discharge or microamps of current leak through the pins from something else that still has power. These are issues that will need to be documented on the troubleshooting page. Fortunately, it is pretty easy to check with a multimeter whether the power really went all the way to zero volts.

The on/off feature is so very useful for people making battery powered projects. It would seem like quite a shame to have this in the hardware and not make it available to users.


That just shows that UARTS on pins keep alive - there is at least one variant in those posts where USB gets ODD with current stack - those would be the important ones to make sure the code can restart/reconnect

This one does that - when externally powered with cut traces:: From 5/19 post #2889 when using external power with VIN<>VUSB trace cut

I tried to read through your messages again. There seems to be a lot of talk where the USB communication not restarting is mixed up with the on/off power management. Some parts I can't quite parse what you mean.

I also see a lot of talk about an Orico Hub/Drive which unintentionally powers T4 through the host port. While that's wrong hub behavior and we may see if from other hubs, as far as T4 is concerned this is the same as if you connected external 5V power to VIN. Nothing I can do about that in the T4 hardware or software.

Are there other outstanding issues I should investigate? Did I miss anything else in those messages?
 
I also see a lot of talk about an Orico Hub/Drive which unintentionally powers T4 through the host port. While that's wrong hub behavior and we may see if from other hubs, as far as T4 is concerned this is the same as if you connected external 5V power to VIN. Nothing I can do about that in the T4 hardware or software.

Are there other outstanding issues I should investigate? Did I miss anything else in those messages?
@Paul and @defragster - this was my b) part in the earlier message:
b) Powered USB Hub... I am thinking this is maybe more support chip differences between the T3.6 and your T4 breakout board.

That is if you look at the Teensy 3.5/6 schematic (https://www.pjrc.com/teensy/schematic.html)
You will see the chip TPD3S014 (http://www.ti.com/lit/ds/symlink/tpd3s014.pdf), which I think is controlling the USB power to the host port. And it has an enable pin connected to PTE6 which has a PD resistor connected to it and which the USBHost code specifically enables int USBHost::begin()...

I believe that the breakout boards are using a TPS055A chip? (looks like: https://www.ti.com/lit/ds/symlink/tps2058a.pdf) marking 2055a and it looks like the enable is simply tied to +5v. do not sure if there could be some voltage coming in on D+/D- or the like, which may float enable high enough?

So my guess is if someone wanted to hardware experiment to get T4 to act like T3.6 here could try:
1) Use same chip as T3.6 and use an IO pin with PD resistor to enable pin
2) Try current breakout board, Disconnect pin 4 (enable) currently tied to +5v, and run a jumper to some IO pin with PD resistor... Obviously will then need to enable this pin, when a program wishes to use USB Host...
I believe that @defragster said that this disk/hub did not power up a T3.6... So looking at differences in the hardware, it looks like for these breakout boards you chose a different support chip to limit current and that on T3.6 the enable pin was tied to an IO pin and on your breakout it is set to +5v... For me probably not an issue, but wondering what are the trade offs of the two different chips.

That is I am thinking of ordering a batch of the breakout board I am playing with and wondering which way to go...

Also wondering where best to place the flat ribbon connector for the SD card under the chip... But different subject
 
PROPSHIELD/MPL3115A2
I ported over the MPL code into a separate library format and tested it on the T3.5 and the T4. Again works on the T3.5 but not on the T4 for some strange reason - just hangs at the same point. The port is over on my WIP GitHub page: https://github.com/mjs513/WIP/tree/master/MPL3115 if somebody with a prop shield wants to give it a try.

Thanks
Mike
 
@Paul and @defragster - this was my b) part in the earlier message:

I believe that @defragster said that this disk/hub did not power up a T3.6... So looking at differences in the hardware, it looks like for these breakout boards you chose a different support chip to limit current and that on T3.6 the enable pin was tied to an IO pin and on your breakout it is set to +5v... For me probably not an issue, but wondering what are the trade offs of the two different chips.

That is I am thinking of ordering a batch of the breakout board I am playing with and wondering which way to go...

Also wondering where best to place the flat ribbon connector for the SD card under the chip... But different subject

@Paul and KurtE

Good to know you've walked through the issues - indeed they all relate to some core powered parts powered when not 'apparent'.

Kurt - ... - of course T_3.6 acts better - there was an MCU pin handy for better power control that makes sense now.

Gotta run - but knowing the USB is under control with that issue fixed - and there aren't any other aspects of VamPower going to bite like brown out startup did all good
 
Re: WavFilePlayer

There has been a problem with WavFilePlayer on T3.6 with BUILTIN_SDCARD, see https://forum.pjrc.com/threads/56239-Simple-WavFilePlayer-not-working

I decided to test on T4B2. T4B2 WavFilePlayer example "works" from audio adapter uSD (SPI) (I don't have needed SMD resistor for codec, so i get noise through ear buds, but it appears WAV files are playing). If I use BUILTIN_SDCARD, i get no audio and serial monitor never says it's "playing". Example listfiles and other SD IO seems to work with BUILTIN_SDCARD (1.8.8/1.47-beta2)

Can others confirm ?

Editing play_sd_wav.h and play_sd_wav.cpp
I aligned buffer and commented out __disable_irq() before SD.open(), and WavFilePlayer seems to be playing on T4B2 (observed with scope), fix based on following:
https://forum.pjrc.com/threads/56355-AudioPlaySdWav-DMA-timing-and-buffer-misalignment-issues

AudioPlaySdRaw with BUILTIN_SDCARD also hangs -- works if you remove __disable_irq() before SD.open() in libraries/Audio/play_sd_raw.cpp

maybe this pull request: https://github.com/PaulStoffregen/Audio/pull/294

more discussions
 
Last edited:
Also wondering where best to place the flat ribbon connector for the SD card under the chip...

The ones I used on the last round of breakout boards are Digikey AE11351-ND.

For the end plugging into the bottom side of T4, I had to put a ~90 degree kink in the blue tab by bending it over the edge of needle nose pliers.
 
PROPSHIELD/MPL3115A2
I ported over the MPL code into a separate library format and tested it on the T3.5 and the T4. Again works on the T3.5 but not on the T4 for some strange reason - just hangs at the same point. The port is over on my WIP GitHub page: https://github.com/mjs513/WIP/tree/master/MPL3115 if somebody with a prop shield wants to give it a try.

Thanks
Mike

Hi @mjs513 - Looks like it is hanging in Wire library... I am pretty sure I have it hooked up reasonably ...
Ran the scanner sketch with wire...
Code:
Scanning...
Device found at address 0x1E  (LSM303D,HMC5883L,FXOS8700,LIS3DSH)
Device found at address 0x20  (MCP23017,MCP23008,PCF8574,FXAS21002,SoilMoisture)
Device found at address 0x60  (MPL3115,MCP4725,MCP4728,TEA5767,Si5351)
done

Scanning...
Device found at address 0x1E  (LSM303D,HMC5883L,FXOS8700,LIS3DSH)
Device found at address 0x20  (MCP23017,MCP23008,PCF8574,FXAS21002,SoilMoisture)
Device found at address 0x60  (MPL3115,MCP4725,MCP4728,TEA5767,Si5351)
done

I hacked up the wireimxrt.cpp code to be able to turn on/off debug and output to Serial...
Code:
#include "Wire.h"

#if defined(__IMXRT1052__) || defined(__IMXRT1062__)

#define DEBUG_WIRE
#ifdef DEBUG_WIRE
#define DBGPrintf Serial.printf
#else
void inline DBGPrintf(...) {};
#endif
//#include "debug/printf.h"

void TwoWire::begin(void)
{
        // use 24 MHz clock
        CCM_CSCDR2 = (CCM_CSCDR2 & ~CCM_CSCDR2_LPI2C_CLK_PODF(63)) | CCM_CSCDR2_LPI2C_CLK_SEL;
	hardware.clock_gate_register |= hardware.clock_gate_mask;
        port->MCR = LPI2C_MCR_RST;
        setClock(100000);
	hardware.sda_mux_register = hardware.sda_mux_value;
	hardware.scl_mux_register = hardware.scl_mux_value;
	hardware.sda_input_register = hardware.sda_input_value;
	hardware.scl_input_register = hardware.scl_input_value;
	hardware.sda_pad_register |= IOMUXC_PAD_PKE | IOMUXC_PAD_PUE | IOMUXC_PAD_PUS(3);
	hardware.scl_pad_register |= IOMUXC_PAD_PKE | IOMUXC_PAD_PUE | IOMUXC_PAD_PUS(3);
}

void TwoWire::begin(uint8_t address)
{
	// TODO: slave mode
}

void TwoWire::end()
{
}

size_t TwoWire::write(uint8_t data)
{
	if (transmitting || slave_mode) {
		if (txBufferLength >= BUFFER_LENGTH+1) {
			setWriteError();
			return 0;
		}
		txBuffer[txBufferLength++] = data;
		return 1;
	}
	return 0;
}

size_t TwoWire::write(const uint8_t *data, size_t quantity)
{
	if (transmitting || slave_mode) {
		size_t avail = BUFFER_LENGTH+1 - txBufferLength;
		if (quantity > avail) {
			quantity = avail;
			setWriteError();
		}
		memcpy(txBuffer + txBufferLength, data, quantity);
		txBufferLength += quantity;
		return quantity;
	}
	return 0;
}

uint8_t TwoWire::endTransmission(uint8_t sendStop)
{
	uint32_t i=0, len, status;

	len = txBufferLength;
	if (!len) return 4; // no data to transmit

	// wait while bus is busy
	while (1) {
		status = port->MSR; // pg 2899 & 2892
		if (!(status & LPI2C_MSR_BBF)) break; // bus is available
		if (status & LPI2C_MSR_MBF) break; // we already have bus control
		// TODO: timeout...
	}
	DBGPrintf("m=%x\n", status);

	// TODO: is this correct if the prior use didn't send stop?
	//port->MSR = LPI2C_MSR_PLTF | LPI2C_MSR_ALF | LPI2C_MSR_NDF | LPI2C_MSR_SDF; // clear flags
	port->MSR = status;

	DBGPrintf("MSR=%lX, MFSR=%lX\n", status, port->MFSR);
	elapsedMillis timeout=0;

	while (1) {
		// transmit stuff, if we haven't already
		if (i <= len) {
			uint32_t fifo_used = port->MFSR & 0x07; // pg 2914
			if (fifo_used < 4) DBGPrintf("t=%ld\n", fifo_used);
			while (fifo_used < 4) {
				if (i == 0) {
					DBGPrintf("start %x\n", txBuffer[0]);
					port->MTDR = LPI2C_MTDR_CMD_START | txBuffer[0];
					i = 1;
				} else if (i < len) {
					port->MTDR = LPI2C_MTDR_CMD_TRANSMIT | txBuffer[i++];
				} else {
					if (sendStop) port->MTDR = LPI2C_MTDR_CMD_STOP;
					i++;
					break;
				}
				fifo_used = fifo_used + 1;
			}
		}
		// monitor status
		status = port->MSR; // pg 2899 & 2892
		if (status & LPI2C_MSR_ALF) {
			DBGPrintf("arbitration lost\n");
			return 4; // we lost bus arbitration to another master
		}
		if (status & LPI2C_MSR_NDF) {
			DBGPrintf("NACK, f=%d, i=%d\n", port->MFSR & 0x07, i);
			// TODO: check that hardware really sends stop automatically
			port->MCR = LPI2C_MCR_MEN | LPI2C_MCR_RTF;  // clear the FIFO
			// TODO: is always sending a stop the right way to recover?
			port->MTDR = LPI2C_MTDR_CMD_STOP;
			return 2; // NACK for address
			//return 3; // NACK for data TODO: how to discern addr from data?
		}
		if (status & LPI2C_MSR_PLTF) {
			DBGPrintf("bus stuck - what to do?\n");
			return 4;
		}

		if (timeout > 100) {
			DBGPrintf("status = %x\n", status);
			timeout = 0;
		}

		if (sendStop) {
			if (status & LPI2C_MSR_SDF) {
				// master automatically sends stop condition on some
				// types of errors, so this flag only means success
				// when all comments in fifo have been fully used
				uint32_t fifo = port->MFSR & 0x07;
				if (fifo == 0) return 0;
			}
		} else {
			uint32_t fifo_used = port->MFSR & 0x07; // pg 2914
			if (fifo_used == 0) {
				//digitalWriteFast(15, HIGH);
				//delayMicroseconds(2);
				//digitalWriteFast(15, LOW);
				// TODO: this returns before the last data transmits!
				// Should verify every byte ACKs, arbitration not lost
				DBGPrintf("fifo empty, msr=%x\n", status);
				return 0;
			}
		}
	}
}

uint8_t TwoWire::requestFrom(uint8_t address, uint8_t length, uint8_t sendStop)
{
	uint32_t cmd=0, status, fifo;

	// wait while bus is busy
	while (1) {
		status = port->MSR; // pg 2899 & 2892
		if (!(status & LPI2C_MSR_BBF)) break; // bus is available
		if (status & LPI2C_MSR_MBF) break; // we already have bus control
		// TODO: timeout...
	}
	DBGPrintf("idle2, msr=%x\n", status);

	// TODO: is this correct if the prior use didn't send stop?
	port->MSR = LPI2C_MSR_PLTF | LPI2C_MSR_ALF | LPI2C_MSR_NDF | LPI2C_MSR_SDF; // clear flags

	//DBGPrintf("MSR=%lX, MFSR=%lX\n", status, port->MFSR);
	address = (address & 0x7F) << 1;
	if (length < 1) length = 1;
	if (length > 255) length = 255;
	rxBufferIndex = 0;
	rxBufferLength = 0;

	elapsedMillis timeout=0;

	while (1) {
		// transmit stuff, if we haven't already
		if (cmd < 3) {
			fifo = port->MFSR & 0x07; // pg 2914
			//if (fifo < 4) DBGPrintf("t=%ld\n", fifo);
			while (fifo < 4 && cmd < 3) {
				if (cmd == 0) {
					port->MTDR = LPI2C_MTDR_CMD_START | 1 | address;
				} else if (cmd == 1) {
					// causes bus stuck... need way to recover
					//port->MTDR = LPI2C_MTDR_CMD_START | (length - 1);
					port->MTDR = LPI2C_MTDR_CMD_RECEIVE | (length - 1);
				} else {
					if (sendStop) port->MTDR = LPI2C_MTDR_CMD_STOP;
				}
				cmd++;
				fifo = fifo + 1;
			}
		}
		// receive stuff
		if (rxBufferLength < sizeof(rxBuffer)) {
			fifo = (port->MFSR >> 16) & 0x07;
			//if (fifo > 0) DBGPrintf("r=%ld\n", fifo);
			while (fifo > 0 && rxBufferLength < sizeof(rxBuffer)) {
				rxBuffer[rxBufferLength++] = port->MRDR;
				fifo = fifo - 1;
			}
		}
		// monitor status
		status = port->MSR; // pg 2899 & 2892
		if (status & LPI2C_MSR_ALF) {
			DBGPrintf("arbitration lost\n");
			break;
		}
		if (status & LPI2C_MSR_NDF) {
			DBGPrintf("got NACK\n");
			// TODO: how to make sure stop is sent?
			break;
		}

		if (timeout > 250) {
			DBGPrintf("Status = %x\n", status);
			timeout = 0;
		}

		if (rxBufferLength >= length && cmd >= 3) break;
	}
	//digitalWriteFast(15, HIGH);
	//delayMicroseconds(2);
	//digitalWriteFast(15, LOW);
	return rxBufferLength;
}





PROGMEM
constexpr TwoWire::I2C_Hardware_t TwoWire::i2c1_hardware = {
        CCM_CCGR2, CCM_CCGR2_LPI2C1(CCM_CCGR_ON),
	IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_01, // 18/A4  AD_B1_01  GPIO1.17  I2C1_SDA
	IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_00, // 19/A5  AD_B1_00  GPIO1.16  I2C1_SCL
	IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B1_01,
	IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B1_00,
	IOMUXC_LPI2C1_SDA_SELECT_INPUT,
	IOMUXC_LPI2C1_SCL_SELECT_INPUT,
	3 | 0x10,
	3 | 0x10,
	1,
	1,
        IRQ_LPI2C1
};
TwoWire Wire(&IMXRT_LPI2C1, TwoWire::i2c1_hardware);

PROGMEM
constexpr TwoWire::I2C_Hardware_t TwoWire::i2c3_hardware = {
        CCM_CCGR2, CCM_CCGR2_LPI2C3(CCM_CCGR_ON),
	IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_06, // 17/A3  AD_B1_06  GPIO1.22  I2C3_SDA
	IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_07, // 16/A2  AD_B1_07  GPIO1.23  I2C3_SCL
	IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B1_06,
	IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B1_07,
	IOMUXC_LPI2C3_SDA_SELECT_INPUT,
	IOMUXC_LPI2C3_SCL_SELECT_INPUT,
	1 | 0x10,
	1 | 0x10,
	2,
	2,
        IRQ_LPI2C3
};
TwoWire Wire1(&IMXRT_LPI2C3, TwoWire::i2c3_hardware);

PROGMEM
constexpr TwoWire::I2C_Hardware_t TwoWire::i2c4_hardware = {
        CCM_CCGR6, CCM_CCGR6_LPI2C4_SERIAL(CCM_CCGR_ON),
	IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B0_13, // 25/A11  AD_B0_13  GPIO1.13  I2C4_SDA
	IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B0_12, // 24/A10  AD_B1_12  GPIO1.12  I2C4_SCL
	IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B0_13,
	IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B0_12,
	IOMUXC_LPI2C4_SDA_SELECT_INPUT,
	IOMUXC_LPI2C4_SCL_SELECT_INPUT,
	0 | 0x10,
	0 | 0x10,
	1,
	1,
        IRQ_LPI2C4
};
TwoWire Wire2(&IMXRT_LPI2C4, TwoWire::i2c4_hardware);





void TwoWire::setClock(uint32_t frequency)
{
        port->MCR = 0;
	if (frequency < 400000) {
		// 100 kHz
		port->MCCR0 = LPI2C_MCCR0_CLKHI(55) | LPI2C_MCCR0_CLKLO(59) |
			LPI2C_MCCR0_DATAVD(25) | LPI2C_MCCR0_SETHOLD(40);
		port->MCFGR1 = LPI2C_MCFGR1_PRESCALE(1);
		port->MCFGR2 = LPI2C_MCFGR2_FILTSDA(5) | LPI2C_MCFGR2_FILTSCL(5) |
			LPI2C_MCFGR2_BUSIDLE(3900);
	} else if (frequency < 1000000) {
		// 400 kHz
		port->MCCR0 = LPI2C_MCCR0_CLKHI(26) | LPI2C_MCCR0_CLKLO(28) |
			LPI2C_MCCR0_DATAVD(12) | LPI2C_MCCR0_SETHOLD(18);
		port->MCFGR1 = LPI2C_MCFGR1_PRESCALE(0);
		port->MCFGR2 = LPI2C_MCFGR2_FILTSDA(2) | LPI2C_MCFGR2_FILTSCL(2) |
			LPI2C_MCFGR2_BUSIDLE(3900);
	} else {
		// 1 MHz
		port->MCCR0 = LPI2C_MCCR0_CLKHI(9) | LPI2C_MCCR0_CLKLO(10) |
			LPI2C_MCCR0_DATAVD(4) | LPI2C_MCCR0_SETHOLD(7);
		port->MCFGR1 = LPI2C_MCFGR1_PRESCALE(0);
		port->MCFGR2 = LPI2C_MCFGR2_FILTSDA(1) | LPI2C_MCFGR2_FILTSCL(1) |
			LPI2C_MCFGR2_BUSIDLE(3900);
	}
        port->MCCR1 = port->MCCR0;
        port->MCFGR0 = 0;
        port->MCFGR3 = LPI2C_MCFGR3_PINLOW(3900);
        port->MFCR = LPI2C_MFCR_RXWATER(1) | LPI2C_MFCR_TXWATER(1);
        port->MCR = LPI2C_MCR_MEN;
}

#endif

With some of the debug stuff turned on, you see it hang with status = 1300
Code:
Before Wire Begin
After Wire Begin
Start MPL3115A2::init
MPL3115A2::writeByte 60 26=4
    EndTransmission
m=1
MSR=1, MFSR=0
t=0
start c0
NACK, f=1, i=4
MPL Reset
m=3000401
MSR=3000401, MFSR=1
t=1
start c0
NACK, f=1, i=3
idle2, msr=3000701
got NACK
FF
m=3000700
MSR=3000700, MFSR=2
t=2
start c0
status = 1300
status = 1300
status = 1300
status = 1300
status = 1300
status = 1300
status = 1300
status = 1300

Wonder if the last send did not do a stop, if the next send should do a start? Or should it be repeat... I am not an I2C expert!
 
I've added the WavFilePlayer and MP3115 issues to the list on msg #6, so I'll remember to look at them in a couple weeks.

I still have another day or so of work to do on the test fixture. That's taken almost all my time since Maker Faire, but it's critically important to get done now. The last ~20 beta boards are sitting here waiting for testing. Those are the last virgin boards (OTP fuses in original state from NXP) to use with the test fixture until we get the first production run.

Next up will be more work on the bootloader and also the EEPROM library. So far, the bootloader has made 75% of the flash chip available for user code. The other 25% has been "reserved", so only the top 4K so far used to store a copy of the restore program. I'm probably going to reduce the reserved area to something like 64K to 128K. Will really depend on the EEPROM emulation, which I must confess I've been putting off because it's so difficult.

In a couple weeks (or whenever I get EEPROM working and a new bootloader rev done) I'm going to transition to filling out the rest of the USB device code and investigating these many issues. I know it's frustrating to have issues get put on hold, but please try to put anything that's broken onto the msg #6 list.
 
@KurtE - @PaulStoffregen

Thanks for giving it a sanity check for me. Thinking it has something to do with endTransmission(false) not really being working correctly going to try and look at it a bit more as well as what you identified with
Wonder if the last send did not do a stop, if the next send should do a start? Or should it be repeat... I am not an I2C expert!
Unfortunately I never played with I2C either so am groping in dark but maybe I can see something.

@Paul - don't envy you working the EEPROM was looking at the EEPROM driver in the STM32duino core for the H7, argh.....
 
Very well may be a bug in the Wire lib. Will look into this in a week or two, but first need to finish the test fixture, and work on the bootloader & EEPROM support.
 
@Paul
Understood - my text was that I was going to poke around a bit see if I could learn something along the way - no rush. The test fixture has to come first and then the bootloader and probably the USB. Then the EEPROM
 
PROPSHIELD/MPL3115A2
I ported over the MPL code into a separate library format and tested it on the T3.5 and the T4. Again works on the T3.5 but not on the T4 for some strange reason - just hangs at the same point. The port is over on my WIP GitHub page: https://github.com/mjs513/WIP/tree/master/MPL3115 if somebody with a prop shield wants to give it a try.

Thanks
Mike
MPL3115A2

With my propshield, I first used Sparkfun lib and MPL3115A2 example -- worked on T3.2, T3.6 and T4B2 (3v3 GND SDA SCL and Wire lib). This sensor uses I2C repeated start.

I tried your example on T4B2 and nothing printed. I then ran your sketch on T3.6 and it printed
995.80, 33.50
995.84, 33.50

I2C scanner worked on T4B2
Code:
Scanning...
Device found at address 0x1E  (LSM303D,HMC5883L,FXOS8700,LIS3DSH)
Device found at address 0x20  (MCP23017,MCP23008,PCF8574,FXAS21002,SoilMoisture)
Device found at address 0x60  (MPL3115,MCP4725,MCP4728,TEA5767,Si5351)
done

sparkfun lib https://github.com/sparkfun/MPL3115A2_Breakout

EDIT: I ran a dragonfly (Wire lib) version of Kris Winer's propshield sketch. sketch works on dragonfly and T3.6 but hangs on T4B2
 
Last edited:
MPL3115A2

With my propshield, I first used Sparkfun lib and MPL3115A2 example -- worked on T3.2, T3.6 and T4B2 (3v3 GND SDA SCL and Wire lib). This sensor uses I2C repeated start.

I tried your example on T4B2 and nothing printed. I then ran your sketch on T3.6 and it printed
995.80, 33.50
995.84, 33.50

I2C scanner worked on T4B2
Code:
Scanning...
Device found at address 0x1E  (LSM303D,HMC5883L,FXOS8700,LIS3DSH)
Device found at address 0x20  (MCP23017,MCP23008,PCF8574,FXAS21002,SoilMoisture)
Device found at address 0x60  (MPL3115,MCP4725,MCP4728,TEA5767,Si5351)
done

sparkfun lib https://github.com/sparkfun/MPL3115A2_Breakout

@manitou - other differences in pressure and temperature values that exactly what I am seeing. I tested it with the same Sparkfun library as you.

You made a comment about "This sensor uses I2C repeated start." I've seen that someplace before and how to handle it. Can't remember where now.
 
@manitou - other differences in pressure and temperature values that exactly what I am seeing. I tested it with the same Sparkfun library as you.

You made a comment about "This sensor uses I2C repeated start." I've seen that someplace before and how to handle it. Can't remember where now.

i think T4 wire lib is handling repeated start (using Wire.endTransmission(false); ) since sensor is working with sparkfun lib. I added a note about using a Wire-lib port of Kris Winer's sketch in my previous post -- it ran on T3.6 and dragonfly, but hung on T4B2
 
i think T4 wire lib is handling repeated start (using Wire.endTransmission(false); ) since sensor is working with sparkfun lib. I added a note about using a Wire-lib port of Kris Winer's sketch in my previous post -- it ran on T3.6 and dragonfly, but hung on T4B2

I agree I thought that also. The lib uses this for readByte:
Code:
uint8_t MPL3115A2::readByte(uint8_t address, uint8_t subAddress)
{
  uint8_t data; // `data` will store the register data   
  Wire.beginTransmission(address);         // Initialize the Tx buffer
  Wire.write(subAddress);                  // Put slave register address in Tx buffer
  Wire.endTransmission(false);       // Send the Tx buffer, but send a restart to keep connection alive
  //Wire.endTransmission(I2C_NOSTOP);        // Send the Tx buffer, but send a restart to keep connection alive
  Wire.requestFrom(address, (size_t) 1);   // Read one byte from slave register address 
  data = Wire.read();                      // Fill Rx buffer with result
  return data;                             // Return data read from slave register
}
As @KurtE showed in his debug it hangs on that second read. Think maybe will just wait until Paul has more time - don't want to give him any more distractions unless its critical. :) Will keep playing of course.
 
I agree I thought that also. The lib uses this for readByte:
Code:
uint8_t MPL3115A2::readByte(uint8_t address, uint8_t subAddress)
{
  uint8_t data; // `data` will store the register data   
  Wire.beginTransmission(address);         // Initialize the Tx buffer
  Wire.write(subAddress);                  // Put slave register address in Tx buffer
  Wire.endTransmission(false);       // Send the Tx buffer, but send a restart to keep connection alive
  //Wire.endTransmission(I2C_NOSTOP);        // Send the Tx buffer, but send a restart to keep connection alive
  Wire.requestFrom(address, (size_t) 1);   // Read one byte from slave register address 
  data = Wire.read();                      // Fill Rx buffer with result
  return data;                             // Return data read from slave register
}
As @KurtE showed in his debug it hangs on that second read. Think maybe will just wait until Paul has more time - don't want to give him any more distractions unless its critical. :) Will keep playing of course.

it worked if i added a delay(1) in readByte() after Wire.endTransmission(). maybe T4 is too fast
 
@manitou

Damn. You got it! Works for me as well. I did add a delay but put it between calls to readByte….. close. You might be right that the T4 is just too fast. Wonder if we put the delay(1) in the Wire lib for endTransmission?

Such a nice simple fix :)

Thanks.
 
@manitou

Damn. You got it! Works for me as well. I did add a delay but put it between calls to readByte….. close. You might be right that the T4 is just too fast. Wonder if we put the delay(1) in the Wire lib for endTransmission?

Such a nice simple fix :)

Thanks.
With the delay(1) (maybe a shorter microsecond delay will work?), the Wire adaptation (attached) of Kris Winer's propshield sketch works on T4B2, exercising all the MPU sensors. We'll need EEPROM to run the NXPMotionSense examples.

may also need delay(1) in readBytes()
 

Attachments

  • propshield.ino
    70.5 KB · Views: 68
Last edited:
@manitou
A couple of years ago I converted Kris's sketch into a library format call psIMU. I did the calibration a little different that what Paul has using his calibration tool. It has two options, (1) do it each time the way Kris's sketch does it or (2) put the calibration data in a file for accel and magnetometometer using a different tool I have used for the FreeIMU library. I then have two sketches where the first one interfaces with Madgwick and Mahoney filters and the other one links to the NXPSensorFusion that Paul has. Had to rewicker that of course to get it to work but at least for now it doesn't use the EEPROM library. That will come later. Will let you know it I get it all working with T4 and Propshield.

Like you suggested want to play with the delay a bit first.
 
@KurtE and @manitou

If I use a delayMicroseconds(150) just using MPL library it works fine. In the full sensor sketch looks like a delayMicroseconds(250) is needed for some reason. I am using 400k for clock in the sensor sketch. Anyway tested it my PSImu library using the NXPSensorFusion from Paul library and it seems to working. Have a few things to check and re-verify since its been a while since I tried it and then update the GitHub. But here is sample of the output:
Code:
---------------------
Orientation: 346.63 -0.14 0.63
rate = 80.82 Hz
---------------------
Orientation: 346.60 -0.13 0.63
rate = 80.82 Hz
---------------------
Orientation: 346.57 -0.13 0.65
rate = 80.82 Hz
---------------------

EDIT: So once the EEPROM lib is done I don't think there will be a problem running the NXPMotionSense examples. But that's a test for another day.
 
Status
Not open for further replies.
Back
Top