Browse Source

Merge pull request #1 from PaulStoffregen/master

Update to my fork
main
Mike S 5 years ago
parent
commit
31857bba97
No account linked to committer's email address
6 changed files with 144 additions and 38 deletions
  1. +3
    -0
      teensy4/EventResponder.cpp
  2. +65
    -0
      teensy4/IPAddress.cpp
  3. +18
    -1
      teensy4/delay.c
  4. +29
    -29
      teensy4/imxrt.h
  5. +4
    -4
      teensy4/pwm.c
  6. +25
    -4
      teensy4/startup.c

+ 3
- 0
teensy4/EventResponder.cpp View File



// TODO: this doesn't work for IMXRT - no longer using predefined names // TODO: this doesn't work for IMXRT - no longer using predefined names
extern "C" volatile uint32_t systick_millis_count; extern "C" volatile uint32_t systick_millis_count;
extern "C" volatile uint32_t systick_cycle_count;
extern "C" uint32_t systick_safe_read; // micros() synchronization
extern "C" void systick_isr(void) extern "C" void systick_isr(void)
{ {
systick_cycle_count = ARM_DWT_CYCCNT;
systick_millis_count++; systick_millis_count++;
MillisTimer::runFromTimer(); MillisTimer::runFromTimer();
} }

+ 65
- 0
teensy4/IPAddress.cpp View File

/*
IPAddress.cpp - Base class that provides IPAddress
Copyright (c) 2011 Adrian McEwen. All right reserved.

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library 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
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/

#include <Arduino.h>
#include "IPAddress.h"

size_t IPAddress::printTo(Print& p) const
{
int i=0;
while (1) {
p.print(_address.bytes[i], DEC);
if (++i >= 4) return 4;
p.write('.');
}
}

bool IPAddress::fromString(const char *address)
{
unsigned int acc = 0; // Accumulator
unsigned int dots = 0;

while (*address) {
char c = *address++;
if (c >= '0' && c <= '9') {
acc = acc * 10 + (c - '0');
if (acc > 255) {
// Value out of [0..255] range
return false;
}
} else if (c == '.') {
if (dots == 3) {
// Too much dots (there must be 3 dots)
return false;
}
_address.bytes[dots++] = acc;
acc = 0;
} else {
// Invalid char
return false;
}
}
if (dots != 3) {
// Too few dots (there must be 3 dots)
return false;
}
_address.bytes[3] = acc;
return true;
}


+ 18
- 1
teensy4/delay.c View File

#include "core_pins.h" #include "core_pins.h"
#include "arm_math.h" // micros() synchronization


//volatile uint32_t F_CPU = 396000000; //volatile uint32_t F_CPU = 396000000;
//volatile uint32_t F_BUS = 132000000; //volatile uint32_t F_BUS = 132000000;
volatile uint32_t systick_millis_count = 0; volatile uint32_t systick_millis_count = 0;
volatile uint32_t systick_cycle_count = 0;
uint32_t systick_safe_read; // micros() synchronization


// page 411 says "24 MHz XTALOSC can be the external clock source of SYSTICK" // page 411 says "24 MHz XTALOSC can be the external clock source of SYSTICK"
// Testing shows the frequency is actually 100 kHz - but how? Did NXP really // Testing shows the frequency is actually 100 kHz - but how? Did NXP really
// TODO... // TODO...
} }


uint32_t micros(void)
{
uint32_t ccdelta, usec, smc, scc;
do {
__LDREXW(&systick_safe_read);
smc = systick_millis_count;
scc = systick_cycle_count;
} while ( __STREXW(1, &systick_safe_read));
ccdelta = ARM_DWT_CYCCNT - scc;
usec = 1000*smc + (ccdelta/(F_CPU_ACTUAL/1000000));
return usec;
}

#if 0 // kept to compare test to cycle count micro()
uint32_t micros(void) uint32_t micros(void)
{ {
uint32_t msec, tick, elapsed, istatus, usec; uint32_t msec, tick, elapsed, istatus, usec;
prev_usec = usec; prev_usec = usec;
return usec; return usec;
} }
#endif

+ 29
- 29
teensy4/imxrt.h View File

#define FLEXIO3_SHIFTBUFNIS1 (IMXRT_FLEXIO3_b.offset384) #define FLEXIO3_SHIFTBUFNIS1 (IMXRT_FLEXIO3_b.offset384)
#define FLEXIO3_SHIFTBUFNIS2 (IMXRT_FLEXIO3_b.offset388) #define FLEXIO3_SHIFTBUFNIS2 (IMXRT_FLEXIO3_b.offset388)
#define FLEXIO3_SHIFTBUFNIS3 (IMXRT_FLEXIO3_b.offset38C) #define FLEXIO3_SHIFTBUFNIS3 (IMXRT_FLEXIO3_b.offset38C)
#define FLEXIO_CTRL_DOZEN ((uint16_t)(1<<31))
#define FLEXIO_CTRL_DBGE ((uint16_t)(1<<30))
#define FLEXIO_CTRL_FASTACC ((uint16_t)(1<<2))
#define FLEXIO_CTRL_SWRST ((uint16_t)(1<<1))
#define FLEXIO_CTRL_FLEXEN ((uint16_t)(1<<0))
#define FLEXIO_SHIFTCTL_TIMSEL(n) ((uint16_t)(((n) & 0x03) << 24))
#define FLEXIO_SHIFTCTL_TIMPOL ((uint16_t)(1<<23))
#define FLEXIO_SHIFTCTL_PINCFG(n) ((uint16_t)(((n) & 0x03) << 16))
#define FLEXIO_SHIFTCTL_PINSEL(n) ((uint16_t)(((n) & 0x1F) << 8))
#define FLEXIO_SHIFTCTL_PINPOL ((uint16_t)(1<<7))
#define FLEXIO_SHIFTCTL_SMOD(n) ((uint16_t)(((n) & 0x07) << 0))
#define FLEXIO_SHIFTCFG_PWIDTH(n) ((uint16_t)(((n) & 0x1F) << 16))
#define FLEXIO_SHIFTCFG_INSRC ((uint16_t)(1<<8))
#define FLEXIO_SHIFTCFG_SSTOP(n) ((uint16_t)(((n) & 0x03) << 4))
#define FLEXIO_SHIFTCFG_SSTART(n) ((uint16_t)(((n) & 0x03) << 0))
#define FLEXIO_TIMCTL_TRGSEL(n) ((uint16_t)(((n) & 0x3F) << 24))
#define FLEXIO_TIMCTL_TRGPOL ((uint16_t)(1<<23))
#define FLEXIO_TIMCTL_TRGSRC ((uint16_t)(1<<22))
#define FLEXIO_TIMCTL_PINCFG(n) ((uint16_t)(((n) & 0x03) << 16))
#define FLEXIO_TIMCTL_PINSEL(n) ((uint16_t)(((n) & 0x1F) << 8))
#define FLEXIO_TIMCTL_PINPOL ((uint16_t)(1<<7))
#define FLEXIO_TIMCTL_TIMOD(n) ((uint16_t)(((n) & 0x03) << 0))
#define FLEXIO_TIMCFG_TIMOUT(n) ((uint16_t)(((n) & 0x03) << 24))
#define FLEXIO_TIMCFG_TIMDEC(n) ((uint16_t)(((n) & 0x03) << 20))
#define FLEXIO_TIMCFG_TIMRST(n) ((uint16_t)(((n) & 0x07) << 16))
#define FLEXIO_TIMCFG_TIMDIS(n) ((uint16_t)(((n) & 0x07) << 12))
#define FLEXIO_TIMCFG_TIMENA(n) ((uint16_t)(((n) & 0x07) << 8))
#define FLEXIO_TIMCFG_TSTOP(n) ((uint16_t)(((n) & 0x03) << 4))
#define FLEXIO_TIMCFG_TSTART ((uint16_t)(1<<1))
#define FLEXIO_CTRL_DOZEN ((uint32_t)(1<<31))
#define FLEXIO_CTRL_DBGE ((uint32_t)(1<<30))
#define FLEXIO_CTRL_FASTACC ((uint32_t)(1<<2))
#define FLEXIO_CTRL_SWRST ((uint32_t)(1<<1))
#define FLEXIO_CTRL_FLEXEN ((uint32_t)(1<<0))
#define FLEXIO_SHIFTCTL_TIMSEL(n) ((uint32_t)(((n) & 0x03) << 24))
#define FLEXIO_SHIFTCTL_TIMPOL ((uint32_t)(1<<23))
#define FLEXIO_SHIFTCTL_PINCFG(n) ((uint32_t)(((n) & 0x03) << 16))
#define FLEXIO_SHIFTCTL_PINSEL(n) ((uint32_t)(((n) & 0x1F) << 8))
#define FLEXIO_SHIFTCTL_PINPOL ((uint32_t)(1<<7))
#define FLEXIO_SHIFTCTL_SMOD(n) ((uint32_t)(((n) & 0x07) << 0))
#define FLEXIO_SHIFTCFG_PWIDTH(n) ((uint32_t)(((n) & 0x1F) << 16))
#define FLEXIO_SHIFTCFG_INSRC ((uint32_t)(1<<8))
#define FLEXIO_SHIFTCFG_SSTOP(n) ((uint32_t)(((n) & 0x03) << 4))
#define FLEXIO_SHIFTCFG_SSTART(n) ((uint32_t)(((n) & 0x03) << 0))
#define FLEXIO_TIMCTL_TRGSEL(n) ((uint32_t)(((n) & 0x3F) << 24))
#define FLEXIO_TIMCTL_TRGPOL ((uint32_t)(1<<23))
#define FLEXIO_TIMCTL_TRGSRC ((uint32_t)(1<<22))
#define FLEXIO_TIMCTL_PINCFG(n) ((uint32_t)(((n) & 0x03) << 16))
#define FLEXIO_TIMCTL_PINSEL(n) ((uint32_t)(((n) & 0x1F) << 8))
#define FLEXIO_TIMCTL_PINPOL ((uint32_t)(1<<7))
#define FLEXIO_TIMCTL_TIMOD(n) ((uint32_t)(((n) & 0x03) << 0))
#define FLEXIO_TIMCFG_TIMOUT(n) ((uint32_t)(((n) & 0x03) << 24))
#define FLEXIO_TIMCFG_TIMDEC(n) ((uint32_t)(((n) & 0x03) << 20))
#define FLEXIO_TIMCFG_TIMRST(n) ((uint32_t)(((n) & 0x07) << 16))
#define FLEXIO_TIMCFG_TIMDIS(n) ((uint32_t)(((n) & 0x07) << 12))
#define FLEXIO_TIMCFG_TIMENA(n) ((uint32_t)(((n) & 0x07) << 8))
#define FLEXIO_TIMCFG_TSTOP(n) ((uint32_t)(((n) & 0x03) << 4))
#define FLEXIO_TIMCFG_TSTART ((uint32_t)(1<<1))


// 28.4.1: page 1354 // 28.4.1: page 1354
typedef struct { typedef struct {

+ 4
- 4
teensy4/pwm.c View File

case 0: flexpwm = &IMXRT_FLEXPWM1; break; case 0: flexpwm = &IMXRT_FLEXPWM1; break;
case 1: flexpwm = &IMXRT_FLEXPWM2; break; case 1: flexpwm = &IMXRT_FLEXPWM2; break;
case 2: flexpwm = &IMXRT_FLEXPWM3; break; case 2: flexpwm = &IMXRT_FLEXPWM3; break;
case 3: flexpwm = &IMXRT_FLEXPWM4;
default: flexpwm = &IMXRT_FLEXPWM4;
} }
flexpwmWrite(flexpwm, info->module & 0x03, info->channel, val); flexpwmWrite(flexpwm, info->module & 0x03, info->channel, val);
} else if (info->type == 2) { } else if (info->type == 2) {
case 0: qtimer = &IMXRT_TMR1; break; case 0: qtimer = &IMXRT_TMR1; break;
case 1: qtimer = &IMXRT_TMR2; break; case 1: qtimer = &IMXRT_TMR2; break;
case 2: qtimer = &IMXRT_TMR3; break; case 2: qtimer = &IMXRT_TMR3; break;
case 3: qtimer = &IMXRT_TMR4;
default: qtimer = &IMXRT_TMR4;
} }
quadtimerWrite(qtimer, info->module & 0x03, val); quadtimerWrite(qtimer, info->module & 0x03, val);
} else { } else {
case 0: flexpwm = &IMXRT_FLEXPWM1; break; case 0: flexpwm = &IMXRT_FLEXPWM1; break;
case 1: flexpwm = &IMXRT_FLEXPWM2; break; case 1: flexpwm = &IMXRT_FLEXPWM2; break;
case 2: flexpwm = &IMXRT_FLEXPWM3; break; case 2: flexpwm = &IMXRT_FLEXPWM3; break;
case 3: flexpwm = &IMXRT_FLEXPWM4;
default: flexpwm = &IMXRT_FLEXPWM4;
} }
flexpwmFrequency(flexpwm, info->module & 0x03, info->channel, frequency); flexpwmFrequency(flexpwm, info->module & 0x03, info->channel, frequency);
} else if (info->type == 2) { } else if (info->type == 2) {
case 0: qtimer = &IMXRT_TMR1; break; case 0: qtimer = &IMXRT_TMR1; break;
case 1: qtimer = &IMXRT_TMR2; break; case 1: qtimer = &IMXRT_TMR2; break;
case 2: qtimer = &IMXRT_TMR3; break; case 2: qtimer = &IMXRT_TMR3; break;
case 3: qtimer = &IMXRT_TMR4;
default: qtimer = &IMXRT_TMR4;
} }
quadtimerFrequency(qtimer, info->module & 0x03, frequency); quadtimerFrequency(qtimer, info->module & 0x03, frequency);
} }

+ 25
- 4
teensy4/startup.c View File

static void memory_copy(uint32_t *dest, const uint32_t *src, uint32_t *dest_end); static void memory_copy(uint32_t *dest, const uint32_t *src, uint32_t *dest_end);
static void memory_clear(uint32_t *dest, uint32_t *dest_end); static void memory_clear(uint32_t *dest, uint32_t *dest_end);
static void configure_systick(void); static void configure_systick(void);
static void reset_PFD();
extern void systick_isr(void); extern void systick_isr(void);
extern void pendablesrvreq_isr(void); extern void pendablesrvreq_isr(void);
void configure_cache(void); void configure_cache(void);
for (i=0; i < NVIC_NUM_INTERRUPTS; i++) NVIC_SET_PRIORITY(i, 128); for (i=0; i < NVIC_NUM_INTERRUPTS; i++) NVIC_SET_PRIORITY(i, 128);
SCB_VTOR = (uint32_t)_VectorsRam; SCB_VTOR = (uint32_t)_VectorsRam;


reset_PFD();
// Configure clocks // Configure clocks
// TODO: make sure all affected peripherals are turned off! // TODO: make sure all affected peripherals are turned off!
// PIT & GPT timers to run from 24 MHz clock (independent of CPU speed) // PIT & GPT timers to run from 24 MHz clock (independent of CPU speed)


configure_cache(); configure_cache();
configure_systick(); configure_systick();
usb_pll_start();

usb_pll_start();
reset_PFD(); //TODO: is this really needed?
set_arm_clock(600000000); set_arm_clock(600000000);
//set_arm_clock(984000000); Ludicrous Speed //set_arm_clock(984000000); Ludicrous Speed


// the ARM clock to run at different speeds. // the ARM clock to run at different speeds.
#define SYSTICK_EXT_FREQ 100000 #define SYSTICK_EXT_FREQ 100000


extern volatile uint32_t systick_cycle_count;
static void configure_systick(void) static void configure_systick(void)
{ {
_VectorsRam[14] = pendablesrvreq_isr; _VectorsRam[14] = pendablesrvreq_isr;
SCB_SHPR3 = 0x20000000; // Systick = priority 32 SCB_SHPR3 = 0x20000000; // Systick = priority 32
ARM_DEMCR |= ARM_DEMCR_TRCENA; ARM_DEMCR |= ARM_DEMCR_TRCENA;
ARM_DWT_CTRL |= ARM_DWT_CTRL_CYCCNTENA; // turn on cycle counter ARM_DWT_CTRL |= ARM_DWT_CTRL_CYCCNTENA; // turn on cycle counter
systick_cycle_count = ARM_DWT_CYCCNT; // compiled 0, corrected w/1st systick
} }




} }
} }


__attribute__((section(".progmem")))
void reset_PFD()
{
//Reset PLL2 PFDs, set default frequencies:
CCM_ANALOG_PFD_528_SET = (1 << 31) | (1 << 23) | (1 << 15) | (1 << 7);
CCM_ANALOG_PFD_528 = 0x2018101B; // PFD0:352, PFD1:594, PFD2:396, PFD3:297 MHz
//PLL3:
CCM_ANALOG_PFD_480_SET = (1 << 31) | (1 << 23) | (1 << 15) | (1 << 7);
CCM_ANALOG_PFD_480 = 0x13110D0C; // PFD0:720, PFD1:664, PFD2:508, PFD3:454 MHz
}


// Stack frame // Stack frame
// xPSR // xPSR
// R2 // R2
// R1 // R1
// R0 // R0
__attribute__((weak))
void unused_interrupt_vector(void) void unused_interrupt_vector(void)
{ {
// TODO: polling Serial to complete buffered transmits // TODO: polling Serial to complete buffered transmits
printf(" %x\n", addr); printf(" %x\n", addr);
#endif #endif
#if 1 #if 1
if ( F_CPU_ACTUAL >= 600000000 )
set_arm_clock(100000000);
IOMUXC_SW_MUX_CTL_PAD_GPIO_B0_03 = 5; // pin 13 IOMUXC_SW_MUX_CTL_PAD_GPIO_B0_03 = 5; // pin 13
IOMUXC_SW_PAD_CTL_PAD_GPIO_B0_03 = IOMUXC_PAD_DSE(7); IOMUXC_SW_PAD_CTL_PAD_GPIO_B0_03 = IOMUXC_PAD_DSE(7);
GPIO2_GDIR |= (1<<3); GPIO2_GDIR |= (1<<3);
while (1) { while (1) {
volatile uint32_t n; volatile uint32_t n;
GPIO2_DR_SET = (1<<3); //digitalWrite(13, HIGH); GPIO2_DR_SET = (1<<3); //digitalWrite(13, HIGH);
for (n=0; n < 2000000; n++) ;
for (n=0; n < 2000000/6; n++) ;
GPIO2_DR_CLEAR = (1<<3); //digitalWrite(13, LOW); GPIO2_DR_CLEAR = (1<<3); //digitalWrite(13, LOW);
for (n=0; n < 1500000; n++) ;
for (n=0; n < 1500000/6; n++) ;
} }
#else #else
if ( F_CPU_ACTUAL >= 600000000 )
set_arm_clock(100000000);
while (1) { while (1) {
} }
#endif #endif

Loading…
Cancel
Save