adafruit / ArduinoCore-samd

114 stars 116 forks source link

UART SERCOM ref clock seems to be Main 120MHz, not SERCOM_FREQ_REF = 48MHz #341

Open SimonMerrett opened 1 year ago

SimonMerrett commented 1 year ago

Up front, this is a custom design, based on ItsyBitsy M4. I've made several variants based on your excellent ItsyBitsy M4 foundation but this is the first time I have wanted to use the hardware UART. Took me a little while to find what was going on but it appeared that the UART baud was 2.5x the value passed to the Serial.begin() function. This makes me suspect that somehow the UART SERCOM is taking the 120MHz main clock instead of the expected 48MHz clock in #define SERCOM_FREQ_REF 48000000ul in SERCOM.h.

I have obviously tested on my ItsyBitsy M4 and as expected the baud rate is perfect. I'm using the same SERCOM (3), the same port pins (PA16, PA17), same pads settings, same 120 MHz main clock. Only difference hardware-wise that I can see is that I'm using the J variant with more pins.

I have .build.extra_flags=-D__SAMD51J19A__ -D__SAMD51__ {build.usb_flags} -D__FPU_PRESENT -DARM_MATH_CM4 -DCRYSTALLESS -mfloat-abi=hard -mfpu=fpv4-sp-d16 in boards.txt so I am expecting the __SAMD51__ flag is triggering the relevant preprocessor macros, such as these lines in SERCOM.cpp:

    // Asynchronous fractional mode (Table 24-2 in datasheet)
    //   BAUD = fref / (sampleRateValue * fbaud)
    // (multiply by 8, to calculate fractional piece)
#if defined(__SAMD51__)
    uint32_t baudTimes8 = (SERCOM_FREQ_REF * 8) / (sampleRateValue * baudrate);
#else
    uint32_t baudTimes8 = (SystemCoreClock * 8) / (sampleRateValue * baudrate);
#endif

What could be causing the build to fail to recognise that flag and skip to the !__SAMD51__ condition? Happy to post more but not sure what would be most useful.

kaysievers commented 1 year ago

Hmm, I would not expect the image to build and run successfully if something goes wrong with the __SAMD51__ define. Can you just put a typo / wrong character in the line you expect to be ignored and check if the compilation fails? Only to see if it's really that sort of problem.