debian: update package version 3.14.1
ODROID-COMMON: support hardware PWM with sysnode. Support pwm with gpiomem mode. not sys mode. ANDROID: Add Android.mk for android. Signed-off-by: steve.jeong <jkhpro1003@gmail.com> Change-Id: Ic6005c0cb81586c9f945b9b6c75f904fa79e3915
This commit is contained in:
8
Android.mk
Normal file
8
Android.mk
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
LOCAL_PATH := $(my-dir)
|
||||||
|
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
LOCAL_MODULE := odroid-wpi-pwm.sh
|
||||||
|
LOCAL_MODULE_CLASS := ETC
|
||||||
|
LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)
|
||||||
|
LOCAL_SRC_FILES := etc/$(LOCAL_MODULE)
|
||||||
|
include $(BUILD_PREBUILT)
|
||||||
7
debian/changelog
vendored
7
debian/changelog
vendored
@@ -1,3 +1,10 @@
|
|||||||
|
odroid-wiringpi (3.14.1) stable; urgency=medium
|
||||||
|
|
||||||
|
* ODROID-COMMON: allow permission pwm sys nodes and use with gpiomem mode.
|
||||||
|
* ANDROID: Add Android.mk for android.
|
||||||
|
|
||||||
|
-- steve <jkhpro1003@gmail.com> Wed, 23 Nov 2022 10:41:05 +0900
|
||||||
|
|
||||||
odroid-wiringpi (3.14.0) stable; urgency=medium
|
odroid-wiringpi (3.14.0) stable; urgency=medium
|
||||||
|
|
||||||
* ODROID-N2L: new support ODROID-N2L
|
* ODROID-N2L: new support ODROID-N2L
|
||||||
|
|||||||
1
debian/odroid-wiringpi.install
vendored
1
debian/odroid-wiringpi.install
vendored
@@ -1 +1,2 @@
|
|||||||
udev/rules.d/* usr/lib/udev/rules.d/
|
udev/rules.d/* usr/lib/udev/rules.d/
|
||||||
|
etc/* etc/
|
||||||
|
|||||||
2
debian/odroid-wiringpi.postrm
vendored
2
debian/odroid-wiringpi.postrm
vendored
@@ -5,6 +5,8 @@ set -e
|
|||||||
case "$1" in
|
case "$1" in
|
||||||
purge)
|
purge)
|
||||||
rm -f /etc/udev/rules.d/99-odroid-wiringpi-*
|
rm -f /etc/udev/rules.d/99-odroid-wiringpi-*
|
||||||
|
rm -f /etc/odroid-wpi-pwm.sh
|
||||||
|
rm -f /etc/sudoers.d/odroid-wpi-sudoers
|
||||||
;;
|
;;
|
||||||
|
|
||||||
remove|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear)
|
remove|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear)
|
||||||
|
|||||||
18
etc/odroid-wpi-pwm.sh
Normal file
18
etc/odroid-wpi-pwm.sh
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# /etc/odroid-wpi-pwm.sh
|
||||||
|
# written by steve.jeong <jkhpro1003@gmail.com>
|
||||||
|
#
|
||||||
|
# allow access pwm sys node (with odroid-wiringpi gpiomem).
|
||||||
|
# udev rules: 99-odroid-wiringpi-pwm.rules
|
||||||
|
# param: "/sys/class/pwm/pwmchip*" default.
|
||||||
|
|
||||||
|
cutoff=0
|
||||||
|
|
||||||
|
while [ ! -d "$1" ]; do
|
||||||
|
cutoff=$(expr ${cutoff} + 1)
|
||||||
|
[ ${cutoff} -gt 5 ] && break
|
||||||
|
sleep .1
|
||||||
|
done
|
||||||
|
|
||||||
|
chmod -R ugo+rw $1
|
||||||
2
etc/sudoers.d/odroid-wpi-sudoers
Normal file
2
etc/sudoers.d/odroid-wpi-sudoers
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
# Allow members of the odroid group change permission of wpi
|
||||||
|
%odroid ALL = (ALL) NOPASSWD: /usr/bin/sh /etc/odroid-wpi-pwm.sh*
|
||||||
1
udev/rules.d/99-odroid-wiringpi-pwm.rules
Normal file
1
udev/rules.d/99-odroid-wiringpi-pwm.rules
Normal file
@@ -0,0 +1 @@
|
|||||||
|
ACTION=="add", KERNEL=="pwmchip*", SUBSYSTEM=="pwm", RUN+="/bin/sh /etc/odroid-wpi-pwm.sh /sys/class/pwm/pwmchip*"
|
||||||
@@ -5,6 +5,7 @@
|
|||||||
//
|
//
|
||||||
//
|
//
|
||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
|
#include <dirent.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
@@ -15,6 +16,7 @@
|
|||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <asm/ioctl.h>
|
#include <asm/ioctl.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
#include "softPwm.h"
|
#include "softPwm.h"
|
||||||
@@ -47,7 +49,7 @@ static const int pinToGpio[64] = {
|
|||||||
474, 475, // 30 | 31 : GPIOA.14(I2C-3_SDA), GPIOA.15(I2C-3_SCL)
|
474, 475, // 30 | 31 : GPIOA.14(I2C-3_SDA), GPIOA.15(I2C-3_SCL)
|
||||||
// Padding:
|
// Padding:
|
||||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 32...47
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 32...47
|
||||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 48...63
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 // 48...63
|
||||||
};
|
};
|
||||||
|
|
||||||
static const int phyToGpio[64] = {
|
static const int phyToGpio[64] = {
|
||||||
@@ -79,6 +81,62 @@ static const int phyToGpio[64] = {
|
|||||||
-1, -1, -1, -1, -1, -1, -1 // 57...63
|
-1, -1, -1, -1, -1, -1, -1 // 57...63
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const char *pinToPwm[64] = {
|
||||||
|
// wiringPi number to pwm group number
|
||||||
|
"ffd1a000", "ffd19000", // 0 | 1 : GPIOX.3(PWM_CD), GPIOX.16(PWM_EF)
|
||||||
|
"None", "ffd19000", // 2 | 3 : GPIOX.4, GPIOX.7(PWM_EF)
|
||||||
|
"None", "None", // 4 | 5 : GPIOX.0, GPIOX.1
|
||||||
|
"None", "ffd1a000", // 6 | 7 : GPIOX.2, GPIOX.5(PWM_CD)
|
||||||
|
"None", "None", // 8 | 9 : GPIOX.17(I2C-2_SDA), GPIOX.18(I2C-2_SCL)
|
||||||
|
"None", "None", // 10 | 11 : GPIOX.10(SPI_SS), GPIOH.6
|
||||||
|
"None", "None", // 12 | 13 : GPIOX.8(SPI_MOSI), GPIOX.9(SPI_MISO)
|
||||||
|
"None", "None", // 14 | 15 : GPIOX.11(SPI_CLK), GPIOX.12(UART_TX_B)
|
||||||
|
"None", "None", // 16 | 17 : GPIOX.13(UART_RX_B),
|
||||||
|
"None", "None", // 18 | 19 :
|
||||||
|
"None", "None", // 20 | 21 : , GPIOX.14
|
||||||
|
"None", "ffd1b000", // 22 | 23 : GPIOX.15, GPIOX.6(PWM_AB)
|
||||||
|
"ffd1b000", "None", // 24 | 25 : GPIOX.19(PWM_AB), ADC.AIN3
|
||||||
|
"None", "None", // 26 | 27 : GPIOH.7, GPIOH.5
|
||||||
|
"None", "None", // 28 | 29 : REF1.8V OUT, ADC.AIC4
|
||||||
|
"None", "None", // 30 | 31 : GPIOA.14(I2C-3_SDA), GPIOA.15(I2C-3_SCL)
|
||||||
|
// Padding:
|
||||||
|
"None","None","None","None","None","None","None","None","None","None","None","None","None","None","None","None", // 32...47
|
||||||
|
"None","None","None","None","None","None","None","None","None","None","None","None","None","None","None","None" // 48...63
|
||||||
|
};
|
||||||
|
|
||||||
|
static const int pinToPwmNum[64] = {
|
||||||
|
// wiringPi number to pwm pin number
|
||||||
|
3, 4, // 0 | 1 : GPIOX.3(PWM_D), GPIOX.16(PWM_E)
|
||||||
|
-1, 5, // 2 | 3 : GPIOX.4, GPIOX.7(PWM_F)
|
||||||
|
-1, -1, // 4 | 5 : GPIOX.0, GPIOX.1
|
||||||
|
-1, 2, // 6 | 7 : GPIOX.2, GPIOX.5(PWM_C)
|
||||||
|
-1, -1, // 8 | 9 : GPIOX.17(I2C-2_SDA), GPIOX.18(I2C-2_SCL)
|
||||||
|
-1, -1, // 10 | 11 : GPIOX.10(SPI_SS), GPIOH.6
|
||||||
|
-1, -1, // 12 | 13 : GPIOX.8(SPI_MOSI), GPIOX.9(SPI_MISO)
|
||||||
|
-1, -1, // 14 | 15 : GPIOX.11(SPI_CLK), GPIOX.12(UART_TX_B)
|
||||||
|
-1, -1, // 16 | 17 : GPIOX.13(UART_RX_B),
|
||||||
|
-1, -1, // 18 | 19 :
|
||||||
|
-1, -1, // 20 | 21 : , GPIOX.14
|
||||||
|
-1, 0, // 22 | 23 : GPIOX.15, GPIOX.6(PWM_A)
|
||||||
|
1, -1, // 24 | 25 : GPIOX.19(PWM_B), ADC.AIN3
|
||||||
|
-1, -1, // 26 | 27 : GPIOH.7, GPIOH.5
|
||||||
|
-1, -1, // 28 | 29 : REF1.8V OUT, ADC.AIC4
|
||||||
|
-1, -1, // 30 | 31 : GPIOA.14(I2C-3_SDA), GPIOA.15(I2C-3_SCL)
|
||||||
|
// Padding:
|
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 32...47
|
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 // 48...63
|
||||||
|
};
|
||||||
|
|
||||||
|
static char pwmPinPath[10][(BLOCK_SIZE)] = {
|
||||||
|
"","",
|
||||||
|
"","",
|
||||||
|
"","",
|
||||||
|
// Padding:
|
||||||
|
"None","None","None","None"
|
||||||
|
};
|
||||||
|
|
||||||
|
static char setupedPwmPinPath[BLOCK_SIZE];
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
//
|
//
|
||||||
// Global variable define
|
// Global variable define
|
||||||
@@ -95,6 +153,18 @@ static volatile uint32_t *gpio;
|
|||||||
/* wiringPi Global library */
|
/* wiringPi Global library */
|
||||||
static struct libodroid *lib = NULL;
|
static struct libodroid *lib = NULL;
|
||||||
|
|
||||||
|
/* pwm sysnode */
|
||||||
|
static DIR *pwm;
|
||||||
|
static struct dirent *pwmchip;
|
||||||
|
/* pwm params */
|
||||||
|
static char sysPwmPath[(BLOCK_SIZE / 4)];
|
||||||
|
static char pwmExport[(BLOCK_SIZE / 16)];
|
||||||
|
static char pwmUnexport[(BLOCK_SIZE / 16)];
|
||||||
|
static char pwmPeriod[(BLOCK_SIZE / 16)];
|
||||||
|
static char pwmDuty[(BLOCK_SIZE / 16)];
|
||||||
|
static unsigned int pwmClock;
|
||||||
|
static unsigned int pwmRange;
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
// Function prototype define
|
// Function prototype define
|
||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
@@ -106,7 +176,12 @@ static int gpioToShiftReg (int pin);
|
|||||||
static int gpioToGPFSELReg (int pin);
|
static int gpioToGPFSELReg (int pin);
|
||||||
static int gpioToDSReg (int pin);
|
static int gpioToDSReg (int pin);
|
||||||
static int gpioToMuxReg (int pin);
|
static int gpioToMuxReg (int pin);
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
// Function of pwm define
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
static int pinToSysPwmPath (int pin);
|
||||||
|
static int pwmSetup (int pin);
|
||||||
|
static int pwmRelease (int pin);
|
||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
// wiringPi core function
|
// wiringPi core function
|
||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
@@ -119,9 +194,12 @@ static int _getPUPD (int pin);
|
|||||||
static int _pullUpDnControl (int pin, int pud);
|
static int _pullUpDnControl (int pin, int pud);
|
||||||
static int _digitalRead (int pin);
|
static int _digitalRead (int pin);
|
||||||
static int _digitalWrite (int pin, int value);
|
static int _digitalWrite (int pin, int value);
|
||||||
|
static int _pwmWrite (int pin, int value);
|
||||||
static int _analogRead (int pin);
|
static int _analogRead (int pin);
|
||||||
static int _digitalWriteByte (const unsigned int value);
|
static int _digitalWriteByte (const unsigned int value);
|
||||||
static unsigned int _digitalReadByte (void);
|
static unsigned int _digitalReadByte (void);
|
||||||
|
static void _pwmSetRange (unsigned int range);
|
||||||
|
static void _pwmSetClock (int divisor);
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
// board init function
|
// board init function
|
||||||
@@ -271,6 +349,114 @@ static int gpioToMuxReg (int pin)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
//
|
||||||
|
// config pwm sys path. "/sys/class/pwm/pwmchip?"
|
||||||
|
//
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
static int pinToSysPwmPath (int pin)
|
||||||
|
{
|
||||||
|
const char *pwmGroup;
|
||||||
|
char pwmLinkSrc[(BLOCK_SIZE / 8)];
|
||||||
|
char pwmPath[(BLOCK_SIZE / 8)];
|
||||||
|
int sz_link;
|
||||||
|
|
||||||
|
memset(pwmLinkSrc, 0, sizeof(pwmLinkSrc));
|
||||||
|
memset(pwmPath, 0, sizeof(pwmPath));
|
||||||
|
|
||||||
|
pwmGroup = pinToPwm[pin];
|
||||||
|
pwm = opendir("/sys/class/pwm");
|
||||||
|
if (pwm == NULL) {
|
||||||
|
printf("need to set device: pwm\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
pwmchip = readdir(pwm);
|
||||||
|
|
||||||
|
if (pwmchip == NULL) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strlen(pwmchip->d_name) <= 2)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
sprintf(pwmPath, "%s/%s", "/sys/class/pwm", pwmchip->d_name);
|
||||||
|
sz_link = readlink(pwmPath, pwmLinkSrc, sizeof(pwmLinkSrc));
|
||||||
|
if (sz_link < 0) {
|
||||||
|
perror("Read symbolic link fail");
|
||||||
|
return sz_link;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strstr(pwmLinkSrc, pwmGroup) != NULL) {
|
||||||
|
strncpy(sysPwmPath, pwmPath, (sizeof(sysPwmPath) - 1));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
closedir(pwm);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int pwmSetup (int pin) {
|
||||||
|
char cmd[(BLOCK_SIZE * 2)];
|
||||||
|
int pwmPin, ret;
|
||||||
|
|
||||||
|
memset(cmd, 0, sizeof(cmd));
|
||||||
|
memset(pwmExport, 0, sizeof(pwmExport));
|
||||||
|
|
||||||
|
if ((ret = pinToSysPwmPath(pin)) < 0) {
|
||||||
|
perror("set pwm dtb overlays");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strstr(sysPwmPath, "pwmchip") == NULL) {
|
||||||
|
printf("config pwm dtb overlays\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pwmPin = pinToPwmNum[pin];
|
||||||
|
sprintf(pwmExport, "%d", (pwmPin % 2));
|
||||||
|
sprintf(pwmPinPath[pwmPin], "%s/pwm%d", sysPwmPath, (pwmPin % 2));
|
||||||
|
strncpy(setupedPwmPinPath, pwmPinPath[pwmPin], (sizeof(setupedPwmPinPath) - 1));
|
||||||
|
#ifdef ANDROID
|
||||||
|
sprintf(cmd, "su -s sh -c %s %s", PWM_ACCESS_SCRIPT, pwmPinPath[pwmPin]);
|
||||||
|
#else
|
||||||
|
sprintf(cmd, "sudo sh %s %s", PWM_ACCESS_SCRIPT, pwmPinPath[pwmPin]);
|
||||||
|
#endif
|
||||||
|
inputToSysNode(sysPwmPath, "export", pwmExport);
|
||||||
|
system(cmd);
|
||||||
|
inputToSysNode(pwmPinPath[pwmPin], "polarity", "normal");
|
||||||
|
inputToSysNode(pwmPinPath[pwmPin], "enable", "1");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int pwmRelease (int pin) {
|
||||||
|
int pwmPin, ret;
|
||||||
|
|
||||||
|
if ((ret = pinToSysPwmPath(pin)) < 0) {
|
||||||
|
perror("set pwm dtb overlays");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strstr(sysPwmPath, "pwmchip") == NULL) {
|
||||||
|
printf("config pwm dtb overlays\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pwmPin = pinToPwmNum[pin];
|
||||||
|
sprintf(pwmUnexport, "%d", (pwmPin % 2));
|
||||||
|
sprintf(pwmPinPath[pwmPin], "%s/pwm%d", sysPwmPath, (pwmPin % 2));
|
||||||
|
if ((pwm = opendir(pwmPinPath[pwmPin])) != NULL) {
|
||||||
|
inputToSysNode(pwmPinPath[pwmPin], "enable", "0");
|
||||||
|
inputToSysNode(sysPwmPath, "unexport", pwmUnexport);
|
||||||
|
closedir(pwm);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
static int _getModeToGpio (int mode, int pin)
|
static int _getModeToGpio (int mode, int pin)
|
||||||
{
|
{
|
||||||
@@ -356,6 +542,7 @@ static int _pinMode (int pin, int mode)
|
|||||||
if ((pin = _getModeToGpio(lib->mode, pin)) < 0)
|
if ((pin = _getModeToGpio(lib->mode, pin)) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
pwmRelease (origPin);
|
||||||
softPwmStop (origPin);
|
softPwmStop (origPin);
|
||||||
softToneStop (origPin);
|
softToneStop (origPin);
|
||||||
|
|
||||||
@@ -375,6 +562,9 @@ static int _pinMode (int pin, int mode)
|
|||||||
case SOFT_TONE_OUTPUT:
|
case SOFT_TONE_OUTPUT:
|
||||||
softToneCreate (pin);
|
softToneCreate (pin);
|
||||||
break;
|
break;
|
||||||
|
case PWM_OUTPUT:
|
||||||
|
pwmSetup(origPin);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
msg(MSG_WARN, "%s : Unknown Mode %d\n", __func__, mode);
|
msg(MSG_WARN, "%s : Unknown Mode %d\n", __func__, mode);
|
||||||
return -1;
|
return -1;
|
||||||
@@ -512,6 +702,36 @@ static int _digitalWrite (int pin, int value)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
// PWM signal ___-----------___________---------------_______-----_
|
||||||
|
// <--value--> <----value---->
|
||||||
|
// <-------range--------><-------range-------->
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
static int _pwmWrite (int pin, int value)
|
||||||
|
{
|
||||||
|
unsigned int duty;
|
||||||
|
int pwmPin;
|
||||||
|
|
||||||
|
memset(pwmDuty, 0, sizeof(pwmDuty));
|
||||||
|
|
||||||
|
if (lib->mode == MODE_GPIO_SYS)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (((unsigned int)value > pwmRange) || (pwmRange <= 0)) {
|
||||||
|
printf("Set \'pwmWrite\' valied value. ( < pwm range)\n");
|
||||||
|
printf("pwmSetRange value is greater than or equal pwmWrite's\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pwmPin = pinToPwmNum[pin];
|
||||||
|
duty = ((value * 100) / pwmRange);
|
||||||
|
sprintf(pwmDuty, "%d", ((atoi(pwmPeriod) * duty) / 100));
|
||||||
|
|
||||||
|
inputToSysNode(pwmPinPath[pwmPin], "duty_cycle", pwmDuty);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
static int _analogRead (int pin)
|
static int _analogRead (int pin)
|
||||||
{
|
{
|
||||||
@@ -624,6 +844,57 @@ static unsigned int _digitalReadByte (void)
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
// PWM signal ___-----------___________---------------_______-----_
|
||||||
|
// <--value--> <----value---->
|
||||||
|
// <-------range--------><-------range-------->
|
||||||
|
// PWM frequency == (PWM clock) / range
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void _pwmSetRange (unsigned int range)
|
||||||
|
{
|
||||||
|
unsigned int freq, period;
|
||||||
|
|
||||||
|
memset(pwmPeriod, 0, sizeof(pwmPeriod));
|
||||||
|
|
||||||
|
if (lib->mode == MODE_GPIO_SYS)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (pwmClock < 2) {
|
||||||
|
printf("Set \'pwmSetClock\' valied value.\n");
|
||||||
|
printf("pwm freq: %dMHz / (pwmSetClock's value) >= 2\n", (C4_PWM_INTERNAL_CLK / 1000000));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pwmRange = range;
|
||||||
|
if ((pwmRange < 1) || (pwmRange >= pwmClock)) {
|
||||||
|
printf("Set \'pwmSetRange\' valied value. ( < pwm freq)\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
freq = (pwmClock / pwmRange);
|
||||||
|
period = (1000000000 / freq); // period: s to ns.
|
||||||
|
sprintf(pwmPeriod, "%d", period);
|
||||||
|
if (strstr(setupedPwmPinPath, "pwm") == NULL) {
|
||||||
|
printf("Not setuped pwm target.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
inputToSysNode(setupedPwmPinPath, "period", pwmPeriod);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
// Internal clock == 24MHz
|
||||||
|
// PWM clock == (Internal clock) / divisor
|
||||||
|
// PWM frequency == (PWM clock) / range
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void _pwmSetClock (int divisor)
|
||||||
|
{
|
||||||
|
pwmClock = (C4_PWM_INTERNAL_CLK / divisor);
|
||||||
|
}
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
static void init_gpio_mmap (void)
|
static void init_gpio_mmap (void)
|
||||||
{
|
{
|
||||||
@@ -706,9 +977,12 @@ void init_odroidc4 (struct libodroid *libwiring)
|
|||||||
libwiring->pullUpDnControl = _pullUpDnControl;
|
libwiring->pullUpDnControl = _pullUpDnControl;
|
||||||
libwiring->digitalRead = _digitalRead;
|
libwiring->digitalRead = _digitalRead;
|
||||||
libwiring->digitalWrite = _digitalWrite;
|
libwiring->digitalWrite = _digitalWrite;
|
||||||
|
libwiring->pwmWrite = _pwmWrite;
|
||||||
libwiring->analogRead = _analogRead;
|
libwiring->analogRead = _analogRead;
|
||||||
libwiring->digitalWriteByte = _digitalWriteByte;
|
libwiring->digitalWriteByte = _digitalWriteByte;
|
||||||
libwiring->digitalReadByte = _digitalReadByte;
|
libwiring->digitalReadByte = _digitalReadByte;
|
||||||
|
libwiring->pwmSetRange = _pwmSetRange;
|
||||||
|
libwiring->pwmSetClock = _pwmSetClock;
|
||||||
|
|
||||||
/* specify pin base number */
|
/* specify pin base number */
|
||||||
libwiring->pinBase = C4_GPIO_PIN_BASE;
|
libwiring->pinBase = C4_GPIO_PIN_BASE;
|
||||||
|
|||||||
@@ -49,6 +49,8 @@
|
|||||||
#define C4_GPIOX_MUX_4_REG_OFFSET 0x1B4
|
#define C4_GPIOX_MUX_4_REG_OFFSET 0x1B4
|
||||||
#define C4_GPIOX_MUX_5_REG_OFFSET 0x1B5
|
#define C4_GPIOX_MUX_5_REG_OFFSET 0x1B5
|
||||||
|
|
||||||
|
#define C4_PWM_INTERNAL_CLK 24000000 // 24MHz
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1311,6 +1311,20 @@ int wiringPiSetupPhys (void)
|
|||||||
* Initialisation (again), however this time we are using the /sys/class/gpio
|
* Initialisation (again), however this time we are using the /sys/class/gpio
|
||||||
* interface to the GPIO systems - slightly slower, but always usable as
|
* interface to the GPIO systems - slightly slower, but always usable as
|
||||||
* a non-root user, assuming the devices are already exported and setup correctly.
|
* a non-root user, assuming the devices are already exported and setup correctly.
|
||||||
|
*
|
||||||
|
* -----------------------------------------------------------------------------
|
||||||
|
* Applies from "odroid-wiringpi" 3.14.1 and later.
|
||||||
|
*
|
||||||
|
* [The odroid hardware pwm uses sysnode, but it is separate from it.]
|
||||||
|
* I decided to use the wiringpi service as gpiomem base for odroid,
|
||||||
|
* but the pwm is using sysnode.
|
||||||
|
*
|
||||||
|
* In addition, i designed the API in common so that devices such as gpio as well as pwm
|
||||||
|
* can be directly accessed and used by sysnode.
|
||||||
|
*
|
||||||
|
* "inputToSysNode" is what it is.
|
||||||
|
*
|
||||||
|
* Authored by steve.jeong <jkhpro1003@gmail.com>, <steve.jeong@hardkernel.com>
|
||||||
*/
|
*/
|
||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
int wiringPiSetupSys (void)
|
int wiringPiSetupSys (void)
|
||||||
|
|||||||
@@ -102,6 +102,9 @@
|
|||||||
// Module names
|
// Module names
|
||||||
#define AML_MODULE_I2C "aml_i2c"
|
#define AML_MODULE_I2C "aml_i2c"
|
||||||
|
|
||||||
|
// syspwm
|
||||||
|
#define PWM_ACCESS_SCRIPT "/etc/odroid-wpi-pwm.sh"
|
||||||
|
|
||||||
// Threads
|
// Threads
|
||||||
#define PI_THREAD(X) void *X (UNU void *dummy)
|
#define PI_THREAD(X) void *X (UNU void *dummy)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user