Teensyduino 1.52 Beta #4

Status
Not open for further replies.

Paul

Administrator
Staff member
Here is a fourth beta test for Teensyduino 1.52.


Edit: links removed, please use 1.52-beta5.


Changes since Teensyduino 1.52-beta3:

Fix RTC auto-set on Teensy 4.x with daylight savings time
Fix RTC set on Teensy 4.0 (Silverlock)
Audio ADC input on Teensy 4.0 - experimental
Hardware serial pin fixes for Teensy 4.1 (KurtE)
Add dummy Keyboard.h on Teensy 4, for Arduino compatibility
Use standard (not low power) ADC mode
Align DMA buffers to 32 bytes (Frank B)
Fix ADC_ETC defines
Use recommended analog bias current on Teensy 4.x (Frank B)
Update Snooze library
 
No Trouble:: Win 10 Installed TD 1.52b4 on IDE 1.8.12.

ONLINE: T_3.6, T_4.0, T_4.1

Uploaded TimeAlarmExample to each to work when BOARD and PORT properly changed with IDE t_SerMon online.

Then in turn upload to see start time correctly matches PC time::
T_3.6:
Code:
RTC has set the system time
12:24:18 4 5 2020

T_4.0:
Code:
RTC has set the system time
12:25:04 4 5 2020

T_4.1:
Code:
RTC has set the system time
12:26:54 4 5 2020

On Windows turned off: 'Adjust for daylight savings time automatically'
PC Clock dropped an hour and T_4.1 properly shows this:
Code:
RTC has set the system time
11:30:53 4 5 2020
 
Just installed TD1.52b4 and ran a couple of RA8876 sketches since I already had that attached with no problems. Same for a couple of the extRam sketches. No issues.
 
works very well with Windows 10 and Teensy Convolution SDR.

Special thanks to you, Paul, for fixing the daylight saving issue ;-) !

Central European Summertime seems to be supported by T1.52 beta-4 in combination with Windows 10 :).
 
No problems with Linux ARM install on Raspbian Stretch with Arduino IDE 1.8.12.

T4.0 clock matched PC time after upload.

Set PC date/time ahead to Dec 1 2020 14:00 MST (after DST ends) and uploaded to T4.0 again. T4.0 clock showed Dec 1 2020 14:00.

Manually set T4.0 RTC to another time, powered off and back on again. RTC remembered the manually set time.

Looks like the RTC issues are a thing of the past. Thank you!
 
T_4.1 beta thread got updated FNET - IDE left open from above test - reconnected T_4.1 after adding magjack and on compile I got this SerMon start error???

Put github\fnet in \libraries after started IDE and opened \example from there? It built and worked to find the lib - even though the lib was not there when IDE opened.

SerMon wouldn't start. Restarted IDE and then it connects and builds and all is well … but this happened::
Using library TeensyThreads at version 1.0.1 in folder: T:\arduino-1.8.12\hardware\teensy\avr\libraries\TeensyThreads
Using library FNET at version 0.1.3 in folder: T:\tCode\libraries\FNET
"T:\\arduino-1.8.12\\hardware\\teensy/../tools/arm/bin/arm-none-eabi-size" -A "T:\\TEMP\\arduino_build_244608/FNET_Native_Ethernet.ino.elf"
Sketch uses 75152 bytes (0%) of program storage space. Maximum is 8126464 bytes.
Global variables use 244896 bytes (46%) of dynamic memory, leaving 279392 bytes for local variables. Maximum is 524288 bytes.
T:\arduino-1.8.12\hardware\teensy/../tools/teensy_post_compile -file=FNET_Native_Ethernet.ino -path=T:\TEMP\arduino_build_244608 -tools=T:\arduino-1.8.12\hardware\teensy/../tools -board=TEENSY41 -reboot -port=usb:0/140000/0/5/2 -portlabel=COM17 Serial -portprotocol=Teensy
Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: Java heap space
at processing.app.FifoDocument.<init>(FifoDocument.java:148)
at processing.app.TeensyPipeMonitor.<init>(TeensyPipeMonitor.java:55)
at cc.arduino.packages.MonitorFactory.newMonitor(MonitorFactory.java:51)
at processing.app.Editor.handleSerial(Editor.java:2242)
at processing.app.EditorToolbar.handleSelectionPressed(EditorToolbar.java:503)
at processing.app.EditorToolbar.mousePressed(EditorToolbar.java:448)
at java.awt.Component.processMouseEvent(Component.java:6536)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3324)
at java.awt.Component.processEvent(Component.java:6304)
at java.awt.Container.processEvent(Container.java:2239)
at java.awt.Component.dispatchEventImpl(Component.java:4889)
at java.awt.Container.dispatchEventImpl(Container.java:2297)
at java.awt.Component.dispatchEvent(Component.java:4711)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4904)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4532)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4476)
at java.awt.Container.dispatchEventImpl(Container.java:2283)
at java.awt.Window.dispatchEventImpl(Window.java:2746)
at java.awt.Component.dispatchEvent(Component.java:4711)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:760)
at java.awt.EventQueue.access$500(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:709)
at java.awt.EventQueue$3.run(EventQueue.java:703)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:74)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:84)
at java.awt.EventQueue$4.run(EventQueue.java:733)
at java.awt.EventQueue$4.run(EventQueue.java:731)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:74)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:730)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:205)
 
All good on Windows 10 Except i'm running into trap stack overflow issue with my sketch on all the 1.52 beta :confused:

Arduino IDE 1.8.12.

For now this is my quick fix:
\cores\teensy4\startup.c
Code:
FLASHMEM void configure_cache(void)
{
  //printf("MPU_TYPE = %08lX\n", SCB_MPU_TYPE);
  //printf("CCR = %08lX\n", SCB_CCR);

  // TODO: check if caches already active - skip?

  SCB_MPU_CTRL = 0; // turn off MPU

  uint32_t i = 0;
  SCB_MPU_RBAR = 0x00000000 | REGION(i++); //https://developer.arm.com/docs/146793866/10/why-does-the-cortex-m7-initiate-axim-read-accesses-to-memory-addresses-that-do-not-fall-under-a-defined-mpu-region
  SCB_MPU_RASR = SCB_MPU_RASR_TEX(0) | NOACCESS | NOEXEC | SIZE_4G;
  
  SCB_MPU_RBAR = 0x00000000 | REGION(i++); // ITCM
  SCB_MPU_RASR = MEM_NOCACHE | READWRITE | SIZE_512K;

  // TODO: trap regions should be created last, because the hardware gives
  //  priority to the higher number ones.
[COLOR="#FF0000"]  // --SCB_MPU_RBAR = 0x00000000 | REGION(i++); // trap NULL pointer deref // <------------------
  // --SCB_MPU_RASR =  DEV_NOCACHE | NOACCESS | SIZE_32B; // <------------------[/COLOR]

  SCB_MPU_RBAR = 0x00200000 | REGION(i++); // Boot ROM
  SCB_MPU_RASR = MEM_CACHE_WT | READONLY | SIZE_128K;

  SCB_MPU_RBAR = 0x20000000 | REGION(i++); // DTCM
  SCB_MPU_RASR = MEM_NOCACHE | READWRITE | NOEXEC | SIZE_512K;
  
[COLOR="#FF0000"]  // -- SCB_MPU_RBAR = ((uint32_t)&_ebss) | REGION(i++); // trap stack overflow // <------------------
  // -- SCB_MPU_RASR = SCB_MPU_RASR_TEX(0) | NOACCESS | NOEXEC | SIZE_32B; // <------------------[/COLOR]

  SCB_MPU_RBAR = 0x20200000 | REGION(i++); // RAM (AXI bus)
  SCB_MPU_RASR = MEM_CACHE_WBWA | READWRITE | NOEXEC | SIZE_1M;

  SCB_MPU_RBAR = 0x40000000 | REGION(i++); // Peripherals
  SCB_MPU_RASR = DEV_NOCACHE | READWRITE | NOEXEC | SIZE_64M;

  SCB_MPU_RBAR = 0x60000000 | REGION(i++); // QSPI Flash
  SCB_MPU_RASR = MEM_CACHE_WBWA | READONLY | SIZE_16M;

  SCB_MPU_RBAR = 0x70000000 | REGION(i++); // FlexSPI2
  SCB_MPU_RASR = MEM_CACHE_WBWA | READONLY | SIZE_256M;

  SCB_MPU_RBAR = 0x70000000 | REGION(i++); // FlexSPI2
  SCB_MPU_RASR = MEM_CACHE_WBWA | READWRITE | SIZE_16M;

  // TODO: protect access to power supply config

  SCB_MPU_CTRL = SCB_MPU_CTRL_ENABLE;

  // cache enable, ARM DDI0403E, pg 628
  asm("dsb");
  asm("isb");
  SCB_CACHE_ICIALLU = 0;

  asm("dsb");
  asm("isb");
  SCB_CCR |= (SCB_CCR_IC | SCB_CCR_DC);
}
 
All good on Windows 10 Except i'm running into trap stack overflow issue with my sketch on all the 1.52 beta :confused:

Arduino IDE 1.8.12.

For now this is my quick fix:
\cores\teensy4\startup.c
// ...

That would suggest a NULL pointer is used in the code?
 
Thanks defragster.
I have no idea really it has taken me two days to figure this out, at least it's running on Teensy 4.0 and Teensy 4.1 beta now.
Because of my eye injury today at work I will not be able to create complete source code & details to reproduce any issue.
I'm heavy duty diesel mechanic by trade.
 
Get well soon! Best wishes.
It looks like a bug in your program.

What Frank said - All the best.
Paul added that on purpose to trigger on NULL pointers to catch them - which halts the Teensy - but prevents it from going wacky later and wondering why.

In general are you doing anything crazy with function pointers - otherwise it would seem to be a data reference with a null pointer.
 
Thanks defragster.
I have no idea really it has taken me two days to figure this out, at least it's running on Teensy 4.0 and Teensy 4.1 beta now.
Because of my eye injury today at work I will not be able to create complete source code & details to reproduce any issue.
I'm heavy duty diesel mechanic by trade.

Just wanted to say ditto to what everyone else said - get better soon and don't strain the eye too much.
 
Installed 1.52b4 on Windows 10 Pro 64 with Arduino 1.8.12.

Teensy 4.0: the Snooze-based sketch which did not compile with 1.52b3 now builds successfully. :)
 
Thanks guys.
It's no fun getting injured with this covid-19 crap going on but the doctor said I'll be okay.

@defragster
Paul added that on purpose to trigger on NULL pointers to catch them - which halts the Teensy - but prevents it from going wacky later and wondering why.
Yeah I was surprised too, the code was running for two weeks straight no issues on Teensy 4.0 - Teensyduino 1.51 :confused:

@Frank B
It looks like a bug in your program.
99.9% yes but i do use your Spectrum-Analyzer :p
https://forum.pjrc.com/threads/28430-Spectrum-Analyzer


The code is based on Jarkko: Arduino Music Player on Teensy Audio Shield of course heavily modified which allows me to load music files from microSD card in ( uint8_t SD_MusicData[500000] DMAMEM; ) on the fly.
I'm going to strip it down to the bare minimum today, not easy because I am using multiple libraries.
Using library SdFat-beta at version 2.0.0-beta.8
Using library ILI9341_t3n-T4x_DMA at version 1.0
Using library Audio at version 1.3
Using library MTP
 
@defragster... "Paul added that on purpose to trigger on NULL pointers"

Yeah I was surprised too, the code was running for two weeks straight no issues on Teensy 4.0 - Teensyduino 1.51 :confused:

...

What did you do to determine it was a Null pointer fault? Just pulled out that changed code in startup?
 
What did you do to determine it was a Null pointer fault? Just pulled out that changed code in startup?
Yeah something like that I was comparing files with Teensyduino 1.51 and Teensyduino 1.52 beta4.

Here is a PMF Player SdFat v2 BETA + DMAMEM Buffer + Audio USB example.
pmf_player_2_minimum.zip has all the files.
Needs SdFat-beta ver "2.0.0"8 (Fix for Teensy 4.1) beta version of SdFat Version 2

ISSUE: Audio library pulls in SD.h library but we need SdFat-beta ver 2.0.0.8 !!!!
Windows 10 C:\Users\---?----\Desktop\arduino-1.8.12 BETA4\hardware\teensy\avr\libraries\Audio
Needs editing in play_sd_raw.h, play_sd_raw.ccp, play_sd_wav.h & play_sd_wav.ccp.
IN *.h ( #include "SD.h" ) TO - > ( #include "SdFat.h" )
IN *.ccp ( wavfile = SD.open(filename); // SD.h } TO - > { wavfile.open(filename); // SdFat.h )
Or use the Audio_fix.zip

How to use this example:
Set Audio USB in Arduino IDE Tools menu - USB Type: "Audio"
Open serial monitor and change to Newline or Carriage return at the bottom, press Send.
Needs micro SD card with PMF files.

Code:
//============================================================================
// PMF Player SdFat v2 BETA + DMAMEM Buffer + Audio USB example.
//
// Copyright (c) 2019, Profoundic Technologies, Inc.
// All rights reserved.
//----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//     * Neither the name of Profoundic Technologies nor the names of its
//       contributors may be used to endorse or promote products derived from
//       this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL PROFOUNDIC TECHNOLOGIES BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//============================================================================

// Chris O.
// How to use this example:
// Set Audio USB in Arduino IDE Tools menu - USB Type: "Audio"
// Open serial monitor and change to Newline or Carriage return at the bottom, press send.


// https://forum.pjrc.com/threads/58284-Arduino-Music-Player-on-Teensy-Audio-Shield
// You can download the project at: https://github.com/JarkkoPFC/arduino-music-player

// world's largest collections of music modules. The Mod Archive is currently enjoying its 23rd year online and is still as active as ever.
// https://modarchive.org/

// In order to use other music files than the one that comes with the project you'll need to use PMF Converter tool.
// How to use PMF Converter tool:
// Go to Windows icon on left bottom first, type C now look for - Command prompt and letf click mouse botton - click yas to waring window - select run as Administrator. ( now you shuld see Administrator Command Prompt).
// then type Exeple:  "C:\Users\ --??-- \Desktop\pmf_converter\bin\pmf_converter" -hex -dro -o C:\OPEN_MPT\\OPENMPT2\aws_aqua.pmf -i C:\OPEN_MPT\OPENMPT2\aws_aqua.xm

#pragma message ( "ISSUE: Audio library pulls in SD.h library but we need SdFat-beta ver 2.0.0.8 !!!! Needs editing in play_sd_raw.h, play_sd_raw.ccp, play_sd_wav.h & play_sd_wav.ccp." )
// ---- NOTE ISSUE: Audio library pulls in SD.h library but we need SdFat-beta ver "2.0.0"8
// Needs editing in play_sd_raw.h, play_sd_raw.ccp, play_sd_wav.h & play_sd_wav.ccp.
// IN *.h   ( #include "SD.h" ) TO - > ( #include "SdFat.h" )
// IN *.ccp ( wavfile = SD.open(filename); // SD.h }   TO - >  { wavfile.open(filename); // SdFat.h )

// https://forum.pjrc.com/threads/60746-Teensyduino-1-52-Beta-4
// ISSUE: trap stack overflow, trap NULL pointer deref
// C:\Users\-------\Desktop\arduino-1.8.12 BETA4\hardware\teensy\avr\cores\teensy4\startup.c
// quick fix - about line 211:
/*
  FLASHMEM void configure_cache(void)
  {
  //printf("MPU_TYPE = %08lX\n", SCB_MPU_TYPE);
  //printf("CCR = %08lX\n", SCB_CCR);

  // TODO: check if caches already active - skip?

  SCB_MPU_CTRL = 0; // turn off MPU

  uint32_t i = 0;
  SCB_MPU_RBAR = 0x00000000 | REGION(i++); //https://developer.arm.com/docs/146793866/10/why-does-the-cortex-m7-initiate-axim-read-accesses-to-memory-addresses-that-do-not-fall-under-a-defined-mpu-region
  SCB_MPU_RASR = SCB_MPU_RASR_TEX(0) | NOACCESS | NOEXEC | SIZE_4G;

  SCB_MPU_RBAR = 0x00000000 | REGION(i++); // ITCM
  SCB_MPU_RASR = MEM_NOCACHE | READWRITE | SIZE_512K;

  // TODO: trap regions should be created last, because the hardware gives
  //  priority to the higher number ones.
  // --SCB_MPU_RBAR = 0x00000000 | REGION(i++); // trap NULL pointer deref // <------------------
  // --SCB_MPU_RASR =  DEV_NOCACHE | NOACCESS | SIZE_32B; // <------------------

  SCB_MPU_RBAR = 0x00200000 | REGION(i++); // Boot ROM
  SCB_MPU_RASR = MEM_CACHE_WT | READONLY | SIZE_128K;

  SCB_MPU_RBAR = 0x20000000 | REGION(i++); // DTCM
  SCB_MPU_RASR = MEM_NOCACHE | READWRITE | NOEXEC | SIZE_512K;

  // -- SCB_MPU_RBAR = ((uint32_t)&_ebss) | REGION(i++); // trap stack overflow // <------------------
  // -- SCB_MPU_RASR = SCB_MPU_RASR_TEX(0) | NOACCESS | NOEXEC | SIZE_32B; // <------------------

  SCB_MPU_RBAR = 0x20200000 | REGION(i++); // RAM (AXI bus)
  SCB_MPU_RASR = MEM_CACHE_WBWA | READWRITE | NOEXEC | SIZE_1M;

  SCB_MPU_RBAR = 0x40000000 | REGION(i++); // Peripherals
  SCB_MPU_RASR = DEV_NOCACHE | READWRITE | NOEXEC | SIZE_64M;

  SCB_MPU_RBAR = 0x60000000 | REGION(i++); // QSPI Flash
  SCB_MPU_RASR = MEM_CACHE_WBWA | READONLY | SIZE_16M;

  SCB_MPU_RBAR = 0x70000000 | REGION(i++); // FlexSPI2
  SCB_MPU_RASR = MEM_CACHE_WBWA | READONLY | SIZE_256M;

  SCB_MPU_RBAR = 0x70000000 | REGION(i++); // FlexSPI2
  SCB_MPU_RASR = MEM_CACHE_WBWA | READWRITE | SIZE_16M;

  // TODO: protect access to power supply config

  SCB_MPU_CTRL = SCB_MPU_CTRL_ENABLE;

  // cache enable, ARM DDI0403E, pg 628
  asm("dsb");
  asm("isb");
  SCB_CACHE_ICIALLU = 0;

  asm("dsb");
  asm("isb");
  SCB_CCR |= (SCB_CCR_IC | SCB_CCR_DC);
  }
*/

#include "pmf_player.h"
#include <Audio.h>

//============================================================================
// SdFat version 2.0.0 BETA ONLY
//============================================================================
// NEED THIS BEFORE MTP LIB.
#include <SdFat.h> // SdFat V "2.0.0"
const char *SDFAT_ver = SD_FAT_VERSION;

// Use built-in SD for SPI modes on Teensy 3.5/3.6.
// Teensy 4.0 use first SPI port.
// SDCARD_SS_PIN is defined for the built-in SD on some boards.
#ifndef SDCARD_SS_PIN
const uint8_t SD_CS_PIN = SS;
#else  // SDCARD_SS_PIN
// Assume built-in SD is used.
const uint8_t SD_CS_PIN = SDCARD_SS_PIN;
#endif  // SDCARD_SS_PIN

// SD_FAT_TYPE = 0 for SdFat/File as defined in SdFatConfig.h,
// 1 for FAT16/FAT32, 2 for exFAT, 3 for FAT16/FAT32 and exFAT.
#define SD_FAT_TYPE 3

SdFat sd; // SD

// The file to be parsed.
File m_pSource;

uint32_t FILESIZE;
const int DIR_max = 60; // [# of Directory - max]
const int max_DIR_name_lenght = 100;
char CURDIRname[max_DIR_name_lenght] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; // 
uint32_t DIRcount = 1; // COUNT of all DIRs on SD CARD
char DIR_list_array[DIR_max][max_DIR_name_lenght]; // [# of DIRs max][max DIR name lenght];
bool op_sd = 0;
char PMFfilename[max_DIR_name_lenght]; // SDFAT
uint32_t CUR_PMF_FILE_counter = 1 ;
uint32_t PMF_FILE_counter = 0 ;
int receivedChar; // an array to store the received data
boolean newData = false;

//----------------------------------------------------------------------------


//============================================================================
// Audio lib. Volume level
//============================================================================
float Volume = 1.00; // 100%

//============================================================================
// music data
//============================================================================
// static const uint8_t PROGMEM s_pmf_file[] =
static const uint8_t FLASHMEM s_pmf_file[] =
{
#include "music.h"
};
//----------------------------------------------------------------------------


//============================================================================
// SD FILE music data storage
//============================================================================
//uint8_t SD_MusicData[450000] DMAMEM; // Upper MEMORY
uint8_t SD_MusicData[500000] DMAMEM; // Upper MEMORY

uint32_t array_counter = 0;
uint32_t TOTAL_PMF_FILE_counter = 0;
//----------------------------------------------------------------------------


//============================================================================
// globals
//============================================================================
static pmf_player s_player;
static unsigned s_effect_channel = 0;
char SDPmfIDCheck[14] = {};
char PmfID[14] = {'/', '/', ' ', 'S', 'o', 'n', 'g', ' ', 'n', 'a', 'm', 'e', ':', ' '}; // Profoundic Music File format - TEXT ID
//----------------------------------------------------------------------------


//============================================================================
// row_callback_test
//============================================================================
void row_callback_test(void *custom_data_, uint8_t channel_idx_, uint8_t &note_idx_, uint8_t &inst_idx_, uint8_t &volume_, uint8_t &effect_, uint8_t &effect_data_)
{
  if (channel_idx_ == s_effect_channel)
  {
    static unsigned s_counter = 1;
    if (--s_counter == 0)
    {
      note_idx_ = 0 + 5 * 12; // C-5 (note+octave*12, note: 0=C, 1=C#, 2=D, 3=D#, 4=E, 5=F, 6=F#, 7=G, 8=G#, 9=A, 10=A#, 11=B)
      inst_idx_ = 2;    // sample 2
      volume_ = 63;     // volume 63 (max)
      s_counter = 8;    // hit note every 8th row
    }
  }
}
//----------------------------------------------------------------------------


//============================================================================
// Teensy 4.0 Serial Number and MAC     // 04:E9:E5:09:6A:F3
//============================================================================
static void teensyMAC(uint8_t *mac)
{
  uint32_t m1 = HW_OCOTP_MAC1;
  uint32_t m2 = HW_OCOTP_MAC0;
  mac[0] = m1 >> 8;
  mac[1] = m1 >> 0;
  mac[2] = m2 >> 24;
  mac[3] = m2 >> 16;
  mac[4] = m2 >> 8;
  mac[5] = m2 >> 0;
}
//----------------------------------------------------------------------------


//============================================================================
// setup
//============================================================================
void setup()
{
  Serial.begin(38400);
  while (!Serial && millis() < 1000) {}  // wait for Serial Monitor with 1s. timeout.

  Serial.print("Teensy Serial# and MAC: ");
  uint8_t mac[6];
  teensyMAC(mac);
  for (uint8_t i = 0; i < 6; ++i) {
    Serial.printf("%02X", mac[i]);
    if (i < 5) {
      Serial.print(":");
    }
  }
  Serial.println("");

  Serial.print(tempmonGetTemp(), 1); // TEENSY 4.0
  Serial.println(" CPU TEMP");

  // no mtp
  // storage.init(); // MTP

  if (!sd.begin(SdioConfig(FIFO_SDIO))) { // SdFat.h Ver 2.0.0 Beta
    Serial.println("m.SD initialization failed!");
    s_player.load(s_pmf_file); // play from h. file
    Serial.println(F(" Playing from h. file"));
  } else {
    Serial.println("m.SD initialization OK");

    LISTDIRs();

    m_pSource = sd.open("/"); // ROOT
    PrintFiles(m_pSource);
    m_pSource.close();
  }

  s_player.load(s_pmf_file); // play from h. file
  Serial.println(F(" Playing from music.h. file"));
  s_player.start(44100); //22050
  s_player.Volumelevel(Volume,  Volume); // SET AT Volume
}
//----------------------------------------------------------------------------

//============================================================================
// loop
//============================================================================
void loop()
{
  if (Serial.available() > 0) {
    receivedChar = Serial.read();
    newData = true;
    Serial.print("This just in ... ");
    Serial.print(receivedChar);
    Serial.print(" ascii: ");
    Serial.write(receivedChar);
    Serial.println();
  }

  // PMF accessors
  //uint8_t num_pattern_channels() const;
  //uint8_t num_playback_channels() const;
  //uint16_t playlist_length() const;
  //float arr_p_x() const;
  //-------------------------------------------------------------------------

  // player control
  //void start(uint32_t sampling_freq_ =/*44100*/22050, uint16_t playlist_pos_ = 0);
  //void stop();
  //void update();
  //-------------------------------------------------------------------------

  // playback state accessors
  //float fftlevelbuffer(uint8_t fft_0_) const;
  //void Volumelevel(float mixerVol1_, float mixerVol2_) const;

  //bool is_playing() const;
  //uint8_t playlist_pos() const;
  //uint8_t pattern_row() const;
  //uint8_t pattern_speed() const;

  // auto skip, next song.
  // some songs will never get to the end.

  //__disable_irq();
  if (( s_player.playlist_length() == s_player.playlist_pos() + 1 /*&& s_player.pattern_row() >= 20*/ ) || (newData == true) ) {
    //__enable_irq();

    newData = false;
    s_player.stop(); // todo
    // s_player.stop_playback(); // ?
    Serial.println("stop# ");

    if (op_sd == 0) {
      m_pSource = sd.open("/"); //root
      op_sd = 1;
      PMF_FILE_counter = 0;
      Serial.println ("ok 1st open ");
    }

    if (m_pSource.isOpen()) {
      Serial.println(" m_pSource is open "); // SDFAT LIB

      int len = strlen(PMFfilename);
      char *extension = PMFfilename + len - 4;
      while (true) {

        File entry = m_pSource.openNextFile();
        //FsFile entry = m_pSource.openNextFile();
        if (! entry) {
          // no more files
          Serial.println("\t **no more files**"), Serial.println();
          //op_sd = 0; // bool
          PMF_FILE_counter = 0; // reset
          entry.close();
          m_pSource.close();

          // TO DO OPEN WITH  dirIndex  135
          m_pSource = sd.open("/"); //root
        }
        entry.getName(PMFfilename, sizeof(PMFfilename));

        if (entry.isDirectory()) {
          // skip
        } else {
          Serial.print(PMFfilename); // SDFAT LIB
          // files have sizes, directories do not
          Serial.print("       \t");
          Serial.println(entry.size(), DEC);

          len = strlen(PMFfilename);
          extension = PMFfilename + len - 4;
          Serial.println(*extension);

          if (!strcmp(".pmf", extension) || !strcmp(".PMF", extension)) { // PMF File Format
            // See if there's any touch data for us
            /*
              if (ts.tirqTouched()) {
              TouchData();
              }
            */

            uint32_t index = entry.dirIndex() ;
            Serial.print("\t index  ~  "), Serial.println(index);

            //entry.close();
            PMF_FILE_counter ++;
            Serial.print("\t PMF_FILE_counter ++;  ~  "), Serial.println(PMF_FILE_counter);
            Serial.print("\t CUR_PMF_FILE_counter ++  ~  "), Serial.println(CUR_PMF_FILE_counter);
            //BTserial.print("PMF FILE# -> "), BTserial.print(CUR_PMF_FILE_counter);
            //BTserial.print(" of "), BTserial.println(TOTAL_PMF_FILE_counter);

            if (CUR_PMF_FILE_counter == PMF_FILE_counter) {
              PMF_FILE_counter = 0;
              CUR_PMF_FILE_counter++;
              if (CUR_PMF_FILE_counter >= TOTAL_PMF_FILE_counter) { //
                CUR_PMF_FILE_counter = 1;
              }
              if (CUR_PMF_FILE_counter == 4294967295) { // 0xFFFFFFFF
                CUR_PMF_FILE_counter = 1;
              }

              Serial.print(PMFfilename); // SDFAT LIB
              Serial.print("\t PMF player Audio File Format Supported  ~  "), Serial.println(PMFfilename);

              m_pSource.close();
              m_pSource = sd.open(PMFfilename, FILE_READ); //

              // uint8_t SD_MusicData[500000] DMAMEM; // Upper MEMORY

              ParsePmfHeader( entry.curPosition() );
              entry.close();
              s_player.load(SD_MusicData); // play from SD buffered file
              // player control
              //void start(uint32_t sampling_freq_ =/*44100*/22050, uint16_t playlist_pos_ = 0);
              //void stop();
              //void update();
              s_player.start(44100); //(44100,0)
              s_player.Volumelevel(Volume,  Volume); // SET AT Volume

              //Serial.println("\t debug 1 ");
              break;
            }
          }
        }
        entry.close();
      }
      //BTserial.print("PMF FILE# -> "), BTserial.print(CUR_PMF_FILE_counter - 1);
      //BTserial.print(" of "), BTserial.println(TOTAL_PMF_FILE_counter);
    }
  } else {
    s_player.update(); // keep updating the audio buffer...
  }
} // loop end
//----------------------------------------------------------------------------


// # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
//============================================================================
//------------ LIST ALL DIRs ON SD CARD & SAVE IN DIR_list_array -------------
//============================================================================
void LISTDIRs() {
  Serial.println("\t**List Directories**");
  m_pSource = sd.open("/"); // ROOT
  char dirname[max_DIR_name_lenght]; // SDFAT // max_DIR_name_lenght
  if (m_pSource.isDirectory()) {
    strcpy(DIR_list_array[DIRcount], "/"); // array

    Serial.print("ROOT# ");
    Serial.print(DIRcount);
    Serial.print("\t");
    Serial.println(DIR_list_array[DIRcount]); // SDFAT LIB
    DIRcount++;
  }
  while (true) {
    File DIR = m_pSource.openNextFile();

    if (! DIR) {
      // no more files
      Serial.println("\t **no more Directories** ");
      //dir.close();
      break;
    }
    DIR.getName(dirname, sizeof(dirname));
    if (DIR.isDirectory()) {
      //DIRcount++;
      strcpy(DIR_list_array[DIRcount], dirname); // array
      strcat(DIR_list_array[DIRcount], "/");
      Serial.print("DIR# ");
      Serial.print(DIRcount);
      Serial.print("\t");
      Serial.println(DIR_list_array[DIRcount]); // SDFAT LIB
      DIRcount++;
    }
    DIR.close();
  }
  DIRcount --;
  Serial.print("\t **Directory count ");
  Serial.print(DIRcount), Serial.println(" **"), Serial.println();
  m_pSource.close();
}

//============================================================================
// Print Files in Cur. Directory
//============================================================================
void PrintFiles(File dir) {
  Serial.println("\t**List Files in Cur. Directory**");
  char filename[max_DIR_name_lenght]; // SDFAT

  int len = strlen(filename);
  char *extension = filename + len - 4;

  while (true) {

    File entry = dir.openNextFile();
    if (! entry) {
      // no more files
      Serial.println("\t **no more files**");
      entry.close();
      Serial.print("\t TOTAL PMF_FILE_counter: "), Serial.println(TOTAL_PMF_FILE_counter), Serial.println();
      //BTserial.print("TOTAL PMF FILE counter "), BTserial.println(TOTAL_PMF_FILE_counter);
      break;
    }
    entry.getName(filename, sizeof(filename));

    if (entry.isDirectory()) {
      // skip
    } else {
      Serial.print(filename); // SDFAT LIB
      // files have sizes, directories do not
      Serial.print("       \t");
      Serial.print(entry.size(), DEC);

      Serial.print("\t dirIndex  "), Serial.println(entry.dirIndex());

      // PMF File Format counter
      len = strlen(filename);
      extension = filename + len - 4;
      if (!strcmp(".pmf", extension) || !strcmp(".PMF", extension)) {
        TOTAL_PMF_FILE_counter++;
      }
    }
    entry.close();
  }
}
//----------------------------------------------------------------------------

//============================================================================
//   Parse File Header.
//============================================================================
// Read a single character.
byte Get(int _CurfilePos )
{
  byte in = (m_pSource.read());
  // Serial.print("ASCII "), Serial.write(in), Serial.print(" DEC "), Serial.print(in), Serial.println();
  if (!m_pSource.available()) { // available(), number of bytes available from the current position to EOF
    Serial.println("Unexpected EOF while reading file");
  }
  return byte(in);
}
//----------------------------------------------------------------------------

//============================================================================
// Read text Pmf ID, (1st 14 Characters -->>// Song name: <<)
//============================================================================
void ReadPmfID(int filepos)
{
  Serial.println("\t-- Reading PMF Text Header (Profoundic Music File): "); // DEBUG
  SDPmfIDCheck[0] = Get(m_pSource.curPosition());
  SDPmfIDCheck[1] = Get(m_pSource.curPosition());
  SDPmfIDCheck[2] = Get(m_pSource.curPosition());
  SDPmfIDCheck[3] = Get(m_pSource.curPosition());
  SDPmfIDCheck[4] = Get(m_pSource.curPosition());
  SDPmfIDCheck[5] = Get(m_pSource.curPosition());
  SDPmfIDCheck[6] = Get(m_pSource.curPosition());
  SDPmfIDCheck[7] = Get(m_pSource.curPosition());
  SDPmfIDCheck[8] = Get(m_pSource.curPosition());
  SDPmfIDCheck[9] = Get(m_pSource.curPosition());
  SDPmfIDCheck[10] = Get(m_pSource.curPosition());
  SDPmfIDCheck[11] = Get(m_pSource.curPosition());
  SDPmfIDCheck[12] = Get(m_pSource.curPosition());
  SDPmfIDCheck[13] = Get(m_pSource.curPosition());
  //Serial.println(m_pSource.curPosition()); // DEBUG
}
//----------------------------------------------------------------------------

//============================================================================
// interpret the ascii digits in[0] and in[1] as hex
// notation and convert to an integer 0..255.
//============================================================================
int hex8(char *in)
{
  uint8_t c, h;

  c = in[0];

  if (c <= '9' && c >= '0') {
    c -= '0';
  }
  else if (c <= 'f' && c >= 'a') {
    c -= ('a' - 0x0a);
  }
  else if (c <= 'F' && c >= 'A') {
    c -= ('A' - 0x0a);
  }
  else return (-1);

  h = c;

  c = in[1];

  if (c <= '9' && c >= '0') {
    c -= '0';
  }
  else if (c <= 'f' && c >= 'a') {
    c -= ('a' - 0x0a);
  }
  else if (c <= 'F' && c >= 'A') {
    c -= ('A' - 0x0a);
  }
  else return (-1);

  return ( h << 4 | c);
}
//----------------------------------------------------------------------------

//============================================================================
// Parse Pmf Header
//============================================================================
void ParsePmfHeader(int _Fpos)
{

  Serial.println();
  Serial.println("\t--BEGIN -- Parse Text Header of PMF file, 1st 14 characters");
  //BTserial.println();
  //BTserial.println("\t--BEGIN -- Parse Text Header of PMF file");
  // BTserial.println();

  if (m_pSource.isDirectory()) {
    Serial.println(" / ");
  } else {
    char filename[255]; // SDFAT
    m_pSource.getName(filename, sizeof(filename)); // SDfat
    const char* n = filename; // SDfat
    Serial.print("\t-- The file to be parsed -> "), Serial.print(n);
    //BTserial.print("\t-- The file to be parsed -> "), BTserial.println(n);
    // files have sizes, directories do not
    Serial.print("\t size: ");
    Serial.println(m_pSource.size(), DEC);
    //BTserial.print("\t size: ");
    //BTserial.println(m_pSource.size(), DEC);
  }
  int filepos = _Fpos; // m_pSource.curPosition();
  bool PMF_check = 1;
  ReadPmfID(filepos);
  PMF_check = memcmp(SDPmfIDCheck, PmfID, sizeof(SDPmfIDCheck)); // compares 2 chuncks of memory.
  if (PMF_check == 0)
  {
    Serial.print("\t-- Text Header matches OK");
    Serial.println();
    //BTserial.println("\t-- Text Header matches OK");
    //BTserial.println();

    m_pSource.seekSet (0);

    // Parsing Header Text
    char a = 0;
    char b = 0;
    char c = 0;
    while (a != 'x' && b != '7' && c != '0' ) {
      char y;
      y = (m_pSource.read()); // read next char

      if (y == '0') {
        char temp2 = y;
        y = (m_pSource.read());
        if (y != 'x') { //
          Serial.print(temp2);
          Serial.print(y);
          //BTserial.print(temp2);
          //BTserial.print(y);
        }
      } else if (y == 10) { // 10 0x0A, LF  Line Feed
        Serial.println();
        //BTserial.println();
      } else {
        if (y != 'x') {
          Serial.print(y);
          //BTserial.print(y);
        }
      }

      if (y == 'x') {
        char temp1 = y;
        y = (m_pSource.read()); // read next char
        if (y == '7') {
          y = (m_pSource.read());
          if (y == '0') {
            a = 'x';
            b = '7';
            c = y;
            uint32_t fpos = m_pSource.curPosition ();
            Serial.print(" DEBUG           fpos ");
            Serial.println(fpos);
            m_pSource.seekSet(fpos - 4); // now ready for Header Data
          }
        } else if (y != '7') {
          Serial.print(temp1);
          Serial.print(y);
          //BTserial.print(temp1);
          //BTserial.print(y);
        }
      }
    }

    // Parsing Header Data
    while (m_pSource.available()) {
      char x;
      x = (m_pSource.read());

      if (x == '0') {
        x = (m_pSource.read()); // read next char
        if (x == 'x') { //
          char tmp[2];
          int n = 0;
          tmp[0] = (m_pSource.read());
          tmp[1] = (m_pSource.read());
          // tmp now has two char hex value
          /// ?? n = strtol(tmp, NULL, 16); // n has numeric value
          n = hex8(tmp); // well this works ok, arduino strtol had some issue with some pfm files ?
          SD_MusicData[array_counter] = (char)n; // SD_MusicData[X] has character value

          //if (n > 255) { // debug
          //  Serial.print(" ASCII to hex issue: ");
          //  Serial.println(n);
          //  delay(2000);
          //}

          if (array_counter < 4) {
            //Serial.println(array_counter);
            if (array_counter == 0) {
              Serial.println(" DATA Header: ");
              Serial.print(array_counter);
              Serial.print(" Ascii: ");
              Serial.write(SD_MusicData[array_counter]);
              Serial.println();
            } else {
              Serial.print(array_counter);
              Serial.print(" Ascii: ");
              Serial.write(SD_MusicData[array_counter]);
              Serial.println();
            }
          }

          array_counter++;
          if (array_counter >= sizeof SD_MusicData) {
            Serial.println(), Serial.println();
            Serial.println(" Error file is too large for destination buffer ( : ");
            Serial.print(" byte counter : "), Serial.println(array_counter);
            //BTserial.println(), BTserial.println();
            //BTserial.println(" Error file is too large for destination buffer ( : ");
            //BTserial.print(" byte counter : "), BTserial.println(array_counter);
            array_counter = 0;
            // return;
            break; // ? 
          }
        }
      } else if (x == 13) { // 13  0x0D, CR  Carriage Return
        x = (m_pSource.read()); // read next char
        if (x == 10) { // 10 0x0A, LF  Line Feed
        }
      }
    }
  } else {
    Serial.print("No luck");
  }

  Serial.print(" , Size after conversion : "), Serial.println(array_counter), Serial.println();
  array_counter = 0;
}
//----------------------------------------------------------------------------

Also I had no USB Audio on Windows 10 till I was messing with sound settings and choose listen to this device somewhere in Recording - Properties.
LISTEN TO THIS DEVICE.jpg
 

Attachments

  • PMF1_AUDIO.zip
    1.1 MB · Views: 342
  • PMF2_AUDIO.zip
    843 KB · Views: 151
  • pmf_player_2_minimum.zip
    38.4 KB · Views: 123
  • Audio_fix.zip
    9 KB · Views: 88
@Chris O. - asking because I wrote a wrapper for the PJRC debug fault handler code to activate it - but it never gets enough interest to keep me interested as Teensy's change - started in T_3.6 during Beta IIRC - then touched it again during T_4.0 and again recently - but faults are rare enough - about as rare as new Teensy's .

I should make a simple pared down version that is easy to include for fault detect and nothing more I suppose.
 
#include <core_cm7.h>

C:\Arduino\hardware\teensy\avr\cores\teensy4/core_cm7.h:63:10: fatal error: cmsis_version.h: No such file or directory
 
@Paul - if you work on the installer in the next weeks or months (mid-term) - can you add a little feature? it would be great if it could just ignore write-protected files (or ask to overwrite).
After a while, it is a bit frustrating to patch everything again and again with every beta to keep basic features (that Arduino (or you ;) refuses to add) working...

Things like platfom.txt, boards.txt or other patched files.
 
Last edited:
@Paul - As I know you have lots of time and little to do... Or was it the other way around ;)

I thought I would mention again with the current Teensy terminal, there is an issue of doing cuts and pasts from the terminal window to other places, often double spaces on the paste. I believe that you are holding onto the \r ....

Here is the output of a program if I do cut and paste:
Code:
Change all LSS Servos from 115200 to 500000 baud
Scan servos at 115200
*7QD42


*9QD-1134


*11QD-692


Press any key to continue

Try set baud cammand

Reset

Scan servos at 500000
*7QD42


*9QD-1134


*11QD-692


Press any key to try again
The actual screen looks like:
screenshot.jpg

The actual code:
Code:
static const uint32_t from_speed = 115200;
static const uint32_t to_speed = 500000;
void setup()
{
  while (!Serial && millis() < 5000) ;
  Serial.printf("Change all LSS Servos from %u to %u baud\n", from_speed, to_speed);
}
void loop() {
  Serial1.begin(from_speed);
  Serial.printf("Scan servos at %u\n", from_speed);
  bool Servos_found = ScanServos();
  if (Servos_found) {
    Serial.println("Press any key to continue");
    while (Serial.read() == -1) ;
    while (Serial.read() != -1) ;
    delay(250);
    Serial.println("Try set baud cammand");
    Serial1.printf("#254CB%u\r", to_speed);
    delay(250);
    Serial.println("Reset");
    Serial1.print("#254RESET\r");
    delay(3000);
    Serial1.end();
    Serial1.begin(to_speed);
    delay(250);
    Serial.printf("Scan servos at %u\n", to_speed);
    ScanServos();
  }
  Serial1.end();
  Serial.println("Press any key to try again");
  while (Serial.read() == -1) ;
  while (Serial.read() != -1) ;
}

bool ScanServos() {
  bool found_servo = false;
  for (uint8_t servo_id = 0; servo_id < 254; servo_id++) {
    Serial1.printf("#%uQD\r", servo_id);
    Serial1.flush();
    delay(25);
    if (Serial1.available()) {
      int ch;
      while ((ch = Serial1.read()) != -1) {
        Serial.write(ch);
      }
      found_servo = true;
      Serial.println();
    }
  }
  return found_servo;
}
 
MacOS 10.15.4 Catalina install, no problems, all RTC issues, (and I think I was struggling with all of them) on T4.0 and T4.1 have been resolved. Don't have the spacing issue @KurtE notes above. Successfully using Wire, Wire1, SPI, Audio ect at the same time on T4.x, finally.

thanks everyone !
 
The spacing issue is from Teensy putting both \r\n on println() and the T_SerMon storing/returning it that way - at least on Windows as Kurt notes.

Using TyCommander as Sermon this does not happen - lines copy and paste on Windows to Notepad or other without 'blank lines' from println(). But when cut and paste from T_SerMon - the \r\n on the output results in blank lines for each println().

It would be nice if someday T_SerMon on Windows didn't do that duplication - until then Serial.print('\n'); works better than Serial.println(); for cut and paste.
 
Status
Not open for further replies.
Back
Top