Skip to content

Commit 0af2f08

Browse files
committed
Add Oneshot module
1 parent af0e218 commit 0af2f08

6 files changed

Lines changed: 768 additions & 2 deletions

File tree

docs/man/man9/hostmot2.9

Lines changed: 89 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ The valid entries in the format string are:
114114
[num_resolvers=\fIN\fB]
115115
[num_pwmgens=\fIN\fB]
116116
[num_3pwmgens=\fIN\fB]
117+
[num_oneshots=\fIN\fB]
117118
[num_rcpwmgens=\fIN\fB]
118119
[num_stepgens=\fIN\fB]
119120
[stepgen_width=\fIN\fB]
@@ -967,6 +968,94 @@ that affects all instances:
967968
Sets the master PWM frequency. Maximum is approx 48 kHz, minimum
968969
is 1 kHz. Defaults to 20 kHz.
969970

971+
.SS oneshot
972+
The oneshot is a hardware one-shot device suitable for various timing, delay,
973+
signal conditioning and watchdog functions. The oneshot module includes 2 timers
974+
to allow variable pulse delays for applications like phase control.
975+
Trigger sources can be software, external inputs, the DPLL timer, a built in
976+
rate generator or the other timer.
977+
Oneshots have names like "hm2_\fI<BoardType>\fR.\fI<BoardNum>\fR.oneshot.\fI<Instance>\fR"
978+
where <Instance> is a 2-digit number. There will be num_oneshots instances,
979+
starting at 00. Each instance allocates up to two input and two output pins.
980+
981+
Pins:
982+
983+
.TP
984+
(float rw) width1
985+
Sets the pulse width of timer1 in ms. Default is 1 ms (1/1000 s).
986+
987+
.TP
988+
(float rw) width2
989+
Sets the pulse width of timer2 in ms. Default is 1 ms (1/1000 s).
990+
991+
.TP
992+
(float rw) filter1
993+
Sets digital filter time constant for timer1's external trigger input
994+
Filter time is in ms. Default filter time constant time is 0.1 ms.
995+
External trigger response will be delayed by the filter time setting
996+
997+
.TP
998+
(float rw) filter2
999+
Sets digital filter time constant for timer1's external trigger input
1000+
Filter time is in ms. Default filter time constant time is 0.1 ms.
1001+
External trigger response will be delayed by the filter time setting
1002+
1003+
.TP
1004+
(float rw) rate
1005+
Sets the frequency of the built in rate generator (in Hz)
1006+
1007+
.TP
1008+
(u32 rw) trigger_select1,trigger_select2
1009+
Sets the trigger source for timer1,timer2 respectively.
1010+
Trigger sources are:
1011+
.nf
1012+
0 Trigger disabled
1013+
1 Software trigger: triggered when hal pin swtrigger1 is true
1014+
2 External hardware: trigger
1015+
3 DPLL trigger: triggered by selected DPLL timer
1016+
4 Rate trigger: triggered by build in rate generator.
1017+
5 Timer1 trigger: triggered by timer1 output
1018+
6 Timer2 trigger: triggered by timer2 output
1019+
1020+
.TP
1021+
(bit rw) trigger_on_rise1,trigger_on_rise2
1022+
When true,trigger timer1,timer2 respectively on the
1023+
rising edge of the trigger source.
1024+
1025+
.TP
1026+
(bit rw) trigger_on_fall1,trigger_on_fall2
1027+
When true, trigger timer1,timer2 respectively on the
1028+
falling edge of the trigger source.
1029+
1030+
.TP
1031+
(bit rw) retriggerable1,retriggerable2
1032+
When true, the associated timer is retriggerable, meaning
1033+
the timer will reset to full time on a trigger event
1034+
even durin the output pulse period.
1035+
When false the timer is not retriggerable, meaning
1036+
it will ignore trigger events during the output
1037+
pulse period.
1038+
1039+
.TP
1040+
(bit rw) enable1,enable2
1041+
trigger enable for timer1 and timer2 respectively
1042+
True to enable.
1043+
1044+
.TP
1045+
(bit rw) reset1,reset2
1046+
If true, resets timer1,timer2 respectively,
1047+
aborting any pulse in progress.
1048+
1049+
.TP
1050+
(bit ro) out1,out2
1051+
Pulse output status bit for timer 1,timer2
1052+
1053+
.TP
1054+
(bit ro) exttrigger1,exttrigger2
1055+
External trigger input status bits for timer 1,timer2.
1056+
These monitor the filtered inputs.
1057+
1058+
9701059
.SS rcpwmgen
9711060
The rcpwmgen is a simple PWM generator optimized for use with standard RC servos
9721061
that use pulse width to determine position.
@@ -999,7 +1088,6 @@ Sets the per channel pulse width scaling, for example, setting the scale to 90
9991088
and the offset to 1.5 mS would result in a position range of +-45 degrees
10001089
scale in degrees for 1-2 mS servos with a full motion range of 90 degrees
10011090

1002-
10031091
.SS stepgen
10041092

10051093
stepgens have names like

src/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1009,6 +1009,7 @@ hostmot2-objs := \
10091009
hal/drivers/mesa-hostmot2/pins.o \
10101010
hal/drivers/mesa-hostmot2/pktuart.o \
10111011
hal/drivers/mesa-hostmot2/pwmgen.o \
1012+
hal/drivers/mesa-hostmot2/oneshot.o \
10121013
hal/drivers/mesa-hostmot2/raw.o \
10131014
hal/drivers/mesa-hostmot2/rcpwmgen.o \
10141015
hal/drivers/mesa-hostmot2/resolver.o \

src/hal/drivers/mesa-hostmot2/hostmot2.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ static void hm2_read(void *void_hm2, long period) {
114114
hm2_sserial_process_tram_read(hm2, period);
115115
hm2_bspi_process_tram_read(hm2, period);
116116
hm2_absenc_process_tram_read(hm2, period);
117+
hm2_oneshot_process_tram_read(hm2);
117118
//UARTS PktUARTS need to be explicitly handled by an external component
118119

119120
hm2_tp_pwmgen_process_read(hm2); // check the status of the fault bit
@@ -135,6 +136,7 @@ static void hm2_write(void *void_hm2, long period) {
135136
hm2_watchdog_prepare_tram_write(hm2);
136137
hm2_ioport_gpio_prepare_tram_write(hm2);
137138
hm2_pwmgen_prepare_tram_write(hm2);
139+
hm2_oneshot_prepare_tram_write(hm2);
138140
hm2_rcpwmgen_prepare_tram_write(hm2);
139141
hm2_inmux_prepare_tram_write(hm2);
140142
hm2_inm_prepare_tram_write(hm2);
@@ -152,6 +154,7 @@ static void hm2_write(void *void_hm2, long period) {
152154
hm2_ioport_write(hm2); // handles gpio.is_output but not gpio.out (that's done in tram_write() above)
153155
hm2_watchdog_write(hm2, period); // in case the user has written to the watchdog.timeout_ns param
154156
hm2_pwmgen_write(hm2); // update pwmgen registers if needed
157+
hm2_oneshot_write(hm2); // update oneshot registers if needed
155158
hm2_rcpwmgen_write(hm2); // update rcpwmgen registers if needed
156159
hm2_inmux_write(hm2); // update inmux control register if needed
157160
hm2_inm_write(hm2); // update inm control register if needed
@@ -317,6 +320,8 @@ const char *hm2_get_general_function_name(int gtag) {
317320
case HM2_GTAG_XY2MOD: return "xy2mod Galvo interface";
318321
case HM2_GTAG_DPAINTER: return "Data Painter";
319322
case HM2_GTAG_SSR: return "SSR";
323+
case HM2_GTAG_ONESHOT: return "OneShot";
324+
320325
default: {
321326
static char unknown[100];
322327
rtapi_snprintf(unknown, 100, "(unknown-gtag-%d)", gtag);
@@ -394,6 +399,7 @@ static int hm2_parse_config_string(hostmot2_t *hm2, char *config_string) {
394399
hm2->config.num_leds = -1;
395400
hm2->config.num_ssrs = -1;
396401
hm2->config.num_outms = -1;
402+
hm2->config.num_oneshots = -1;
397403
hm2->config.enable_raw = 0;
398404
hm2->config.firmware = NULL;
399405

@@ -452,6 +458,10 @@ static int hm2_parse_config_string(hostmot2_t *hm2, char *config_string) {
452458
token += 10;
453459
hm2->config.num_outms = simple_strtol(token, NULL, 0);
454460

461+
} else if (strncmp(token, "num_oneshots=", 13) == 0) {
462+
token += 10;
463+
hm2->config.num_oneshots = simple_strtol(token, NULL, 0);
464+
455465
} else if (strncmp(token, "num_ssrs=", 9) == 0) {
456466
token += 9;
457467
hm2->config.num_ssrs = simple_strtol(token, NULL, 0);
@@ -547,6 +557,7 @@ static int hm2_parse_config_string(hostmot2_t *hm2, char *config_string) {
547557
HM2_DBG(" num_inmuxs=%d\n", hm2->config.num_inmuxs);
548558
HM2_DBG(" num_inms=%d\n", hm2->config.num_inms);
549559
HM2_DBG(" num_outms=%d\n", hm2->config.num_outms);
560+
HM2_DBG(" num_oneshots=%d\n", hm2->config.num_oneshots);
550561
HM2_DBG(" num_ssrs=%d\n", hm2->config.num_ssrs);
551562
HM2_DBG(" num_xy2mods=%d\n", hm2->config.num_xy2mods);
552563
HM2_DBG(" num_3pwmgens=%d\n", hm2->config.num_tp_pwmgens);
@@ -1046,6 +1057,10 @@ static int hm2_parse_module_descriptors(hostmot2_t *hm2) {
10461057
case HM2_GTAG_OUTM:
10471058
md_accepted = hm2_outm_parse_md(hm2, md_index);
10481059
break;
1060+
1061+
case HM2_GTAG_ONESHOT:
1062+
md_accepted = hm2_oneshot_parse_md(hm2, md_index);
1063+
break;
10491064

10501065
case HM2_GTAG_RCPWMGEN:
10511066
md_accepted = hm2_rcpwmgen_parse_md(hm2, md_index);
@@ -1124,6 +1139,7 @@ static void hm2_cleanup(hostmot2_t *hm2) {
11241139
hm2_bspi_cleanup(hm2);
11251140
hm2_ssr_cleanup(hm2);
11261141
hm2_outm_cleanup(hm2);
1142+
hm2_oneshot_cleanup(hm2);
11271143
hm2_rcpwmgen_cleanup(hm2);
11281144

11291145
// free all the tram entries
@@ -1145,6 +1161,7 @@ void hm2_print_modules(hostmot2_t *hm2) {
11451161
hm2_ioport_print_module(hm2);
11461162
hm2_ssr_print_module(hm2);
11471163
hm2_outm_print_module(hm2);
1164+
hm2_oneshot_print_module(hm2);
11481165
hm2_watchdog_print_module(hm2);
11491166
hm2_inmux_print_module(hm2);
11501167
hm2_inm_print_module(hm2);
@@ -1806,6 +1823,7 @@ void hm2_force_write(hostmot2_t *hm2) {
18061823
hm2_inmux_force_write(hm2);
18071824
hm2_inm_force_write(hm2);
18081825
hm2_xy2mod_force_write(hm2);
1826+
hm2_oneshot_force_write(hm2);
18091827

18101828
// NOTE: It's important that the SSR is written *after* the
18111829
// ioport is written. Initialization of the SSR requires that

src/hal/drivers/mesa-hostmot2/hostmot2.h

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@
132132
#define HM2_GTAG_TWIDDLER (194) // Not supported
133133
#define HM2_GTAG_SSR (195)
134134
#define HM2_GTAG_SMARTSERIALB (198) // smart-serial with 224 data bits
135+
#define HM2_GTAG_ONESHOT (199) // One shot
135136

136137

137138
//
@@ -575,6 +576,79 @@ typedef struct {
575576
rtapi_u32 enable_reg; // one register for the whole Function
576577
} hm2_pwmgen_t;
577578

579+
//
580+
// oneshot
581+
//
582+
583+
584+
typedef struct {
585+
586+
struct {
587+
588+
struct {
589+
hal_float_t *width1;
590+
hal_float_t *width2;
591+
hal_float_t *filter1;
592+
hal_float_t *filter2;
593+
hal_float_t *rate;
594+
hal_u32_t *trigselect1;
595+
hal_u32_t *trigselect2;
596+
hal_bit_t *trigrise1;
597+
hal_bit_t *trigrise2;
598+
hal_bit_t *trigfall1;
599+
hal_bit_t *trigfall2;
600+
hal_bit_t *retrig1;
601+
hal_bit_t *retrig2;
602+
hal_bit_t *enable1;
603+
hal_bit_t *enable2;
604+
hal_bit_t *reset1;
605+
hal_bit_t *reset2;
606+
hal_bit_t *swtrig1;
607+
hal_bit_t *swtrig2;
608+
hal_bit_t *exttrig1;
609+
hal_bit_t *exttrig2;
610+
hal_bit_t *out1;
611+
hal_bit_t *out2;
612+
613+
hal_s32_t *dpll_timer_num;
614+
} pin;
615+
616+
} hal;
617+
618+
} hm2_oneshot_instance_t;
619+
620+
621+
622+
typedef struct {
623+
int num_instances;
624+
hm2_oneshot_instance_t *instance;
625+
626+
rtapi_u32 clock_frequency;
627+
rtapi_u8 version;
628+
629+
rtapi_u32 width1_addr;
630+
rtapi_u32 *width1_reg;
631+
632+
rtapi_u32 width2_addr;
633+
rtapi_u32 *width2_reg;
634+
635+
rtapi_u32 filter1_addr;
636+
rtapi_u32 *filter1_reg;
637+
638+
rtapi_u32 filter2_addr;
639+
rtapi_u32 *filter2_reg;
640+
641+
rtapi_u32 rate_addr;
642+
rtapi_u32 *rate_reg;
643+
644+
rtapi_u32 control_addr;
645+
rtapi_u32 *control_reg;
646+
647+
rtapi_u32 control_read_addr;
648+
rtapi_u32 *control_read_reg;
649+
650+
} hm2_oneshot_t;
651+
578652
//
579653
// rcpwmgen pwmgen optimized for RC servos
580654
//
@@ -1489,6 +1563,7 @@ typedef struct {
14891563
int num_xy2mods;
14901564
int num_ssrs;
14911565
int num_outms;
1566+
int num_oneshots;
14921567
char sserial_modes[4][8];
14931568
int enable_raw;
14941569
char *firmware;
@@ -1538,6 +1613,7 @@ typedef struct {
15381613
hm2_led_t led;
15391614
hm2_ssr_t ssr;
15401615
hm2_outm_t outm;
1616+
hm2_oneshot_t oneshot;
15411617

15421618
hm2_raw_t *raw;
15431619

@@ -1686,6 +1762,18 @@ void hm2_pwmgen_write(hostmot2_t *hm2);
16861762
void hm2_pwmgen_force_write(hostmot2_t *hm2);
16871763
void hm2_pwmgen_prepare_tram_write(hostmot2_t *hm2);
16881764

1765+
//
1766+
// oneshot functions
1767+
//
1768+
1769+
int hm2_oneshot_parse_md(hostmot2_t *hm2, int md_index);
1770+
void hm2_oneshot_print_module(hostmot2_t *hm2);
1771+
void hm2_oneshot_cleanup(hostmot2_t *hm2);
1772+
void hm2_oneshot_write(hostmot2_t *hm2);
1773+
void hm2_oneshot_force_write(hostmot2_t *hm2);
1774+
void hm2_oneshot_prepare_tram_write(hostmot2_t *hm2);
1775+
void hm2_oneshot_process_tram_read(hostmot2_t *hm2);
1776+
16891777
//
16901778
// rcpwmgen functions
16911779
//
@@ -1891,6 +1979,16 @@ void hm2_outm_force_write(hostmot2_t *hm2);
18911979
void hm2_outm_prepare_tram_write(hostmot2_t *hm2);
18921980
void hm2_outm_print_module(hostmot2_t *hm2);
18931981

1982+
//
1983+
// ONESHOT functions
1984+
//
1985+
1986+
int hm2_oneshot_parse_md(hostmot2_t *hm2, int md_index);
1987+
void hm2_oneshot_cleanup(hostmot2_t *hm2);
1988+
void hm2_oneshot_force_write(hostmot2_t *hm2);
1989+
void hm2_oneshot_prepare_tram_write(hostmot2_t *hm2);
1990+
void hm2_oneshot_print_module(hostmot2_t *hm2);
1991+
18941992

18951993
//
18961994
// the raw interface lets you peek and poke the hostmot2 instance from HAL

0 commit comments

Comments
 (0)