How to add support for SAM D51/Cortex M4?



  • Hello,
    my name is Karl-Heinz and I discovered MySensor a few days ago. I am very impressed and would like to use it for all my sensors.
    I have 8bit and 32bit MCUs.
    My latest MCU is an SAM D51 (Adafruit Itsybitsy M4).
    I can use it when I make a minor modification to MySensors/hal/architecture/SAMD/MyHwSAMD.cpp.
    When I try to compile Arduino IDE throws an error, that ADC is not defined in this context -> uint16_t hwCPUVoltage()
    I have not much experience with programming. Therefore I commented all code lines in uint16_t hwCPUVoltage() and added hardcoded "return 3.3;"
    Then I can compile at least what I tested so far for the SAM D51.

    Of course this is not a solution. Therefore I would like to ask what is the proper way to modify MySensors for use with the Cortex M4 processors.

    Thanks a lot and keep the good work going!!

    Sincerely

    Karl-Heinz


  • Mod

    A (still incomplete but) less inelegant solution is to

    return FUNCTION_NOT_SUPPORTED;
    

    As is done for esp32 for example: https://github.com/mysensors/MySensors/blob/6ffe29cb5fcfa33fa83133044c2d16ee45c66697/hal/architecture/ESP32/MyHwESP32.cpp#L119



  • Hallo Mikael,
    thank you for your hint.

    I modified the hwCPUVoltage() part of MyHwSAMD.cpp like this. It works for me. Maybe it is not the best solution, however.

    Sincerely

    Karl-Heinz

    uint16_t hwCPUVoltage()
    {
    	#ifdef __SAMD51__ 
    	   return FUNCTION_NOT_SUPPORTED;
    	#else
    
    	// disable ADC
    	while (ADC->STATUS.bit.SYNCBUSY);
    	ADC->CTRLA.bit.ENABLE = 0x00;
    
    	// internal 1V reference (default)
    	analogReference(AR_INTERNAL1V0);
    	// 12 bit resolution (default)
    	analogWriteResolution(12);
    	// MUXp 0x1B = SCALEDIOVCC/4 => connected to Vcc
    	ADC->INPUTCTRL.bit.MUXPOS = 0x1B ;
    
    	// enable ADC
    	while (ADC->STATUS.bit.SYNCBUSY);
    	ADC->CTRLA.bit.ENABLE = 0x01;
    	// start conversion
    	while (ADC->STATUS.bit.SYNCBUSY);
    	ADC->SWTRIG.bit.START = 1;
    	// clear the Data Ready flag
    	ADC->INTFLAG.bit.RESRDY = 1;
    	// start conversion again, since The first conversion after the reference is changed must not be used.
    	while (ADC->STATUS.bit.SYNCBUSY);
    	ADC->SWTRIG.bit.START = 1;
    
    	// waiting for conversion to complete
    	while (!ADC->INTFLAG.bit.RESRDY);
    	const uint32_t valueRead = ADC->RESULT.reg;
    
    	// disable ADC
    	while (ADC->STATUS.bit.SYNCBUSY);
    	ADC->CTRLA.bit.ENABLE = 0x00;
    
    	return valueRead * 4;
            #endif
    }
    

 

344
Online

7.9k
Users

8.7k
Topics

93.6k
Posts