From f660834a7a5a9707d55db1947aef29b6a71df4de Mon Sep 17 00:00:00 2001 From: joan2937 Date: Sun, 14 Jul 2019 20:47:20 +0100 Subject: [PATCH] V69+: BCM2711 PLLD 500->750 MHz Crystal 19.2->54M --- command.c | 4 ++-- pigpio.3 | 24 ++++++++++++++---------- pigpio.c | 28 +++++++++++++++++++++------- pigpio.h | 33 +++++++++++++++++++-------------- pigpio.py | 29 ++++++++++++++++------------- pigpiod_if2.3 | 18 ++++++++++-------- pigpiod_if2.c | 2 +- pigpiod_if2.h | 19 ++++++++++--------- pigs.1 | 16 ++++++++-------- setup.py | 2 +- 10 files changed, 102 insertions(+), 73 deletions(-) diff --git a/command.c b/command.c index 5d02652..4a1da4d 100644 --- a/command.c +++ b/command.c @@ -515,9 +515,9 @@ static errInfo_t errInfo[]= {PI_NOT_SERVO_GPIO , "GPIO is not in use for servo pulses"}, {PI_NOT_HCLK_GPIO , "GPIO has no hardware clock"}, {PI_NOT_HPWM_GPIO , "GPIO has no hardware PWM"}, - {PI_BAD_HPWM_FREQ , "hardware PWM frequency not 1-125M"}, + {PI_BAD_HPWM_FREQ , "invalid hardware PWM frequency"}, {PI_BAD_HPWM_DUTY , "hardware PWM dutycycle not 0-1M"}, - {PI_BAD_HCLK_FREQ , "hardware clock frequency not 4689-250M"}, + {PI_BAD_HCLK_FREQ , "invalid hardware clock frequency"}, {PI_BAD_HCLK_PASS , "need password to use hardware clock 1"}, {PI_HPWM_ILLEGAL , "illegal, PWM in use for main clock"}, {PI_BAD_DATABITS , "serial data bits not 1-32"}, diff --git a/pigpio.3 b/pigpio.3 index 54e23e1..f8c1675 100644 --- a/pigpio.3 +++ b/pigpio.3 @@ -5585,7 +5585,7 @@ Frequencies above 30MHz are unlikely to work. .EX gpio: see description .br -clkfreq: 0 (off) or 4689-250000000 (250M) +clkfreq: 0 (off) or 4689-250M (13184-375M for the BCM2711) .br .EE @@ -5669,7 +5669,7 @@ main clock defaults to PCM but may be overridden by a call to .EX gpio: see description .br -PWMfreq: 0 (off) or 1-125000000 (125M) +PWMfreq: 0 (off) or 1-125M (1-187.5M for the BCM2711) .br PWMduty: 0 (off) to 1000000 (1M)(fully on) .br @@ -5726,18 +5726,18 @@ The GPIO must be one of the following. .br The actual number of steps beween off and fully on is the -integral part of 250 million divided by PWMfreq. +integral part of 250M/PWMfreq (375M/PWMfreq for the BCM2711). .br .br -The actual frequency set is 250 million / steps. +The actual frequency set is 250M/steps (375M/steps for the BCM2711). .br .br -There will only be a million steps for a PWMfreq of 250. -Lower frequencies will have more steps and higher +There will only be a million steps for a PWMfreq of 250 (375 for +the BCM2711). Lower frequencies will have more steps and higher frequencies will have fewer steps. PWMduty is automatically scaled to take this into account. @@ -7978,7 +7978,7 @@ A single character, an 8 bit quantity able to store 0-255. .br -.IP "\fBclkfreq\fP: 4689-250M" 0 +.IP "\fBclkfreq\fP: 4689-250M (13184-375M for the BCM2711)" 0 .br @@ -7994,6 +7994,8 @@ PI_HW_CLK_MIN_FREQ 4689 .br PI_HW_CLK_MAX_FREQ 250000000 .br +PI_HW_CLK_MAX_FREQ_2711 375000000 +.br .EE @@ -9057,7 +9059,7 @@ PI_HW_PWM_RANGE 1000000 .br -.IP "\fBPWMfreq\fP: 5-250K" 0 +.IP "\fBPWMfreq\fP: 1-125M (1-187.5M for the BCM2711)" 0 The hardware PWM frequency. .br @@ -9069,6 +9071,8 @@ PI_HW_PWM_MIN_FREQ 1 .br PI_HW_PWM_MAX_FREQ 125000000 .br +PI_HW_PWM_MAX_FREQ_2711 187500000 +.br .EE @@ -10263,11 +10267,11 @@ A 16-bit word value. .br #define PI_NOT_HPWM_GPIO -95 // GPIO has no hardware PWM .br -#define PI_BAD_HPWM_FREQ -96 // hardware PWM frequency not 1-125M +#define PI_BAD_HPWM_FREQ -96 // invalid hardware PWM frequency .br #define PI_BAD_HPWM_DUTY -97 // hardware PWM dutycycle not 0-1M .br -#define PI_BAD_HCLK_FREQ -98 // hardware clock frequency not 4689-250M +#define PI_BAD_HCLK_FREQ -98 // invalid hardware clock frequency .br #define PI_BAD_HCLK_PASS -99 // need password to use hardware clock 1 .br diff --git a/pigpio.c b/pigpio.c index 5187078..a41a3d7 100644 --- a/pigpio.c +++ b/pigpio.c @@ -511,6 +511,7 @@ bit 0 READ_LAST_NOT_SET_ERROR #define CLK_CTL_SRC_PLLD 6 #define CLK_OSC_FREQ 19200000 +#define CLK_OSC_FREQ_2711 54000000 #define CLK_PLLD_FREQ 500000000 #define CLK_PLLD_FREQ_2711 750000000 @@ -1219,7 +1220,11 @@ static volatile uint32_t pi_dram_bus = 0x40000000; static volatile uint32_t pi_mem_flag = 0x0C; static volatile uint32_t pi_ispi = 0; static volatile uint32_t pi_is_2711 = 0; +static volatile uint32_t clk_osc_freq = CLK_OSC_FREQ; static volatile uint32_t clk_plld_freq = CLK_PLLD_FREQ; +static volatile uint32_t hw_pwm_max_freq = PI_HW_PWM_MAX_FREQ; +static volatile uint32_t hw_clk_min_freq = PI_HW_CLK_MIN_FREQ; +static volatile uint32_t hw_clk_max_freq = PI_HW_CLK_MAX_FREQ; static int libInitialised = 0; @@ -12668,7 +12673,7 @@ int gpioHardwareClock(unsigned gpio, unsigned frequency) int cctl[] = {CLK_GP0_CTL, CLK_GP1_CTL, CLK_GP2_CTL}; int cdiv[] = {CLK_GP0_DIV, CLK_GP1_DIV, CLK_GP2_DIV}; int csrc[CLK_SRCS] = {CLK_CTL_SRC_OSC, CLK_CTL_SRC_PLLD}; - uint32_t cfreq[CLK_SRCS]={CLK_OSC_FREQ, clk_plld_freq}; + uint32_t cfreq[CLK_SRCS]={clk_osc_freq, clk_plld_freq}; unsigned clock, mode, mash; int password = 0; double f; @@ -12688,11 +12693,12 @@ int gpioHardwareClock(unsigned gpio, unsigned frequency) if (!clkDef[gpio]) SOFT_ERROR(PI_NOT_HCLK_GPIO, "bad gpio for clock (%d)", gpio); - if (((frequency < PI_HW_CLK_MIN_FREQ) || - (frequency > PI_HW_CLK_MAX_FREQ)) && + if (((frequency < hw_clk_min_freq) || + (frequency > hw_clk_max_freq)) && (frequency)) SOFT_ERROR(PI_BAD_HCLK_FREQ, - "bad hardware clock frequency (%d)", frequency); + "bad hardware clock frequency %d-%d: (%d)", + hw_clk_min_freq, hw_clk_max_freq, frequency); clock = (clkDef[gpio] >> 4) & 3; @@ -12727,7 +12733,8 @@ int gpioHardwareClock(unsigned gpio, unsigned frequency) else { SOFT_ERROR(PI_BAD_HCLK_FREQ, - "bad hardware clock frequency (%d)", frequency); + "bad hardware clock frequency %d-%d: (%d)", + hw_clk_min_freq, hw_clk_max_freq, frequency); } } else @@ -12766,10 +12773,12 @@ int gpioHardwarePWM( SOFT_ERROR(PI_BAD_HPWM_DUTY, "bad PWM dutycycle (%d)", dutycycle); if (((frequency < PI_HW_PWM_MIN_FREQ) || - (frequency > PI_HW_PWM_MAX_FREQ)) && + (frequency > hw_pwm_max_freq)) && (frequency)) SOFT_ERROR(PI_BAD_HPWM_FREQ, - "bad hardware PWM frequency (%d)", frequency); + "bad hardware PWM frequency %d-%d: (%d)", + PI_HW_PWM_MIN_FREQ, hw_pwm_max_freq, frequency); + if (gpioCfg.clockPeriph == PI_CLOCK_PWM) SOFT_ERROR(PI_HPWM_ILLEGAL, "illegal, PWM in use for main clock"); @@ -13477,7 +13486,12 @@ unsigned gpioHardwareRevision(void) pi_mem_flag = 0x04; pi_is_2711 = 1; pi_ispi = 1; + clk_osc_freq = CLK_OSC_FREQ_2711; clk_plld_freq = CLK_PLLD_FREQ_2711; + hw_pwm_max_freq = PI_HW_PWM_MAX_FREQ_2711; + hw_clk_min_freq = PI_HW_CLK_MIN_FREQ_2711; + hw_clk_max_freq = PI_HW_CLK_MAX_FREQ_2711; + fclose(filp); if (!gpioMaskSet) { diff --git a/pigpio.h b/pigpio.h index 77164bd..72852d5 100644 --- a/pigpio.h +++ b/pigpio.h @@ -30,7 +30,7 @@ For more information, please refer to #include #include -#define PIGPIO_VERSION 6906 +#define PIGPIO_VERSION 6909 /*TEXT @@ -610,13 +610,16 @@ typedef void *(gpioThreadFunc_t) (void *); /* hardware PWM */ #define PI_HW_PWM_MIN_FREQ 1 -#define PI_HW_PWM_MAX_FREQ 125000000 +#define PI_HW_PWM_MAX_FREQ 125000000 +#define PI_HW_PWM_MAX_FREQ_2711 187500000 #define PI_HW_PWM_RANGE 1000000 /* hardware clock */ -#define PI_HW_CLK_MIN_FREQ 4689 -#define PI_HW_CLK_MAX_FREQ 250000000 +#define PI_HW_CLK_MIN_FREQ 4689 +#define PI_HW_CLK_MIN_FREQ_2711 13184 +#define PI_HW_CLK_MAX_FREQ 250000000 +#define PI_HW_CLK_MAX_FREQ_2711 375000000 #define PI_NOTIFY_SLOTS 32 @@ -3982,7 +3985,7 @@ Frequencies above 30MHz are unlikely to work. . . gpio: see description -clkfreq: 0 (off) or 4689-250000000 (250M) +clkfreq: 0 (off) or 4689-250M (13184-375M for the BCM2711) . . Returns 0 if OK, otherwise PI_BAD_GPIO, PI_NOT_HCLK_GPIO, @@ -4027,7 +4030,7 @@ main clock defaults to PCM but may be overridden by a call to . . gpio: see description -PWMfreq: 0 (off) or 1-125000000 (125M) +PWMfreq: 0 (off) or 1-125M (1-187.5M for the BCM2711) PWMduty: 0 (off) to 1000000 (1M)(fully on) . . @@ -4054,12 +4057,12 @@ The GPIO must be one of the following. . . The actual number of steps beween off and fully on is the -integral part of 250 million divided by PWMfreq. +integral part of 250M/PWMfreq (375M/PWMfreq for the BCM2711). -The actual frequency set is 250 million / steps. +The actual frequency set is 250M/steps (375M/steps for the BCM2711). -There will only be a million steps for a PWMfreq of 250. -Lower frequencies will have more steps and higher +There will only be a million steps for a PWMfreq of 250 (375 for +the BCM2711). Lower frequencies will have more steps and higher frequencies will have fewer steps. PWMduty is automatically scaled to take this into account. D*/ @@ -5312,13 +5315,14 @@ char:: A single character, an 8 bit quantity able to store 0-255. -clkfreq::4689-250M +clkfreq::4689-250M (13184-375M for the BCM2711) The hardware clock frequency. . . PI_HW_CLK_MIN_FREQ 4689 PI_HW_CLK_MAX_FREQ 250000000 +PI_HW_CLK_MAX_FREQ_2711 375000000 . . count:: @@ -5770,12 +5774,13 @@ The hardware PWM dutycycle. PI_HW_PWM_RANGE 1000000 . . -PWMfreq::5-250K +PWMfreq::1-125M (1-187.5M for the BCM2711) The hardware PWM frequency. . . PI_HW_PWM_MIN_FREQ 1 PI_HW_PWM_MAX_FREQ 125000000 +PI_HW_PWM_MAX_FREQ_2711 187500000 . . range::25-40000 @@ -6379,9 +6384,9 @@ after this command is issued. #define PI_NOT_SERVO_GPIO -93 // GPIO is not in use for servo pulses #define PI_NOT_HCLK_GPIO -94 // GPIO has no hardware clock #define PI_NOT_HPWM_GPIO -95 // GPIO has no hardware PWM -#define PI_BAD_HPWM_FREQ -96 // hardware PWM frequency not 1-125M +#define PI_BAD_HPWM_FREQ -96 // invalid hardware PWM frequency #define PI_BAD_HPWM_DUTY -97 // hardware PWM dutycycle not 0-1M -#define PI_BAD_HCLK_FREQ -98 // hardware clock frequency not 4689-250M +#define PI_BAD_HCLK_FREQ -98 // invalid hardware clock frequency #define PI_BAD_HCLK_PASS -99 // need password to use hardware clock 1 #define PI_HPWM_ILLEGAL -100 // illegal, PWM in use for main clock #define PI_BAD_DATABITS -101 // serial data bits not 1-32 diff --git a/pigpio.py b/pigpio.py index d66485d..4da6171 100644 --- a/pigpio.py +++ b/pigpio.py @@ -300,7 +300,7 @@ import threading import os import atexit -VERSION = "1.43" +VERSION = "1.44" exceptions = True @@ -788,9 +788,9 @@ _errors=[ [PI_NOT_SERVO_GPIO , "GPIO is not in use for servo pulses"], [PI_NOT_HCLK_GPIO , "GPIO has no hardware clock"], [PI_NOT_HPWM_GPIO , "GPIO has no hardware PWM"], - [PI_BAD_HPWM_FREQ , "hardware PWM frequency not 1-125M"], + [PI_BAD_HPWM_FREQ , "invalid hardware PWM frequency"], [PI_BAD_HPWM_DUTY , "hardware PWM dutycycle not 0-1M"], - [PI_BAD_HCLK_FREQ , "hardware clock frequency not 4689-250M"], + [PI_BAD_HCLK_FREQ , "invalid hardware clock frequency"], [PI_BAD_HCLK_PASS , "need password to use hardware clock 1"], [PI_HPWM_ILLEGAL , "illegal, PWM in use for main clock"], [PI_BAD_DATABITS , "serial data bits not 1-32"], @@ -1909,7 +1909,7 @@ class pi(): Frequencies above 30MHz are unlikely to work. gpio:= see description - clkfreq:= 0 (off) or 4689-250000000 (250M) + clkfreq:= 0 (off) or 4689-250M (13184-375M for the BCM2711) Returns 0 if OK, otherwise PI_NOT_PERMITTED, PI_BAD_GPIO, @@ -1959,7 +1959,7 @@ class pi(): pigpio daemon is started (option -t). gpio:= see descripton - PWMfreq:= 0 (off) or 1-125000000 (125M). + PWMfreq:= 0 (off) or 1-125M (1-187.5M for the BCM2711). PWMduty:= 0 (off) to 1000000 (1M)(fully on). Returns 0 if OK, otherwise PI_NOT_PERMITTED, PI_BAD_GPIO, @@ -1985,14 +1985,15 @@ class pi(): . . The actual number of steps beween off and fully on is the - integral part of 250 million divided by PWMfreq. + integral part of 250M/PWMfreq (375M/PWMfreq for the BCM2711). - The actual frequency set is 250 million / steps. + The actual frequency set is 250M/steps (375M/steps + for the BCM2711). - There will only be a million steps for a PWMfreq of 250. - Lower frequencies will have more steps and higher - frequencies will have fewer steps. PWMduty is - automatically scaled to take this into account. + There will only be a million steps for a PWMfreq of 250 + (375 for the BCM2711). Lower frequencies will have more + steps and higher frequencies will have fewer steps. + PWMduty is automatically scaled to take this into account. ... pi.hardware_PWM(18, 800, 250000) # 800Hz 25% dutycycle @@ -5184,7 +5185,7 @@ def xref(): byte_val: 0-255 A whole number. - clkfreq: 4689-250M + clkfreq: 4689-250M (13184-375M for the BCM2711) The hardware clock frequency. connected: @@ -5340,6 +5341,8 @@ def xref(): PI_NOT_SPI_GPIO = -142 PI_BAD_EVENT_ID = -143 PI_CMD_INTERRUPTED = -144 + PI_NOT_ON_BCM2711 = -145 + PI_ONLY_ON_BCM2711 = -146 . . event:0-31 @@ -5532,7 +5535,7 @@ def xref(): PWMduty: 0-1000000 (1M) The hardware PWM dutycycle. - PWMfreq: 1-125000000 (125M) + PWMfreq: 1-125M (1-187.5M for the BCM2711) The hardware PWM frequency. range_: 25-40000 diff --git a/pigpiod_if2.3 b/pigpiod_if2.3 index f39dfa4..2354d88 100644 --- a/pigpiod_if2.3 +++ b/pigpiod_if2.3 @@ -1412,7 +1412,7 @@ Frequencies above 30MHz are unlikely to work. .br gpio: see description .br -frequency: 0 (off) or 4689-250000000 (250M) +frequency: 0 (off) or 4689-250M (13184-375M for the BCM2711) .br .EE @@ -1498,7 +1498,7 @@ daemon is started (option -t). .br gpio: see descripton .br -PWMfreq: 0 (off) or 1-125000000 (125M) +PWMfreq: 0 (off) or 1-125M (1-187.5M for the BCM2711) .br PWMduty: 0 (off) to 1000000 (1M)(fully on) .br @@ -1556,18 +1556,18 @@ The GPIO must be one of the following. .br The actual number of steps beween off and fully on is the -integral part of 250 million divided by PWMfreq. +integral part of 250M/PWMfreq (375M/PWMfreq for the BCM2711). .br .br -The actual frequency set is 250 million / steps. +The actual frequency set is 250M/steps (375M/steps for the BCM2711). .br .br -There will only be a million steps for a PWMfreq of 250. -Lower frequencies will have more steps and higher +There will only be a million steps for a PWMfreq of 250 (375 for +the BCM2711). Lower frequencies will have more steps and higher frequencies will have fewer steps. PWMduty is automatically scaled to take this into account. @@ -6294,7 +6294,7 @@ A single character, an 8 bit quantity able to store 0-255. .br -.IP "\fBclkfreq\fP: 4689-250000000 (250M)" 0 +.IP "\fBclkfreq\fP: 4689-250M (13184-375M for the BCM2711)" 0 The hardware clock frequency. .br @@ -6972,7 +6972,7 @@ The hardware PWM dutycycle. .br -.IP "\fBPWMfreq\fP: 1-125000000 (125M)" 0 +.IP "\fBPWMfreq\fP: 1-125M (1-187.5M for the BCM2711)" 0 The hardware PWM frequency. .br @@ -6984,6 +6984,8 @@ The hardware PWM frequency. .br #define PI_HW_PWM_MAX_FREQ 125000000 .br +#define PI_HW_PWM_MAX_FREQ_2711 187500000 +.br .EE diff --git a/pigpiod_if2.c b/pigpiod_if2.c index fa97d31..cd343c0 100644 --- a/pigpiod_if2.c +++ b/pigpiod_if2.c @@ -25,7 +25,7 @@ OTHER DEALINGS IN THE SOFTWARE. For more information, please refer to */ -/* PIGPIOD_IF2_VERSION 14 */ +/* PIGPIOD_IF2_VERSION 15 */ #include #include diff --git a/pigpiod_if2.h b/pigpiod_if2.h index 4cd7cf8..b63dbc7 100644 --- a/pigpiod_if2.h +++ b/pigpiod_if2.h @@ -30,7 +30,7 @@ For more information, please refer to #include "pigpio.h" -#define PIGPIOD_IF2_VERSION 14 +#define PIGPIOD_IF2_VERSION 15 /*TEXT @@ -1049,7 +1049,7 @@ Frequencies above 30MHz are unlikely to work. . . pi: >=0 (as returned by [*pigpio_start*]). gpio: see description -frequency: 0 (off) or 4689-250000000 (250M) +frequency: 0 (off) or 4689-250M (13184-375M for the BCM2711) . . Returns 0 if OK, otherwise PI_NOT_PERMITTED, PI_BAD_GPIO, @@ -1096,7 +1096,7 @@ daemon is started (option -t). . . pi: >=0 (as returned by [*pigpio_start*]). gpio: see descripton -PWMfreq: 0 (off) or 1-125000000 (125M) +PWMfreq: 0 (off) or 1-125M (1-187.5M for the BCM2711) PWMduty: 0 (off) to 1000000 (1M)(fully on) . . @@ -1124,12 +1124,12 @@ The GPIO must be one of the following. . . The actual number of steps beween off and fully on is the -integral part of 250 million divided by PWMfreq. +integral part of 250M/PWMfreq (375M/PWMfreq for the BCM2711). -The actual frequency set is 250 million / steps. +The actual frequency set is 250M/steps (375M/steps for the BCM2711). -There will only be a million steps for a PWMfreq of 250. -Lower frequencies will have more steps and higher +There will only be a million steps for a PWMfreq of 250 (375 for +the BCM2711). Lower frequencies will have more steps and higher frequencies will have fewer steps. PWMduty is automatically scaled to take this into account. D*/ @@ -3749,7 +3749,7 @@ typedef void (*CBFuncEx_t) char:: A single character, an 8 bit quantity able to store 0-255. -clkfreq::4689-250000000 (250M) +clkfreq::4689-250M (13184-375M for the BCM2711) The hardware clock frequency. count:: @@ -4053,12 +4053,13 @@ The hardware PWM dutycycle. #define PI_HW_PWM_RANGE 1000000 . . -PWMfreq::1-125000000 (125M) +PWMfreq::1-125M (1-187.5M for the BCM2711) The hardware PWM frequency. . . #define PI_HW_PWM_MIN_FREQ 1 #define PI_HW_PWM_MAX_FREQ 125000000 +#define PI_HW_PWM_MAX_FREQ_2711 187500000 . . range::25-40000 diff --git a/pigs.1 b/pigs.1 index 0780ab5..3926b64 100644 --- a/pigs.1 +++ b/pigs.1 @@ -1705,11 +1705,11 @@ $ pigs hp 19 100 200000 # 20% dutycycle .br .br -$ pigs hp 19 125000001 100000 +$ pigs hp 19 400000000 100000 .br -96 .br -ERROR: hardware PWM frequency not 1-125M +ERROR: invalid hardware PWM frequency .br .EE @@ -1745,14 +1745,14 @@ The GPIO must be one of the following. .br The actual number of steps beween off and fully on is the -integral part of 250 million divided by \fBpf\fP. +integral part of 250M/\fBpf\fP (375M/\fBpf\fP for the BCM2711). .br -The actual frequency set is 250 million / steps. +The actual frequency set is 250M/steps (375M/steps for the BCM2711). .br -There will only be a million steps for a \fBpf\fP of 250. -Lower frequencies will have more steps and higher +There will only be a million steps for a \fBpf\fP of 250 (375 for +the BCM2711). Lower frequencies will have more steps and higher frequencies will have fewer steps. \fBpdc\fP is automatically scaled to take this into account. @@ -5125,7 +5125,7 @@ The command expects a SPI channel. .br -.IP "\fBcf\fP - hardware clock frequency (4689-250M)" 0 +.IP "\fBcf\fP - hardware clock frequency (4689-250M, 13184-375M for the BCM2711)" 0 The command expects a frequency. .br @@ -5408,7 +5408,7 @@ The command expects a dutycycle. .br -.IP "\fBpf\fP - hardware PWM frequency (1-125M)" 0 +.IP "\fBpf\fP - hardware PWM frequency (1-125M, 1-187.5M for the BCM2711)" 0 The command expects a frequency. .br diff --git a/setup.py b/setup.py index a0cb293..2b5505c 100644 --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ from distutils.core import setup setup(name='pigpio', - version='1.43', + version='1.44', author='joan', author_email='joan@abyz.me.uk', maintainer='joan',