ILI9488_t3 - Support for the ILI9488 on T3.x and beyond...

@KurtE - @defragster

Trying to take your code to identify the display and add it into the lib but it balking as I expected at what I am doing - just not sure how to fix it unless we just redo the array each time:
Code:
const uint8_t KEDEIRPI35_t3::MADCTLRotionValues[4];

void KEDEIRPI35_t3::getTouchIOValue() {
  spi_port->beginTransaction(SPISettings(2000000, MSBFIRST, SPI_MODE0));
  DIRECT_WRITE_LOW(_touchcsport, _touchcspinmask);  
  spi_port->transfer(0xe7); // Start a conversion.
  uint16_t value = spi_port->transfer(0) << 8;
  DIRECT_WRITE_HIGH(_touchcsport, _touchcspinmask);
  spi_port->endTransaction();
  if((value | spi_port->transfer(0)) == 0) {
	  MADCTLRotionValues[4] = {0xEA, 0x4A, 0x2A, 0x8A};
  } else {
	  MADCTLRotionValues[4] = {0xAA, 0x0A, 0x6A, 0xCA };
  }
}
 
Okay that fixed rotation on my display - when I saw Kurt's post - I thought that meant it was implemented in code already. And my few minutes here and gone figured it was something unique …

Touch Paint changes colors and draws as expected on my R1 populated setting.

I just went through that - if you can make it a STRUCT for the 4 values you can assign at run time - other wise an array is filled at creation.

Code:
struct TS_MAP {
  int16_t xMi;
  int16_t xMa;
  int16_t yMi;
  int16_t yMa;
};

TS_MAP tsMap;
tsMap = { xpMax, xpMin, ypMin, ypMax };

As they are all bytes - they should store the same as array without adding packed.

Or maybe ::
Code:
struct rotVal {  uint8_t Here[4]; } mine; // assuming you never need to ref by name in the struct
mine =  {0xEA, 0x4A, 0x2A, 0x8A};
 
@KurtE - @defragster

Ok got it. It is now setup to automatically select the correct rotation matrix for the display. Just tested it partially so if you want to give it a try on your displays - let me know what I messed up - also fixed a couple of the warnings.

View attachment KeDeiRPI35_t3.zip
 
Good Morning @mjs513 and @defragster

I hope you don't mind and think I jumped the gun,

But went ahead and updated the library with this stuff :D Just did a commit.

Note, I made a few minor changes, including:

change: setMADCTLRotionValues to setMADCTLRotationValues ;)

I #if 0 - the init code at the start that tried to talk to the XPT2046 and ask for that special value, as we do it later correctly. The earlier code had too fast of a SPI speed to work, and we did not look at the values anyway.

Removed compiler warning

Added: uint8_t getMADCTLRotationValue(uint8_t rotation) {return MADCTLRotionValues[rotation];}

So the rotation test program could get the values. It used to directly access the static array.

Touchpaint: Changed the color Pink to color Navy.

Turns out Pink IS a duplicate:
Code:
#define KEDEIRPI35_MAGENTA     CL( 255,   0, 255 )
#define KEDEIRPI35_PINK        CL( 255, 0,  255 )

Tested on my one display. The rotations looked correct :D
 
@KurtE - @defragster

Thanks Kurt - never good spell.

Glad you got the corrections up on GitHub.

Never could have updated the library without you and everything you put together to decode what was going on :) All those helper sketches that you put together really did the trick all I did was use them :)

Now - the fun thing is going to be to see if it works with your new board when it get there. Not sure what else we can do with this display:)
 
Good news and good work. I am supposed to be on my way somewhere so will try later. Glad that the color wasn't another bug.
 
Thanks,

As I put in the checkin, that the information/changes came from the three of us...

As you mentioned, I am thinking we are pretty well done with it!

:eek: - But than again, didn't I say that several days ago? ;)

Although who knows, maybe I will hack up a T4 breakout board with the RPI like connector on it, so then we could just plug it in :lol:

Would maybe need to look at a few hats, to see what pins should go where.

For example I have an Audio Hat with speakers and Microphone:
https://smile.amazon.com/gp/product/B07B3WYMN8
 
@mjs513 @defragster and @anyone too stubborn to give up on these displays :D

I also just pushed up an update to the Read Me file for the project. If you find you need a nap and having a hard time falling asleep, you might look it over and see if there are things I should change.
 
@KurtE - @defragster

- But than again, didn't I say that several days ago?
Yes you did and we are still at it - but it didn't beat us! :)

Although who knows, maybe I will hack up a T4 breakout board with the RPI like connector on it, so then we could just plug it in :lol:
Actually - you know that display breakout board I have - it wouldn't be too hard to hack that one up for an RPI style connector - just have would have to figure out the pins :) and you know me and the RPI.

UNCANNYEYES:
Went back to playing with ST7735 UncannyEyes sketch - really hard to debug a sketch when it just crashes. Any started taking out code and putting it back in and see what crashed on the T4. Think I isolated it down to this piece of code:
Code:
  // X/Y movement
  static boolean  eyeInMotion      = false;
  static int16_t  eyeOldX = 512, eyeOldY = 512, eyeNewX = 512, eyeNewY = 512;
  static uint32_t eyeMoveStartTime = 0L;
  static int32_t  eyeMoveDuration  = 0L;

  int32_t dt = t - eyeMoveStartTime;      // uS elapsed since last eye event
  if (eyeInMotion) {                      // Currently moving?
    if (dt >= eyeMoveDuration) {          // Time up?  Destination reached.
      eyeInMotion      = false;           // Stop moving
      eyeMoveDuration  = random(3000000); // 0-3 sec stop
      eyeMoveStartTime = t;               // Save initial time of stop
      eyeX = eyeOldX = eyeNewX;           // Save position
      eyeY = eyeOldY = eyeNewY;
    } else { // Move time's not yet fully elapsed -- interpolate position
      int16_t e = ease[255 * dt / eyeMoveDuration] + 1;   // Ease curve
      eyeX = eyeOldX + (((eyeNewX - eyeOldX) * e) / 256); // Interp X
      eyeY = eyeOldY + (((eyeNewY - eyeOldY) * e) / 256); // and Y
    }
  } else {                                // Eye stopped
    eyeX = eyeOldX;
    eyeY = eyeOldY;
    if (dt > eyeMoveDuration) {           // Time up?  Begin new move.
      int16_t  dx, dy;
      uint32_t d;
      do {                                // Pick new dest in circle
        eyeNewX = random(1024);
        eyeNewY = random(1024);
        dx      = (eyeNewX * 2) - 1023;
        dy      = (eyeNewY * 2) - 1023;
      } while ((d = (dx * dx + dy * dy)) > (1023 * 1023)); // Keep trying
      eyeMoveDuration  = random(72000, 144000); // ~1/14 - ~1/7 sec
      eyeMoveStartTime = t;               // Save initial time of move
      eyeInMotion      = true;            // Start move on next frame
    }
  }
Took out a lot of ifdefs that we weren't using just to simplify the logic. That code is in the Frame function.
 
@KurtE - @defragster

Did a little more commenting out. If I comment out the eye movement section I can do what I want to config without an issue. This is what I took out:
Code:
    /*
    if (dt >= eyeMoveDuration) {          // Time up?  Destination reached.
      eyeInMotion      = false;           // Stop moving
      eyeMoveDuration  = random(3000000); // 0-3 sec stop
      eyeMoveStartTime = t;               // Save initial time of stop
      eyeX = eyeOldX = eyeNewX;           // Save position
      eyeY = eyeOldY = eyeNewY;
    } else { // Move time's not yet fully elapsed -- interpolate position
      int16_t e = ease[255 * dt / eyeMoveDuration] + 1;   // Ease curve
      eyeX = eyeOldX + (((eyeNewX - eyeOldX) * e) / 256); // Interp X
      eyeY = eyeOldY + (((eyeNewY - eyeOldY) * e) / 256); // and Y
    }
    */
 
Got latest Github KeDei from KurtE. Ran TouchPaint - all looks good. Only thing is Maybe the pressure detection on touch - seem to get weird liftoff dots?

Navy resolved Pink .vs. Magenta issue:
20190720_150737.jpg

Pic shows pulling each color down - L>R than Black swept across the color lines.

Did this with pointer included with a display - the accuracy of the dot to pixel Map looks right across the screen.

When I touch edge/corner with pointer - I get diagonal lines tracing to the screen center? This is 7 touches with the pointer.
20190720_151951.jpg

Color much more usable - the left RED end is the bright LED spillage end where cable is routed to board.
 
@defragster

I noticed that as well but I figure the only thing we haven't really done is a calibration to get the min/max's for the display. Have a feeling that may be the cause of the problem. What you think?
 
@KurtE - @defragster

Did a little more commenting out. If I comment out the eye movement section I can do what I want to config without an issue. This is what I took out:
Code:
    /*
    if (dt >= eyeMoveDuration) {          // Time up?  Destination reached.
      eyeInMotion      = false;           // Stop moving
      eyeMoveDuration  = random(3000000); // 0-3 sec stop
      eyeMoveStartTime = t;               // Save initial time of stop
      eyeX = eyeOldX = eyeNewX;           // Save position
      eyeY = eyeOldY = eyeNewY;
    } else { // Move time's not yet fully elapsed -- interpolate position
      int16_t e = ease[255 * dt / eyeMoveDuration] + 1;   // Ease curve
      eyeX = eyeOldX + (((eyeNewX - eyeOldX) * e) / 256); // Interp X
      eyeY = eyeOldY + (((eyeNewY - eyeOldY) * e) / 256); // and Y
    }
    */
Hi, Mike,

With things like this I always wonder is, it the code or is it just how it makes things line up... As you are getting a lot of screwy behavior.

However with this code I am not sure how some of this may or may not work properly.
Example: eyeMoveDuration = random(3000000);

Where: static int32_t eyeMoveDuration = 0L;

So eyeMoveDuration can hold value +-32767 but asked to hold a value up to 3000000
So probably a bug...

Also if random returns the value 0, then int16_t e = ease[255 * dt / eyeMoveDuration] + 1;
Will have a divide by zero...

But then again maybe nothing to do with the code
 
@defragster

I noticed that as well but I figure the only thing we haven't really done is a calibration to get the min/max's for the display. Have a feeling that may be the cause of the problem. What you think?

Yep - That is sort of what I figured as well... If you wish to play, if you enter anything in the debug monitor it will toggle on outputting of the raw and converted touchpoint values to look at.
 
Yep - That is sort of what I figured as well... If you wish to play, if you enter anything in the debug monitor it will toggle on outputting of the raw and converted touchpoint values to look at.

As noted - the pointer HITS where I touch - the error seems to be pressure shutoff for values returned.

It is getting NOISE when pressure is not hard enough to register properly - but the .z Pressure element test is allowing light hits to be processed.

Most code had if (.z> 500 ) where 500 was some value below which readings were to be rejected as not touched. There is a threshold built into the XPT_touch code - it may need tweaked.

Has the _irq code with pin been tested?

I've got an outing tomorrow and need to go do a couple hours of work to get ready for that … I can look into it if not done …

If they are different here and causing trouble [ printing them in sketch will show where the cutoff should be ] - then the .begin() might get a set of default/ adjustable params for non #define var change in the class.

in T:\Ard186t4b2\hardware\teensy\avr\libraries\XPT2046_Touchscreen\XPT2046_Touchscreen.cpp::
Code:
#include "XPT2046_Touchscreen.h"

#define Z_THRESHOLD     400
#define Z_THRESHOLD_INT	75


// …

void XPT2046_Touchscreen::update()
{
	int16_t data[6];

	if (!isrWake) return;
	uint32_t now = millis();
	if (now - msraw < MSEC_THRESHOLD) return;
	
	SPI.beginTransaction(SPI_SETTING);
	digitalWrite(csPin, LOW);
	SPI.transfer(0xB1 /* Z1 */);
	int16_t z1 = SPI.transfer16(0xC1 /* Z2 */) >> 3;
	int z = z1 + 4095;
	int16_t z2 = SPI.transfer16(0x91 /* X */) >> 3;
	z -= z2;
	if (z >= Z_[B]THRESHOLD[/B]) {
		SPI.transfer16(0x91 /* X */);  // dummy X measure, 1st is always noisy
		data[0] = SPI.transfer16(0xD1 /* Y */) >> 3;
		data[1] = SPI.transfer16(0x91 /* X */) >> 3; // make 3 x-y measurements
		data[2] = SPI.transfer16(0xD1 /* Y */) >> 3;
		data[3] = SPI.transfer16(0x91 /* X */) >> 3;
	}
	else data[0] = data[1] = data[2] = data[3] = 0;	// Compiler warns these values may be used unset on early exit.
	data[4] = SPI.transfer16(0xD0 /* Y */) >> 3;	// Last Y touch power down
	data[5] = SPI.transfer16(0) >> 3;
	digitalWrite(csPin, HIGH);
	SPI.endTransaction();
	//Serial.printf("z=%d  ::  z1=%d,  z2=%d  ", z, z1, z2);
	if (z < 0) z = 0;
	if (z < Z_[B]THRESHOLD[/B]) { //	if ( !touched ) {
		// Serial.println();
		zraw = 0;
		if (z < Z_[B]THRESHOLD[/B]_INT) { //	if ( !touched ) {
			if (255 != tirqPin) isrWake = false;
		}
		return;
	}
	zraw = z;

// ...
 
This is TOO MUCH for the RED corner color selector ::
Code:
#include "XPT2046_Touchscreen.h"

#define Z_THRESHOLD     1050

But it is an improvement

First step in SKETCH was stopping the noise outputs in debug::
Code:
  if (debug_touch [COLOR="#FF0000"]&& p.z > 10[/COLOR]) {
    Serial.print("X = "); Serial.print(p.x);
    Serial.print("\tY = "); Serial.print(p.y);
    Serial.print("\tPressure = "); Serial.print(p.z);  

  }
 
  // Scale from ~0->4000 to tft.width using the calibration #'s
  p.x = map(p.x, TS_MAXX, TS_MINX, 0, tft.width());  // X's reversed
  p.y = map(p.y, TS_MINY, TS_MAXY, 0, tft.height());

  if (debug_touch [COLOR="#FF0000"]&& p.z > 10[/COLOR]) {
    Serial.print(" ("); Serial.print(p.x);
    Serial.print(", "); Serial.print(p.y);
    Serial.println(")");
  }
 
@KurtE

Thanks for the input just a couple of things:
1. eyeMoveDuration is an int32 so shouldn't be able to hold eyeMoveDuration, if it were int16 then it would be 32,767?

2.
Also if random returns the value 0, then int16_t e = ease[255 * dt / eyeMoveDuration] + 1; Will have a divide by zero..
Now this may be a problem - have to try it.

But then again it may have nothing to do with code.

EDIT: Ok made a couple of changes including the e matrix in progmem - just a shot. But also added a bunch of prints to the frame function just to see what the data looked like. I was able to make changes without locking up the USB and loosing the T4. Tested pretty good. BUT: Commented out the serial.prints and it hung again. Really have no clue anymore on this one.
 
Last edited:
another quick minute it has to go at least this low :: #define Z_THRESHOLD 700
for red to be usable - then the diagonals return on other locations.

Same driver code indeed works - but wondering if the return values across the larger resistive layer have something unique - or maybe try it on a T_3.6 that runs a bit slower?

Also need to check on the SPI speed - when I pushed it higher beyond a point on ili9341 it got flakey. - is it still using the 2M in the XPT_Touch code?

Also a big diff in sample speed touched or not - bright pin_13_LED? I suppose the touch 'bounce' timer is only reset on valid touch - not on a polled read with no touch?
 
Ok - just a quick update on ST7735 uncannyeyes - same code that gives me a problem on the T4 runs without issue on a T3.2. So no idea....
 
IIRC MichaelM as noted certain issues with certain speeds - may have been MCU dependent?

With the Teensy 3.2-3.6, I mostly saw that it was the SSD1306 (OLED screens) that were problematical with higher SPI bus speeds. I don't recall having to slow down the SPI bus for the ST7735, but it maybe at the faster Teensy 4 speeds you do.
 
@KurtE - @defragster - @MichaelMeissner

I did try to change the SPI clock down to 12Mhz but still exhibited the same behavior. Even tried at lower CPU clocks with no luck. However, playing around a little more I got it working by adding a single print statement to the eye movement loop, and fixed the whole issue:
Code:
    if (dt >= eyeMoveDuration) {          // Time up?  Destination reached.
      eyeInMotion      = false;           // Stop moving
      eyeMoveDuration  = random(1,3000000); // 0-3 sec stop
      eyeMoveStartTime = t;               // Save initial time of stop
      eyeX = eyeOldX = eyeNewX;           // Save position
      eyeY = eyeOldY = eyeNewY;
      [COLOR="#FF0000"]Serial.printf("%d(eMD)\n", eyeMoveDuration);[/COLOR]
    }
 
@mjs513 ...

Again when I first had the issue with it totally taking out USB and could not reprogram, unless after 15 second...

I would have Serial4 hooked up to some terminal monitor at 115200, and normally the teensy will boot up and show some stuff. When I would crash like that, it was at startup, and it appeared like it was before startup was ever called. So again wondering if Serial.print has anything to do with it or just potluck?
 
@mjs513 ...

Again when I first had the issue with it totally taking out USB and could not reprogram, unless after 15 second...

I would have Serial4 hooked up to some terminal monitor at 115200, and normally the teensy will boot up and show some stuff. When I would crash like that, it was at startup, and it appeared like it was before startup was ever called. So again wondering if Serial.print has anything to do with it or just potluck?

As you said - the issue was even before startup, saw the same thing on the Sermon when I hooked up Serial4. To be honest I don't think Serial.print necessarily has anything to do with but was just trying to see what would make it work - interesting thing is if I just do Serial.print(Any text) problem still exists. Only dumping data fixes it. I really have no idea what the problem really is - its too weird. Frank B did say there is no hang when using GCC6.
 
@KurtE - @defragster

You got me thinking so I tried something. I commented out the serial.print but added the code that @defragster added to capture the fault from the sketch that we used in the startup.c file. See below. Well that fixed the issue with the USB hang when I made changes but it messed the eyes up:

20190721_090617.jpg

Code:
#if 1
#ifdef __cplusplus
extern "C" {
#endif

#if defined(__IMXRT1052__) || defined(__IMXRT1062__)
uint32_t set_arm_clock(uint32_t frequency);
void HardFault_HandlerC(unsigned int *hardfault_args) {
  volatile unsigned int stacked_r0 ;
  volatile unsigned int stacked_r1 ;
  volatile unsigned int stacked_r2 ;
  volatile unsigned int stacked_r3 ;
  volatile unsigned int stacked_r12 ;
  volatile unsigned int stacked_lr ;
  volatile unsigned int stacked_pc ;
  volatile unsigned int stacked_psr ;
  volatile unsigned int _CFSR ;
  volatile unsigned int _HFSR ;
  volatile unsigned int _DFSR ;
  volatile unsigned int _AFSR ;
  volatile unsigned int _BFAR ;
  volatile unsigned int _MMAR ;
  volatile unsigned int addr ;
  volatile unsigned int nn ;

  stacked_r0 = ((unsigned int)hardfault_args[0]) ;
  stacked_r1 = ((unsigned int)hardfault_args[1]) ;
  stacked_r2 = ((unsigned int)hardfault_args[2]) ;
  stacked_r3 = ((unsigned int)hardfault_args[3]) ;
  stacked_r12 = ((unsigned int)hardfault_args[4]) ;
  stacked_lr = ((unsigned int)hardfault_args[5]) ;
  stacked_pc = ((unsigned int)hardfault_args[6]) ;
  stacked_psr = ((unsigned int)hardfault_args[7]) ;
  // Configurable Fault Status Register
  // Consists of MMSR, BFSR and UFSR
  //(n & ( 1 << k )) >> k
  _CFSR = (*((volatile unsigned int *)(0xE000ED28))) ;  
  // Hard Fault Status Register
  _HFSR = (*((volatile unsigned int *)(0xE000ED2C))) ;
  // Debug Fault Status Register
  _DFSR = (*((volatile unsigned int *)(0xE000ED30))) ;
  // Auxiliary Fault Status Register
  _AFSR = (*((volatile unsigned int *)(0xE000ED3C))) ;
  // Read the Fault Address Registers. These may not contain valid values.
  // Check BFARVALID/MMARVALID to see if they are valid values
  // MemManage Fault Address Register
  _MMAR = (*((volatile unsigned int *)(0xE000ED34))) ;
  // Bus Fault Address Register
  _BFAR = (*((volatile unsigned int *)(0xE000ED38))) ;
  //__asm("BKPT #0\n") ; // Break into the debugger // NO Debugger here.

  asm volatile("mrs %0, ipsr\n" : "=r" (addr)::);
  printf("\nFault irq %d\n", addr & 0x1FF);
  printf(" stacked_r0 ::  %x\n", stacked_r0);
  printf(" stacked_r1 ::  %x\n", stacked_r1);
  printf(" stacked_r2 ::  %x\n", stacked_r2);
  printf(" stacked_r3 ::  %x\n", stacked_r3);
  printf(" stacked_r12 ::  %x\n", stacked_r12);
  printf(" stacked_lr ::  %x\n", stacked_lr);
  printf(" stacked_pc ::  %x\n", stacked_pc);
  printf(" stacked_psr ::  %x\n", stacked_psr);
  printf(" _CFSR ::  %x\n", _CFSR);
 
  if(_CFSR > 0){
    //Memory Management Faults
    if((_CFSR & 1) == 1){
    printf("      (IACCVIOL) Instruction Access Violation\n");
    } else  if(((_CFSR & (0x02))>>1) == 1){
    printf("      (DACCVIOL) Data Access Violation\n");
    } else if(((_CFSR & (0x08))>>3) == 1){
    printf("      (MUNSTKERR) MemMange Fault on Unstacking\n");
    } else if(((_CFSR & (0x10))>>4) == 1){
    printf("      (MSTKERR) MemMange Fault on stacking\n");
    } else if(((_CFSR & (0x20))>>5) == 1){
    printf("      (MLSPERR) MemMange Fault on FP Lazy State\n");
    }
    if(((_CFSR & (0x80))>>7) == 1){
    printf("      (MMARVALID) MemMange Fault Address Valid\n");
    }
    //Bus Fault Status Register
    if(((_CFSR & 0x100)>>8) == 1){
    printf("      (IBUSERR) Instruction Bus Error\n");
    } else  if(((_CFSR & (0x200))>>9) == 1){
    printf("      (PRECISERR) Data bus error(address in BFAR)\n");
    } else if(((_CFSR & (0x400))>>10) == 1){
    printf("      (IMPRECISERR) Data bus error but address not related to instruction\n");
    } else if(((_CFSR & (0x800))>>11) == 1){
    printf("      (UNSTKERR) Bus Fault on unstacking for a return from exception \n");
    } else if(((_CFSR & (0x1000))>>12) == 1){
    printf("      (STKERR) Bus Fault on stacking for exception entry\n");
    } else if(((_CFSR & (0x2000))>>13) == 1){
    printf("      (LSPERR) Bus Fault on FP lazy state preservation\n");
    }
    if(((_CFSR & (0x8000))>>15) == 1){
    printf("      (BFARVALID) Bus Fault Address Valid\n");
    }  
    //Usuage Fault Status Register
    if(((_CFSR & 0x10000)>>16) == 1){
    printf("      (UNDEFINSTR) Undefined instruction\n");
    } else  if(((_CFSR & (0x20000))>>17) == 1){
    printf("      (INVSTATE) Instruction makes illegal use of EPSR)\n");
    } else if(((_CFSR & (0x40000))>>18) == 1){
    printf("      (INVPC) Usage fault: invalid EXC_RETURN\n");
    } else if(((_CFSR & (0x80000))>>19) == 1){
    printf("      (NOCP) No Coprocessor \n");
    } else if(((_CFSR & (0x1000000))>>24) == 1){
    printf("      (UNALIGNED) Unaligned access UsageFault\n");
    } else if(((_CFSR & (0x2000000))>>25) == 1){
    printf("      (DIVBYZERO) Divide by zero\n");
    }
  }
  printf(" _HFSR ::  %x\n", _HFSR);
  if(_HFSR > 0){
    //Memory Management Faults
    if(((_HFSR & (0x02))>>1) == 1){
    printf("      (VECTTBL) Bus Fault on Vec Table Read\n");
    } else if(((_HFSR & (0x40000000))>>30) == 1){
    printf("      (FORCED) Forced Hard Fault\n");
    } else if(((_HFSR & (0x80000000))>>31) == 31){
    printf("      (DEBUGEVT) Reserved for Debug\n");
    } 
  }
  printf(" _DFSR ::  %x\n", _DFSR);
  printf(" _AFSR ::  %x\n", _AFSR);
  printf(" _BFAR ::  %x\n", _BFAR);
  printf(" _MMAR ::  %x\n", _MMAR);

  IOMUXC_SW_MUX_CTL_PAD_GPIO_B0_03 = 5; // pin 13
  IOMUXC_SW_PAD_CTL_PAD_GPIO_B0_03 = IOMUXC_PAD_DSE(7);
  GPIO2_GDIR |= (1 << 3);
  GPIO2_DR_SET = (1 << 3);
  GPIO2_DR_CLEAR = (1 << 3); //digitalWrite(13, LOW);

  if ( F_CPU_ACTUAL >= 600000000 )
    set_arm_clock(300000000);

  while (1)
  {
    GPIO2_DR_SET = (1 << 3); //digitalWrite(13, HIGH);
    // digitalWrite(13, HIGH);
    for (nn = 0; nn < 2000000/2; nn++) ;
    GPIO2_DR_CLEAR = (1 << 3); //digitalWrite(13, LOW);
    // digitalWrite(13, LOW);
    for (nn = 0; nn < 18000000/2; nn++) ;
  }
}
#endif
#ifdef __cplusplus
} // extern "C"
#endif
#endif
 
Back
Top