Teensy 4.0 First Beta Test

Status
Not open for further replies.
The T4 tree doesn't have file :: wiring_private.h
T:\arduino-1.8.8T4_146\hardware\teensy\avr\cores\teensy3\wiring_private.h:
1 /*
2: wiring_private.h - Internal header file.
3 Part of Arduino - http://www.arduino.cc/

Was going to try SSD1306 - and that came up.

Then this : T:\arduino-1.8.8T4_146\hardware\teensy\avr\libraries\Adafruit_GFX\glcdfont.c:13:0: warning: "PROGMEM" redefined
Put this in :
Code:
[B]#elif defined(__IMXRT1052__)
 #include <avr/pgmspace.h>[/B]
#else
 #define PROGMEM


Cascades to : T:\arduino-1.8.8T4_146\hardware\teensy\avr\libraries\Adafruit_GFX\Adafruit_SPITFT_Macros.h
T:\arduino-1.8.8T4_146\hardware\teensy\avr\libraries\Adafruit_GFX\Adafruit_SPITFT_Macros.h: In function 'uint8_t _avr_spi_read()':
T:\arduino-1.8.8T4_146\hardware\teensy\avr\libraries\Adafruit_GFX\Adafruit_SPITFT_Macros.h:93:5: error: 'SPDR' was not declared in this scope
T:\arduino-1.8.8T4_146\hardware\teensy\avr\libraries\Adafruit_GFX\Adafruit_SPITFT_Macros.h:94:13: error: 'SPSR' was not declared in this scope

T:\arduino-1.8.8T4_146\hardware\teensy\avr\libraries\Adafruit_GFX\Adafruit_SPITFT_Macros.h:94:24: error: 'SPIF' was not declared in this scope

>> That goes on with a couple other things in that file. All from dragging in SPI when I connect i2c.

Where this used to work:
Code:
    #if defined (__AVR__) || defined([B]TEENSYDUINO[/B])
static inline uint8_t _avr_spi_read(void) __attribute__((always_inline));
static inline uint8_t _avr_spi_read(void) {
    uint8_t r = 0;
    SPDR = r;
    while(!(SPSR & _BV(SPIF)));
    r = SPDR;

NOTE: Test Verfiy build for T_3.2 and T_3.6 fail also with::
Code:
T:\arduino-1.8.8T4_146\hardware\teensy\avr\libraries\Adafruit_SSD1306\Adafruit_SSD1306.cpp:206:5: error: 'Wire' was not declared in this scope


KurtE update - Crossed/Loopback SERIALX1.begin(4000000); and SERIALX5.begin(4000000); been running most of the last 24 hours! First half may have been 2 or 3 Mbaud before upped to 4 about 11 hours ago.
With 750,000 IntervalTimer [simple _isr{jj++;}] interrupts each 1.5 seconds and running a value to the 8 digit LedControl updated every 1 seconds.
All seems stable and good with IDE and T4 - MCU not hot - warm to touch ~96°.
Just added a split write to each of the two upper digits every 6 ms and shortened delay down to 200 ms from 500 ms each second - proportional drop in IntervalTimer _isr counts each shorter period to 600K printed on lower 6 digits of LED each second.
 
It looks like the on pin0/2 the duty and pulse widths are reversed from pins2/3. Not sure what the pulse widths should be. Sketch is pretty simple:
Are you happy with analogWrite now? I have seen sometimes on my scope, where the text reports the Duty cycle inverted, but the waveform is true to the duty specified in analogWrite(). If you have a screenshot of waveform with duty cycle "reversed", then we have a problem. As to "what the pulse widths should be", the 2nd argument to analogWrite() is duty, with default resolution of 8-bits. So duty of 128 should show up as 50% on scope, duty of 50 as 19.5%.

your simple sketch, can be simpler. You don't need pinMode(), analogWrite() sets the GPIO to the ALT for PWM. And usually, you just do analogWrite() in setup(), and PWM happily runs forever. Your re-issuing analogWrite() in loop() might cause a slight shift in phase, but nothing very observable. The URL you referenced does have an example with analogWrtie() in loop() flipping a single pin's duty cycle with a delay, and then watching that on a scope with a probe on a resistor-capacitor filter to convert digital PWM to analog voltage.
 
Morning @manitou,

I have seen sometimes on my scope, where the text reports the Duty cycle inverted, but the waveform is true to the duty specified in analogWrite().
Yep for 50, my scope is showing -Duty as 19.5%, so in my data table duty should be (100-(+Duty).

Ok I simplified the sketch down to two lines in setup:
Code:
  analogWrite(0, 50);
  analogWrite(2, 50);

In this case the two signals should have identical waveforms correct and line up correc? The Yellow trace is pin 0, Blue trace is pin 2.
20190105_065102.jpg

Look close, pin 0 trace is inverted from pin 2 and slightly shifted to the left. As a test I did analogWrite(3,5) and the waveforms were absolutely identical.

EDIT: Pulse width for pin 0 shows a 179.2us while pin 2 shows as43.6us

EDIT2: On a T3.2 and a T3.5 the PW=400.0us, duty=19.5% and freq=488.2hz
The freq on the T4 = 4.484 khz
Is this right, for frequency on the T4

EDIT3: Did a test, changed freq to 488 on pins 0 and 2, Pin 2's PW=400us which matches the T3.2/T3.5 PW. But on Pin0 it gives me a PW=1.648us with a duty = 80.5%, the signal on pin0 still inverted from pin2 though.
 
Last edited:
latest hack, add code to SPI.h to set SPI clock from SPISettings. SPI mode and bit order are still static at 0, and the deprecated clock setting functions have not been modified. Max SPI clock will be 37 MHz, but the waveform is iffy, so 25 mhz is safer. Tested with scope, MOSI-MISO loopback.
 

Attachments

  • SPI.h
    44.2 KB · Views: 85
Look close, pin 0 trace is inverted from pin 2 and slightly shifted to the left. As a test I did analogWrite(3,5) and the waveforms were absolutely identical.

EDIT: Pulse width for pin 0 shows a 179.2us while pin 2 shows as43.6us

EDIT2: On a T3.2 and a T3.5 the PW=400.0us, duty=19.5% and freq=488.2hz
The freq on the T4 = 4.484 khz
Is this right, for frequency

I see the same thing on my scope?? very strange ....

yes, there are two PWM timers used on T4 (flexpwm and quadtimer), see pin table in post #3. flexpwm runs at 4.46 khz, qtmr at 3.62 khz
 
latest hack, add code to SPI.h to set SPI clock from SPISettings. SPI mode and bit order are still static at 0, and the deprecated clock setting functions have not been modified. Max SPI clock will be 37 MHz, but the waveform is iffy, so 25 mhz is safer. Tested with scope, MOSI-MISO loopback.

Thank you. Any chance to get 60MHz?
 
yes, there are two PWM timers used on T4 (flexpwm and quadtimer), see pin table in post #3. flexpwm runs at 4.46 khz, qtmr at 3.62 khz
Yep. I see that in the analogWrite function just can't figure out the translation from pin to which timer is used, i.e.:
Code:
info = pwm_pin_info + pin;
and
if (info->type == 1) {
and
		switch ((info->module >> 4) & 3) {
Poking around pwm_pin_info looks like it is always 0? And haven't figured out that struct yet - think I have to do some printf :)
 
Thank you. Any chance to get 60MHz?

Maybe, I can't speak to signal quality. in hardware/teensy/avr/libraries/SPI/SPI.cpp the LPSPI clock is configured with
Code:
CCM_CBCMR = (CCM_CBCMR & ~(CCM_CBCMR_LPSPI_PODF_MASK | CCM_CBCMR_LPSPI_CLK_SEL_MASK)) |
		CCM_CBCMR_LPSPI_PODF(6) | CCM_CBCMR_LPSPI_CLK_SEL(2); // pg 714
That results in a 528mhz/7 clock that is the base clock for the prescaler (DIV) of the LPSPI code that SPISettings changes. You could try changing the PODF(6) to a smaller number. Note, the DIV value is treated as +2, hence the max spi is 528/7/2
 
@Paul - With changes to SerialX code - which way would you like to work? I could issue a PR at any time to pick up current stuff,
Could do this when you are ready for making a build....
Or could do it now and keep working and you do the pull when you are ready...
Could try to do with each little thing added/tested.. But doing lots of small PRs to same set of code, but that can cause issues.
 
@Paul - With changes to SerialX code - which way would you like to work? I could issue a PR at any time to pick up current stuff,

Please send a PR sometime today, whenever you're ready. I'm going to go through the many issues reported recently and probably package up beta7 this evening or early Sunday.
 
FreqMeasure input is pin 22.
My fault, read b08.... Here are the results. Would say its working. Used ChrisO's ublox library to change the PPS rate. Tested up to 4000 hz. Would say it works fine.

Code:
PPS       FreqCount
1          1.00
100       100.00
1000     1000.02
2000     2000.05
4000     4000.11
 
@KurtE
On the T3.x's we were able to go in and the buffer size's if need be, and most of the time we did when using the UBLOX M8Ns. Can't remember now if we used 128 or 256. Right now you have them set to 64 or 40. Will there be an issue if we make them larger?

EDIT: Seems to compile file if I manually change it to 256 on Serial1

EDIT2: 128 works fine for a buffer size on serial1. If I try and use 256 the orange LED blinks brightly very rapidly and nothing go to the Serial Monitor
 
I have ILI9341 DMA *almost* working - was much fiddling with the LSSPI registers..

Hint: If you want to output data with SPI with DMA, and if you don't need the RX-Data, use the following:
Code:
 LPSPI4_CR &= ~LPSPI_CR_MEN;
 LPSPI4_CFGR1 |= LPSPI_CFGR1_NOSTALL;
 LPSPI4_DER |= LPSPI_DER_TDDE; //TX DMA Request Enable
Otherwise SPI stalls if you don't read the RX Data.

I'm still struggling with an important detail :
DMA works so far, if I use dmatx.triggerManual(); for every word to transmit.

I can't get it working automatically with dmatx.triggerAtHardwareEvent( DMAMUX_SOURCE_LPSPI4_TX );
I have set LPSPI4_DER |= LPSPI_DER_TDDE; //TX DMA Request Enable
What is missing?
 
@Paul - WIll put in PR sometime today... Right now putting in support for different formats.
Some support for 9 bit - maybe not all pieces in here yet.
Have the RS485 support in.
Have some CTS/RTS code in - not sure if they are working yet.
As mentioned earlier have hopefully support for now reading in everything in FIFO on interrupt.

Soon - Move each object into different files: HardwareSerial1.cpp, HardwareSerial2.cpp...

Again needs lots of testing.

@MSJ513 - You should be able to set different sizes for the buffers... Have not fully tested. Also had some initial code put in, that allows a program to add a second buffer onto RX and/or TX buffers.
There were debates about APIs for this about a year ago, so put in something simple for now... As for 256 not working may need to test and find if there is an uart8_t used somewhere...
 
@KurtE
The only place I noticed a uint8_t was in HardwareSeril.h:
Code:
#ifdef SERIAL_9BIT_SUPPORT
#define BUFTYPE uint16_t
#else
#define BUFTYPE uint8_t
#endif
Think you got it reversed? As a hack a changed uint8_t to uint16_t and 256 worked.

Thanks
Mike
 
Re: analogWrite() anomalies

In my testing pin 0 and pin 1 PWM are inverted??? There is a polarity bit in OCTRL, but that is zero'd, so it should be OK. So as a hack, I reversed polarity for pins 0 and 1 in flexpwmWrite() in hardware/teensy/avr/cores/teensy4/pwm.c
Code:
void flexpwmWrite(IMXRT_FLEXPWM_t *p, unsigned int submodule, uint8_t channel, uint16_t val)
{
    uint16_t mask = 1 << submodule;
    uint32_t modulo = p->SM[submodule].VAL1;
    uint32_t cval = ((uint32_t)val * (modulo + 1)) >> analog_write_res;
    if (cval > modulo) cval = modulo; // TODO: is this check correct?

    //printf("flexpwmWrite, p=%08lX, sm=%d, ch=%c, cval=%ld\n",
        //(uint32_t)p, submodule, channel == 0 ? 'X' : (channel == 1 ? 'A' : 'B'), cval);
    p->MCTRL |= FLEXPWM_MCTRL_CLDOK(mask);
    switch (channel) {
      case 0: // X
        p->SM[submodule].VAL0 = cval;
        [B]p->SM[submodule].OCTRL =  FLEXPWM_SMOCTRL_POLX;[/B]
        p->OUTEN |= FLEXPWM_OUTEN_PWMX_EN(mask);
        //printf(" write channel X\n");
        break;
      case 1: // A
...
that seemed to fix duty polarity on pins 0 and 1. Doesn't make sense (is there an errata?), and there may be a better fix.

EDIT: with T4 breakout board, confirmed PWM polarity fix also worked on pins 24 and 25
 
Last edited:
@KurtE
The only place I noticed a uint8_t was in HardwareSeril.h:
Code:
#ifdef SERIAL_9BIT_SUPPORT
#define BUFTYPE uint16_t
#else
#define BUFTYPE uint8_t
#endif
Think you got it reversed? As a hack a changed uint8_t to uint16_t and 256 worked.

Thanks
Mike
Thanks for testing!

In theory that part should not impact it? That is, the BUFTYPE is configured if you turn on 9 bit writes support. That is the ability to output characters that are 9 bits long (Also potentially 10 bits as well, I have not double checked if this USART supports 10 bits or not.

As mentioned in previous post, working on supporting more of the features. Will need lots of testing! :D
 
Have ILI9341 DMA working, yeah ..
Only a very basic version that just enables the "autorefresh".
Now to the boring rest..
 
Great, thank you, i'll look tomorrow.
Currently, my SPI is working very slow - for test's and writing the rest of the library its ok.

If possible, i'll make two modes - "normal speed", and "overclocked" (spi as fast as the display allows) - need that for my emu :)
 
Thanks for testing!

In theory that part should not impact it? That is, the BUFTYPE is configured if you turn on 9 bit writes support. That is the ability to output characters that are 9 bits long (Also potentially 10 bits as well, I have not double checked if this USART supports 10 bits or not.

As mentioned in previous post, working on supporting more of the features. Will need lots of testing!


@KurtE
First, thats a fantastic job you are doing with the Hardware serial. Never ceases to amaze me, what you all can do. I tend to struggle through it, but i learn - sometimes :)

Anyway, I tested change for a couple of reasons, let me tell you my rationale and if i am wrong let me know when you get some time. I was looking at .cpp file and saw these lines where you are using Serial1_RX_BUFFER_SIZE
Code:
static BUFTYPE tx_buffer1[SERIAL1_TX_BUFFER_SIZE];
static BUFTYPE rx_buffer1[SERIAL1_RX_BUFFER_SIZE];

That lead me to the .h where you have:
Code:
	constexpr HardwareSerial(IMXRT_LPUART_t *myport, const hardware_t *myhardware, 
		volatile BUFTYPE *_tx_buffer, size_t _tx_buffer_size, 
		volatile BUFTYPE *_rx_buffer, size_t _rx_buffer_size) :
Which then lead me to:
Code:
#ifdef [COLOR="#FF0000"]SERIAL_9BIT_SUPPORT[/COLOR]
#define BUFTYPE uint16_t
#else
#define BUFTYPE uint8_t
#endif
Now since I am not using 9bit the BUFTYPE should default to:
Code:
#define BUFTYPE uint8_t
which I remember a uint8_t could cause a problem with specifying a buffer size of 256.

Thanks for your patience
Mike
 
Status
Not open for further replies.
Back
Top