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.

AM3359: McSPI slave clock configuration AM3359.

Part Number: AM3359

Hi All,

Please see we are using our custom board based on sitara AM3359 processor(reference design from EVM ICEv2),
Currently our board has two SPI interface in which McSPI0 is connected with FPGA. Here McSPI0 acts as Master and FPGA SPI acts as a slave.

Also from u-boot commands (sspi), we are able to transfer data between processor & FPGA, However as mentioned in datasheet & as per our understanding,
Functional clock is observed to be 48 MHz but while probing we observed that transection is happening at 800khz, Here we are not sure how this 800khz conversion is happening.

Furthermore, Dealing with config register ( MCSPI_CH0CONF  - 12Ch; McSPI channel 0 configuration register), bit 2-5, No change were reflected in oscilloscope while probing.
Could you please let us know, how to deal with the slave clock for McSPI ?How to change the SCLK of McSPI ?

Awaiting Reply,

Thanks & Regards,
Chinmay

  • Hello Chinmay,

    To confirm: are you in uboot when you observe the 800kHz transaction?

    Regards,

    Nick

  • Yes we are in uboot..
    We tried running u-boot command sspi after which probing the hardware pins of SPI SCLK going to FPGA in oscilloscope, we observed this value.

    Please see we are not changing any configuration value, only in pinmux file, we have updated the instances.

    let me know if you need any other information..

    Regards,
    Chinmay

  • Hi Chinmay,
    For your reference, I ran the following cmds @u-boot prompt, and captured output with my comments on SPI speed calculation:

    => md 0x4803012C 1
    4803012c: 00060000	=> CLKG=0 & CLKD=0 => FOUT=48/1=48MHz
    => sf probe 0
    SF: Detected w25q64cv with page size 256 Bytes, erase size 4 KiB, total 8 MiB
    => md 0x4803012C 1
    4803012c: 000113c7	=> CLKG=0 & CLKD=1 => FOUT=48/2=24MHz
    => sspi
    => md 0x4803012C 1
    4803012c: 000103d8 	=> CLKG=0 & CLKD=6 => FOUT=48/64=750KHz

    Note that

    1. For "sf probe 0" cmd, SPI speed is defined as 24MHz as shown below in "/cmd/sf.c":

    static int do_spi_flash_probe(int argc, char * const argv[])
    {
    ...
    	unsigned int speed = CONFIG_SF_DEFAULT_SPEED;		/* #define CONFIG_SF_DEFAULT_SPEED		24000000 */
    ...
    }

    2. For "sspi" cmd, SPI speed is configured as 1MHz as shown below in "/cmd/spi.c", but real speed is 750KHz.
    So it is possible to adjust SPI speed for "sspi" cmd as needed in this function.

    static int do_spi_xfer(int bus, int cs)
    {
    ...
    	slave = spi_setup_slave(bus, cs, 1000000, mode);
    ...
    }

    Best,

    -Hong

  • Hi Hong,

    Thanks for a quick response, after changing the slave clock to 48 Mhz in uboot command definition, we were able to see 50 MHz in Oscilloscope .
    However we want to know, Internally which registers are modified at this rate of transection.


    Regards,
    Chinmay

  • Hi Chinmay,

    Chinmay Choudhary said:
    we want to know, Internally which registers are modified at this rate of transection.

    SPI0 clock is configured in MCSPI_CH0CONF register @0x4803012C.
    A good reference on SPI clock vs CLKG/CLKD with examples is listed in Table 24-8. Clock Granularity Examples of AM335x TRM.
    MCSPI_CH0CONF is set-up in u-boot SPI driver "/drivers/spi/omap3_spi.c" based on calling routine as shown in examples in my last reply.
    I captured a complete call flow of MCSPI_CH0CONF clock set-up when running "sspi" @u-boot prompt, and uploaded it in attachment for your reference.

    Best,

    -Hong

    am3_6.3_sspi_clock.txt
    B::area_log1
    
    
    
    
    
    
    
    
    
    
    
    
    ===================================================
    12. Nov 2020
    15:53:22
    ===================================================
    B::Register
    N _  R0   BDF4E6B0  R8          1  ^S+ ^Stack_+
    Z _  R1   000103C0  R9   BDF45EB8
    C _  R2   48030100  R10  BDF4E608
    V _  R3   48030100  R11         1
    Q _  R4         14  R12  BDF4E6E8
         R5          0  R13  BDF37730
    0 _  R6   BDF4E6B0  R14  BFF903C1
    1 _  R7          0  PC   BFF902D2
    2 _  SPSR        0  CPSR     01B3
    3 _
    4 _  USR:           FIQ:
         R8          1  R8          0
         R9   BDF45EB8  R9          0
    I I  R10  BDF4E608  R10  20000000
    F _  R11         1  R11  00010000
         R12  BDF4E6E8  R12         0
    T T  R13         0  R13         0
    J _  R14         0  R14         0
    svc                 SPSR        0
    nsec
         SVC:           IRQ:
    A A  R13  BDF37730  R13  00800500
    E _  R14  BFF903C1  R14  04100003
         SPSR        0  SPSR        0
    0 _
    1 _  UND:           ABT:
    2 _  R13  EC0EA4F4  R13         0
    3 _  R14  04CA8181  R14         0
         SPSR        0  SPSR        0
    
         MON:
         R13
         R14
         SPSR
    B::Var.Frame_%DECIMAL_%OPEN.1_/Locals_/Caller
    -000|omap3_spi_write_chconf(
        |    priv = 0xBDF4E6B0 -> (
        |      slave = (bus = 0 = 0x0, cs = 0 = 0x0, mode = 0 = 0x0, wordlen = 8 = 0x8, max_read_size = 0 = 0x0, max_write_size = 0 = 0x0, memory_map = 0x0, flags = 0 = 0x0),
        |      regs = 0x48030100,
        |      cs = 0 = 0x0,
        |      freq = 1000000 = 0x000F4240,
        |      mode = 0 = 0x0,
        |      wordlen = 8 = 0x8,
        |      pin_dir = 0 = 0x0),
        |    val = 66496 = 0x000103C0)
        |  __v = 66496 = 0x000103C0
        |
    -001|omap3_spi_set_speed(inline)
    -001|spi_claim_bus(
        |    slave = 0xBDF4E6B0 -> (
        |      bus = 0 = 0x0,
        |      cs = 0 = 0x0,
        |      mode = 0 = 0x0,
        |      wordlen = 8 = 0x8,
        |      max_read_size = 0 = 0x0,
        |      max_write_size = 0 = 0x0,
        |      memory_map = 0x0,
        |      flags = 0 = 0x0))
        |  priv = 0xBDF4E6B0 -> (
        |    slave = (bus = 0 = 0x0, cs = 0 = 0x0, mode = 0 = 0x0, wordlen = 8 = 0x8, max_read_size = 0 = 0x0, max_write_size = 0 = 0x0, memory_map = 0x0, flags = 0 = 0x0),
        |    regs = 0x48030100,
        |    cs = 0 = 0x0,
        |    freq = 1000000 = 0x000F4240,
        |    mode = 0 = 0x0,
        |    wordlen = 8 = 0x8,
        |    pin_dir = 0 = 0x0)
        |  __v = 2 = 0x2
        |  __v = 21 = 0x15
        |  __v = 1 = 0x1
        |  priv = 0xBDF4E6B0 -> (
        |    slave = (bus = 0 = 0x0, cs = 0 = 0x0, mode = 0 = 0x0, wordlen = 8 = 0x8, max_read_size = 0 = 0x0, max_write_size = 0 = 0x0, memory_map = 0x0, flags = 0 = 0x0),
        |    regs = 0x48030100,
        |    cs = 0 = 0x0,
        |    freq = 1000000 = 0x000F4240,
        |    mode = 0 = 0x0,
        |    wordlen = 8 = 0x8,
        |    pin_dir = 0 = 0x0)
        |  priv = 0xBDF4E6B0 -> (
        |    slave = (bus = 0 = 0x0, cs = 0 = 0x0, mode = 0 = 0x0, wordlen = 8 = 0x8, max_read_size = 0 = 0x0, max_write_size = 0 = 0x0, memory_map = 0x0, flags = 0 = 0x0),
        |    regs = 0x48030100,
        |    cs = 0 = 0x0,
        |    freq = 1000000 = 0x000F4240,
        |    mode = 0 = 0x0,
        |    wordlen = 8 = 0x8,
        |    pin_dir = 0 = 0x0)
        |
        |        /* Transmit & receive mode */
        |        confr &= ~OMAP3_MCSPI_CHCONF_TRM_MASK;
        |
        |        omap3_spi_write_chconf(priv, confr);
    -002|do_spi_xfer(inline)
    -002|do_spi(
        |  ?,
        |  ?,
        |  apargc = 1 = 0x1,
        |  ?)
        |  cp = 0x0 -> NULL
        |  cs = 0 = 0x0
        |  bus = 0 = 0x0
        |  slave = 0xBDF4E6B0 -> (
        |    bus = 0 = 0x0,
        |    cs = 0 = 0x0,
        |    mode = 0 = 0x0,
        |    wordlen = 8 = 0x8,
        |    max_read_size = 0 = 0x0,
        |    max_write_size = 0 = 0x0,
        |    memory_map = 0x0,
        |    flags = 0 = 0x0)
        |  ret = -1108023632 = 0xBDF4E6B0
        |
        |        }
        |#endif
        |
        |        ret = spi_claim_bus(slave);
    -003|cmd_call(inline)
    -003|cmd_process(
        |  ?,
        |    argc = 1 = 0x1,
        |    argv = 0xBDF4E608 -> 0xBDF4E5F8 -> 115 = 0x73,
        |    repeatable = 0xBFFD330C -> 1 = 0x1,
        |    ticks = 0x0 -> NULL)
        |  cmdtp = 0xBFFD1BB0 -> (
        |    name = 0xBFFC5467,
        |    maxargs = 5 = 0x5,
        |    repeatable = 1 = 0x1,
        |    cmd = 0xBFF70B81,
        |    usage = 0xBFFC546C,
        |    help = 0xBFFC5480,
        |    complete = 0x0)
        |  argv = 0xBDF4E608 -> 0xBDF4E5F8 -> 115 = 0x73
        |  argc = 1 = 0x1
        |  flag = 0 = 0x0
        |  cmdtp = 0xBFFD1BB0 -> (
        |    name = 0xBFFC5467,
        |    maxargs = 5 = 0x5,
        |    repeatable = 1 = 0x1,
        |    cmd = 0xBFF70B81,
        |    usage = 0xBFFC546C,
        |    help = 0xBFFC5480,
        |    complete = 0x0)
        |
        |...
        | * executing a command.
        | *
        | * @param cmdtp         Pointer to the command to execute
        | * @param flag          Some flags normally 0 (see CMD_FLAG_.. above)
        | * @param argc          Number of arguments (arg 0 must be the command text)
        | * @param argv          Arguments
        | * @return 0 if command succeeded, else non-zero (CMD_RET_...)
        | */
        |static int cmd_call(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
        |{
        |        int result;
        |
        |        result = (cmdtp->cmd)(cmdtp, flag, argc, argv);
        |                rc = cmd_call(cmdtp, flag, argc, argv);
    -004|run_pipe_real(inline)
    -004|run_list_real(inline)
    -004|run_list_real(
        |  ?)
        |  save_name = 0x0 -> NULL
        |cmlist = 0x0 -> NULL
        |cmsave_list = 0x0 -> NULL
        |  flag_rep = 0 = 0x0
        |  rcode = 0 = 0x0
        |  flag_skip = 1 = 0x1
        |  flag_restore = 0 = 0x0
        |  if_code = 0 = 0x0
        |  next_if_code = 0 = 0x0
        |  skip_more_in_this_rmode = RES_XXXX = 11 = 0x0B
        |  pi = 0xBDF4E570 -> (
        |    num_progs = 1 = 0x1,
        |    progs = 0xBDF4E628,
        |    next = 0xBDF4E660,
        |    followup = PIPE_SEQ = 1 = 0x1,
        |    r_mode = RES_NONE = 0 = 0x0)
        |  save_name = 0x0 -> NULL
        |  save_list = 0x0 -> NULL
        |  rpipe = 0x0 -> NULL
        |
        |
        |
        |
        |
        |  flag_rep = 0 = 0x0
        |  flag_restore = 0 = 0x0
        |  if_code = 0 = 0x0
        |  next_if_code = 0 = 0x0
        |..rmode = RES_NONE = 0 = 0x0
        | *pi = 0xBDF4E570 -> (
        |    num_progs = 1 = 0x1,
        |    progs = 0xBDF4E628,
        |    next = 0xBDF4E660,
        |    followup = PIPE_SEQ = 1 = 0x1,
        |    r_mode = RES_NONE = 0 = 0x0)
        | *child = 0xBDF4E628 -> (
        |    argv = 0xBDF4E608,
        |    argv_nonnull = 0xBDF4E618,
        |    argc = 1 = 0x1,
        |    group = 0x0,
        |    sp = 0 = 0x0,
        |    type = 2 = 0x2)
        |
        |                }
        |                /* Process the command */
        |                return cmd_process(flag, child->argc, child->argv,
    -005|run_list(inline)
    -005|parse_stream_outer(
        |  liinp = 0xBDF3784C -> (
        |      p = 0xBFFD341D,
        |      __promptme = 1 = 0x1,
        |      promptmode = 2 = 0x2,
        |      get = 0xBFF73DA5,
        |      peek = 0xBFF73FF5),
        |  ifflag = 2 = 0x2)
        |  ctx = (
        |    child = 0xBDF4E690,
        |    list_head = 0xBDF4E570,
        |    pipe = 0xBDF4E678,
        |    w = RES_NONE = 0 = 0x0,
        |    old_flag = 0 = 0x0,
        |    stack = 0x0,
        |    type = 2 = 0x2)
        |  temp = (
        |    data = 0xBDF4E588,
        |    length = 0 = 0x0,
        |    maxlen = 100 = 0x64,
        |    quote = 0 = 0x0,
        |    nonnull = 0 = 0x0)
        |  rcode = 0 = 0x0
        |  pi = 0xBDF4E570 -> (
        |    num_progs = 1 = 0x1,
        |    progs = 0xBDF4E628,
        |    next = 0xBDF4E660,
        |    followup = PIPE_SEQ = 1 = 0x1,
        |    r_mode = RES_NONE = 0 = 0x0)
        |
        |}
        |
        |/* Select which version we will use */
        |static int run_list(struct pipe *pi)
        |{
        |        int rcode=0;
        |#ifndef __U_BOOT__
        |        if (fake_mode==0) {
        |#endif
        |                rcode = run_list_real(pi);
    -006|parse_file_outer()
        |  rcode = -1108023632 = 0xBDF4E6B0
        |  input = (
        |    p = 0xBFFD341D,
        |    __promptme = 1 = 0x1,
        |    promptmode = 2 = 0x2,
        |    get = 0xBFF73DA5,
        |    peek = 0xBFF73FF5)
        |
        |#endif
        |        rcode = parse_stream_outer(&input, FLAG_PARSE_SEMICOLON);
    -007|cli_loop()
        |
        |}
        |#endif /* CONFIG_IS_ENABLED(OF_CONTROL) */
        |
        |void cli_loop(void)
        |{
        |#ifdef CONFIG_HUSH_PARSER
        |        parse_file_outer();
    -008|bootstage_mark_name(inline)
    -008|main_loop()
        |  s = 0xBDF4A560 -> 105 = 0x69
        |
        |        cli_loop();
    -009|run_main_loop()
        |  return = -1108023632 = 0xBDF4E6B0
        |
        |        for (;;)
        |                main_loop();
        |        return 0;
        |}
        |
        |/*
    -010|initcall_run_list(
        |    init_sequence = 0xBFFCB78C -> 0xBFF752F9 -> )
        |  init_fnc_ptr = 0xBFFCB824 -> 0xBFF75311 ->
        |} ret = -1108023632 = 0xBDF4E6B0
        |
        |                if (ret) {
    -011|board_init_r(
        |  ?,
        |  ?)
        |
        |#endif
        |
        |        if (initcall_run_list(init_sequence_r))
        |                hang();
        |
        |        /* NOTREACHED - run_main_loop() does not return */
        |        hang();
    -012|board_init_r(
        |    new_gd = 0xBDF4E6B0 -> (
        |      bd = 0x0,
        |      flags = 0 = 0x0,
        |      baudrate = 0 = 0x0,
        |      cpu_clk = 8 = 0x8,
        |      bus_clk = 0 = 0x0,
        |      pci_clk = 0 = 0x0,
        |      mem_clk = 0 = 0x0,
        |      have_console = 0 = 0x0,
        |      env_addr = 1208156416 = 0x48030100,
        |      env_valid = 0 = 0x0,
        |      env_has_init = 1000000 = 0x000F4240,
        |      env_load_prio = 0 = 0x0,
        |      ram_base = 8 = 0x8,
        |      ram_top = 0 = 0x0,
        |      relocaddr = 0 = 0x0,
        |      ram_size = 37337 = 0x91D9,
        |      mon_len = 3221010516 = 0xBFFCB854,
    

  • Hong,

    Thanks for your efforts & help, we are pleased, It helped us a lot..!! 

    -Chinmay..