This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSPM0G3107: MCAN using internal clock in MSPM0G3107

Part Number: MSPM0G3107
Other Parts Discussed in Thread: SYSCONFIG, LP-MSPM0L1306

Tool/software:

Hi

I'm using the MSPM0G3107 chip and I need to use MCAN to communicate several chips from different manufacturers. I'm using the TCAN1057A chip, however I can't get any output. I'm measuring with a direct logic analyzer on pins PA12 and PA13 but I'm not getting any output. My goal is to make it work without an external crystal, so I'm using the example "mcan_loopback_LP_MGPM0G3507_nortos_ticlang" and I've changed the input to "SYSPLLCLK1".

Settings:

SYSCTL -> Use Clock Tree (Disable)

SYSCTL->Clock Configuration->SYSPLL->Enable SYSPLLCLK1 (Enable)

SYSCTL->CANCLK->CANCLK Source (SYSPLLCLK1)

 

I haven't touched the rest of the settings. What do I need to configure for it to work?

Note: If I leave the "Use Clock Tree" setting active, the MSPM0 does lose when setting the Clock.

CSS: 12.8.0.00012
Compiler: TI Clang V3.2.2.LTS
MSPM0 SDK: 2.2.0.05
SysConfig: 1.21.0

  • Hi Camilo,

    When you use clock tree what are your settings? If using Sysosc, you can set this through the SYSPLL and have the PDIV at 1 ,QDiv at 5,, and CLK1_Div at 4. This will give you a 40MHz clock to the CANCLK. You can make the same configurations without clock tree, double check the SYSPLL settings

    But, I have to advise against using SYSOSC for CAN. SYSOSC has a 2.5% accuracy down to 1.2% (with a ideal 0.1% 100k resistor on ROSC). I typically recommend an external crystal because the CAN bus needs high accuracy itself (1.58% across the bus). So any inaccuracies on the whole system can propagate to an accuracy larger than the 1.58%. Having an external crystal will reduce our impact on the total bus clock accuracy error. While you can technically use SYSOSC with the ROSC resistor, it can be a challenge on the whole system to maintain the required accuracy.

    Regards,
    Luke

  • Thanks for your help
    Indeed, the use of the external clock is necessary, however, the hardware that was designed does not have the space to add the crystal, it will be implemented in a future version. The use of CAN at this time is of low speed to transmit small data packets and is only used as point to point communication.
    I tried with the settings you indicated but I'm still in the same situation, I don't see anything on the pin output.
     
    This is the project configuration file.
  • Hi Camilo,

    Your project configuration file did not send with your post.

    When you say you don't see anything on the pin output, are you transmitting or receiving; if transmitting can you place a breakpoint before the transmission function to verify that the function is getting sent?

    Regards,
    Luke

  • Hi Luke,

    I can't upload the file, I'll send the generated code.

    I'm using the transmit function, I add a breakpoint at the end of the transmission and it goes up to that point so I'm sure the functions are executed without problem. However, there is no change in the transmit pin (it always stays at logic 1)

    /**
     * These arguments were used when this file was generated. They will be automatically applied on subsequent loads
     * via the GUI or CLI. Run CLI with '--help' for additional information on how to override these arguments.
     * @cliArgs --device "MSPM0G310X" --part "Default" --package "VQFN-32(RHB)" --product "mspm0_sdk@2.02.00.05"
     * @v2CliArgs --device "MSPM0G3107" --package "VQFN-32(RHB)" --product "mspm0_sdk@2.02.00.05"
     * @versions {"tool":"1.21.0+3721"}
     */
    
    /**
     * Import the modules used in this configuration.
     */
    const ADC12         = scripting.addModule("/ti/driverlib/ADC12", {}, false);
    const ADC121        = ADC12.addInstance();
    const GPIO          = scripting.addModule("/ti/driverlib/GPIO", {}, false);
    const GPIO1         = GPIO.addInstance();
    const GPIO2         = GPIO.addInstance();
    const I2C           = scripting.addModule("/ti/driverlib/I2C", {}, false);
    const I2C1          = I2C.addInstance();
    const MCAN          = scripting.addModule("/ti/driverlib/MCAN", {}, false);
    const MCAN1         = MCAN.addInstance();
    const SYSCTL        = scripting.addModule("/ti/driverlib/SYSCTL");
    const TIMER         = scripting.addModule("/ti/driverlib/TIMER", {}, false);
    const TIMER1        = TIMER.addInstance();
    const UART          = scripting.addModule("/ti/driverlib/UART", {}, false);
    const UART1         = UART.addInstance();
    const UART2         = UART.addInstance();
    const UART3         = UART.addInstance();
    const ProjectConfig = scripting.addModule("/ti/project_config/ProjectConfig");
    
    /**
     * Write custom configuration values to the imported modules.
     */
    ADC121.$name                 = "ADC12_0";
    ADC121.sampClkDiv            = "DL_ADC12_CLOCK_DIVIDE_32";
    ADC121.samplingOperationMode = "sequence";
    ADC121.endAdd                = 1;
    ADC121.adcMem1chansel        = "DL_ADC12_INPUT_CHAN_1";
    ADC121.enabledInterrupts     = ["DL_ADC12_INTERRUPT_MEM1_RESULT_LOADED"];
    ADC121.sampClkSrc            = "DL_ADC12_CLOCK_ULPCLK";
    ADC121.adcPin0Config.$name   = "ti_driverlib_gpio_GPIOPinGeneric10";
    ADC121.adcPin1Config.$name   = "ti_driverlib_gpio_GPIOPinGeneric11";
    
    const Board                       = scripting.addModule("/ti/driverlib/Board", {}, false);
    Board.peripheral.$assign          = "DEBUGSS";
    Board.peripheral.swclkPin.$assign = "PA20";
    Board.peripheral.swdioPin.$assign = "PA19";
    
    GPIO1.port                           = "PORTA";
    GPIO1.$name                          = "GPIO";
    GPIO1.associatedPins.create(5);
    GPIO1.associatedPins[0].$name        = "LED3";
    GPIO1.associatedPins[0].initialValue = "SET";
    GPIO1.associatedPins[0].assignedPin  = "27";
    GPIO1.associatedPins[1].$name        = "LED4";
    GPIO1.associatedPins[1].assignedPin  = "24";
    GPIO1.associatedPins[2].$name        = "GPS_ONOFF";
    GPIO1.associatedPins[2].assignedPin  = "23";
    GPIO1.associatedPins[3].$name        = "DEV_ON";
    GPIO1.associatedPins[3].assignedPin  = "6";
    GPIO1.associatedPins[3].initialValue = "SET";
    GPIO1.associatedPins[4].$name        = "PIN_0";
    
    GPIO2.port                               = "PORTA";
    GPIO2.$name                              = "GPIO_SW";
    GPIO2.associatedPins[0].direction        = "INPUT";
    GPIO2.associatedPins[0].polarity         = "FALL";
    GPIO2.associatedPins[0].internalResistor = "PULL_UP";
    GPIO2.associatedPins[0].assignedPin      = "17";
    GPIO2.associatedPins[0].$name            = "BTN";
    
    I2C1.$name                             = "I2C";
    I2C1.basicEnableController             = true;
    I2C1.basicControllerStandardBusSpeed   = "Fast";
    I2C1.advControllerRXFIFOTRIG           = "BYTES_8";
    I2C1.advControllerTXFIFOTRIG           = "BYTES_7";
    I2C1.intController                     = ["TXFIFO_TRIGGER","TX_DONE"];
    I2C1.sdaPinConfig.hideOutputInversion  = scripting.forceWrite(false);
    I2C1.sdaPinConfig.onlyInternalResistor = scripting.forceWrite(false);
    I2C1.sdaPinConfig.passedPeripheralType = scripting.forceWrite("Digital");
    I2C1.sdaPinConfig.$name                = "ti_driverlib_gpio_GPIOPinGeneric2";
    I2C1.sclPinConfig.hideOutputInversion  = scripting.forceWrite(false);
    I2C1.sclPinConfig.onlyInternalResistor = scripting.forceWrite(false);
    I2C1.sclPinConfig.passedPeripheralType = scripting.forceWrite("Digital");
    I2C1.sclPinConfig.$name                = "ti_driverlib_gpio_GPIOPinGeneric3";
    
    MCAN1.$name             = "MCAN0";
    MCAN1.fdMode            = false;
    MCAN1.wkupReqEnable     = true;
    MCAN1.txPinConfig.$name = "ti_driverlib_gpio_GPIOPinGeneric8";
    MCAN1.rxPinConfig.$name = "ti_driverlib_gpio_GPIOPinGeneric9";
    
    SYSCTL.SYSPLL_CLK1En         = true;
    SYSCTL.forceDefaultClkConfig = true;
    SYSCTL.CANCLKSource          = "SYSPLLCLK1";
    SYSCTL.validateClkStatus     = true;
    SYSCTL.SYSPLL_Qdiv           = 5;
    
    TIMER1.$name              = "TIMER_0";
    TIMER1.timerMode          = "PERIODIC";
    TIMER1.interrupts         = ["ZERO"];
    TIMER1.timerClkDiv        = 8;
    TIMER1.timerClkPrescale   = 40;
    TIMER1.timerPeriod        = "1 ms";
    TIMER1.timerStartTimer    = true;
    TIMER1.peripheral.$assign = "TIMG0";
    
    UART1.$name                    = "UART_0";
    UART1.enabledInterrupts        = ["EOT_DONE","RX"];
    UART1.peripheral.$assign       = "UART0";
    UART1.peripheral.rxPin.$assign = "PA11";
    UART1.peripheral.txPin.$assign = "PA10";
    UART1.txPinConfig.$name        = "ti_driverlib_gpio_GPIOPinGeneric0";
    UART1.rxPinConfig.$name        = "ti_driverlib_gpio_GPIOPinGeneric1";
    
    UART2.$name                            = "UART_GPS";
    UART2.enabledInterrupts                = ["EOT_DONE","RX"];
    UART2.peripheral.$assign               = "UART2";
    UART2.txPinConfig.direction            = scripting.forceWrite("OUTPUT");
    UART2.txPinConfig.hideOutputInversion  = scripting.forceWrite(false);
    UART2.txPinConfig.onlyInternalResistor = scripting.forceWrite(false);
    UART2.txPinConfig.passedPeripheralType = scripting.forceWrite("Digital");
    UART2.txPinConfig.$name                = "ti_driverlib_gpio_GPIOPinGeneric4";
    UART2.rxPinConfig.hideOutputInversion  = scripting.forceWrite(false);
    UART2.rxPinConfig.onlyInternalResistor = scripting.forceWrite(false);
    UART2.rxPinConfig.passedPeripheralType = scripting.forceWrite("Digital");
    UART2.rxPinConfig.$name                = "ti_driverlib_gpio_GPIOPinGeneric5";
    
    UART3.$name                            = "UART_BLE";
    UART3.targetBaudRate                   = 115200;
    UART3.enableFIFO                       = true;
    UART3.rxFifoThreshold                  = "DL_UART_RX_FIFO_LEVEL_ONE_ENTRY";
    UART3.enableInternalLoopback           = true;
    UART3.enableDMARX                      = false;
    UART3.enableDMATX                      = false;
    UART3.enabledInterrupts                = ["EOT_DONE","RX"];
    UART3.peripheral.$assign               = "UART3";
    UART3.peripheral.rxPin.$assign         = "PA25";
    UART3.peripheral.txPin.$assign         = "PA26";
    UART3.txPinConfig.direction            = scripting.forceWrite("OUTPUT");
    UART3.txPinConfig.hideOutputInversion  = scripting.forceWrite(false);
    UART3.txPinConfig.onlyInternalResistor = scripting.forceWrite(false);
    UART3.txPinConfig.passedPeripheralType = scripting.forceWrite("Digital");
    UART3.txPinConfig.$name                = "ti_driverlib_gpio_GPIOPinGeneric6";
    UART3.rxPinConfig.hideOutputInversion  = scripting.forceWrite(false);
    UART3.rxPinConfig.onlyInternalResistor = scripting.forceWrite(false);
    UART3.rxPinConfig.passedPeripheralType = scripting.forceWrite("Digital");
    UART3.rxPinConfig.$name                = "ti_driverlib_gpio_GPIOPinGeneric7";
    
    ProjectConfig.genLinker          = false;
    ProjectConfig.migrationCondition = true;
    scripting.suppress("All four File Generation options must be enabled in order to guarantee Device Migration support\\. If an option is disabled, the user must manually configure that setting on its own file\\.", ProjectConfig);
    
    /**
     * Pinmux solution for unlocked pins/peripherals. This ensures that minor changes to the automatic solver in a future
     * version of the tool will not impact the pinmux you originally saw.  These lines can be completely deleted in order to
     * re-solve from scratch.
     */
    ADC121.peripheral.$suggestSolution           = "ADC1";
    ADC121.peripheral.adcPin0.$suggestSolution   = "PA15";
    ADC121.peripheral.adcPin1.$suggestSolution   = "PA16";
    GPIO1.associatedPins[0].pin.$suggestSolution = "PA27";
    GPIO1.associatedPins[1].pin.$suggestSolution = "PA24";
    GPIO1.associatedPins[2].pin.$suggestSolution = "PA23";
    GPIO1.associatedPins[3].pin.$suggestSolution = "PA6";
    GPIO1.associatedPins[4].pin.$suggestSolution = "PA2";
    GPIO2.associatedPins[0].pin.$suggestSolution = "PA17";
    I2C1.peripheral.$suggestSolution             = "I2C0";
    I2C1.peripheral.sdaPin.$suggestSolution      = "PA0";
    I2C1.peripheral.sclPin.$suggestSolution      = "PA1";
    MCAN1.peripheral.$suggestSolution            = "CANFD0";
    MCAN1.peripheral.rxPin.$suggestSolution      = "PA13";
    MCAN1.peripheral.txPin.$suggestSolution      = "PA12";
    SYSCTL.peripheral.$suggestSolution           = "SYSCTL";
    UART2.peripheral.rxPin.$suggestSolution      = "PA22";
    UART2.peripheral.txPin.$suggestSolution      = "PA21";

  • Hi Camilo, 

    I'm trying to acquire some transceivers to test on my end, have you been able to replicate this on the launchpad?

    Regards,
    Luke

  • Hi Luke,

    At this moment I only have a generic programmer and a LP-MSPM0L1306 launchpad so I have no way to validate the examples.

  • Hi Camilo,

    One of my colleagues has gotten the SYSOSC to work with MCAN in the past, but it does limit your frequency in order to be within an accurate range. Considering the GPIO itself is not changing I am more concerned with the design use case itself as you should be able to see a pull down.

    Can you configure the PA13 and PA12 pins to normal IOs and toggle them, I want to confirm that there isn't any missing connections on a hardware perspective before going further into the code configuration.

  • Hi Luke,

    Thanks for your reply

    The MCAN pin configuration appears in the configuration tree and the pins PA13 and PA12 are assigned. To validate the hardware, I put a simple blink on the pins and measured the output, they work without problem so I assume there is no hardware error, I consider that the problem is in the configuration but I cannot detect where the fault is.