hm2 BSPI documentation, examples?

More
19 May 2023 22:33 - 19 May 2023 22:38 #271698 by blazini36
I'm working on a PCB that is a BoB for a 7i92. It has a couple of ADCs that are to be read by the BSPI module. The only example of a bspi subdriver I can find is the 7i65 component. I can't find any hal examples. A friend is gonna help me with the hal component for this, he's written me some hal components in the past but he's not a "linuxcnc guy".

I found the bspi driver docs here
linuxcnc.org/docs/stable/html/man/man3/

Is there any more info? I'm not a code person so I can't say whether this is enough info to pass on to get this going but I'd like to get as much as I can
Last edit: 19 May 2023 22:38 by blazini36.

Please Log in or Create an account to join the conversation.

More
20 May 2023 00:44 #271702 by PCW
I would say:

bspi driver (src/hal/drivers/mesa-hostmot2/bspi.c
7I65 comp (src/hal//drivers/mesa_7i65.comp)

and hostmot2 register map:
freeby.mesanet.com/regmap

Are the main sources

Please Log in or Create an account to join the conversation.

More
20 May 2023 03:32 #271704 by blazini36
The register map would probably be helpful to the guy writing the component. I'm looking for a hal file example  for my own understanding. Since the only subdriver that seems to exist is the 7i65 comp I assume nobody's really used it like this or at least shared what they did but someone must be using a 7i65 right? I'm just looking to see how they instantiated the channels and addf'd the component.

Please Log in or Create an account to join the conversation.

More
20 May 2023 03:51 #271705 by PCW
Yes the 7I76 comp is used to run the 7I65
The register map is just there if there are questions
about the LinuxCNC driver (bspi.c). You don need to do
any low level register access, all access is via functions
in bspi.c

Please Log in or Create an account to join the conversation.

More
31 May 2023 15:40 #272579 by blazini36
I was looking for a specific HAL file example of how the (d)bspi channels are handled in a hal file. I've seen the documentation that is linked above, but I can't find anything regarding the actual hal usage of a 7i65 or anything else. I held off on posting a response so I could ping pong this off my friend that is helping but it looks like I might have to put some hardware in his hands.

for reference, this is the test component my friend whipped up (based on the 7i65 comp):
component bspi_test "test bspi";

description "Does stuff";

pin out float happy_output_pin;
pin in float happy_input_pin;

option extra_setup yes;
//option count_function yes;

variable unsigned *read_frame;
variable unsigned *write_frame;

license "Proprietary";

include <hostmot2-serial.h>;
;;

static int read(void *subdata) {
    struct __comp_state *__comp_inst = subdata;

    rtapi_print("rx: %08x\n", *read_frame);

    *write_frame = 0xa5a5a5a;

    return 0;
}

static int write(void *subdata) {
    struct __comp_state *__comp_inst = subdata;
    *write_frame = 0xdeadbeef;
    return 0;
}

EXTRA_SETUP(){
    int i, r;
    char *name = "hm2_7i92.0.bspi.0";

    //hm2_bspi_setup_chan(name, chan, cs, bits, mhz, delay(ns), cpol, cpha, /clear, /echo, samplelate)
    // CS0 loopback Echo, CS0, ~ 4 MHz, CPOL, 32 bits
    r = hm2_bspi_setup_chan(name, 0, 0, 32, 4, 0, 1, 0, 0, 0, 0);
    if (r < 0) {
        rtapi_print_msg(RTAPI_MSG_ERR,
                      "There have been %i errors during channel setup, "
                      "quitting\n", -r);
        return -EINVAL;
    }

    // Clear BSPI Rx & Tx FIFOs.
    // This discards the received data from the ADC setup writes above,
    // and any other old stale data.
    r = hm2_bspi_clear_fifo(name);
    if (r < 0) {
        rtapi_print_msg(RTAPI_MSG_ERR, "failed to clear BSPI fifos on %s\n", name);
    }

    // Add BSPI Frames
    r = hm2_tram_add_bspi_frame(name, 1, &write_frame, &read_frame);

    // This is required, or nothing happens.
    r += hm2_allocate_bspi_tram(name);

    // Tell the bspi driver which function to call
    r += hm2_bspi_set_read_function(name, &read, __comp_inst);

    // no separate write function in this example, but it would be:
    r += hm2_bspi_set_write_function(name, &write, __comp_inst);

    if (r < 0) {
        rtapi_print_msg(RTAPI_MSG_ERR,
                      "There have been %i errors during TRAM allocation setup, "
                      "quitting\n", -r);
        return -EINVAL;
    }
    return 0;
}

These are my hal file's instantiation lines:
loadrt [KINS]KINEMATICS
loadrt [EMCMOT]EMCMOT servo_period_nsec=[EMCMOT]SERVO_PERIOD num_joints=[KINS]JOINTS
loadrt hostmot2
loadrt hm2_eth board_ip="10.10.10.10" config="num_encoders=0 num_pwmgens=2 num_stepgens=6 num_bspis=1"
setp    hm2_7i92.0.pwmgen.pwm_frequency 1000
setp    hm2_7i92.0.pwmgen.pdm_frequency 6000000
setp    hm2_7i92.0.watchdog.timeout_ns 5000000
loadrt pid names=pid.x,pid.y,pid.z,pid.a,pid.b
loadrt bspi_test

addf hm2_7i92.0.read          servo-thread
addf motion-command-handler   servo-thread
addf motion-controller        servo-thread
addf pid.x.do-pid-calcs       servo-thread
addf pid.y.do-pid-calcs       servo-thread
addf pid.z.do-pid-calcs       servo-thread
addf pid.a.do-pid-calcs       servo-thread
addf pid.b.do-pid-calcs       servo-thread
addf hm2_7i92.0.write         servo-thread
setp hm2_7i92.0.dpll.01.timer-us -50
setp hm2_7i92.0.stepgen.timer-number 1

Not doing anything else in hal, cuz I'm not sure what else needs to be done. This is what I get:
[color=#000000]$ linuxcnc ~/linuxcnc/configs/PnP/PnP.ini [/color]
LINUXCNC - 2.9.0~pre1+git20230208.f1270d6ed7
Machine configuration directory is '/home/justin/linuxcnc/configs/PnP'
Machine configuration file is 'PnP.ini'
Starting LinuxCNC...
linuxcnc TPMOD=tpmod HOMEMOD=homemod EMCMOT=motmod
Note: Using POSIX realtime
Found file(REL): ./PnP.hal
hm2: loading Mesa HostMot2 driver version 0.15
hm2_eth: loading Mesa AnyIO HostMot2 ethernet driver version 0.2
hm2_eth: 10.10.10.10: INFO: Hardware address (MAC): 00:60:1b:12:80:41
hm2_eth: discovered 7I92T
hm2/hm2_7i92.0: Low Level init 0.15
hm2/hm2_7i92.0: created Buffered SPI function hm2_7i92.0.bspi.0.
hm2/hm2_7i92.0: Smart Serial Firmware Version 43
hm2/hm2_7i92.0: 34 I/O Pins used:
hm2/hm2_7i92.0:     IO Pin 000 (P2-01): IOPort
hm2/hm2_7i92.0:     IO Pin 001 (P2-14): IOPort
hm2/hm2_7i92.0:     IO Pin 002 (P2-02): IOPort
hm2/hm2_7i92.0:     IO Pin 003 (P2-15): IOPort
hm2/hm2_7i92.0:     IO Pin 004 (P2-03): IOPort
hm2/hm2_7i92.0:     IO Pin 005 (P2-16): IOPort
hm2/hm2_7i92.0:     IO Pin 006 (P2-04): IOPort
hm2/hm2_7i92.0:     IO Pin 007 (P2-17): IOPort
hm2/hm2_7i92.0:     IO Pin 008 (P2-05): IOPort
hm2/hm2_7i92.0:     IO Pin 009 (P2-06): IOPort
hm2/hm2_7i92.0:     IO Pin 010 (P2-07): IOPort
hm2/hm2_7i92.0:     IO Pin 011 (P2-08): IOPort
hm2/hm2_7i92.0:     IO Pin 012 (P2-09): IOPort
hm2/hm2_7i92.0:     IO Pin 013 (P2-10): Buffered SPI Interface #0, pin /Frame (Output)
hm2/hm2_7i92.0:     IO Pin 014 (P2-11): Buffered SPI Interface #0, pin CS0 (Output)
hm2/hm2_7i92.0:     IO Pin 015 (P2-12): Buffered SPI Interface #0, pin Serial In (Input)
hm2/hm2_7i92.0:     IO Pin 016 (P2-13): Buffered SPI Interface #0, pin Clock (Output)
hm2/hm2_7i92.0:     IO Pin 017 (P1-01): StepGen #0, pin Step (Output)
hm2/hm2_7i92.0:     IO Pin 018 (P1-14): StepGen #0, pin Direction (Output)
hm2/hm2_7i92.0:     IO Pin 019 (P1-02): StepGen #1, pin Step (Output)
hm2/hm2_7i92.0:     IO Pin 020 (P1-15): StepGen #1, pin Direction (Output)
hm2/hm2_7i92.0:     IO Pin 021 (P1-03): StepGen #2, pin Step (Output)
hm2/hm2_7i92.0:     IO Pin 022 (P1-16): StepGen #2, pin Direction (Output)
hm2/hm2_7i92.0:     IO Pin 023 (P1-04): StepGen #3, pin Step (Output)
hm2/hm2_7i92.0:     IO Pin 024 (P1-17): StepGen #3, pin Direction (Output)
hm2/hm2_7i92.0:     IO Pin 025 (P1-05): StepGen #4, pin Step (Output)
hm2/hm2_7i92.0:     IO Pin 026 (P1-06): StepGen #4, pin Direction (Output)
hm2/hm2_7i92.0:     IO Pin 027 (P1-07): StepGen #5, pin Step (Output)
hm2/hm2_7i92.0:     IO Pin 028 (P1-08): StepGen #5, pin Direction (Output)
hm2/hm2_7i92.0:     IO Pin 029 (P1-09): IOPort
hm2/hm2_7i92.0:     IO Pin 030 (P1-10): IOPort
hm2/hm2_7i92.0:     IO Pin 031 (P1-11): IOPort
hm2/hm2_7i92.0:     IO Pin 032 (P1-12): PWMGen #0, pin Out0 (PWM or Up) (Output)
hm2/hm2_7i92.0:     IO Pin 033 (P1-13): PWMGen #1, pin Out0 (PWM or Up) (Output)
hm2/hm2_7i92.0: registered
hm2/hm2_7i92.0: The selected write channel (1) on bspi instance hm2_7i92.0.bspi.0.
Has not been configured.
There have been 1 errors during TRAM allocation setup, quitting
bspi_test: rtapi_app_main: Invalid argument (-22)
./PnP.hal:11: waitpid failed /usr/bin/rtapi_app bspi_test
./PnP.hal:11: /usr/bin/rtapi_app exited without becoming ready
./PnP.hal:11: insmod for bspi_test failed, returned -1
Shutting down and cleaning up LinuxCNC...
Running HAL shutdown script
hm2_eth: in hm2_eth_reset
hm2_eth: HostMot2 ethernet driver unloaded
hm2: unloading
Note: Using POSIX realtime
LinuxCNC terminated with an error.  You can find more information in the log:
   /home/justin/linuxcnc_debug.txt
and
   /home/justin/linuxcnc_print.txt
as well as in the output of the shell command 'dmesg' and in the terminal

So my friend might be able to dig through the driver code or whatever to figure out what if anything else needs to be done in hal just to get through instantiating the component pins but I figure at least upto this point there has to be some usage example or somebody can tell me if I need to addf some bspi read/write channel or something.

I'd be more than glad to submit the working component/configuration to LinuxCNC when we get it going but the nature of my break out board and spi in general are going to make this too specific to be of any use to anyone else unless someone wants to strip it down. LinuxCNC should have some kind of example configuration for bspi/dbspi.

Please Log in or Create an account to join the conversation.

More
31 May 2023 16:19 #272586 by andypugh
At a guess the initial problem is

r = ...setup_bspi....(name, 0 ...)
r = ...add_bspi_frame(name, 1...)

Your comp sets up channel 0 then tries to use channel 1.

Please Log in or Create an account to join the conversation.

More
31 May 2023 16:42 #272589 by blazini36

At a guess the initial problem is

r = ...setup_bspi....(name, 0 ...)
r = ...add_bspi_frame(name, 1...)

Your comp sets up channel 0 then tries to use channel 1.
 

Good catch. My friend isn't able to load it right now since he has no mesa card, just a LinuxCNC install and some emails.

It does load now and the dummy pins are created. The terminal is getting blasted with "rx: 00000000". not sure where that is coming from.

As for HAL, there's nothing else that needs to be done? no addf's or anything?

Please Log in or Create an account to join the conversation.

More
31 May 2023 18:38 #272595 by andypugh
It looks like BSPI is configured with a read function (and write function) and automatically calls it every thread cycle.
(Which is something that I had forgotten)

Please Log in or Create an account to join the conversation.

More
02 Aug 2023 00:34 #276749 by blazini36
Just got back around to messing with this, there hasn't been much work on the component but I think we're expecting that it do...something, a clock or cycling CS lines. The firmware on the 7i92 is the newer setup from PCW where bspi/dbspi are automatically configured, not sure that that makes a difference.

Checking the card, I have no SCK, and both CS lines stay high, any ideas? In hal all I have is "num_bspis=1" and "loadrt pnp servo-thread" (this component)
component pnp "pnp";

description "Does stuff";

pin out float happy_output_pin;
pin in float happy_input_pin;

option extra_setup yes;
//option count_function yes;

variable unsigned *_step_drive_rx;
variable unsigned *_step_drive_tx;
variable unsigned *_analog_rx;
variable unsigned *_analog_tx;

license "GPLv2";

include <hostmot2-serial.h>;
;;

static int
read(void* subdata) {
    struct __comp_state* __comp_inst = subdata;

    if (*_step_drive_rx != 0) rtapi_print("step_drive: %08x\n", *_step_drive_rx);
    if (*_analog_rx != 0) rtapi_print("analog: %08x\r\n", *_analog_rx);

    *_step_drive_tx = 0x0123456;

    return 0;
}

static int
write(void* subdata) {
    struct __comp_state* __comp_inst = subdata;
    *_step_drive_tx = 0xdeadbeef;
    return 0;
}

EXTRA_SETUP() {
    int i, r;
    char* name = "hm2_7i92.0.bspi.0"; // Exact channel name needed to work here, but it should be done with [extra_arg] like the 7i65 comp//

    //hm2_bspi_setup_chan(name, chan, cs, bits, mhz, delay(ns), cpol, cpha, /clear, /echo, samplelate)
    // CS0 loopback Echo, CS0, ~ 4 MHz, CPOL, 32 bits
    r = hm2_bspi_setup_chan(name, 0, 0, 32, 4, 0, 1, 0, 0, 0, 0);
    r = hm2_bspi_setup_chan(name, 1, 1, 32, 4, 0, 1, 0, 0, 0, 0);
    if (r < 0) {
        rtapi_print_msg(
            RTAPI_MSG_ERR,
            "There have been %i errors during channel setup, "
            "quitting\n",
            -r);
        return -EINVAL;
    }

    // Clear BSPI Rx & Tx FIFOs.
    // This discards the received data from the ADC setup writes above,
    // and any other old stale data.
    r = hm2_bspi_clear_fifo(name);
    if (r < 0) { rtapi_print_msg(RTAPI_MSG_ERR, "failed to clear BSPI fifos on %s\n", name); }

    // Add BSPI Frames
    r = hm2_tram_add_bspi_frame(name, 0, &_step_drive_tx, &_step_drive_rx);
    r = hm2_tram_add_bspi_frame(name, 1, &_analog_tx, &_analog_rx);

    // This is required, or nothing happens.
    r += hm2_allocate_bspi_tram(name);

    // Tell the bspi driver which function to call
    r += hm2_bspi_set_read_function(name, &read, __comp_inst);

    // no separate write function in this example, but it would be:
    r += hm2_bspi_set_write_function(name, &write, __comp_inst);

    if (r < 0) {
        rtapi_print_msg(
            RTAPI_MSG_ERR,
            "There have been %i errors during TRAM allocation setup, "
            "quitting\n",
            -r);
        return -EINVAL;
    }
    return 0;
}

 

Please Log in or Create an account to join the conversation.

Time to create page: 0.164 seconds
Powered by Kunena Forum