[solved] compile error swiching from Arduino to Teensy

Hi,
I want to port a project from Arduino 2560 to Teensy 3.2 with a 3rd party library SimpleSDAudio.
I’m advancing step by step. Replacing fast PWM on Arduino with IntervalTimer and DAC works. Now I want to port the SD part which is a simplified version of SDFat and very fast.

The code of the first step is:

#include "audio.h"

//#include <sd_l2.h> 

elapsedMicros blinkPrint=0;
uint16_t looping=0;

byte isr_disen =0;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  
  SdPlay.init();

  Serial.print("Symbol ARDUINO = ");Serial.println(ARDUINO);
}

void loop() {

  unsigned long blinkCopy;  // holds a copy of the blinkCount

  // to read a variable which the interrupt code writes, we
  // must temporarily disable interrupts, to be sure it will
  // not change while we are reading.  To minimize the time
  // with interrupts off, just quickly make a copy, and then
  // use the copy while allowing the interrupt to keep working.
  
  delay(50);
  if (blinkPrint > 1000000) { // every second
    blinkPrint = 0;
    
    noInterrupts();
    blinkCopy = SdPlay.blinkCount;
    interrupts();

    Serial.print("blinkCount = ");
    Serial.print(blinkCopy);

    Serial.print("  isr_disen=");Serial.println(isr_disen);
    if (isr_disen) {
      SdPlay.start();           // method 4
      isr_disen=0;
    }
    else {
      SdPlay.stop();            // method 4
      isr_disen=1;
    }
    looping++;
  }
}

I works. The IntervalTimer is started in setup() with SdPlay.init() and the LED is blinking for 1 sec, then stops blinking for 1 sec, and so on.

Next the line //#include <sd_l2.h> in the beginning is decommented. And now the compiler reports a lot of errors in core libraries, like

...\arduino-1.8.4\hardware\tools\arm\arm-none-eabi\include\machine\_default_types.h: Assembler messages:

...\arduino-1.8.4\hardware\tools\arm\arm-none-eabi\include\machine\_default_types.h:27: Error: bad instruction `typedef signed char __int8_t'

...\arduino-1.8.4\hardware\tools\arm\arm-none-eabi\include\machine\_default_types.h:29: Error: bad instruction `typedef unsigned char __uint8_t'

The part of code in _default_types.h with the reported error of the example (lines 27, 29 marked):

/*
 *  $Id$
 */

#ifndef _MACHINE__DEFAULT_TYPES_H
#define _MACHINE__DEFAULT_TYPES_H

#include <sys/features.h>

/*
 * Guess on types by examining *_MIN / *_MAX defines.
 */
#if __GNUC_PREREQ (3, 3)
/* GCC >= 3.3.0 has __<val>__ implicitly defined. */
#define __EXP(x) __##x##__
#else
/* Fall back to POSIX versions from <limits.h> */
#define __EXP(x) x
#include <limits.h>
#endif

#ifdef __cplusplus
extern "C" {
#endif

#ifdef __INT8_TYPE__
typedef __INT8_TYPE__ __int8_t;                         <----------------line 27
#ifdef __UINT8_TYPE__
typedef __UINT8_TYPE__ __uint8_t;                      <----------------line 29
#else
typedef unsigned __INT8_TYPE__ __uint8_t;
#endif

Similar errors are reported in other header files of the core library.

Also such type of error is reported:

...\arduino-1.8.4\hardware\teensy\avr\cores\teensy3\kinetis.h:146: Error: bad instruction `enum IRQ_NUMBER_t {'

...\arduino-1.8.4\hardware\teensy\avr\cores\teensy3\kinetis.h:147: Error: junk at end of line, first unrecognized character is `,'

...\arduino-1.8.4\hardware\teensy\avr\cores\teensy3\kinetis.h:148: Error: junk at end of line, first unrecognized character is `,'

Lines 144 - 150 of kinetis.h where the errors are reported from:

// Teensy 3.1 & 3.2
#elif defined(__MK20DX256__)
enum IRQ_NUMBER_t {
	IRQ_DMA_CH0 =		0,
	IRQ_DMA_CH1 =		1,
	IRQ_DMA_CH2 =		2,
	IRQ_DMA_CH3 =		3,

I don’t understand these error messages at all. What about such curious error messages in core libraries!
Compilation for Arduino is ok, but not for Teensy.

Is there a different compiler for Arduino and Teensy?

It’s not a matter of non matching libraries. What to do now?

supArdu

It looks like those header files are being included from an assembly file (.S) somewhere. That's why it says "Assembler messages:" and "Error: bad instruction".

SupArdu:
Is there a different compiler for Arduino and Teensy?

There is no specific compiler for "Arduino" or "Teensy". The Mega 2560 is part of the Arduino AVR Boards hardware package which uses the avr-gcc compiler. Some Teensy boards are also AVR and use that compiler, other Teensy boards are not AVR and use a different compiler. In this case you're seeing errors from files included with arm-none-eabi, which is not used by Arduino AVR Boards.

What is this sd_l2.h? Is it part of the Teensy hardware package or a library you installed. If the latter then you need to post a link to where you downloaded it from.

It looks like those header files are being included from an assembly file (.S) somewhere.

If so then it is clear that an Assembler cannot understand such a code.
But this also means that the build mechanism is totally confused. An Assembler cannot understand C code.
I will post this problem in the Teensy forum.

What is this sd_l2.h?

The header file sd_l2.h is part of a 3rd party library, SimpleSDAudio. This library allows to replay audio data from a SD card using fast PWM of Arduino and functions to read consecutive blocks of 512 bytes from SD. There is not much overhead using these SD functions and therefore reading is very fast.
You can find the library and a detailed description of usage on Arduino Playground, https://playground.arduino.cc/Main/LibraryList#Audio.

The header file sd_l2.h does not contain any #include statements. Therefore I cannot understand why including sd_l2.h can have such an influence.
The code of sd_l2.h is:

#ifndef SD_L2_H
#define SD_L2_H

#define SD_ENABLE_DIR_VIEW          1

/** No valid MBR/FAT-BS signature found in sector 0 */
#define SD_L2_ERROR_INVAL_SECT0     0x30
/** Malformed FAT boot sector */
#define SD_L2_ERROR_INVAL_BS        0x31
/** FAT12 is not supported */
#define SD_L2_ERROR_FAT12           0x32
/** FAT not initialized properly */
#define SD_L2_ERROR_FAT_NOT_INIT    0x33
/** End of cluster reached (not a real error, just information) */
#define SD_L2_ERROR_DIR_EOC         0x34
/** File not found after reaching end of directory */
#define SD_L2_ERROR_FILE_NOT_FOUND  0x35
/** Fragmentation found */
#define SD_L2_ERROR_FRAGMET_FOUND   0x36
/** Error in FAT entry */
#define SD_L2_ERROR_FAT_ENTRY       0x37
/** End of file reached */
#define SD_L2_ERROR_EOF             0x38
/** WorkBuf not set */
#define SD_L2_ERROR_WORKBUF         0x39


#define SD_L2_PARTTYPE_UNKNOWN      0
#define SD_L2_PARTTYPE_SUPERFLOPPY  1
#define SD_L2_PARTTYPE_FAT16        2
#define SD_L2_PARTTYPE_FAT32        3

typedef struct  {
    uint8_t     PartType;       // Use this to test whether it is FAT16 or FAT32 or not initialized
	
	// Stuff from FAT boot sector
	uint8_t     SecPerClus;
	uint16_t    RsvdSecCnt;
	uint8_t     NumFATs;
	uint16_t    RootEntryCount;
	uint32_t    TotalSec;
	uint32_t    SecPerFAT;
	uint32_t    RootClus;
	
	// For cluster calculations
	uint8_t     ClusterSizeShift;
	uint32_t    ClusterCount;
	
	// Start addresses (all in blocks / sector addresses)
	uint32_t    BootSectorStart;    // Address of boot sector from FAT
	uint32_t    FatStart;           // First file allocation table starts here
	uint32_t    RootDirStart;       // Root directory starts here
	uint32_t    DataStart;          // Cluster 0 starts here
	
	uint32_t    ClusterEndMarker;   // if Cluster >= this then end of file reached.
	
} SD_L2_FAT_t;

typedef struct {
	uint8_t     Attributes;
	uint32_t    Size;           // in bytes
	uint32_t    FirstCluster;   // First cluster
    
	uint32_t    ActSector;      // 0 to (SD_L2_FAT.SecPerClus - 1)
	uint32_t    ActBytePos;     // 0 to Size
} SD_L2_File_t;

extern SD_L2_FAT_t SD_L2_FAT;

uint8_t     SD_L2_Init(uint8_t *pWorkBuf);
void        SD_L2_DeInit();

uint8_t     SD_L2_SearchFile(uint8_t *filename, const uint32_t cluster, const uint8_t maskSet, const uint8_t maskUnset, SD_L2_File_t *fileinfo);
uint32_t    SD_L2_Cluster2Sector(uint32_t cluster);

uint8_t     SD_L2_IsFileFragmented(SD_L2_File_t *fileinfo);

#if SD_ENABLE_DIR_VIEW 
  uint8_t SD_L2_Dir(const uint32_t cluster, const uint8_t maskSet, const uint8_t maskUnset, void (*callback)(char *entryLine));
#endif  /* SD_ENABLE_DIR_VIEW */

#endif

Hopefully I can solve this problem or find another library to read blocks of data from SD card. I read about SDFs which is said to be very fast, and will have a look on it.

SupArdu

As I suspected, there is a .S file in that library, SimpleSDAudioAsm.S. It has this line:

#include <avr/io.h>

That file is part of the toolchain and thus a different version of that file is used when compiling for Mega 2560 vs your Teensy board. My guess is that the AVR toolchain’s io.h is amenable to being included from an assembly file but that the Teensy toolchain’s io.h is not.

The .S file is a relic from the original Arduino version. I believed that it will not be compiled because in my first steps of Teensy version it is not used. Nowhere there is a reference or include to it.

Now I learned that a .S file always is compiled when a header file in the same folder is included from anywhere.

The lot of errors disappeared after deleting the .S file from the folder, just deleting and it compiles!
Now I can advance one step more and test the SD functions.

Thank you for your tips. They helped me :slight_smile:

supArdu