From 0700508922a320928b824f8a55a254aedcc0e5ae Mon Sep 17 00:00:00 2001 From: Qubot <1445788683@qq.com> Date: Tue, 28 Nov 2023 16:40:56 +0800 Subject: [PATCH] update --- examples/pwm.c | 169 +++- gpio/gpio.c | 5 - gpio/readall.c | 66 +- wiringPi/wiringPi.c | 2083 ++++++++++++++++++++++++++++++++++++------- wiringPi/wiringPi.h | 669 +++++++++----- 5 files changed, 2397 insertions(+), 595 deletions(-) diff --git a/examples/pwm.c b/examples/pwm.c index bbee89d..35c29a1 100644 --- a/examples/pwm.c +++ b/examples/pwm.c @@ -1,8 +1,123 @@ -#include +#include #include #include #include +typedef struct { + unsigned int ccr; + unsigned int arr; + unsigned int div; + unsigned int div_stepping; +} pwm_info; + +static pwm_info pwm_info_t; + +static void set_pwm_info(int pin) +{ + int model; + + piBoardId (&model); + + switch (model) + { + case PI_MODEL_ZERO_2: + + if (pin != 3 && pin != 4 && pin != 21 && pin != 22) { + fprintf (stderr, "the pin you choose doesn't support hardware PWM\n") ; + exit(1); + } + + pwm_info_t.ccr = 512; + pwm_info_t.arr = 1024; + pwm_info_t.div = 1; + pwm_info_t.div_stepping = 1; + break; + + case PI_MODEL_ZERO_2_W: + + if (pin != 2 && pin != 9 && pin != 21 && pin != 22) { + fprintf (stderr, "the pin you choose doesn't support hardware PWM\n") ; + exit(1); + } + + pwm_info_t.ccr = 512; + pwm_info_t.arr = 1024; + pwm_info_t.div = 1; + pwm_info_t.div_stepping = 1; + break; + + case PI_MODEL_3_PLUS: + + if (pin != 2 && pin != 16) { + fprintf (stderr, "the pin you choose doesn't support hardware PWM\n") ; + exit(1); + } + + pwm_info_t.ccr = 500; + pwm_info_t.arr = 1000; + pwm_info_t.div = 120; + pwm_info_t.div_stepping = 1; + break; + + case PI_MODEL_5: + + if (pin != 0 && pin != 2 && pin != 5 && pin != 8 && pin != 9 && pin != 10 && pin != 14 && pin != 16) { + fprintf (stderr, "the pin you choose doesn't support hardware PWM\n") ; + exit(1); + } + + pwm_info_t.ccr = 500; + pwm_info_t.arr = 1000; + pwm_info_t.div = 120; + pwm_info_t.div_stepping = 2; + break; + + case PI_MODEL_5B: + + if (pin != 0 && pin != 2 && pin != 5 && pin != 8 && pin != 9 && pin != 10 && pin != 13 && pin != 15) { + fprintf (stderr, "the pin you choose doesn't support hardware PWM\n") ; + exit(1); + } + + pwm_info_t.ccr = 500; + pwm_info_t.arr = 1000; + pwm_info_t.div = 120; + pwm_info_t.div_stepping = 2; + break; + + case PI_MODEL_5_PLUS: + + if (pin != 0 && pin != 1 && pin != 2 && pin != 6 && pin != 9 && pin != 10 && pin != 13 && pin != 21 && pin != 22) { + fprintf (stderr, "the pin you choose doesn't support hardware PWM\n") ; + exit(1); + } + + pwm_info_t.ccr = 500; + pwm_info_t.arr = 1000; + pwm_info_t.div = 120; + pwm_info_t.div_stepping = 2; + break; + + case PI_MODEL_CM4: + case PI_MODEL_3B: + + if (pin != 2 && pin != 21) { + fprintf (stderr, "the pin you choose doesn't support hardware PWM\n") ; + exit(1); + } + + pwm_info_t.ccr = 500; + pwm_info_t.arr = 1000; + pwm_info_t.div = 120; + pwm_info_t.div_stepping = 2; + break; + + default: + printf("Oops - unable to determine board type..."); + exit(1); + } +} + int main(int argc, char *argv []) { int i = 0; @@ -16,39 +131,34 @@ int main(int argc, char *argv []) pin = (unsigned int)strtoul (argv [1], NULL, 10) ; - if (pin != 3 && pin != 4 && pin != 21 && pin != 22 && pin != 2 && pin != 9 ) { - fprintf (stderr, "the pin you choose doesn't support hardware PWM\n") ; - exit (1) ; - } - // 初始化 printf("wiringPiSetup start\n"); wiringPiSetup(); + set_pwm_info(pin); pinMode(pin,PWM_OUTPUT); printf("wiringPiSetup end\n"); // 开始测试 - while(1) - { - pwmSetRange(pin,1024); - pwmSetClock(pin,1); - pwmWrite(pin,512); + while(1) { + pwmSetRange(pin,pwm_info_t.arr); + pwmSetClock(pin,pwm_info_t.div); + pwmWrite(pin,pwm_info_t.ccr); //1. 调节PWM占空比 //1.1 通过设置ARR调节PWM占空比 printf("Modified ARR test start\n"); for (i = 0 ; i <= 8 ; i++) { - pwmSetRange(pin,1024+i*128); + pwmSetRange(pin,pwm_info_t.arr + i * (pwm_info_t.arr / 8)); delay(500); } delay(5000); for (i = 7 ; i >= 0 ; i-- ) { - pwmSetRange(pin,1024+i*128); + pwmSetRange(pin,pwm_info_t.arr + i * (pwm_info_t.arr / 8)); delay(500); } @@ -56,46 +166,38 @@ int main(int argc, char *argv []) printf("Modified ARR test end\n"); - pwmSetMode(pin,PWM_MODE_BAL); - delay(5000); - pwmSetMode(pin,PWM_MODE_MS); - - //1.2 通过设置CRR调节PWM占空比 - printf("Modified CRR test start\n"); + //1.2 通过设置CCR调节PWM占空比 + printf("Modified CCR test start\n"); for (i = 0 ; i <= 8 ; i++) { - pwmWrite(pin,512 + i*64); + pwmWrite(pin,pwm_info_t.ccr + i * (pwm_info_t.ccr / 8)); delay(500); } delay(5000); for (i = 7 ; i >= 0 ; i-- ) { - pwmWrite(pin,512 + i*64); + pwmWrite(pin,pwm_info_t.ccr + i * (pwm_info_t.ccr / 8)); delay(500); } delay(5000); - printf("Modified active range test end\n"); - - pwmSetMode(pin,PWM_MODE_BAL); - delay(5000); - pwmSetMode(pin,PWM_MODE_MS); + printf("Modified CCR test end\n"); //2.调节PWM频率 //2.1通过设置分频系数调节PWM频率 printf("Modified frequency division test start\n"); - for (i = 1 ; i <= 10; i++) { + for (i = pwm_info_t.div_stepping ; i <= 10 * pwm_info_t.div_stepping; i += pwm_info_t.div_stepping) { pwmSetClock(pin,i); delay(500); } delay(5000); - for (i = 9 ; i >= 1 ; i--) { + for (i = 9 * pwm_info_t.div_stepping; i >= pwm_info_t.div_stepping ; i -= pwm_info_t.div_stepping) { pwmSetClock(pin,i); delay(500); } @@ -104,25 +206,16 @@ int main(int argc, char *argv []) printf("Modified frequency division test end\n"); - pwmSetMode(pin,PWM_MODE_BAL); - delay(5000); - pwmSetMode(pin,PWM_MODE_MS); - //2.2 直接设置PWM频率 printf("Modified PWM frequency test start\n"); for (i = 1 ; i <= 10; i++) { - pwmToneWrite(pin,2000*i); + pwmToneWrite(pin,2000 * i); delay(2000); } delay(5000); printf("Modified PWM frequency test end\n"); - - pwmSetMode(pin,PWM_MODE_BAL); - delay(5000); - pwmSetMode(pin,PWM_MODE_MS); } - return 0; } diff --git a/gpio/gpio.c b/gpio/gpio.c index 42f0680..c057e90 100644 --- a/gpio/gpio.c +++ b/gpio/gpio.c @@ -1354,11 +1354,6 @@ static void doPwmClock (int argc, char *argv []) pin = (unsigned int)strtoul (argv [2], NULL, 10) ; clock = (unsigned int)strtoul (argv [3], NULL, 10) ; - if ((clock < 1) || (clock > 4095)) { - fprintf (stderr, "%s: clock must be between 0 and 4096\n", argv [0]) ; - exit (1) ; - } - pwmSetClock (pin,clock) ; } diff --git a/gpio/readall.c b/gpio/readall.c index d237cfc..7a855f7 100644 --- a/gpio/readall.c +++ b/gpio/readall.c @@ -1143,6 +1143,61 @@ static char * physNames_CM4[64] = " GND", "GPIO3_D1", }; +static int physToWpi_3PLUS[64] = +{ + -1, //0 + -1, -1, //1,2 + 0, -1, //3,4 + 1, -1, //5,6 + 2, 3, //7,8 + -1, 4, //9,10 + 5, 6, //11,12 + 7, -1, //13,14 + 8, 9, //15,16 + -1, 10, //17,18 + 11, -1, //19,20 + 12, 13, //21,22 + 14, 15, //23,24 + -1, 16, //25,26 + 17, 18, //27,28 + 19, -1, //29,30 + 20, 21, //31,32 + 22, -1, //33,34 + 23, 24, //35,36 + 25, 26, //37,38 + -1, 27, //39,40 + + // Padding: + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 56 + -1, -1, -1, -1, -1, -1, -1, // ... 63 +}; + +static char * physNames_3PLUS[64] = +{ + NULL, + " 3.3V", "5V ", + " SDA_M3", "5V ", + " SCL_M3", "GND ", + " PWM_F", "TXD_A ", + " GND", "RXD_A ", + " PAO7", "PA12 ", + " RXD_B", "GND ", + " TXD_B", "PH8 ", + " 3.3V", "PA3 ", + " MOSI_B", "GND ", + " MISO_B", "PAO5 ", + " SCLK_B", "SSO_B ", + " GND", "PWMAO_C ", + " SDA_M0", "SCL_M0 ", + " PA2", "GND ", + " PC7", "PA4 ", + " PAO10", "GND ", + " PA13", "PA0 ", + " PA7", "PA10 ", + " GND", "PA9 ", +}; + + static int * physToWpi; static char ** physNames; @@ -1470,7 +1525,12 @@ void OrangePiReadAll(int model) physNames = physNames_CM4; alts = alts_rk3588; break; - + case PI_MODEL_3_PLUS: + printf (" +------+-----+----------+--------+---+ PI3 PLUS +---+--------+----------+-----+------+\n"); + physToWpi = physToWpi_3PLUS; + physNames = physNames_3PLUS; + alts = alts_common; + break; default: printf ("Oops - unable to determine board type... model: %d\n", model); break ; @@ -1492,6 +1552,7 @@ void OrangePiReadAll(int model) case PI_MODEL_CM4: case PI_MODEL_3B: case PI_MODEL_ZERO_2_W: + case PI_MODEL_3_PLUS: for (pin = 1 ; pin <= 40; pin += 2) readallPhys(pin); break; @@ -1591,6 +1652,9 @@ void OrangePiReadAll(int model) case PI_MODEL_3B: printf (" +------+-----+----------+--------+---+ PI3B +---+--------+----------+-----+------+\n"); break; + case PI_MODEL_3_PLUS: + printf (" +------+-----+----------+--------+---+ PI3 PLUS +---+--------+----------+-----+------+\n"); + break; default: printf ("Oops - unable to determine board type... model: %d\n", model); break ; diff --git a/wiringPi/wiringPi.c b/wiringPi/wiringPi.c index d7ff6d5..7fa23a2 100644 --- a/wiringPi/wiringPi.c +++ b/wiringPi/wiringPi.c @@ -357,6 +357,26 @@ static int ORANGEPI_PIN_MASK_H3[9][32] = //[BANK] [INDEX] {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PI }; +static int ORANGEPI_PIN_MASK_3PLUS[16][32] = //[BANK] [INDEX] +{ + {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//31 + {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//63 + {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//95 + {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//127 + {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//159 + {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//191 + {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//223 + {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//255 + {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//287 + {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//319 + {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//351 + {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//383 + {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,28,29,30,31,},//415 + {-1, 1, 2, 3, 4, 5, 6,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,31,},//447 + { 0, 1, 2, 3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,27,28,-1,30,31,},//479 + { 0,-1,-1, 3,-1, 5, 6, 7, 8, 9,10,11,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//511 +}; + int (*ORANGEPI_PIN_MASK)[32]; // Extend wiringPi with other pin-based devices and keep track of @@ -524,6 +544,7 @@ rk3328_soc_info rk3328_soc_info_t; rk3399_soc_info rk3399_soc_info_t; rk3588_soc_info rk3588_soc_info_t; rk3566_soc_info rk3566_soc_info_t; +s905d3_gpio_info s905d3_gpio_info_t; // sysFds: // Map a file descriptor from the /sys/class/gpio/gpioX/value @@ -978,27 +999,49 @@ int pinToGpio_CM4[64] = int pinToGpio_R1_PLUS[64] = { - 89, 88, // 0, 1 - 100, 102, // 2, 3 - 112, 103, // 4 5 - 101, 66, // 6, 7 - -1, -1, // 8, 9 - -1, -1, //10,11 - -1, -1, //12,13 - -1, -1, //14,15 - -1, -1, //16,17 - -1, -1, //18,19 - -1, -1, //20,21 - -1, -1, //22,23 - -1, -1, //24,25 - -1, -1, //26,27 - -1, -1, //28,29 - -1, -1, //30,31 + 89, 88, // 0, 1 + 100, 102, // 2, 3 + 112, 103, // 4 5 + 101, 66, // 6, 7 + -1, -1, // 8, 9 + -1, -1, //10,11 + -1, -1, //12,13 + -1, -1, //14,15 + -1, -1, //16,17 + -1, -1, //18,19 + -1, -1, //20,21 + -1, -1, //22,23 + -1, -1, //24,25 + -1, -1, //26,27 + -1, -1, //28,29 + -1, -1, //30,31 - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 47 - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,// ... 63 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 47 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 63 }; +int pinToGpio_3PLUS[64] = +{ + 490, 491, // 0, 1 + 487, 412, // 2, 3 + 413, 419, // 4 5 + 488, 421, // 6, 7 + 420, 451, // 8, 9 + 479, 447, //10,11 + 448, 417, //12,13 + 450, 449, //14,15 + 418, 415, //16,17 + 414, 478, //18,19 + 475, 480, //20,21 + 422, 489, //22,23 + 476, 483, //24,25 + 486, 485, //26,27 + -1, -1, //28,29 + -1, -1, //30,31 + + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 47 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 63 +}; // physToGpio: // Take a physical pin (1 through 26) and re-map it to the GPIO pin @@ -1597,6 +1640,35 @@ int physToGpio_R1_PLUS[64] =//head num map to OrangePi -1, -1, -1, -1, -1, -1, -1, // ... 63 }; +int physToGpio_3PLUS[64] = +{ + -1, // 0 + -1, -1, // 1, 2 + 490, -1, // 3, 4 + 491, -1, // 5, 6 + 487, 412, // 7, 8 + -1, 413, // 9, 10 + 419, 488, // 11, 12 + 421, -1, // 13, 14 + 420, 451, // 15, 16 + -1, 479, // 17, 18 + 447, -1, // 19, 20 + 448, 417, // 21, 22 + 450, 449, // 23, 24 + -1, 418, // 25, 26 + 415, 414, // 27, 28 + 478, -1, // 29, 30 + 475, 480, // 31, 32 + 422, -1, // 33, 34 + 489, 476, // 35, 36 + 483, 486, // 37, 38 + -1, 485, // 39, 40 + + //Padding: + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 56 + -1, -1, -1, -1, -1, -1, -1, // ... 63 +}; + // gpioToGPFSEL: // Map a BCM_GPIO pin to it's Function Selection // control port. (GPFSEL 0-5) @@ -1926,24 +1998,24 @@ void piBoardId (int * model) if (wiringPiDebug) printf ("piBoardId: Board string: %s\n", revision) ; - /**/ if (strncmp(revision, "orangepi3.", 10) == 0) { *model = PI_MODEL_3; } - else if (strncmp(revision, "orangepi3-lts.", 14) == 0) { *model = PI_MODEL_3; } - else if (strncmp(revision, "orangepioneplus.", 16) == 0) { *model = PI_MODEL_LTIE_2; } + /**/ if (strncmp(revision, "orangepi3.", 10) == 0) { *model = PI_MODEL_3; } + else if (strncmp(revision, "orangepi3-lts.", 14) == 0) { *model = PI_MODEL_3; } + else if (strncmp(revision, "orangepioneplus.", 16) == 0) { *model = PI_MODEL_LTIE_2; } else if (strncmp(revision, "orangepilite2.", 14) == 0) { *model = PI_MODEL_LTIE_2; } - else if (strncmp(revision, "orangepizero.", 13) == 0) { *model = PI_MODEL_ZERO; } - else if (strncmp(revision, "orangepizerolts.", 16) == 0) { *model = PI_MODEL_ZERO; } - else if (strncmp(revision, "orangepizero-lts.", 17) == 0) { *model = PI_MODEL_ZERO; } - else if (strncmp(revision, "orangepir1.", 11) == 0) { *model = PI_MODEL_ZERO; } - else if (strncmp(revision, "orangepi-r1.", 12) == 0) { *model = PI_MODEL_ZERO; } - else if (strncmp(revision, "orangepipc.", 11) == 0) { *model = PI_MODEL_H3; } + else if (strncmp(revision, "orangepizero.", 13) == 0) { *model = PI_MODEL_ZERO; } + else if (strncmp(revision, "orangepizerolts.", 16) == 0) { *model = PI_MODEL_ZERO; } + else if (strncmp(revision, "orangepizero-lts.", 17) == 0) { *model = PI_MODEL_ZERO; } + else if (strncmp(revision, "orangepir1.", 11) == 0) { *model = PI_MODEL_ZERO; } + else if (strncmp(revision, "orangepi-r1.", 12) == 0) { *model = PI_MODEL_ZERO; } + else if (strncmp(revision, "orangepipc.", 11) == 0) { *model = PI_MODEL_H3; } else if (strncmp(revision, "orangepipcplus.", 15) == 0) { *model = PI_MODEL_H3; } - else if (strncmp(revision, "orangepione.", 12) == 0) { *model = PI_MODEL_H3; } - else if (strncmp(revision, "orangepilite.", 13) == 0) { *model = PI_MODEL_H3; } - else if (strncmp(revision, "orangepiplus.", 13) == 0) { *model = PI_MODEL_H3; } + else if (strncmp(revision, "orangepione.", 12) == 0) { *model = PI_MODEL_H3; } + else if (strncmp(revision, "orangepilite.", 13) == 0) { *model = PI_MODEL_H3; } + else if (strncmp(revision, "orangepiplus.", 13) == 0) { *model = PI_MODEL_H3; } else if (strncmp(revision, "orangepiplue2e.", 15) == 0) { *model = PI_MODEL_H3; } else if (strncmp(revision, "orangepizeroplus2h3.", 20) == 0) { *model = PI_MODEL_ZERO_PLUS_2; } else if (strncmp(revision, "orangepizeroplus2-h3.", 21) == 0) { *model = PI_MODEL_ZERO_PLUS_2; } - else if (strncmp(revision, "orangepiwin.", 12) == 0) { *model = PI_MODEL_WIN; } + else if (strncmp(revision, "orangepiwin.", 12) == 0) { *model = PI_MODEL_WIN; } else if (strncmp(revision, "orangepiwinplus.", 16) == 0) { *model = PI_MODEL_WIN; } else if (strncmp(revision, "orangepiprime.", 14) == 0) { *model = PI_MODEL_PRIME; } else if (strncmp(revision, "orangepipc2.", 12) == 0) { *model = PI_MODEL_PC_2; } @@ -1951,7 +2023,7 @@ void piBoardId (int * model) else if (strncmp(revision, "orangepizeroplus2h5.", 20) == 0) { *model = PI_MODEL_ZERO_PLUS_2; } else if (strncmp(revision, "orangepizeroplus2-h5.", 21) == 0) { *model = PI_MODEL_ZERO_PLUS_2; } else if (strncmp(revision, "orangepizero2.", 14) == 0) { *model = PI_MODEL_ZERO_2; } - else if (strncmp(revision, "orangepizero2w.", 14) == 0) { *model = PI_MODEL_ZERO_2_W; } + else if (strncmp(revision, "orangepizero2w.", 14) == 0) { *model = PI_MODEL_ZERO_2_W; } else if (strncmp(revision, "orangepizero3.", 14) == 0) { *model = PI_MODEL_ZERO_2; } else if (strncmp(revision, "orangepirk3399.", 15) == 0) { *model = PI_MODEL_RK3399; } else if (strncmp(revision, "orangepi-rk3399.", 16) == 0) { *model = PI_MODEL_RK3399; } @@ -1962,12 +2034,13 @@ void piBoardId (int * model) else if (strncmp(revision, "orangepi-r1plus.", 16) == 0) { *model = PI_MODEL_R1_PLUS; } else if (strncmp(revision, "orangepir1plus-lts.", 18) == 0) { *model = PI_MODEL_R1_PLUS; } else if (strncmp(revision, "orangepi-r1plus-lts.", 20) == 0) { *model = PI_MODEL_R1_PLUS; } - else if (strncmp(revision, "orangepi5.", 10) == 0) { *model = PI_MODEL_5; } - else if (strncmp(revision, "orangepi5b.", 11) == 0) { *model = PI_MODEL_5B; } - else if (strncmp(revision, "orangepi5plus.", 14) == 0) { *model = PI_MODEL_5_PLUS; } - else if (strncmp(revision, "orangepi900.", 12) == 0) { *model = PI_MODEL_900; } - else if (strncmp(revision, "orangepicm4.", 12) == 0) { *model = PI_MODEL_CM4; } - else if (strncmp(revision, "orangepi3b.", 11) == 0) { *model = PI_MODEL_3B; } + else if (strncmp(revision, "orangepi5.", 10) == 0) { *model = PI_MODEL_5; } + else if (strncmp(revision, "orangepi5b.", 11) == 0) { *model = PI_MODEL_5B; } + else if (strncmp(revision, "orangepi5plus.", 14) == 0) { *model = PI_MODEL_5_PLUS; } + else if (strncmp(revision, "orangepi900.", 12) == 0) { *model = PI_MODEL_900; } + else if (strncmp(revision, "orangepicm4.", 12) == 0) { *model = PI_MODEL_CM4; } + else if (strncmp(revision, "orangepi3b.", 11) == 0) { *model = PI_MODEL_3B; } + else if (strncmp(revision, "orangepi3plus.", 14) == 0) { *model = PI_MODEL_3_PLUS; } if (wiringPiDebug) printf("piBoardId: model = %d\n", *model); @@ -2107,27 +2180,55 @@ void sunxi_pwm_set_enable_v2(int en) void sunxi_pwm_set_enable(int en) { - int val = 0; + int val = 0; - if(SUNXI_PWM_TYPE == SUNXI_V2_PWM_TYPE) { - sunxi_pwm_set_enable_v2(en); - return; - } + switch (OrangePiModel) + { + case PI_MODEL_ZERO_2: + case PI_MODEL_ZERO_2_W: - val = readR(SUNXI_PWM_CTRL_REG); + if(SUNXI_PWM_TYPE == SUNXI_V2_PWM_TYPE) { + sunxi_pwm_set_enable_v2(en); + return; + } - if (en) { - val |= (SUNXI_PWM_EN | SUNXI_PWM_SCLK_GATING); - } else { - val &= ~(SUNXI_PWM_EN | SUNXI_PWM_SCLK_GATING); - } + val = readR(SUNXI_PWM_CTRL_REG); - if (wiringPiDebug) - printf(">>function%s,no:%d,enable? :0x%x\n", __func__, __LINE__, val); + if (en) { + val |= (SUNXI_PWM_EN | SUNXI_PWM_SCLK_GATING); + } else { + val &= ~(SUNXI_PWM_EN | SUNXI_PWM_SCLK_GATING); + } - writeR(val, SUNXI_PWM_CTRL_REG); - delay(1); - print_pwm_reg(); + if (wiringPiDebug) + printf(">>function%s,no:%d,enable? :0x%x\n", __func__, __LINE__, val); + + writeR(val, SUNXI_PWM_CTRL_REG); + delay(1); + print_pwm_reg(); + + break; + + case PI_MODEL_3_PLUS: + + val = readR(S905D3_PWM_MISC); + + if (en) { + val |= (1 << S905D3_PWM_EN_0 | 1 << S905D3_PWM_EN_1); + } else { + val &= ~(1 << S905D3_PWM_EN_0 | 1 << S905D3_PWM_EN_1); + } + + if (wiringPiDebug) + printf(">>function%s,no:%d,enable? :0x%x\n", __func__, __LINE__, val); + + writeR(val, S905D3_PWM_MISC); + + break; + + default: + break; + } } @@ -2155,6 +2256,161 @@ void sunxi_pwm_set_mode(int mode) print_pwm_reg(); } +void sunxi_pwm_set_tone(int pin,int freq) +{ + int div ; + unsigned int range ; + unsigned int val; + + if (wiringPiDebug) + printf(">>func:%s no:%d\n", __func__, __LINE__); + + switch (OrangePiModel) + { + case PI_MODEL_5: + case PI_MODEL_5B: + case PI_MODEL_5_PLUS: + + rk3588_set_pwm_reg(pin,&rk3588_soc_info_t); + + if (freq == 0) + sunxi_pwm_set_act (pin, 0); //Off + else { + //enable conlock + val = readR(RK3588_CH_CTRL); + val |= (1 << RK3588_CONLOCK); + writeR(val, RK3588_CH_CTRL); + delay(1); + val = readR(RK3588_CH_CTRL); + + //modifine tone + div = readR(RK3588_CH_CTRL); + div = ((div & 0x00ff0000) >> RK3588_SCALE); //The 16 ~ 23 bits determine the frequency division + div = 2 * div; //The actual frequency division value is (2 * div) + range = 24000000 / (div * freq); //The default pwm clock frequency is 24MHz + + if (range / 2 == 0) { + fprintf(stderr,"gpio: The PWM frequency you set is too high to be possible\n"); + exit(1); + } + + writeR(range,RK3588_CH_PERIOD_HPR); + delay(1); + writeR(range / 2,RK3588_CH_DUTY_LPR); + + //disable conlock + val = readR(RK3588_CH_CTRL); + val &= ~(1 << RK3588_CONLOCK); + writeR(val, RK3588_CH_CTRL); + delay(1); + val = readR(RK3588_CH_CTRL); + + if (wiringPiDebug) + printf("div:%d range:%d\n",div,range); + } + + break; + + case PI_MODEL_ZERO_2: + case PI_MODEL_ZERO_2_W: + + H618_set_pwm_reg(pin,&sunxi_gpio_info_t); + + if (freq == 0) + sunxi_pwm_set_act (pin, 0); // Off + else { + div = readR(SUNXI_PWM_CTRL_REG); + div &= 0x00ff; //The lower 8 bits determine the frequency division + div += 1; //The actual frequency division value is (div + 1) + range = 24000000 / (div * freq); //The default pwm clock frequency is 24MHz + + sunxi_pwm_set_period (pin,range); + sunxi_pwm_set_act (pin, range / 2); + + if (wiringPiDebug) + printf("div:%d range:%d\n",div,range); + } + + break; + + case PI_MODEL_3_PLUS: + + s905d3_set_gpio_reg(pin,&s905d3_gpio_info_t); + + if (freq == 0) + sunxi_pwm_set_act(pin, 0); // Off + else { + div = readR(S905D3_PWM_MISC); + div = ((div & 0x7f00) >> 8); //The 8~14 bits determine the frequency division + div += 1; //The actual frequency division value is (div + 1) + range = 24000000 / (div * freq); //The default pwm clock frequency is 24MHz + + if ((range / 2) == 0) { + fprintf(stderr,"gpio: The PWM frequency you set is too high to be possible\n"); + exit(1); + } + + val = readR(S905D3_PWM_DUTY_CYCLE); + val &= 0x0; + val = ((range/2) << 16) | (range/2); + + writeR(val,S905D3_PWM_DUTY_CYCLE); + val = readR(S905D3_PWM_DUTY_CYCLE); + + if (wiringPiDebug) + printf("div:%d range:%d val:%#x\n",div,range,val); + } + + break; + + case PI_MODEL_CM4: + case PI_MODEL_3B: + + rk3566_set_pwm_reg(pin,&rk3566_soc_info_t); + + if (freq == 0) + sunxi_pwm_set_act (pin, 0); //Off + else { + //enable conlock + val = readR(RK3566_CH_CTRL); + val |= (1 << RK3566_CONLOCK); + writeR(val, RK3566_CH_CTRL); + delay(1); + val = readR(RK3566_CH_CTRL); + + //modifine tone + div = readR(RK3566_CH_CTRL); + div = ((div & 0x00ff0000) >> RK3566_SCALE); //The 16 ~ 23 bits determine the frequency division + div = 2 * div; //The actual frequency division value is (2 * div) + range = 24000000 / (div * freq); //The default pwm clock frequency is 24MHz + + if (range / 2 == 0) { + fprintf(stderr,"gpio: The PWM frequency you set is too high to be possible\n"); + exit(1); + } + + writeR(range,RK3566_CH_PERIOD_HPR); + delay(1); + writeR(range / 2,RK3566_CH_DUTY_LPR); + + //disable conlock + val = readR(RK3566_CH_CTRL); + val &= ~(1 << RK3566_CONLOCK); + writeR(val, RK3566_CH_CTRL); + delay(1); + val = readR(RK3566_CH_CTRL); + + if (wiringPiDebug) + printf("div:%d range:%d\n",div,range); + } + + break; + + default: + break; + } +} + void sunxi_pwm_set_clk_v2(int clk) { int val = 0; @@ -2169,9 +2425,9 @@ void sunxi_pwm_set_clk_v2(int clk) printf("read reg val: 0x%x\n", val); //clear clk to 0 - clk = (clk - 1) < 0 ? 0 : (clk - 1) ; val &= 0x0f00; + clk = (clk - 1) < 0 ? 0 : (clk - 1); val |= (clk & 0xff); //todo check wether clk is invalid or not writeR(val, SUNXI_PWM_CTRL_REG); @@ -2185,37 +2441,170 @@ void sunxi_pwm_set_clk_v2(int clk) } -void sunxi_pwm_set_clk(int clk) +void sunxi_pwm_set_clk(int pin,int clk) { - int val = 0; + int val = 0; + int regval = 0; - if(SUNXI_PWM_TYPE == SUNXI_V2_PWM_TYPE) { - sunxi_pwm_set_clk_v2(clk); - return; - } + if (wiringPiDebug) + printf(">>func:%s no:%d\n", __func__, __LINE__); - if (wiringPiDebug) - printf(">>function%s,no:%d\n", __func__, __LINE__); + switch (OrangePiModel) + { + case PI_MODEL_5: + case PI_MODEL_5B: + case PI_MODEL_5_PLUS: - // sunxi_pwm_set_enable(0); - val = readR(SUNXI_PWM_CTRL_REG); + if ((clk < 2) || (clk > 512)) { + fprintf (stderr, "gpio: clock must be between 2 and 512\n") ; + exit (1) ; + } - if (wiringPiDebug) - printf("read reg val: 0x%x\n", val); + rk3588_set_pwm_reg(pin,&rk3588_soc_info_t); - //clear clk to 0 - val &= 0xf801f0; + if (clk == 512) + val = 0; + else + val = clk / 2; - val |= ((clk & 0xf) << 15); //todo check wether clk is invalid or not - writeR(val, SUNXI_PWM_CTRL_REG); + //enable conlock + regval = readR(RK3588_CH_CTRL); + regval |= (1 << RK3588_CONLOCK); + writeR(regval, RK3588_CH_CTRL); + delay(1); + regval = readR(RK3588_CH_CTRL); - sunxi_pwm_set_enable(1); + //modifine clk + regval = regval = readR(RK3588_CH_CTRL); + regval &= ~(0xff << RK3588_SCALE); + regval |= (val << RK3588_SCALE); + writeR(regval, RK3588_CH_CTRL); + delay(1); + regval = readR(RK3588_CH_CTRL); - if (wiringPiDebug) - printf(">>function%s,no:%d,clk? :0x%x\n", __func__, __LINE__, val); + //disable conlock + regval = readR(RK3588_CH_CTRL); + regval &= ~(1 << RK3588_CONLOCK); + writeR(regval, RK3588_CH_CTRL); + delay(1); + regval = readR(RK3588_CH_CTRL); - delay(1); - print_pwm_reg(); + break; + + case PI_MODEL_ZERO_2: + case PI_MODEL_ZERO_2_W: + + if ((clk < 1) || (clk > 256)) { + fprintf (stderr, "gpio: clock must be between 1 and 256\n") ; + exit (1) ; + } + + H618_set_pwm_reg(pin,&sunxi_gpio_info_t); + + if(SUNXI_PWM_TYPE == SUNXI_V2_PWM_TYPE) { + sunxi_pwm_set_clk_v2(clk); + return; + } + + if (wiringPiDebug) + printf(">>function%s,no:%d\n", __func__, __LINE__); + + // sunxi_pwm_set_enable(0); + val = readR(SUNXI_PWM_CTRL_REG); + + if (wiringPiDebug) + printf("read reg val: 0x%x\n", val); + + //clear clk to 0 + val &= 0xf801f0; + + val |= ((clk & 0xf) << 15); //todo check wether clk is invalid or not + writeR(val, SUNXI_PWM_CTRL_REG); + + sunxi_pwm_set_enable(1); + + if (wiringPiDebug) + printf(">>function%s,no:%d,clk? :0x%x\n", __func__, __LINE__, val); + + delay(1); + print_pwm_reg(); + + break; + + case PI_MODEL_3_PLUS: + + if ((clk < 1) || (clk > 128)) { + fprintf (stderr, "gpio: clock must be between 1 and 128\n") ; + exit (1) ; + } + + s905d3_set_gpio_reg(pin,&s905d3_gpio_info_t); + + if (wiringPiDebug) + printf(">>function%s,no:%d\n", __func__, __LINE__); + + sunxi_pwm_set_enable(0); + val = readR(S905D3_PWM_MISC); + + if (wiringPiDebug) + printf("read reg val: 0x%x\n", val); + + //clear clk to 0 + val &= ~(0x007f7f00); + + clk = (clk - 1) < 0 ? 0 : (clk - 1) ; + val = val | (clk << S905D3_PWM_CLK_DIV_0) | (clk << S905D3_PWM_CLK_DIV_1); + writeR(val, S905D3_PWM_MISC); + + sunxi_pwm_set_enable(1); + + if (wiringPiDebug) + printf(">>function%s,no:%d,clk? :0x%x\n", __func__, __LINE__, val); + + break; + + case PI_MODEL_CM4: + case PI_MODEL_3B: + + if ((clk < 2) || (clk > 512)) { + fprintf (stderr, "gpio: clock must be between 2 and 512\n") ; + exit (1) ; + } + + rk3566_set_pwm_reg(pin,&rk3566_soc_info_t); + + if (clk == 512) + val = 0; + else + val = clk / 2; + + //enable conlock + regval = readR(RK3566_CH_CTRL); + regval |= (1 << RK3566_CONLOCK); + writeR(regval, RK3566_CH_CTRL); + delay(1); + regval = readR(RK3566_CH_CTRL); + + //modifine clk + regval = regval = readR(RK3566_CH_CTRL); + regval &= ~(0xff << RK3566_SCALE); + regval |= (val << RK3566_SCALE); + writeR(regval, RK3566_CH_CTRL); + delay(1); + regval = readR(RK3566_CH_CTRL); + + //disable conlock + regval = readR(RK3566_CH_CTRL); + regval &= ~(1 << RK3566_CONLOCK); + writeR(regval, RK3566_CH_CTRL); + delay(1); + regval = readR(RK3566_CH_CTRL); + + break; + + default: + break; + } } /** @@ -2254,59 +2643,293 @@ int sunxi_pwm_get_act(void) return period_act; } -void sunxi_pwm_set_period(int period_cys) +void sunxi_pwm_set_period(int pin,unsigned int period_cys) { - uint32_t val = 0; + uint32_t val = 0; + uint32_t ccr = 0; - if (wiringPiDebug) - printf(">>func:%s no:%d\n", __func__, __LINE__); + if (wiringPiDebug) + printf(">>func:%s no:%d\n", __func__, __LINE__); - period_cys -= 1; - period_cys &= 0xffff; //set max period to 2^16 - period_cys = period_cys << 16; - val = readR(SUNXI_PWM_PERIOD); + switch (OrangePiModel) + { + case PI_MODEL_5: + case PI_MODEL_5B: + case PI_MODEL_5_PLUS: - if (wiringPiDebug) - printf("read reg val: 0x%x\n", val); + rk3588_set_pwm_reg(pin,&rk3588_soc_info_t); - val &= 0x0000ffff; - period_cys |= val; + ccr = readR(RK3588_CH_DUTY_LPR); - if (wiringPiDebug) - printf("write reg val: 0x%x\n", period_cys); + if (period_cys < ccr) { + fprintf (stderr, "gpio: ARR should be greater than or equal to CCR (%d)\n",ccr); + exit(1); + } - writeR(period_cys, SUNXI_PWM_PERIOD); - delay(1); - val = readR(SUNXI_PWM_PERIOD); + //enable conlock + val = readR(RK3588_CH_CTRL); + val |= (1 << RK3588_CONLOCK); + writeR(val, RK3588_CH_CTRL); + delay(1); + val = readR(RK3588_CH_CTRL); - if (wiringPiDebug) - printf("readback reg val: 0x%x\n", val); + //modifine period + writeR(period_cys, RK3588_CH_PERIOD_HPR); + delay(1); + val = readR(RK3588_CH_PERIOD_HPR); - print_pwm_reg(); + //disable conlock + val = readR(RK3588_CH_CTRL); + val &= ~(1 << RK3588_CONLOCK); + writeR(val, RK3588_CH_CTRL); + delay(1); + val = readR(RK3588_CH_CTRL); + + break; + + case PI_MODEL_ZERO_2: + case PI_MODEL_ZERO_2_W: + + if ((period_cys < 1) || (period_cys > 65536)) { + fprintf (stderr, "gpio: range must be between 1 and 65536\n") ; + exit (1) ; + } + + H618_set_pwm_reg(pin,&sunxi_gpio_info_t); + + period_cys -= 1; + period_cys &= 0xffff; //set max period to 2^16 + period_cys = period_cys << 16; + val = readR(SUNXI_PWM_PERIOD); + + if (wiringPiDebug) + printf("read reg val: 0x%x\n", val); + + val &= 0x0000ffff; + period_cys |= val; + + if (wiringPiDebug) + printf("write reg val: 0x%x\n", period_cys); + + writeR(period_cys, SUNXI_PWM_PERIOD); + delay(1); + val = readR(SUNXI_PWM_PERIOD); + + if (wiringPiDebug) + printf("readback reg val: 0x%x\n", val); + + print_pwm_reg(); + + break; + + case PI_MODEL_3_PLUS: + + s905d3_set_gpio_reg(pin,&s905d3_gpio_info_t); + + ccr = readR(S905D3_PWM_DUTY_CYCLE); + + if (wiringPiDebug) + printf("read reg val: 0x%x\n", ccr); + + ccr = ccr >> 16; + + if (period_cys < ccr) { + fprintf (stderr, "gpio: ARR should be greater than or equal to CCR (%d)\n",ccr) ; + exit(1); + } + + val = (ccr << 16) | (period_cys - ccr); + writeR(val,S905D3_PWM_DUTY_CYCLE); + val = readR(S905D3_PWM_DUTY_CYCLE); + + if (wiringPiDebug) + printf("readback reg val: 0x%x\n", val); + + break; + + case PI_MODEL_CM4: + case PI_MODEL_3B: + + rk3566_set_pwm_reg(pin,&rk3566_soc_info_t); + + ccr = readR(RK3566_CH_DUTY_LPR); + + if (period_cys < ccr) { + fprintf (stderr, "gpio: ARR should be greater than or equal to CCR (%d)\n",ccr); + exit(1); + } + + //enable conlock + val = readR(RK3566_CH_CTRL); + val |= (1 << RK3566_CONLOCK); + writeR(val, RK3566_CH_CTRL); + delay(1); + val = readR(RK3566_CH_CTRL); + + //modifine period + writeR(period_cys, RK3566_CH_PERIOD_HPR); + delay(1); + val = readR(RK3566_CH_PERIOD_HPR); + + //disable conlock + val = readR(RK3566_CH_CTRL); + val &= ~(1 << RK3566_CONLOCK); + writeR(val, RK3566_CH_CTRL); + delay(1); + val = readR(RK3566_CH_CTRL); + + break; + + default: + break; + } } -void sunxi_pwm_set_act(int act_cys) +void sunxi_pwm_set_act(int pin,int act_cys) { - uint32_t per0 = 0; + uint32_t per0 = 0; + uint32_t arr = 0; - //keep period the same, clear act_cys to 0 first - if (wiringPiDebug) - printf(">>func:%s no:%d\n", __func__, __LINE__); - per0 = readR(SUNXI_PWM_PERIOD); + switch (OrangePiModel) + { + case PI_MODEL_5: + case PI_MODEL_5B: + case PI_MODEL_5_PLUS: - if (wiringPiDebug) - printf("read reg val: 0x%x\n", per0); + rk3588_set_pwm_reg(pin,&rk3588_soc_info_t); - per0 &= 0xffff0000; - act_cys &= 0xffff; - act_cys |= per0; + arr = readR(RK3588_CH_PERIOD_HPR); - if (wiringPiDebug) - printf("write reg val: 0x%x\n", act_cys); + if ((unsigned int)act_cys > arr) { + fprintf (stderr, "gpio: CCR should be less than or equal to ARR (%d)\n",arr) ; + exit(1); + } - writeR(act_cys, SUNXI_PWM_PERIOD); - delay(1); - print_pwm_reg(); + //enable conlock + per0 = readR(RK3588_CH_CTRL); + per0 |= (1 << RK3588_CONLOCK); + writeR(per0, RK3588_CH_CTRL); + delay(1); + per0 = readR(RK3588_CH_CTRL); + + //modifine act + writeR(act_cys, RK3588_CH_DUTY_LPR); + delay(1); + per0 = readR(RK3588_CH_DUTY_LPR); + + //disable conlock + per0 = readR(RK3588_CH_CTRL); + per0 &= ~(1 << RK3588_CONLOCK); + writeR(per0, RK3588_CH_CTRL); + delay(1); + per0 = readR(RK3588_CH_CTRL); + + break; + + case PI_MODEL_ZERO_2: + case PI_MODEL_ZERO_2_W: + + if ((act_cys < 0) || (act_cys > 65535)) { + fprintf (stderr, "gpio: range must be between 0 and 65535\n"); + exit (1) ; + } + + H618_set_pwm_reg(pin,&sunxi_gpio_info_t); + + arr = sunxi_pwm_get_period(); + + if (wiringPiDebug) + printf("==> no:%d period now is :%d,act_val to be set:%d\n", __LINE__, arr, act_cys); + + if ((uint32_t)act_cys > (arr+1)) { + printf("val pwmWrite 0 <= X <= 1024\n"); + printf("Or you can set new range by yourself by pwmSetRange(range)\n"); + return; + } + + //keep period the same, clear act_cys to 0 first + if (wiringPiDebug) + printf(">>func:%s no:%d\n", __func__, __LINE__); + per0 = readR(SUNXI_PWM_PERIOD); + + if (wiringPiDebug) + printf("read reg val: 0x%x\n", per0); + + per0 &= 0xffff0000; + act_cys &= 0xffff; + act_cys |= per0; + + if (wiringPiDebug) + printf("write reg val: 0x%x\n", act_cys); + + writeR(act_cys, SUNXI_PWM_PERIOD); + delay(1); + print_pwm_reg(); + + break; + + case PI_MODEL_3_PLUS: + + if (wiringPiDebug) + printf(">>func:%s no:%d\n", __func__, __LINE__); + + s905d3_set_gpio_reg(pin,&s905d3_gpio_info_t); + + per0 = readR(S905D3_PWM_DUTY_CYCLE); + + if (wiringPiDebug) + printf("read reg val: 0x%x\n", per0); + + arr = ((per0 & 0xffff0000) >> 16) + (per0 & 0x0000ffff); + + if ((unsigned int)act_cys > arr) { + fprintf (stderr, "gpio: CCR should be less than or equal to ARR (%d)\n",arr) ; + exit(1); + } else { + per0 = arr - act_cys; + act_cys &= 0xffff; + act_cys = ((act_cys << 16) | per0); + writeR(act_cys, S905D3_PWM_DUTY_CYCLE); + } + + break; + + case PI_MODEL_CM4: + case PI_MODEL_3B: + + rk3566_set_pwm_reg(pin,&rk3566_soc_info_t); + + arr = readR(RK3566_CH_PERIOD_HPR); + + if ((unsigned int)act_cys > arr) { + fprintf (stderr, "gpio: CCR should be less than or equal to ARR (%d)\n",arr) ; + exit(1); + } + + //enable conlock + per0 = readR(RK3566_CH_CTRL); + per0 |= (1 << RK3566_CONLOCK); + writeR(per0, RK3566_CH_CTRL); + delay(1); + per0 = readR(RK3566_CH_CTRL); + + //modifine act + writeR(act_cys, RK3566_CH_DUTY_LPR); + delay(1); + per0 = readR(RK3566_CH_DUTY_LPR); + + //disable conlock + per0 = readR(RK3566_CH_CTRL); + per0 &= ~(1 << RK3566_CONLOCK); + writeR(per0, RK3566_CH_CTRL); + delay(1); + per0 = readR(RK3566_CH_CTRL); + + break; + + default: + break; + } } @@ -2335,17 +2958,22 @@ void pwmSetMode(int pin,int mode) void pwmSetRange(int pin,unsigned int range) { - if (OrangePiModel == PI_MODEL_ZERO_2 || OrangePiModel == PI_MODEL_ZERO_2_W) { - if ((range < 1) || (range > 65536)) { - fprintf (stderr, "gpio: range must be between 1 and 65536\n") ; - exit (1) ; - } else { - H618_set_pwm_reg(pin,&sunxi_gpio_info_t); - } - } + if ((pin & PI_GPIO_MASK) == 0) { + if (wiringPiMode == WPI_MODE_PINS) + pin = pinToGpio[pin]; + else if (wiringPiMode == WPI_MODE_PHYS) + pin = physToGpio[pin]; + else if (wiringPiMode != WPI_MODE_GPIO) + return; + } - sunxi_pwm_set_period(range); - return; + if (-1 == pin) { + printf("[%s:L%d] the pin:%d is invaild,please check it over!\n", __func__, __LINE__, pin); + return; + } + + sunxi_pwm_set_period(pin,range); + return; } /* @@ -2358,18 +2986,22 @@ void pwmSetRange(int pin,unsigned int range) void pwmSetClock(int pin,int divisor) { - if (OrangePiModel == PI_MODEL_ZERO_2 || OrangePiModel == PI_MODEL_ZERO_2_W) { - if ((divisor < 1) || (divisor > 256)) { - fprintf (stderr, "gpio: clock must be between 1 and 256\n") ; - exit (1) ; - } else { - H618_set_pwm_reg(pin,&sunxi_gpio_info_t); - } - } + if ((pin & PI_GPIO_MASK) == 0) { + if (wiringPiMode == WPI_MODE_PINS) + pin = pinToGpio[pin]; + else if (wiringPiMode == WPI_MODE_PHYS) + pin = physToGpio[pin]; + else if (wiringPiMode != WPI_MODE_GPIO) + return; + } - sunxi_pwm_set_clk(divisor); - sunxi_pwm_set_enable(1); - return; + if (-1 == pin) { + printf("[%s:L%d] the pin:%d is invaild,please check it over!\n", __func__, __LINE__, pin); + return; + } + + sunxi_pwm_set_clk(pin,divisor); + return; } /* @@ -2577,19 +3209,13 @@ void pinModeAlt (int pin, int mode) */ void pinMode (int pin, int mode) { - int fSel, shift, alt ; struct wiringPiNodeStruct *node = wiringPiNodes ; - int origPin = pin ; setupCheck ("pinMode") ; if (wiringPiDebug) printf("PinMode: pin:%d,mode:%d\n", pin, mode); - if (OrangePiModel == PI_MODEL_ZERO_2 || OrangePiModel == PI_MODEL_ZERO_2_W) { - H618_set_pwm_reg(pin,&sunxi_gpio_info_t); - } - if ((pin & PI_GPIO_MASK) == 0) { if (wiringPiMode == WPI_MODE_PINS) { pin = pinToGpio[pin]; @@ -2613,21 +3239,7 @@ void pinMode (int pin, int mode) return ; } else if (mode == PWM_OUTPUT) { - if (wiringPiDebug) - printf("OPI: try wiringPi pin %d for PWM pin\n", pin); - if (pin != 5 && pin != 224 && pin != 225 && pin != 226 && pin!= 227 && pin != 267 && pin != 268 && pin != 269 && pin != 270) { - printf("the pin you choose doesn't support hardware PWM\n"); - if (OrangePiModel == PI_MODEL_ZERO_2) - printf("OPI:you can select wiringPi pin 224,225,226,227 for PWM pin\n"); - else if (OrangePiModel == PI_MODEL_ZERO_2_W) - printf("OPI:you can select wiringPi pin 267,268,269,270 for PWM pin\n"); - else - printf("you can select wiringPi pin %d for PWM pin\n", 42); - printf("or you can use it in softPwm mode\n"); - return; - } - else - OrangePi_set_gpio_mode(pin, PWM_OUTPUT); + OrangePi_set_gpio_mode(pin, PWM_OUTPUT); return; } else @@ -2839,81 +3451,46 @@ void digitalWrite8 (int pin, int value) */ void pwmWrite(int pin, int value) { - struct wiringPiNodeStruct *node = wiringPiNodes; + struct wiringPiNodeStruct *node = wiringPiNodes; - if (pinToGpio == 0 || physToGpio == 0) { - printf("please call wiringPiSetup first.\n"); - return; - } + if (pinToGpio == 0 || physToGpio == 0) { + printf("please call wiringPiSetup first.\n"); + return; + } - int a_val = 0; + if (pwmmode == 1) { + sunxi_pwm_set_mode(1); + } else { + sunxi_pwm_set_mode(0); + } - if (OrangePiModel == PI_MODEL_ZERO_2 || OrangePiModel == PI_MODEL_ZERO_2_W) { - if ((value < 0) || (value > 65535)) { - fprintf (stderr, "gpio: range must be between 0 and 65535\n") ; - exit (1) ; - } else { - H618_set_pwm_reg(pin,&sunxi_gpio_info_t); - } - } + // On-Board Pin needto fix me Jim + if (pin < MAX_PIN_NUM) { + if (wiringPiMode == WPI_MODE_PINS) + pin = pinToGpio [pin]; + else if (wiringPiMode == WPI_MODE_PHYS) + pin = physToGpio[pin]; + else if (wiringPiMode != WPI_MODE_GPIO) + return; - if (pwmmode == 1) - { - sunxi_pwm_set_mode(1); - } else { - sunxi_pwm_set_mode(0); - } + if (-1 == pin) { + printf("[%s:L%d] the pin:%d is invaild,please check it over!\n", __func__, __LINE__, pin); + return; + } + sunxi_pwm_set_act(pin,value); + } else { + printf("not on board :%s,%d\n", __func__, __LINE__); + if ((node = wiringPiFindNode(pin)) != NULL) { + if (wiringPiDebug) + printf("Jim find node%s,%d\n", __func__, __LINE__); + node->digitalWrite(node, pin, value); + } + } - if (pin < MAX_PIN_NUM) // On-Board Pin needto fix me Jim - { - if (wiringPiMode == WPI_MODE_PINS) - pin = pinToGpio [pin]; - else if (wiringPiMode == WPI_MODE_PHYS) { - pin = physToGpio[pin]; - } else if (wiringPiMode != WPI_MODE_GPIO) - return; - - if (-1 == pin) { - printf("[%s:L%d] the pin:%d is invaild,please check it over!\n", __func__, __LINE__, pin); - return; - } - - if (wiringPiDebug) - printf("OPI: check pwm pin(%d)\n",pin); - - if (pin != 5 && pin != 224 && pin != 225 && pin != 226 && pin != 227 && pin != 267 && pin != 268 && pin != 269 && pin != 270) { - printf("please use soft pwmmode or choose PWM pin\n"); - return; - } - - a_val = sunxi_pwm_get_period(); - - if (wiringPiDebug) - printf("==> no:%d period now is :%d,act_val to be set:%d\n", __LINE__, a_val, value); - - if (value > (a_val+1)) { - printf("val pwmWrite 0 <= X <= 1024\n"); - printf("Or you can set new range by yourself by pwmSetRange(range)\n"); - return; - } - - //if value changed chang it - sunxi_pwm_set_enable(0); - sunxi_pwm_set_act(value); - sunxi_pwm_set_enable(1); - } else { - printf("not on board :%s,%d\n", __func__, __LINE__); - if ((node = wiringPiFindNode(pin)) != NULL) { - if (wiringPiDebug) - printf("Jim find node%s,%d\n", __func__, __LINE__); - node->digitalWrite(node, pin, value); - } - } - - if (wiringPiDebug) - printf("this fun is ok now %s,%d\n", __func__, __LINE__); + if (wiringPiDebug) + printf("this fun is ok now %s,%d\n", __func__, __LINE__); - return; + return; } /* @@ -2963,30 +3540,25 @@ void analogWrite (int pin, int value) void pwmToneWrite (int pin, int freq) { - int range ; - int div ; + if ((pin & PI_GPIO_MASK) == 0) { + if (wiringPiMode == WPI_MODE_PINS) + pin = pinToGpio[pin]; + else if (wiringPiMode == WPI_MODE_PHYS) + pin = physToGpio[pin]; + else if (wiringPiMode != WPI_MODE_GPIO) + return; + } - setupCheck ("pwmToneWrite") ; + if (-1 == pin) { + printf("[%s:L%d] the pin:%d is invaild,please check it over!\n", __func__, __LINE__, pin); + return; + } - if (OrangePiModel == PI_MODEL_ZERO_2 || OrangePiModel == PI_MODEL_ZERO_2_W) { - H618_set_pwm_reg(pin,&sunxi_gpio_info_t); - } - - if (freq == 0) - pwmWrite (pin, 0) ; // Off - else { - div = readR(SUNXI_PWM_CTRL_REG); - div &= 0x00ff; //The lower 8 bits determine the frequency division - div += 1; //The actual frequency division value is (div + 1) - range = 24000000 / (div * freq) ; //The default pwm clock frequency is 24MHz - - pwmSetRange (pin,range) ; - pwmWrite (pin, range / 2) ; - } + sunxi_pwm_set_tone(pin,freq); + return; } - /* * digitalWriteByte: * digitalReadByte: @@ -3628,6 +4200,11 @@ int wiringPiSetup (void) physToGpio = physToGpio_CM4; ORANGEPI_PIN_MASK = ORANGEPI_PIN_MASK_CM4; break; + case PI_MODEL_3_PLUS: + pinToGpio = pinToGpio_3PLUS; + physToGpio = physToGpio_3PLUS; + ORANGEPI_PIN_MASK = ORANGEPI_PIN_MASK_3PLUS; + break; default: printf ("Oops - unable to determine board type... model: %d\n", OrangePiModel); break ; @@ -3780,6 +4357,22 @@ int wiringPiSetup (void) if ((int32_t)(unsigned long)rk3588_soc_info_t.pmu1cur_base == -1) return wiringPiFailure(WPI_ALMOST, "wiringPiSetup: mmap (RK3588_VCCIO6_IOC_BASE) failed: %s\n", strerror(errno)); + rk3588_soc_info_t.pwm0_base = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, RK3588_PWM0_BASE); + if ((int32_t)(unsigned long)rk3588_soc_info_t.pwm0_base == -1) + return wiringPiFailure(WPI_ALMOST, "wiringPiSetup: mmap (RK3588_PWM0_BASE) failed: %s\n", strerror(errno)); + + rk3588_soc_info_t.pwm1_base = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, RK3588_PWM1_BASE); + if ((int32_t)(unsigned long)rk3588_soc_info_t.pwm1_base == -1) + return wiringPiFailure(WPI_ALMOST, "wiringPiSetup: mmap (RK3588_PWM1_BASE) failed: %s\n", strerror(errno)); + + rk3588_soc_info_t.pwm2_base = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, RK3588_PWM2_BASE); + if ((int32_t)(unsigned long)rk3588_soc_info_t.pwm2_base == -1) + return wiringPiFailure(WPI_ALMOST, "wiringPiSetup: mmap (RK3588_PWM2_BASE) failed: %s\n", strerror(errno)); + + rk3588_soc_info_t.pwm3_base = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, RK3588_PWM3_BASE); + if ((int32_t)(unsigned long)rk3588_soc_info_t.pwm3_base == -1) + return wiringPiFailure(WPI_ALMOST, "wiringPiSetup: mmap (RK3588_PWM3_BASE) failed: %s\n", strerror(errno)); + break; case PI_MODEL_CM4: @@ -3821,6 +4414,35 @@ int wiringPiSetup (void) rk3566_soc_info_t.pmu_cru_base = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, RK3566_PMU_CRU_BASE); if ((int32_t)(unsigned long)rk3566_soc_info_t.pmu_cru_base == -1) return wiringPiFailure(WPI_ALMOST, "wiringPiSetup: mmap (RK3566_PMU_CRU_BASE) failed: %s\n", strerror(errno)); + + rk3566_soc_info_t.pwm2_base = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, RK3566_PWM2_BASE); + if ((int32_t)(unsigned long)rk3566_soc_info_t.pwm2_base == -1) + return wiringPiFailure(WPI_ALMOST, "wiringPiSetup: mmap (RK3566_PWM2_BASE) failed: %s\n", strerror(errno)); + + rk3566_soc_info_t.pwm3_base = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, RK3566_PWM3_BASE); + if ((int32_t)(unsigned long)rk3566_soc_info_t.pwm3_base == -1) + return wiringPiFailure(WPI_ALMOST, "wiringPiSetup: mmap (RK3566_PWM3_BASE) failed: %s\n", strerror(errno)); + break; + + case PI_MODEL_3_PLUS: + + /* GPIO Register */ + s905d3_gpio_info_t.gpio_base = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, S905D3_GPIO_BASE); + if ((int32_t)(unsigned long)s905d3_gpio_info_t.gpio_base == -1) + return wiringPiFailure(WPI_ALMOST, "wiringPiSetup: mmap (S905D3_GPIO_BASE) failed: %s\n", strerror(errno)); + + s905d3_gpio_info_t.gpio_ao_base = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, S905D3_GPIO_AO_BASE); + if ((int32_t)(unsigned long)s905d3_gpio_info_t.gpio_ao_base == -1) + return wiringPiFailure(WPI_ALMOST, "wiringPiSetup: mmap (S905D3_AO_GPIO_BASE) failed: %s\n", strerror(errno)); + + /* PWM Register */ + s905d3_gpio_info_t.gpio_pwm_base = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, S905D3_GPIO_PWM_BASE); + if ((int32_t)(unsigned long)s905d3_gpio_info_t.gpio_pwm_base == -1) + return wiringPiFailure(WPI_ALMOST, "wiringPiSetup: mmap (S905D3_GPIO_PWM_BASE) failed: %s\n", strerror(errno)); + + s905d3_gpio_info_t.gpio_pwm_ao_base = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, S905D3_GPIO_PWM_AO_BASE); + if ((int32_t)(unsigned long)s905d3_gpio_info_t.gpio_pwm_ao_base == -1) + return wiringPiFailure(WPI_ALMOST, "wiringPiSetup: mmap (S905D3_GPIO_PWM_AO_BASE) failed: %s\n", strerror(errno)); break; default: @@ -4039,8 +4661,19 @@ unsigned int readR(unsigned int addr) val = *((unsigned int *)((unsigned char *)rk3588_soc_info_t.vccio3_5_ioc_base + mmap_seek)); else if(mmap_base == RK3588_VCCIO6_IOC_BASE) val = *((unsigned int *)((unsigned char *)rk3588_soc_info_t.vccio6_ioc_base + mmap_seek)); + else if(mmap_base == RK3588_PWM0_BASE) + val = *((unsigned int *)((unsigned char *)rk3588_soc_info_t.pwm0_base + mmap_seek)); + else if(mmap_base == RK3588_PWM1_BASE) + val = *((unsigned int *)((unsigned char *)rk3588_soc_info_t.pwm1_base + mmap_seek)); + else if(mmap_base == RK3588_PWM2_BASE) + val = *((unsigned int *)((unsigned char *)rk3588_soc_info_t.pwm2_base + mmap_seek)); + else if(mmap_base == RK3588_PWM3_BASE) + val = *((unsigned int *)((unsigned char *)rk3588_soc_info_t.pwm3_base + mmap_seek)); + if (wiringPiDebug) + printf("read %#x from [%#x]\n",val,addr); return val; + break; case PI_MODEL_800: case PI_MODEL_4_LTS: @@ -4114,6 +4747,34 @@ unsigned int readR(unsigned int addr) val = *((unsigned int *)((unsigned char *)rk3566_soc_info_t.cru_base + mmap_seek)); else if(mmap_base == RK3566_PMU_CRU_BASE) val = *((unsigned int *)((unsigned char *)rk3566_soc_info_t.pmu_cru_base + mmap_seek)); + else if(mmap_base == RK3566_PWM2_BASE) + val = *((unsigned int *)((unsigned char *)rk3566_soc_info_t.pwm2_base + mmap_seek)); + else if(mmap_base == RK3566_PWM3_BASE) + val = *((unsigned int *)((unsigned char *)rk3566_soc_info_t.pwm3_base + mmap_seek)); + + if (wiringPiDebug) + printf("read %#x from [%#x]\n",val,addr); + + return val; + + break; + + case PI_MODEL_3_PLUS: + + val = 0; + + mmap_base = (addr & 0xfffff000); + mmap_seek = (addr - mmap_base); + + if (mmap_base == S905D3_GPIO_BASE) + val = *(s905d3_gpio_info_t.gpio_base + mmap_seek); + else if (mmap_base == S905D3_GPIO_AO_BASE) + val = *(s905d3_gpio_info_t.gpio_ao_base + mmap_seek); + else if (mmap_base == S905D3_GPIO_PWM_BASE) + val = *(s905d3_gpio_info_t.gpio_pwm_base + mmap_seek); + else if (mmap_base == S905D3_GPIO_PWM_AO_BASE) + val = *(s905d3_gpio_info_t.gpio_pwm_ao_base + mmap_seek); + return val; break; @@ -4187,6 +4848,17 @@ void writeR(unsigned int val, unsigned int addr) *((unsigned int *)((unsigned char *)rk3588_soc_info_t.vccio3_5_ioc_base + mmap_seek)) = val; else if(mmap_base == RK3588_VCCIO6_IOC_BASE) *((unsigned int *)((unsigned char *)rk3588_soc_info_t.vccio6_ioc_base + mmap_seek)) = val; + else if(mmap_base == RK3588_PWM0_BASE) + *((unsigned int *)((unsigned char *)rk3588_soc_info_t.pwm0_base + mmap_seek)) = val; + else if(mmap_base == RK3588_PWM1_BASE) + *((unsigned int *)((unsigned char *)rk3588_soc_info_t.pwm1_base + mmap_seek)) = val; + else if(mmap_base == RK3588_PWM2_BASE) + *((unsigned int *)((unsigned char *)rk3588_soc_info_t.pwm2_base + mmap_seek)) = val; + else if(mmap_base == RK3588_PWM3_BASE) + *((unsigned int *)((unsigned char *)rk3588_soc_info_t.pwm3_base + mmap_seek)) = val; + + if (wiringPiDebug) + printf("write %#x to [%#x]\n",val,addr); break; @@ -4252,6 +4924,31 @@ void writeR(unsigned int val, unsigned int addr) *((unsigned int *)((unsigned char *)rk3566_soc_info_t.cru_base + mmap_seek)) = val; else if(mmap_base == RK3566_PMU_CRU_BASE) *((unsigned int *)((unsigned char *)rk3566_soc_info_t.pmu_cru_base + mmap_seek)) = val; + else if(mmap_base == RK3566_PWM2_BASE) + *((unsigned int *)((unsigned char *)rk3566_soc_info_t.pwm2_base + mmap_seek)) = val; + else if(mmap_base == RK3566_PWM3_BASE) + *((unsigned int *)((unsigned char *)rk3566_soc_info_t.pwm3_base + mmap_seek)) = val; + + if (wiringPiDebug) + printf("write %#x to [%#x]\n",val,addr); + + break; + + case PI_MODEL_3_PLUS: + + mmap_base = (addr & 0xfffff000); + mmap_seek = (addr - mmap_base); + + if (mmap_base == S905D3_GPIO_BASE) { + *(s905d3_gpio_info_t.gpio_base + mmap_seek) = val; + } else if (mmap_base == S905D3_GPIO_AO_BASE) { + *(s905d3_gpio_info_t.gpio_ao_base + mmap_seek) = val; + } else if (mmap_base == S905D3_GPIO_PWM_BASE) { + *(s905d3_gpio_info_t.gpio_pwm_base + mmap_seek) = val; + } else if (mmap_base == S905D3_GPIO_PWM_AO_BASE) { + *(s905d3_gpio_info_t.gpio_pwm_ao_base + mmap_seek) = val; + } + break; default: @@ -4445,6 +5142,22 @@ int OrangePi_get_gpio_mode(int pin) } break; + case PI_MODEL_3_PLUS: + + s905d3_set_gpio_reg(pin,&s905d3_gpio_info_t); + + if (ORANGEPI_PIN_MASK[bank][index] != -1) { + regval = readR(S905D3_GPIO_MUX); + mode = (regval >> S905D3_GPIO_MUX_OFFSET) & 0x7; + + if(mode == 0){ //如果是gpio模式 + regval = readR(S905D3_GPIO_OUT_EN);//获取gpio方向寄存器的值 + return ((regval >> S905D3_GPIO_OUT_EN_OFFSET) + 1) & 0x1;//0为out,1为in + } + return mode + 1;//如果不是gpio模式,返回的alt,从2开始,0和1是out和in + } + break; + default: offset = ((index - ((index >> 3) << 3)) << 2); @@ -4471,52 +5184,291 @@ int OrangePi_get_gpio_mode(int pin) void H618_set_pwm_reg(int pin,sunxi_gpio_info *sunxi_gpio_info_ptr) { - int pin_to_gpio = pinToGpio[pin]; - - switch(pin_to_gpio) { - case 227: - case 267: - sunxi_gpio_info_ptr->pwm_period = SUNXI_V2_PWM1_PERIOD; - sunxi_gpio_info_ptr->pwm_ctrl = SUNXI_V2_PWM1_CTRL_REG; - sunxi_gpio_info_ptr->pwm_clk = SUNXI_V2_PWM1_CLK_REG; - sunxi_gpio_info_ptr->pwm_bit_en = SUNXI_V2_PWM1_EN; - break; - case 226: - case 268: - sunxi_gpio_info_ptr->pwm_period = SUNXI_V2_PWM2_PERIOD; - sunxi_gpio_info_ptr->pwm_ctrl = SUNXI_V2_PWM2_CTRL_REG; - sunxi_gpio_info_ptr->pwm_clk = SUNXI_V2_PWM2_CLK_REG; - sunxi_gpio_info_ptr->pwm_bit_en = SUNXI_V2_PWM2_EN; - break; - case 225: - case 270: - sunxi_gpio_info_ptr->pwm_period = SUNXI_V2_PWM4_PERIOD; - sunxi_gpio_info_ptr->pwm_ctrl = SUNXI_V2_PWM4_CTRL_REG; - sunxi_gpio_info_ptr->pwm_clk = SUNXI_V2_PWM4_CLK_REG; - sunxi_gpio_info_ptr->pwm_bit_en = SUNXI_V2_PWM4_EN; - break; - case 224: - case 269: - sunxi_gpio_info_ptr->pwm_period = SUNXI_V2_PWM3_PERIOD; - sunxi_gpio_info_ptr->pwm_ctrl = SUNXI_V2_PWM3_CTRL_REG; - sunxi_gpio_info_ptr->pwm_clk = SUNXI_V2_PWM3_CLK_REG; - sunxi_gpio_info_ptr->pwm_bit_en = SUNXI_V2_PWM3_EN; - break; - default: - fprintf(stderr,"the pin you choose doesn't support hardware PWM\n"); + switch(pin) { + case 227: + case 267: + sunxi_gpio_info_ptr->pwm_period = SUNXI_V2_PWM1_PERIOD; + sunxi_gpio_info_ptr->pwm_ctrl = SUNXI_V2_PWM1_CTRL_REG; + sunxi_gpio_info_ptr->pwm_clk = SUNXI_V2_PWM1_CLK_REG; + sunxi_gpio_info_ptr->pwm_bit_en = SUNXI_V2_PWM1_EN; + break; + case 226: + case 268: + sunxi_gpio_info_ptr->pwm_period = SUNXI_V2_PWM2_PERIOD; + sunxi_gpio_info_ptr->pwm_ctrl = SUNXI_V2_PWM2_CTRL_REG; + sunxi_gpio_info_ptr->pwm_clk = SUNXI_V2_PWM2_CLK_REG; + sunxi_gpio_info_ptr->pwm_bit_en = SUNXI_V2_PWM2_EN; + break; + case 225: + case 270: + sunxi_gpio_info_ptr->pwm_period = SUNXI_V2_PWM4_PERIOD; + sunxi_gpio_info_ptr->pwm_ctrl = SUNXI_V2_PWM4_CTRL_REG; + sunxi_gpio_info_ptr->pwm_clk = SUNXI_V2_PWM4_CLK_REG; + sunxi_gpio_info_ptr->pwm_bit_en = SUNXI_V2_PWM4_EN; + break; + case 224: + case 269: + sunxi_gpio_info_ptr->pwm_period = SUNXI_V2_PWM3_PERIOD; + sunxi_gpio_info_ptr->pwm_ctrl = SUNXI_V2_PWM3_CTRL_REG; + sunxi_gpio_info_ptr->pwm_clk = SUNXI_V2_PWM3_CLK_REG; + sunxi_gpio_info_ptr->pwm_bit_en = SUNXI_V2_PWM3_EN; + break; + default: + fprintf(stderr,"gpio: the pin you choose doesn't support hardware PWM\n"); } } +void s905d3_set_gpio_reg(int pin,s905d3_gpio_info *s905d3_gpio_info_ptr) +{ + if (pin >= 476 && pin <= 491) { //GPIOA——16pin + + s905d3_gpio_info_ptr->gpio_out_en = S905D3_GPIOA_OUT_EN_REG; + s905d3_gpio_info_ptr->gpio_out = S905D3_GPIOA_OUT_REG; + s905d3_gpio_info_ptr->gpio_in = S905D3_GPIOA_IN_REG; + s905d3_gpio_info_ptr->gpio_pupd = S905D3_GPIOA_PUPD_REG; + s905d3_gpio_info_ptr->gpio_puen = S905D3_GPIOA_PUEN_REG; + s905d3_gpio_info_ptr->gpio_out_offset = pin - 476; + s905d3_gpio_info_ptr->gpio_out_en_offset = pin - 476; + s905d3_gpio_info_ptr->gpio_in_offset = pin - 476; + s905d3_gpio_info_ptr->gpio_pupd_offset = pin - 476; + s905d3_gpio_info_ptr->gpio_puen_offset = pin - 476; + + if (pin <= 483) { + s905d3_gpio_info_ptr->gpio_mux = S905D3_GPIOA_MUX_REG1; + s905d3_gpio_info_ptr->gpio_mux_offset = (pin - 476) * 4; + } else { + s905d3_gpio_info_ptr->gpio_mux = S905D3_GPIOA_MUX_REG2; + s905d3_gpio_info_ptr->gpio_mux_offset = (pin - 484) * 4; + s905d3_gpio_info_ptr->pwm_duty_cycle = S905D3_PWM_DUTY_CYCLE_F_REG; + s905d3_gpio_info_ptr->pwm_misc = S905D3_PWM_MISC_EF_REG; + } + + } else if (pin >= 468 && pin <= 475) { //GPIOC——8pin + + s905d3_gpio_info_ptr->gpio_out_en = S905D3_GPIOC_OUT_EN_REG; + s905d3_gpio_info_ptr->gpio_out = S905D3_GPIOC_OUT_REG; + s905d3_gpio_info_ptr->gpio_in = S905D3_GPIOC_IN_REG; + s905d3_gpio_info_ptr->gpio_pupd = S905D3_GPIOC_PUPD_REG; + s905d3_gpio_info_ptr->gpio_puen = S905D3_GPIOC_PUEN_REG; + s905d3_gpio_info_ptr->gpio_out_en_offset = pin - 468; + s905d3_gpio_info_ptr->gpio_out_offset = pin - 468; + s905d3_gpio_info_ptr->gpio_in_offset = pin - 468; + s905d3_gpio_info_ptr->gpio_pupd_offset = pin - 468; + s905d3_gpio_info_ptr->gpio_puen_offset = pin - 468; + + s905d3_gpio_info_ptr->gpio_mux = S905D3_GPIOC_MUX_REG; + s905d3_gpio_info_ptr->gpio_mux_offset = (pin - 468) * 4; + + } else if (pin >= 443 && pin <= 451) { //GPIOH——9pin + + s905d3_gpio_info_ptr->gpio_out_en = S905D3_GPIOH_OUT_EN_REG; + s905d3_gpio_info_ptr->gpio_out = S905D3_GPIOH_OUT_REG; + s905d3_gpio_info_ptr->gpio_in = S905D3_GPIOH_IN_REG; + s905d3_gpio_info_ptr->gpio_pupd = S905D3_GPIOH_PUPD_REG; + s905d3_gpio_info_ptr->gpio_puen = S905D3_GPIOH_PUEN_REG; + s905d3_gpio_info_ptr->gpio_out_offset = pin - 443; + s905d3_gpio_info_ptr->gpio_out_en_offset = pin - 443; + s905d3_gpio_info_ptr->gpio_in_offset = pin - 443; + s905d3_gpio_info_ptr->gpio_pupd_offset = pin - 443; + s905d3_gpio_info_ptr->gpio_puen_offset = pin - 443; + + if (pin <= 450) { + s905d3_gpio_info_ptr->gpio_mux = S905D3_GPIOH_MUX_REG1; + s905d3_gpio_info_ptr->gpio_mux_offset = (pin - 443) * 4; + } else { + s905d3_gpio_info_ptr->gpio_mux = S905D3_GPIOH_MUX_REG2; + s905d3_gpio_info_ptr->gpio_mux_offset = (pin - 451) * 4; + } + + } else if (pin >= 412 && pin <= 423) { //GPIOAO——12pin + + s905d3_gpio_info_ptr->gpio_out_en = S905D3_GPIOAO_OUT_EN_REG; + s905d3_gpio_info_ptr->gpio_out = S905D3_GPIOAO_OUT_REG; + s905d3_gpio_info_ptr->gpio_in = S905D3_GPIOAO_IN_REG; + s905d3_gpio_info_ptr->gpio_pupd = S905D3_GPIOAO_PUPD_REG; + s905d3_gpio_info_ptr->gpio_puen = S905D3_GPIOAO_PUEN_REG; + s905d3_gpio_info_ptr->gpio_out_offset = pin - 412; + s905d3_gpio_info_ptr->gpio_out_en_offset = pin - 412; + s905d3_gpio_info_ptr->gpio_in_offset = pin - 412; + s905d3_gpio_info_ptr->gpio_pupd_offset = pin - 412; + s905d3_gpio_info_ptr->gpio_puen_offset = pin - 412; + + if (pin <= 419) { + s905d3_gpio_info_ptr->gpio_mux = S905D3_GPIOAO_MUX_REG1; + s905d3_gpio_info_ptr->gpio_mux_offset = (pin - 412) * 4; + s905d3_gpio_info_ptr->pwm_duty_cycle = S905D3_PWM_DUTY_CYCLE_AO_C_REG; + s905d3_gpio_info_ptr->pwm_misc = S905D3_PWM_MISC_AO_CD_REG; + } else { + s905d3_gpio_info_ptr->gpio_mux = S905D3_GPIOAO_MUX_REG2; + s905d3_gpio_info_ptr->gpio_mux_offset = (pin - 420) * 4; + } + + } else { + fprintf(stderr,"gpio: the pin you selected is not available\n"); + } +} + +void rk3588_set_pwm_reg(int pin,rk3588_soc_info *rk3588_soc_info_ptr) +{ + rk3588_soc_info_ptr->pwm_mux = RK3588_BUS_IOC_BASE + ((pin >> 2) << 2); + rk3588_soc_info_ptr->pwm_mux_val = 0xb; + rk3588_soc_info_ptr->pwm_mux_offset = (pin % 4) << 2; + + switch (OrangePiModel) + { + case PI_MODEL_5_PLUS: + + if (pin == 15 || pin == 16) { + rk3588_soc_info_ptr->pwm_mux = RK3588_PMU2_IOC_BASE + (((pin >> 2) - 3) << 2); + rk3588_soc_info_ptr->pwm_mux_val = 0x3; + } + + switch (pin) + { + case 15: + case 34: //PWM0CH0 + rk3588_soc_info_ptr->pwm_base = RK3588_PWM0_BASE; + rk3588_soc_info_ptr->ch_period_hpr = RK3588_CH0_PERIOD_HPR; + rk3588_soc_info_ptr->ch_duty_lpr = RK3588_CH0_DUTY_LPR; + rk3588_soc_info_ptr->ch_crtl = RK3588_CH0_CTRL; + break; + + case 16: + case 35: //PWM0CH1 + rk3588_soc_info_ptr->pwm_base = RK3588_PWM0_BASE; + rk3588_soc_info_ptr->ch_period_hpr = RK3588_CH1_PERIOD_HPR; + rk3588_soc_info_ptr->ch_duty_lpr = RK3588_CH1_DUTY_LPR; + rk3588_soc_info_ptr->ch_crtl = RK3588_CH1_CTRL; + break; + + case 97: //PWM2CH3 + rk3588_soc_info_ptr->pwm_base = RK3588_PWM2_BASE; + rk3588_soc_info_ptr->ch_period_hpr = RK3588_CH3_PERIOD_HPR; + rk3588_soc_info_ptr->ch_duty_lpr = RK3588_CH3_DUTY_LPR; + rk3588_soc_info_ptr->ch_crtl = RK3588_CH3_CTRL; + break; + + case 109: //PWM3CH0 + rk3588_soc_info_ptr->pwm_base = RK3588_PWM3_BASE; + rk3588_soc_info_ptr->ch_period_hpr = RK3588_CH0_PERIOD_HPR; + rk3588_soc_info_ptr->ch_duty_lpr = RK3588_CH0_DUTY_LPR; + rk3588_soc_info_ptr->ch_crtl = RK3588_CH0_CTRL; + break; + + case 110: //PWM3CH1 + rk3588_soc_info_ptr->pwm_base = RK3588_PWM3_BASE; + rk3588_soc_info_ptr->ch_period_hpr = RK3588_CH1_PERIOD_HPR; + rk3588_soc_info_ptr->ch_duty_lpr = RK3588_CH1_DUTY_LPR; + rk3588_soc_info_ptr->ch_crtl = RK3588_CH1_CTRL; + break; + + case 62: + case 114: //PWM3CH2 + rk3588_soc_info_ptr->pwm_base = RK3588_PWM3_BASE; + rk3588_soc_info_ptr->ch_period_hpr = RK3588_CH2_PERIOD_HPR; + rk3588_soc_info_ptr->ch_duty_lpr = RK3588_CH2_DUTY_LPR; + rk3588_soc_info_ptr->ch_crtl = RK3588_CH2_CTRL; + break; + } + break; + + case PI_MODEL_5: + case PI_MODEL_5B: + + if (pin == 28) { + rk3588_soc_info_ptr->pwm_mux = RK3588_PMU2_IOC_BASE + (((pin >> 2) - 3) << 2); + rk3588_soc_info_ptr->pwm_mux_val = 0x3; + } + + switch (pin) + { + case 58: //PWM0CH0 + rk3588_soc_info_ptr->pwm_base = RK3588_PWM0_BASE; + rk3588_soc_info_ptr->ch_period_hpr = RK3588_CH0_PERIOD_HPR; + rk3588_soc_info_ptr->ch_duty_lpr = RK3588_CH0_DUTY_LPR; + rk3588_soc_info_ptr->ch_crtl = RK3588_CH0_CTRL; + break; + + case 35: + case 59: //PWM0CH1 + rk3588_soc_info_ptr->pwm_base = RK3588_PWM0_BASE; + rk3588_soc_info_ptr->ch_period_hpr = RK3588_CH1_PERIOD_HPR; + rk3588_soc_info_ptr->ch_duty_lpr = RK3588_CH1_DUTY_LPR; + rk3588_soc_info_ptr->ch_crtl = RK3588_CH1_CTRL; + break; + + case 28: + case 50: //PWM0CH3 + rk3588_soc_info_ptr->pwm_base = RK3588_PWM0_BASE; + rk3588_soc_info_ptr->ch_period_hpr = RK3588_CH3_PERIOD_HPR; + rk3588_soc_info_ptr->ch_duty_lpr = RK3588_CH3_DUTY_LPR; + rk3588_soc_info_ptr->ch_crtl = RK3588_CH3_CTRL; + break; + + case 47: //PWM3CH1 + rk3588_soc_info_ptr->pwm_base = RK3588_PWM3_BASE; + rk3588_soc_info_ptr->ch_period_hpr = RK3588_CH1_PERIOD_HPR; + rk3588_soc_info_ptr->ch_duty_lpr = RK3588_CH1_DUTY_LPR; + rk3588_soc_info_ptr->ch_crtl = RK3588_CH1_CTRL; + break; + + case 138: //PWM3CH2 + rk3588_soc_info_ptr->pwm_base = RK3588_PWM3_BASE; + rk3588_soc_info_ptr->ch_period_hpr = RK3588_CH2_PERIOD_HPR; + rk3588_soc_info_ptr->ch_duty_lpr = RK3588_CH2_DUTY_LPR; + rk3588_soc_info_ptr->ch_crtl = RK3588_CH2_CTRL; + break; + + case 54: //PWM3CH3 + rk3588_soc_info_ptr->pwm_base = RK3588_PWM3_BASE; + rk3588_soc_info_ptr->ch_period_hpr = RK3588_CH3_PERIOD_HPR; + rk3588_soc_info_ptr->ch_duty_lpr = RK3588_CH3_DUTY_LPR; + rk3588_soc_info_ptr->ch_crtl = RK3588_CH3_CTRL; + break; + } + break; + } +} + +void rk3566_set_pwm_reg(int pin,rk3566_soc_info *rk3566_soc_info_ptr) +{ + rk3566_soc_info_ptr->pwm_mux = RK3566_PWM_MUX_REG; + + switch (pin) + { + case 144: //PWM2CH3 + rk3566_soc_info_ptr->cru_gate_con = RK3566_CRU_GATE_CON31; + rk3566_soc_info_ptr->cru_gate_con_offset = 13; + rk3566_soc_info_ptr->pwm_mux_val = 0x3; + rk3566_soc_info_ptr->pwm_mux_offset = 0; + rk3566_soc_info_ptr->pwm_base = RK3566_PWM2_BASE; + rk3566_soc_info_ptr->ch_period_hpr = RK3566_CH3_PERIOD_HPR; + rk3566_soc_info_ptr->ch_duty_lpr = RK3566_CH3_DUTY_LPR; + rk3566_soc_info_ptr->ch_crtl = RK3566_CH3_CTRL; + break; + + case 147: //PWM3CH3 + rk3566_soc_info_ptr->cru_gate_con = RK3566_CRU_GATE_CON32; + rk3566_soc_info_ptr->cru_gate_con_offset = 0; + rk3566_soc_info_ptr->pwm_mux_val = 0x1; + rk3566_soc_info_ptr->pwm_mux_offset = 12; + rk3566_soc_info_ptr->pwm_base = RK3566_PWM3_BASE; + rk3566_soc_info_ptr->ch_period_hpr = RK3566_CH3_PERIOD_HPR; + rk3566_soc_info_ptr->ch_duty_lpr = RK3566_CH3_DUTY_LPR; + rk3566_soc_info_ptr->ch_crtl = RK3566_CH3_CTRL; + break; + } +} /* * Set GPIO Mode */ int OrangePi_set_gpio_mode(int pin, int mode) { - unsigned int regval = 0; - unsigned int bank = pin >> 5; - unsigned int index = pin - (bank << 5); - unsigned int phyaddr = 0; + unsigned int regval = 0; + unsigned int bank = pin >> 5; + unsigned int index = pin - (bank << 5); + unsigned int phyaddr = 0; int offset; unsigned int cru_phyaddr =0, grf_phyaddr = 0, gpio_phyaddr = 0, ddr_phyaddr = 0; unsigned int cru_val = 0; @@ -4566,31 +5518,44 @@ int OrangePi_set_gpio_mode(int pin, int mode) /* Ignore unused gpio */ if (ORANGEPI_PIN_MASK[bank][index] != -1) { - regval = readR(cru_phyaddr); - regval &= cru_val; - writeR(regval, cru_phyaddr); - - regval = readR(rk3588_bus_ioc_phyaddr); - regval |= 0xffff0000; - regval &= ~(0xf << ((index % 4) << 2)); - writeR(regval, rk3588_bus_ioc_phyaddr); - regval = readR(rk3588_bus_ioc_phyaddr); - - /* Set Input */ if(INPUT == mode) { + regval = readR(cru_phyaddr); + regval |= 0xffff0000; + regval &= cru_val; + writeR(regval, cru_phyaddr); + regval = readR(cru_phyaddr); + + regval = readR(rk3588_bus_ioc_phyaddr); + regval |= 0xffff0000; + regval &= ~(0xf << ((index % 4) << 2)); + writeR(regval, rk3588_bus_ioc_phyaddr); + regval = readR(rk3588_bus_ioc_phyaddr); + regval = readR(ddr_phyaddr); regval |= 0xffff0000; regval &= ~(1 << (index % 16)); writeR(regval, ddr_phyaddr); - if (wiringPiDebug){ + if (wiringPiDebug) { regval = readR(ddr_phyaddr); printf("Input mode set over reg val: %#x\n",regval); } } else if(OUTPUT == mode) - { + { + regval = readR(cru_phyaddr); + regval |= 0xffff0000; + regval &= cru_val; + writeR(regval, cru_phyaddr); + regval = readR(cru_phyaddr); + + regval = readR(rk3588_bus_ioc_phyaddr); + regval |= 0xffff0000; + regval &= ~(0xf << ((index % 4) << 2)); + writeR(regval, rk3588_bus_ioc_phyaddr); + regval = readR(rk3588_bus_ioc_phyaddr); + regval = readR(ddr_phyaddr); regval |= 0xffff0000; regval |= (1 << (index % 16)); @@ -4598,10 +5563,114 @@ int OrangePi_set_gpio_mode(int pin, int mode) if (wiringPiDebug){ regval = readR(ddr_phyaddr); - printf("Input mode set over reg val: %#x\n",regval); + printf("OUTPUT mode set over reg val: %#x\n",regval); } } - else + else if(PWM_OUTPUT == mode) + { + + //set clk——busioc + if (wiringPiDebug) + printf(">>Set cru_busioc_clk_en\n"); + + regval = readR(RK3588_CRU_GATE_CON19); + regval &= 0xfffffffe; + writeR(regval,RK3588_CRU_GATE_CON19); + regval = readR(RK3588_CRU_GATE_CON19); + + //Set clk——pwm123 + if (wiringPiDebug) + printf(">>Set cru_pwm123_clk_en\n"); + + regval = readR(RK3588_CRU_GATE_CON15); + regval &= ~(0x00000ff8); + regval |= 0xffff0920; + writeR(regval,RK3588_CRU_GATE_CON15); + regval = readR(RK3588_CRU_GATE_CON15); + + //Set clk——pwu1pwm + if (wiringPiDebug) + printf(">>Set cru_pmu1pwm_clk_en\n"); + + regval = readR(RK3588_PMU1CRU_GATE_CON1); + regval &= ~(0x00007000); + regval |= 0xffff4000; + writeR(regval,RK3588_PMU1CRU_GATE_CON1); + regval = readR(RK3588_PMU1CRU_GATE_CON1); + + rk3588_set_pwm_reg(pin,&rk3588_soc_info_t); + + //Set mux + if (wiringPiDebug) + printf(">>Set mux\n"); + + regval = readR(RK3588_PWM_MUX); + regval |= 0xffff0000; + regval &= ~(0xf << RK3588_PWM_MUX_OFFSET); + regval |= (RK3588_PWM_MUX_VAL << RK3588_PWM_MUX_OFFSET); + writeR(regval, RK3588_PWM_MUX); + regval = readR(RK3588_PWM_MUX); + + //clear all reg + if (wiringPiDebug) + printf(">>Clear all reg\n"); + + writeR(0, RK3588_CH_PERIOD_HPR); + regval = readR(RK3588_CH_PERIOD_HPR); + + writeR(0, RK3588_CH_DUTY_LPR); + regval = readR(RK3588_CH_DUTY_LPR); + + writeR(0, RK3588_CH_CTRL); + regval = readR(RK3588_CH_CTRL); + + //Set period + if (wiringPiDebug) + printf(">>Set period\n"); + + regval = readR(RK3588_CH_PERIOD_HPR); + regval = 1000; + writeR(regval, RK3588_CH_PERIOD_HPR); + regval = readR(RK3588_CH_PERIOD_HPR); + + //Set duty + if (wiringPiDebug) + printf(">>Set duty\n"); + + regval = readR(RK3588_CH_DUTY_LPR); + regval = 500; + writeR(regval, RK3588_CH_DUTY_LPR); + regval = readR(RK3588_CH_DUTY_LPR); + + //Set ctrl + if (wiringPiDebug) + printf(">>Set ctrl\n"); + + /** + * frequency of clock: 24 MHz / 120 = 200 kHz + * frequency of PWM: 200 kHz / 1000 = 200 Hz + * period of PWM: 1 / 200 Hz = 0.005 s + * duty: 500/1000 = 50% + */ + regval = readR(RK3588_CH_CTRL); + regval = (0 << RK3588_RPT) \ + | (60 << RK3588_SCALE) \ + | (0 << RK3588_PRESCALE) \ + | (0 << RK3588_CLK_SRC_SEL) \ + | (1 << RK3588_CLK_SEL) \ + | (1 << RK3588_FORCE_CLK_EN) \ + | (1 << RK3588_CH_CNT_EN) \ + | (0 << RK3588_CONLOCK) \ + | (0 << RK3588_OUTPUT_MODE) \ + | (0 << RK3588_INACTIVE_POL) \ + | (1 << RK3588_DUTY_POL) \ + | (1 << RK3588_PWM_MODE) \ + | (1 << RK3588_PWM_EN); + + writeR(regval, RK3588_CH_CTRL); + regval = readR(RK3588_CH_CTRL); + } + else { printf("Unknow mode\n"); } @@ -4652,15 +5721,15 @@ int OrangePi_set_gpio_mode(int pin, int mode) regval = readR(gpio_phyaddr); regval &= ~(1 << index); writeR(regval, gpio_phyaddr); - + if (wiringPiDebug){ regval = readR(gpio_phyaddr); printf("Input mode set over reg val: %#x\n",regval); } - } + } + /* Set Output */ else if(OUTPUT == mode) - { - /* Set Output */ + { writeR(0xffff0180, cru_phyaddr); regval = readR(grf_phyaddr); regval |= 0x3 << ((offset << 1) | 0x10); @@ -4676,7 +5745,7 @@ int OrangePi_set_gpio_mode(int pin, int mode) printf("Out mode get value: 0x%x\n",regval); } } - else + else { printf("Unknow mode\n"); } @@ -4802,6 +5871,7 @@ int OrangePi_set_gpio_mode(int pin, int mode) case PI_MODEL_CM4: case PI_MODEL_3B: + if(bank == 0){ cru_phyaddr = RK3566_PMU_CRU_BASE + RK3566_PMUCRU_PMUGATE_CON01_OFFSET; cru_val = ~((0x3 << 9) | (0x3 << (16 + 9))); @@ -4820,38 +5890,142 @@ int OrangePi_set_gpio_mode(int pin, int mode) /* Ignore unused gpio */ if (ORANGEPI_PIN_MASK[bank][index] != -1) { - regval = readR(cru_phyaddr); - regval &= cru_val; - writeR(regval, cru_phyaddr); - regval = readR(grf_phyaddr); - if(wiringPiDebug) - printf("read val(%#x) from register[%#x]\n", regval, grf_phyaddr); - regval |= bit_enable; - regval &= ~(0x7 << offset); - if (wiringPiDebug) - printf("write val(%#x) to register[%#x]\n", regval, grf_phyaddr); - writeR(regval, grf_phyaddr); - regval = readR(grf_phyaddr); - if(wiringPiDebug) - printf("set over reg val: 0x%x\n", regval); + if (INPUT == mode) + { + regval = readR(cru_phyaddr); + regval &= cru_val; + writeR(regval, cru_phyaddr); + regval = readR(cru_phyaddr); - regval = readR(ddr_phyaddr); - if(wiringPiDebug) - printf("read val ddr (%#x) from register[%#x]\n", regval, ddr_phyaddr); + regval = readR(grf_phyaddr); + regval |= bit_enable; + regval &= ~(0x7 << offset); + writeR(regval, grf_phyaddr); + regval = readR(grf_phyaddr); - regval |= 0x1 << (16 + (index % 16)); - if(INPUT == mode) + regval = readR(ddr_phyaddr); + regval |= 0x1 << (16 + (index % 16)); regval &= ~(1 << (index % 16)); - else + writeR(regval, ddr_phyaddr); + regval = readR(ddr_phyaddr); + } + else if (OUTPUT == mode) + { + regval = readR(cru_phyaddr); + regval &= cru_val; + writeR(regval, cru_phyaddr); + regval = readR(cru_phyaddr); + + regval = readR(grf_phyaddr); + regval |= bit_enable; + regval &= ~(0x7 << offset); + writeR(regval, grf_phyaddr); + regval = readR(grf_phyaddr); + + regval = readR(ddr_phyaddr); + regval |= 0x1 << (16 + (index % 16)); regval |= (1 << (index % 16)); + writeR(regval, ddr_phyaddr); + regval = readR(ddr_phyaddr); + } + else if (PWM_OUTPUT == mode) + { + /*//set clk——busioc + if (wiringPiDebug) + printf(">>Set cru_busioc_clk_en\n"); - writeR(regval, ddr_phyaddr); - if (wiringPiDebug) - printf("write val(%#x) to register[%#x]\n", regval, ddr_phyaddr); + regval = readR(RK3588_CRU_GATE_CON19); + regval &= 0xfffffffe; + writeR(regval,RK3588_CRU_GATE_CON19); + regval = readR(RK3588_CRU_GATE_CON19);*/ + + rk3566_set_pwm_reg(pin,&rk3566_soc_info_t); + + //Set clk——pwm + if (wiringPiDebug) + printf(">>Set cru_pwm_clk_en\n"); + + regval = readR(RK3566_CRU_GATE_CON); + regval &= ~(0x7 << RK3566_CRU_GATE_CON_OFFSET); + regval |= (0xffff0000 + (0x4 << RK3566_CRU_GATE_CON_OFFSET)); + writeR(regval,RK3566_CRU_GATE_CON); + regval = readR(RK3566_CRU_GATE_CON); + + //Set mux + if (wiringPiDebug) + printf(">>Set mux\n"); + + regval = readR(RK3566_PWM_MUX); + regval |= 0xffff0000; + regval &= ~(0xf << RK3566_PWM_MUX_OFFSET); + regval |= (RK3566_PWM_MUX_VAL << RK3566_PWM_MUX_OFFSET); + writeR(regval, RK3566_PWM_MUX); + regval = readR(RK3566_PWM_MUX); + + //clear all reg + if (wiringPiDebug) + printf(">>Clear all reg\n"); + + writeR(0, RK3566_CH_PERIOD_HPR); + regval = readR(RK3566_CH_PERIOD_HPR); + + writeR(0, RK3566_CH_DUTY_LPR); + regval = readR(RK3566_CH_DUTY_LPR); + + writeR(0, RK3566_CH_CTRL); + regval = readR(RK3566_CH_CTRL); + + //Set period + if (wiringPiDebug) + printf(">>Set period\n"); + + regval = readR(RK3566_CH_PERIOD_HPR); + regval = 1000; + writeR(regval, RK3566_CH_PERIOD_HPR); + regval = readR(RK3566_CH_PERIOD_HPR); + + //Set duty + if (wiringPiDebug) + printf(">>Set duty\n"); + + regval = readR(RK3566_CH_DUTY_LPR); + regval = 500; + writeR(regval, RK3566_CH_DUTY_LPR); + regval = readR(RK3566_CH_DUTY_LPR); + + //Set ctrl + if (wiringPiDebug) + printf(">>Set ctrl\n"); + + /** + * frequency of clock: 24 MHz / 120 = 200 kHz + * frequency of PWM: 200 kHz / 1000 = 200 Hz + * period of PWM: 1 / 200 Hz = 0.005 s + * duty: 500/1000 = 50% + */ + regval = readR(RK3566_CH_CTRL); + regval = (0 << RK3566_RPT) \ + | (60 << RK3566_SCALE) \ + | (0 << RK3566_PRESCALE) \ + | (0 << RK3566_CLK_SRC_SEL) \ + | (1 << RK3566_CLK_SEL) \ + | (1 << RK3566_FORCE_CLK_EN) \ + | (1 << RK3566_CH_CNT_EN) \ + | (0 << RK3566_CONLOCK) \ + | (0 << RK3566_OUTPUT_MODE) \ + | (0 << RK3566_INACTIVE_POL) \ + | (1 << RK3566_DUTY_POL) \ + | (1 << RK3566_PWM_MODE) \ + | (1 << RK3566_PWM_EN); + + writeR(regval, RK3566_CH_CTRL); + regval = readR(RK3566_CH_CTRL); + } + else + { + printf("Unknow mode\n"); + } - regval = readR(ddr_phyaddr); - if (wiringPiDebug) - printf("set over reg val: 0x%x\n", regval); } else { @@ -4859,6 +6033,140 @@ int OrangePi_set_gpio_mode(int pin, int mode) } break; + case PI_MODEL_3_PLUS: + + s905d3_set_gpio_reg(pin,&s905d3_gpio_info_t); + + if(INPUT == mode) { + /* Set Input */ + //Set mux + regval = readR(S905D3_GPIO_MUX); + + if (wiringPiDebug) + printf("Register[%#x]: %#x\n", S905D3_GPIO_MUX, regval); + + regval &= ~(0xF << S905D3_GPIO_MUX_OFFSET); + + writeR(regval, S905D3_GPIO_MUX); + regval = readR(S905D3_GPIO_MUX); + + if (wiringPiDebug) + printf("Register[%#x]: %#x\n", S905D3_GPIO_MUX, regval); + + //set fsel + regval = readR(S905D3_GPIO_OUT_EN); + + if (wiringPiDebug) + printf("Register[%#x]: %#x\n", S905D3_GPIO_OUT_EN, regval); + + regval |= 1 << S905D3_GPIO_OUT_EN_OFFSET; + + writeR(regval, S905D3_GPIO_OUT_EN); + regval = readR(S905D3_GPIO_OUT_EN); + + if (wiringPiDebug) + printf("Register[%#x]: %#x\n", S905D3_GPIO_OUT_EN, regval); + + } else if (OUTPUT == mode) { + /* Set Output */ + //Set mux + regval = readR(S905D3_GPIO_MUX); + + if (wiringPiDebug) + printf("Register[%#x]: %#x\n", S905D3_GPIO_MUX, regval); + + regval &= ~(0xF << S905D3_GPIO_MUX_OFFSET); + + writeR(regval, S905D3_GPIO_MUX); + regval = readR(S905D3_GPIO_MUX); + + if (wiringPiDebug) + printf("Register[%#x]: %#x\n", S905D3_GPIO_MUX, regval); + + //set fsel + regval = readR(S905D3_GPIO_OUT_EN); + + if (wiringPiDebug) + printf("Register[%#x]: %#x\n", S905D3_GPIO_OUT_EN, regval); + + regval &= ~(1 << S905D3_GPIO_OUT_EN_OFFSET); + + writeR(regval, S905D3_GPIO_OUT_EN); + regval = readR(S905D3_GPIO_OUT_EN); + + if (wiringPiDebug) + printf("Register[%#x]: %#x\n", S905D3_GPIO_OUT_EN, regval); + + } else if (PWM_OUTPUT == mode) { + if (wiringPiDebug) + printf("OPI: try wiringPi pin %d for PWM pin\n", pin); + + if (pin != 418 && pin != 487) { + printf("the pin you choose doesn't support hardware PWM\n"); + printf("OPI:you can select wiringPi pin 418,487 for PWM pin\n"); + printf("or you can use it in softPwm mode\n"); + exit(1); + } + + /* Set PWM_Output */ + //Set mux + regval = readR(S905D3_GPIO_MUX); + + if (wiringPiDebug) + printf("Register[%#x]: %#x\n", S905D3_GPIO_MUX, regval); + + regval &= ~(0xF << S905D3_GPIO_MUX_OFFSET); + regval |= 0x3 << S905D3_GPIO_MUX_OFFSET; + + if (wiringPiDebug) + printf(">>>>>line:%d PWM mode ready to set val: 0x%x\n", __LINE__, regval); + + writeR(regval, S905D3_GPIO_MUX); + regval = readR(S905D3_GPIO_MUX); + + if (wiringPiDebug) + printf("<<<<> 3) << 3)) << 2); @@ -4884,6 +6192,7 @@ int OrangePi_set_gpio_mode(int pin, int mode) regval &= ~(7 << offset); writeR(regval, phyaddr); regval = readR(phyaddr); + if (wiringPiDebug) printf("Input mode set over reg val: %#x\n",regval); } @@ -4892,15 +6201,35 @@ int OrangePi_set_gpio_mode(int pin, int mode) /* Set Output */ regval &= ~(7 << offset); regval |= (1 << offset); + if (wiringPiDebug) printf("Out mode ready set val: 0x%x\n",regval); + writeR(regval, phyaddr); regval = readR(phyaddr); + if (wiringPiDebug) printf("Out mode get value: 0x%x\n",regval); } else if(PWM_OUTPUT == mode) { + if (wiringPiDebug) + printf("OPI: try wiringPi pin %d for PWM pin\n", pin); + + if (OrangePiModel == PI_MODEL_ZERO_2 && pin != 224 && pin != 225 && pin != 226 && pin != 227) { + printf("the pin you choose doesn't support hardware PWM\n"); + printf("OPI:you can select wiringPi pin 224,225,226,227 for PWM pin\n"); + printf("or you can use it in softPwm mode\n"); + exit(1); + } else if (OrangePiModel == PI_MODEL_ZERO_2_W && pin != 267 && pin != 268 && pin != 269 && pin != 270) { + printf("the pin you choose doesn't support hardware PWM\n"); + printf("OPI:you can select wiringPi pin 267,268,269,270 for PWM pin\n"); + printf("or you can use it in softPwm mode\n"); + exit(1); + } + + H618_set_pwm_reg(pin,&sunxi_gpio_info_t); + // set pin PWMx to pwm mode regval &= ~(7 << offset); if (OrangePiModel == PI_MODEL_ZERO_2) @@ -4924,14 +6253,14 @@ int OrangePi_set_gpio_mode(int pin, int mode) writeR(0, SUNXI_PWM_PERIOD); //set default M:S to 1/2 - sunxi_pwm_set_period(1024); - sunxi_pwm_set_act(512); + sunxi_pwm_set_period(pin,1024); + sunxi_pwm_set_act(pin,512); sunxi_pwm_set_mode(PWM_MODE_MS); if (OrangePiModel == PI_MODEL_ZERO_2 || OrangePiModel == PI_MODEL_ZERO_2_W) - sunxi_pwm_set_clk(0); //default clk:24M + sunxi_pwm_set_clk(pin,1); //default clk:24M else - sunxi_pwm_set_clk(PWM_CLK_DIV_120); //default clk:24M/120 + sunxi_pwm_set_clk(pin,PWM_CLK_DIV_120); //default clk:24M/120 delayMicroseconds(200); } else @@ -5188,7 +6517,7 @@ int OrangePi_digitalWrite(int pin, int value) regval = readR(dr_phyaddr); if(wiringPiDebug) - printf("read val(%#x) from register[%#x]\n", regval, dr_phyaddr);; + printf("read val(%#x) from register[%#x]\n", regval, dr_phyaddr); regval |= bit_enable; @@ -5212,6 +6541,40 @@ int OrangePi_digitalWrite(int pin, int value) break; + case PI_MODEL_3_PLUS: + + s905d3_set_gpio_reg(pin,&s905d3_gpio_info_t); + + /* Ignore unused gpio */ + if (ORANGEPI_PIN_MASK[bank][index] != -1) + { + regval = readR(S905D3_GPIO_OUT); + + if(wiringPiDebug) + printf("read val(%#x) from register[%#x]\n", regval, S905D3_GPIO_OUT); + + if(0 == value) + regval &= ~(1 << S905D3_GPIO_OUT_OFFSET); + else + regval |= (1 << S905D3_GPIO_OUT_OFFSET); + + writeR(regval, S905D3_GPIO_OUT); + + if (wiringPiDebug) + printf("write val(%#x) to register[%#x]\n", regval, S905D3_GPIO_OUT); + + regval = readR(S905D3_GPIO_OUT); + + if (wiringPiDebug) + printf("set over reg val: 0x%x\n", regval); + } + else + { + printf("Pin mode failed!\n"); + } + + break; + default: if (bank == 11) @@ -5318,6 +6681,13 @@ int OrangePi_digitalRead(int pin) break; + case PI_MODEL_3_PLUS: + + s905d3_set_gpio_reg(pin,&s905d3_gpio_info_t); + phyaddr = S905D3_GPIO_IN; + + break; + default: if (bank == 11) @@ -5328,7 +6698,7 @@ int OrangePi_digitalRead(int pin) { phyaddr = sunxi_gpio_info_t.gpio_base_addr + sunxi_gpio_info_t.gpio_base_offset + (bank * 36) + 0x10; } - + break; } @@ -5336,11 +6706,18 @@ int OrangePi_digitalRead(int pin) if (ORANGEPI_PIN_MASK[bank][index] != -1) { val = readR(phyaddr); - val = val >> index; + + if (OrangePiModel == PI_MODEL_3_PLUS) { + val = val >> S905D3_GPIO_IN_OFFSET; + } else { + val = val >> index; + } + val &= 1; + if (wiringPiDebug) printf("Read reg val: 0x%#x, bank:%d, index:%d\n", val, bank, index); - + return val; } @@ -5439,6 +6816,45 @@ void OrangePi_set_gpio_pullUpDnControl (int pin, int pud) bit_value = 0; break; + case PI_MODEL_3_PLUS: + + s905d3_set_gpio_reg(pin,&s905d3_gpio_info_t); + + /* Ignore unused gpio */ + if (ORANGEPI_PIN_MASK[bank][index] != -1) + { + if (PUD_UP == pud) { + //Set puen + regval = readR(S905D3_GPIO_PUEN); + regval |= 1 << S905D3_GPIO_PUEN_OFFSET; + writeR(regval, S905D3_GPIO_PUEN); + + //Set pupd + regval = readR(S905D3_GPIO_PUPD); + regval |= 1 << S905D3_GPIO_PUPD_OFFSET; + writeR(regval, S905D3_GPIO_PUPD); + + } else if (PUD_DOWN == pud) { + //Set puen + regval = readR(S905D3_GPIO_PUEN); + regval |= 1 << S905D3_GPIO_PUEN_OFFSET; + writeR(regval, S905D3_GPIO_PUEN); + + //Set pupd + regval = readR(S905D3_GPIO_PUPD); + regval &= ~(1 << S905D3_GPIO_PUPD_OFFSET); + writeR(regval, S905D3_GPIO_PUPD); + + } else if (PUD_OFF == pud) { + //Disable puen + regval = readR(S905D3_GPIO_PUEN); + regval &= ~(1 << S905D3_GPIO_PUEN_OFFSET); + writeR(regval, S905D3_GPIO_PUEN); + } + } + + return; + default: //int offset = ((index - ((index >> 4) << 4)) << 1); offset = ((index % 16) << 1); @@ -5467,6 +6883,7 @@ void OrangePi_set_gpio_pullUpDnControl (int pin, int pud) printf("bank: %d, index: %d\n", bank, index); regval = readR(phyaddr); + if (wiringPiDebug) printf("read val(%#x) from register[%#x]\n", regval, phyaddr); diff --git a/wiringPi/wiringPi.h b/wiringPi/wiringPi.h index fda06bc..190bcae 100644 --- a/wiringPi/wiringPi.h +++ b/wiringPi/wiringPi.h @@ -50,24 +50,24 @@ #define PI_MODEL_ZERO_W 12 #define PI_MODEL_3P 13 -#define PI_VERSION_1 0 -#define PI_VERSION_1_1 1 -#define PI_VERSION_1_2 2 -#define PI_VERSION_2 3 +#define PI_VERSION_1 0 +#define PI_VERSION_1_1 1 +#define PI_VERSION_1_2 2 +#define PI_VERSION_2 3 -#define PI_MAKER_SONY 0 -#define PI_MAKER_EGOMAN 1 -#define PI_MAKER_EMBEST 2 -#define PI_MAKER_UNKNOWN 3 +#define PI_MAKER_SONY 0 +#define PI_MAKER_EGOMAN 1 +#define PI_MAKER_EMBEST 2 +#define PI_MAKER_UNKNOWN 3 /*********** Allwinner H3 *************/ -#define H3_GPIO_BASE_ADDR 0x01C20000U -#define H3_R_GPIO_BASE_ADDR 0x01F02000U +#define H3_GPIO_BASE_ADDR 0x01C20000U +#define H3_R_GPIO_BASE_ADDR 0x01F02000U /*********** Allwinner H3 *************/ /*********** Allwinner H6 *************/ -#define H6_GPIO_BASE_ADDR 0x0300B000U -#define H6_R_GPIO_BASE_ADDR 0x07022000U +#define H6_GPIO_BASE_ADDR 0x0300B000U +#define H6_R_GPIO_BASE_ADDR 0x07022000U /*********** Allwinner H6 *************/ typedef struct { @@ -90,81 +90,81 @@ typedef struct { unsigned int pwm_bit_mode; // SUNXI_PWM_CH0_MS_MODE unsigned int pwm_bit_pulse; // SUNXI_PWM_CH0_PUL_START } sunxi_gpio_info; -#define GPIO_PWM GPIO_PWM_OP +#define GPIO_PWM GPIO_PWM_OP //sunxi_pwm #ifdef OPI -#define SUNXI_PWM_BASE (0x01c21400) -#define SUNXI_PWM_CTRL_REG (SUNXI_PWM_BASE) -#define SUNXI_PWM_CH0_PERIOD (SUNXI_PWM_BASE + 0x4) -#define SUNXI_PWM_CH1_PERIOD (SUNXI_PWM_BASE + 0x8) +#define SUNXI_PWM_BASE (0x01c21400) +#define SUNXI_PWM_CTRL_REG (SUNXI_PWM_BASE) +#define SUNXI_PWM_CH0_PERIOD (SUNXI_PWM_BASE + 0x4) +#define SUNXI_PWM_CH1_PERIOD (SUNXI_PWM_BASE + 0x8) -#define SUNXI_PWM_CH0_EN (1 << 4) -#define SUNXI_PWM_CH0_ACT_STA (1 << 5) -#define SUNXI_PWM_SCLK_CH0_GATING (1 << 6) -#define SUNXI_PWM_CH0_MS_MODE (1 << 7) //pulse mode -#define SUNXI_PWM_CH0_PUL_START (1 << 8) +#define SUNXI_PWM_CH0_EN (1 << 4) +#define SUNXI_PWM_CH0_ACT_STA (1 << 5) +#define SUNXI_PWM_SCLK_CH0_GATING (1 << 6) +#define SUNXI_PWM_CH0_MS_MODE (1 << 7) //pulse mode +#define SUNXI_PWM_CH0_PUL_START (1 << 8) #else -#define SUNXI_PWM_BASE (sunxi_gpio_info_t.pwm_base_addr) -#define SUNXI_PWM_CTRL_REG (sunxi_gpio_info_t.pwm_ctrl) -#define SUNXI_PWM_PERIOD (sunxi_gpio_info_t.pwm_period) -#define SUNXI_PWM_CLK_REG (sunxi_gpio_info_t.pwm_clk) // H616 -#define SUNXI_PWM_EN_REG (sunxi_gpio_info_t.pwm_en) // H616 -#define SUNXI_PWM_TYPE (sunxi_gpio_info_t.pwm_type) -#define SUNXI_PWM_EN (sunxi_gpio_info_t.pwm_bit_en) -#define SUNXI_PWM_ACT_STA (sunxi_gpio_info_t.pwm_bit_act) -#define SUNXI_PWM_SCLK_GATING (sunxi_gpio_info_t.pwm_bit_sclk) -#define SUNXI_PWM_MS_MODE (sunxi_gpio_info_t.pwm_bit_mode) //pulse mode -#define SUNXI_PWM_PUL_START (sunxi_gpio_info_t.pwm_bit_pulse) +#define SUNXI_PWM_BASE (sunxi_gpio_info_t.pwm_base_addr) +#define SUNXI_PWM_CTRL_REG (sunxi_gpio_info_t.pwm_ctrl) +#define SUNXI_PWM_PERIOD (sunxi_gpio_info_t.pwm_period) +#define SUNXI_PWM_CLK_REG (sunxi_gpio_info_t.pwm_clk) // H616 +#define SUNXI_PWM_EN_REG (sunxi_gpio_info_t.pwm_en) // H616 +#define SUNXI_PWM_TYPE (sunxi_gpio_info_t.pwm_type) +#define SUNXI_PWM_EN (sunxi_gpio_info_t.pwm_bit_en) +#define SUNXI_PWM_ACT_STA (sunxi_gpio_info_t.pwm_bit_act) +#define SUNXI_PWM_SCLK_GATING (sunxi_gpio_info_t.pwm_bit_sclk) +#define SUNXI_PWM_MS_MODE (sunxi_gpio_info_t.pwm_bit_mode) //pulse mode +#define SUNXI_PWM_PUL_START (sunxi_gpio_info_t.pwm_bit_pulse) #endif -#define H3_PWM_BASE (0x01c21400) -#define H6_PWM_BASE (0x0300A000) -#define H616_PWM_BASE (0x0300A000) +#define H3_PWM_BASE (0x01c21400) +#define H6_PWM_BASE (0x0300A000) +#define H616_PWM_BASE (0x0300A000) -#define SUNXI_V1_PWM_TYPE (1) -#define SUNXI_V2_PWM_TYPE (2) +#define SUNXI_V1_PWM_TYPE (1) +#define SUNXI_V2_PWM_TYPE (2) -#define SUNXI_V1_PWM_EN_REG (SUNXI_PWM_BASE + 0x0) -#define SUNXI_V1_PWM_CLK_REG (SUNXI_PWM_BASE + 0x0) -#define SUNXI_V1_PWM_CTRL_REG (SUNXI_PWM_BASE + 0x0) -#define SUNXI_V1_PWM_CH0_PERIOD (SUNXI_PWM_BASE + 0x4) +#define SUNXI_V1_PWM_EN_REG (SUNXI_PWM_BASE + 0x0) +#define SUNXI_V1_PWM_CLK_REG (SUNXI_PWM_BASE + 0x0) +#define SUNXI_V1_PWM_CTRL_REG (SUNXI_PWM_BASE + 0x0) +#define SUNXI_V1_PWM_CH0_PERIOD (SUNXI_PWM_BASE + 0x4) -#define SUNXI_V1_PWM_CH0_EN (1 << 4) -#define SUNXI_V1_PWM_CH0_ACT_STA (1 << 5) -#define SUNXI_V1_PWM_SCLK_CH0_GATING (1 << 6) -#define SUNXI_V1_PWM_CH0_MS_MODE (1 << 7) //pulse mode -#define SUNXI_V1_PWM_CH0_PUL_START (1 << 8) +#define SUNXI_V1_PWM_CH0_EN (1 << 4) +#define SUNXI_V1_PWM_CH0_ACT_STA (1 << 5) +#define SUNXI_V1_PWM_SCLK_CH0_GATING (1 << 6) +#define SUNXI_V1_PWM_CH0_MS_MODE (1 << 7) //pulse mode +#define SUNXI_V1_PWM_CH0_PUL_START (1 << 8) //----------------------------------------------------- //SUNXI_V2_PWM Fixed parameters -#define SUNXI_V2_PWM_EN_REG (SUNXI_PWM_BASE + 0x40) -#define SUNXI_V2_PWM_ACT_STA (1 << 8) -#define SUNXI_V2_PWM_SCLK_GATING (1 << 4) -#define SUNXI_V2_PWM_MS_MODE (1 << 9) -#define SUNXI_V2_PWM_PUL_START (1 << 10) +#define SUNXI_V2_PWM_EN_REG (SUNXI_PWM_BASE + 0x40) +#define SUNXI_V2_PWM_ACT_STA (1 << 8) +#define SUNXI_V2_PWM_SCLK_GATING (1 << 4) +#define SUNXI_V2_PWM_MS_MODE (1 << 9) +#define SUNXI_V2_PWM_PUL_START (1 << 10) //SUNXI_V2_PWM Variable parameters -#define SUNXI_V2_PWM1_PERIOD (SUNXI_PWM_BASE + 0x84) -#define SUNXI_V2_PWM1_CTRL_REG (SUNXI_PWM_BASE + 0x80) -#define SUNXI_V2_PWM1_CLK_REG (SUNXI_PWM_BASE + 0x20) -#define SUNXI_V2_PWM1_EN (1 << 1) +#define SUNXI_V2_PWM1_PERIOD (SUNXI_PWM_BASE + 0x84) +#define SUNXI_V2_PWM1_CTRL_REG (SUNXI_PWM_BASE + 0x80) +#define SUNXI_V2_PWM1_CLK_REG (SUNXI_PWM_BASE + 0x20) +#define SUNXI_V2_PWM1_EN (1 << 1) -#define SUNXI_V2_PWM2_PERIOD (SUNXI_PWM_BASE + 0xA4) -#define SUNXI_V2_PWM2_CTRL_REG (SUNXI_PWM_BASE + 0xA0) -#define SUNXI_V2_PWM2_CLK_REG (SUNXI_PWM_BASE + 0x24) -#define SUNXI_V2_PWM2_EN (1 << 2) +#define SUNXI_V2_PWM2_PERIOD (SUNXI_PWM_BASE + 0xA4) +#define SUNXI_V2_PWM2_CTRL_REG (SUNXI_PWM_BASE + 0xA0) +#define SUNXI_V2_PWM2_CLK_REG (SUNXI_PWM_BASE + 0x24) +#define SUNXI_V2_PWM2_EN (1 << 2) -#define SUNXI_V2_PWM3_PERIOD (SUNXI_PWM_BASE + 0xC4) -#define SUNXI_V2_PWM3_CTRL_REG (SUNXI_PWM_BASE + 0xC0) -#define SUNXI_V2_PWM3_CLK_REG (SUNXI_PWM_BASE + 0x24) -#define SUNXI_V2_PWM3_EN (1 << 3) +#define SUNXI_V2_PWM3_PERIOD (SUNXI_PWM_BASE + 0xC4) +#define SUNXI_V2_PWM3_CTRL_REG (SUNXI_PWM_BASE + 0xC0) +#define SUNXI_V2_PWM3_CLK_REG (SUNXI_PWM_BASE + 0x24) +#define SUNXI_V2_PWM3_EN (1 << 3) -#define SUNXI_V2_PWM4_PERIOD (SUNXI_PWM_BASE + 0xE4) -#define SUNXI_V2_PWM4_CTRL_REG (SUNXI_PWM_BASE + 0xE0) -#define SUNXI_V2_PWM4_CLK_REG (SUNXI_PWM_BASE + 0x28) -#define SUNXI_V2_PWM4_EN (1 << 4) +#define SUNXI_V2_PWM4_PERIOD (SUNXI_PWM_BASE + 0xE4) +#define SUNXI_V2_PWM4_CTRL_REG (SUNXI_PWM_BASE + 0xE0) +#define SUNXI_V2_PWM4_CLK_REG (SUNXI_PWM_BASE + 0x28) +#define SUNXI_V2_PWM4_EN (1 << 4) #define PWM_CLK_DIV_120 0 #define PWM_CLK_DIV_180 1 @@ -177,66 +177,123 @@ typedef struct { #define PWM_CLK_DIV_48K 11 #define PWM_CLK_DIV_72K 12 -#define SUNXI_PUD_OFF 0 -#define SUNXI_PUD_UP 1 -#define SUNXI_PUD_DOWN 2 +#define SUNXI_PUD_OFF 0 +#define SUNXI_PUD_UP 1 +#define SUNXI_PUD_DOWN 2 /*********** Rockchip RK3588 *************/ //gpio0~gpio4 register base addr -#define RK3588_GPIO0_BASE 0xfd8a0000U -#define RK3588_GPIO1_BASE 0xfec20000U -#define RK3588_GPIO2_BASE 0xfec30000U -#define RK3588_GPIO3_BASE 0xfec40000U -#define RK3588_GPIO4_BASE 0xfec50000U +#define RK3588_GPIO0_BASE 0xfd8a0000U +#define RK3588_GPIO1_BASE 0xfec20000U +#define RK3588_GPIO2_BASE 0xfec30000U +#define RK3588_GPIO3_BASE 0xfec40000U +#define RK3588_GPIO4_BASE 0xfec50000U //gpio offset -#define RK3588_GPIO_SWPORT_DR_L_OFFSET 0x00U -#define RK3588_GPIO_SWPORT_DR_H_OFFSET 0x04U -#define RK3588_GPIO_SWPORT_DDR_L_OFFSET 0x08U -#define RK3588_GPIO_SWPORT_DDR_H_OFFSET 0x0cU -#define RK3588_GPIO_EXT_PORT_OFFSET 0x70U +#define RK3588_GPIO_SWPORT_DR_L_OFFSET 0x00U +#define RK3588_GPIO_SWPORT_DR_H_OFFSET 0x04U +#define RK3588_GPIO_SWPORT_DDR_L_OFFSET 0x08U +#define RK3588_GPIO_SWPORT_DDR_H_OFFSET 0x0cU +#define RK3588_GPIO_EXT_PORT_OFFSET 0x70U //CRU clock-controller base addr -#define RK3588_CRU_BASE 0xfd7c0000U -#define RK3588_CRU_GATE_CON16_OFFSET 0x0840U //for gpio1 bit 14 15 30 31 -#define RK3588_CRU_GATE_CON17_OFFSET 0x0844U //for gpio2/3/4 - bit 0 1 2 3 4 5 16 17 18 19 20 21 +#define RK3588_CRU_BASE 0xfd7c0000U +#define RK3588_CRU_GATE_CON16_OFFSET 0x0840U //for gpio1 bit 14 15 30 31 +#define RK3588_CRU_GATE_CON17_OFFSET 0x0844U //for gpio2/3/4 - bit 0 1 2 3 4 5 16 17 18 19 20 21 -#define RK3588_PMU1CRU_BASE 0xfd7f0000U -#define RK3588_PMU1CRU_GATE_CON5_OFFSET 0x0814U //for gpio0 - bit 5 6 21 22 +#define RK3588_PMU1CRU_BASE 0xfd7f0000U +#define RK3588_PMU1CRU_GATE_CON5_OFFSET 0x0814U //for gpio0 - bit 5 6 21 22 -#define RK3588_GPIO_NUM (0x40) -#define RK3588_GPIO_BIT(x) (1UL << (x)) +#define RK3588_GPIO_NUM (0x40) +#define RK3588_GPIO_BIT(x) (1UL << (x)) //gpio iomux -#define RK3588_PMU1_IOC_BASE 0xfd5f0000U -#define RK3588_PMU1_IOC_GPIO0A_IOMUX_SEL_L 0x00U //gpio0a0~gpio0b3 -#define RK3588_PMU1_IOC_GPIO0A_IOMUX_SEL_H 0x04U //gpio0a4~gpio0b7 -#define RK3588_PMU1_IOC_GPIO0B_IOMUX_SEL_L 0x08U //gpio0b0~gpio0b3 +#define RK3588_PMU1_IOC_BASE 0xfd5f0000U +#define RK3588_PMU1_IOC_GPIO0A_IOMUX_SEL_L 0x00U //gpio0a0~gpio0b3 +#define RK3588_PMU1_IOC_GPIO0A_IOMUX_SEL_H 0x04U //gpio0a4~gpio0b7 +#define RK3588_PMU1_IOC_GPIO0B_IOMUX_SEL_L 0x08U //gpio0b0~gpio0b3 -#define RK3588_PMU2_IOC_BASE 0xfd5f4000U -#define RK3588_PMU2_IOC_GPIO0B_IOMUX_SEL_H 0x00U //gpio0a5~gpio0b7 -#define RK3588_PMU2_IOC_GPIO0C_IOMUX_SEL_L 0x04U //gpio0a0~gpio0b3 -#define RK3588_PMU2_IOC_GPIO0C_IOMUX_SEL_H 0x08U //gpio0a4~gpio0b7 -#define RK3588_PMU2_IOC_GPIO0D_IOMUX_SEL_L 0x0cU //gpio0a0~gpio0b3 -#define RK3588_PMU2_IOC_GPIO0D_IOMUX_SEL_H 0x10U //gpio0a4~gpio0b6 +#define RK3588_PMU2_IOC_BASE 0xfd5f4000U +#define RK3588_PMU2_IOC_GPIO0B_IOMUX_SEL_H 0x00U //gpio0a5~gpio0b7 +#define RK3588_PMU2_IOC_GPIO0C_IOMUX_SEL_L 0x04U //gpio0a0~gpio0b3 +#define RK3588_PMU2_IOC_GPIO0C_IOMUX_SEL_H 0x08U //gpio0a4~gpio0b7 +#define RK3588_PMU2_IOC_GPIO0D_IOMUX_SEL_L 0x0cU //gpio0a0~gpio0b3 +#define RK3588_PMU2_IOC_GPIO0D_IOMUX_SEL_H 0x10U //gpio0a4~gpio0b6 -#define RK3588_BUS_IOC_BASE 0xfd5f8000U +#define RK3588_BUS_IOC_BASE 0xfd5f8000U //gpio pull up/down -#define RK3588_VCCIO1_4_IOC_BASE 0xfd5f9000U -#define RK3588_VCCIO3_5_IOC_BASE 0xfd5fa000U -#define RK3588_VCCIO6_IOC_BASE 0xfd5fc000U +#define RK3588_VCCIO1_4_IOC_BASE 0xfd5f9000U +#define RK3588_VCCIO3_5_IOC_BASE 0xfd5fa000U +#define RK3588_VCCIO6_IOC_BASE 0xfd5fc000U -#define RK3588_PMU1_IOC_GPIO0A_P 0x0020U -#define RK3588_PMU1_IOC_GPIO0B_P 0x0024U -#define RK3588_PMU2_IOC_GPIO0B_P 0x0028U -#define RK3588_PMU2_IOC_GPIO0C_P 0x002cU -#define RK3588_PMU2_IOC_GPIO0D_P 0x0030U -#define RK3588_VCCIO1_4_IOC_GPIO1A_P 0x0110U -#define RK3588_VCCIO3_5_IOC_GPIO2A_P 0x0120U -#define RK3588_VCCIO6_IOC_GPIO4A_P 0x0140U +#define RK3588_PMU1_IOC_GPIO0A_P 0x0020U +#define RK3588_PMU1_IOC_GPIO0B_P 0x0024U +#define RK3588_PMU2_IOC_GPIO0B_P 0x0028U +#define RK3588_PMU2_IOC_GPIO0C_P 0x002cU +#define RK3588_PMU2_IOC_GPIO0D_P 0x0030U +#define RK3588_VCCIO1_4_IOC_GPIO1A_P 0x0110U +#define RK3588_VCCIO3_5_IOC_GPIO2A_P 0x0120U +#define RK3588_VCCIO6_IOC_GPIO4A_P 0x0140U + +//pwm register base addr +//#define RK3588_CRU_BASE 0xfd7c0000U +//#define RK3588_PMU1CRU_BASE 0xfd7f0000U +#define RK3588_PWM0_BASE 0xfd8b0000U +#define RK3588_PWM1_BASE 0xfe8d0000U +#define RK3588_PWM2_BASE 0xfebe0000U +#define RK3588_PWM3_BASE 0xfebf0000U + +//cru +#define RK3588_CRU_GATE_CON19 (RK3588_CRU_BASE + 0x084CU) //for busioc_clk_en +#define RK3588_CRU_GATE_CON15 (RK3588_CRU_BASE + 0x083CU) //for pwm123_clk_en +#define RK3588_PMU1CRU_GATE_CON1 (RK3588_PMU1CRU_BASE +0x0804U) //for pmu1pwm_clk_en + +//CH0 +#define RK3588_CH0_PERIOD_HPR (RK3588_PWM_BASE + 0x04) +#define RK3588_CH0_DUTY_LPR (RK3588_PWM_BASE + 0x08) +#define RK3588_CH0_CTRL (RK3588_PWM_BASE + 0x0C) + +//CH1 +#define RK3588_CH1_PERIOD_HPR (RK3588_PWM_BASE + 0x14) +#define RK3588_CH1_DUTY_LPR (RK3588_PWM_BASE + 0x18) +#define RK3588_CH1_CTRL (RK3588_PWM_BASE + 0x1C) + +//CH2 +#define RK3588_CH2_PERIOD_HPR (RK3588_PWM_BASE + 0x24) +#define RK3588_CH2_DUTY_LPR (RK3588_PWM_BASE + 0x28) +#define RK3588_CH2_CTRL (RK3588_PWM_BASE + 0x2C) + +//CH3 +#define RK3588_CH3_PERIOD_HPR (RK3588_PWM_BASE + 0x34) +#define RK3588_CH3_DUTY_LPR (RK3588_PWM_BASE + 0x38) +#define RK3588_CH3_CTRL (RK3588_PWM_BASE + 0x3C) + +//for short——pwm +#define RK3588_PWM_BASE (rk3588_soc_info_t.pwm_base) +#define RK3588_PWM_MUX (rk3588_soc_info_t.pwm_mux) +#define RK3588_PWM_MUX_VAL (rk3588_soc_info_t.pwm_mux_val) +#define RK3588_PWM_MUX_OFFSET (rk3588_soc_info_t.pwm_mux_offset) +#define RK3588_CH_PERIOD_HPR (rk3588_soc_info_t.ch_period_hpr) +#define RK3588_CH_DUTY_LPR (rk3588_soc_info_t.ch_duty_lpr) +#define RK3588_CH_CTRL (rk3588_soc_info_t.ch_crtl) + +//pwm_ctrl_offset +#define RK3588_RPT (24) // 24 ~ 31 +#define RK3588_SCALE (16) // 16 ~ 23 +#define RK3588_PRESCALE (12) // 12 ~ 14 +#define RK3588_CLK_SRC_SEL (10) +#define RK3588_CLK_SEL (9) +#define RK3588_FORCE_CLK_EN (8) +#define RK3588_CH_CNT_EN (7) +#define RK3588_CONLOCK (6) +#define RK3588_OUTPUT_MODE (5) +#define RK3588_INACTIVE_POL (4) +#define RK3588_DUTY_POL (3) +#define RK3588_PWM_MODE (1) // 1 ~ 2 +#define RK3588_PWM_EN (0) typedef struct { unsigned int * gpio0_base; @@ -255,6 +312,18 @@ typedef struct { unsigned int * vccio1_4_ioc_base; unsigned int * vccio3_5_ioc_base; unsigned int * vccio6_ioc_base; + + unsigned int * pwm0_base; + unsigned int * pwm1_base; + unsigned int * pwm2_base; + unsigned int * pwm3_base; + unsigned int pwm_base; + unsigned int pwm_mux; + unsigned int pwm_mux_val; + unsigned int pwm_mux_offset; + unsigned int ch_period_hpr; + unsigned int ch_duty_lpr; + unsigned int ch_crtl; } rk3588_soc_info; /*********** Rockchip RK3588 *************/ @@ -262,33 +331,74 @@ typedef struct { /*********** Rockchip RK3566 *************/ //gpio0~gpio4 register base addr -#define RK3566_GPIO0_BASE 0xfdd60000U -#define RK3566_GPIO1_BASE 0xfe740000U -#define RK3566_GPIO2_BASE 0xfe750000U -#define RK3566_GPIO3_BASE 0xfe760000U -#define RK3566_GPIO4_BASE 0xfe770000U +#define RK3566_GPIO0_BASE 0xfdd60000U +#define RK3566_GPIO1_BASE 0xfe740000U +#define RK3566_GPIO2_BASE 0xfe750000U +#define RK3566_GPIO3_BASE 0xfe760000U +#define RK3566_GPIO4_BASE 0xfe770000U //gpio offset -#define RK3566_GPIO_SWPORT_DR_L_OFFSET 0x00U -#define RK3566_GPIO_SWPORT_DR_H_OFFSET 0x04U -#define RK3566_GPIO_SWPORT_DDR_L_OFFSET 0x08U -#define RK3566_GPIO_SWPORT_DDR_H_OFFSET 0x0cU -#define RK3566_GPIO_EXT_PORT_OFFSET 0x70U +#define RK3566_GPIO_SWPORT_DR_L_OFFSET 0x00U +#define RK3566_GPIO_SWPORT_DR_H_OFFSET 0x04U +#define RK3566_GPIO_SWPORT_DDR_L_OFFSET 0x08U +#define RK3566_GPIO_SWPORT_DDR_H_OFFSET 0x0cU +#define RK3566_GPIO_EXT_PORT_OFFSET 0x70U -#define RK3566_PMU_GRF_BASE 0xfdc20000U -#define RK3566_SYS_GRF_BASE 0xfdc60000U -#define RK3566_PMU_CRU_BASE 0xfdd00000U -#define RK3566_CRU_BASE 0xFdd20000U +#define RK3566_PMU_GRF_BASE 0xfdc20000U +#define RK3566_SYS_GRF_BASE 0xfdc60000U +#define RK3566_PMU_CRU_BASE 0xfdd00000U +#define RK3566_CRU_BASE 0xFdd20000U -// clock -#define RK3566_CRU_GATE_CON31_OFFSET 0x37CU -#define RK3566_PMUCRU_PMUGATE_CON01_OFFSET 0x184U //bit 9 bit10 0 enable +//clock +#define RK3566_CRU_GATE_CON31_OFFSET 0x37CU +#define RK3566_CRU_GATE_CON31 (RK3566_CRU_BASE + 0x37CU) +#define RK3566_CRU_GATE_CON32_OFFSET 0x380U +#define RK3566_CRU_GATE_CON32 (RK3566_CRU_BASE + 0x380U) +#define RK3566_PMUCRU_PMUGATE_CON01_OFFSET 0x184U //bit 9 bit10 0 enable -// iomux + pull up/down -#define RK3566_GRF_GPIO1A_IOMUX_L_OFFSET 0x00U -#define RK3566_GRF_GPIO1A_P_OFFSET 0x80U -#define RK3566_PMU_GRF_GPIO0A_IOMUX_L_OFFSET 0x00U -#define RK3566_PMU_GRF_GPIO0A_P_OFFSET 0x20U +//iomux + pull up/down +#define RK3566_GRF_GPIO1A_IOMUX_L_OFFSET 0x00U +#define RK3566_GRF_GPIO1A_P_OFFSET 0x80U +#define RK3566_PMU_GRF_GPIO0A_IOMUX_L_OFFSET 0x00U +#define RK3566_PMU_GRF_GPIO0A_P_OFFSET 0x20U + +//pwm mux register +#define RK3566_PWM_MUX_REG (RK3566_SYS_GRF_BASE + 0x70) + +//pwm register base addr +#define RK3566_PWM2_BASE 0xfe6f0000U +#define RK3566_PWM3_BASE 0xfe700000U + +//CH3 +#define RK3566_CH3_PERIOD_HPR (RK3566_PWM_BASE + 0x34) +#define RK3566_CH3_DUTY_LPR (RK3566_PWM_BASE + 0x38) +#define RK3566_CH3_CTRL (RK3566_PWM_BASE + 0x3C) + +//for short——pwm +#define RK3566_CRU_GATE_CON (rk3566_soc_info_t.cru_gate_con) +#define RK3566_CRU_GATE_CON_OFFSET (rk3566_soc_info_t.cru_gate_con_offset) +#define RK3566_PWM_BASE (rk3566_soc_info_t.pwm_base) +#define RK3566_PWM_MUX (rk3566_soc_info_t.pwm_mux) +#define RK3566_PWM_MUX_VAL (rk3566_soc_info_t.pwm_mux_val) +#define RK3566_PWM_MUX_OFFSET (rk3566_soc_info_t.pwm_mux_offset) +#define RK3566_CH_PERIOD_HPR (rk3566_soc_info_t.ch_period_hpr) +#define RK3566_CH_DUTY_LPR (rk3566_soc_info_t.ch_duty_lpr) +#define RK3566_CH_CTRL (rk3566_soc_info_t.ch_crtl) + +//pwm_ctrl_offset +#define RK3566_RPT (24) // 24 ~ 31 +#define RK3566_SCALE (16) // 16 ~ 23 +#define RK3566_PRESCALE (12) // 12 ~ 14 +#define RK3566_CLK_SRC_SEL (10) +#define RK3566_CLK_SEL (9) +#define RK3566_FORCE_CLK_EN (8) +#define RK3566_CH_CNT_EN (7) +#define RK3566_CONLOCK (6) +#define RK3566_OUTPUT_MODE (5) +#define RK3566_INACTIVE_POL (4) +#define RK3566_DUTY_POL (3) +#define RK3566_PWM_MODE (1) // 1 ~ 2 +#define RK3566_PWM_EN (0) typedef struct { unsigned int * gpio0_base; @@ -302,6 +412,18 @@ typedef struct { unsigned int * cru_base; unsigned int * pmu_cru_base; + + unsigned int * pwm2_base; + unsigned int * pwm3_base; + unsigned int cru_gate_con; + unsigned int cru_gate_con_offset; + unsigned int pwm_base; + unsigned int pwm_mux; + unsigned int pwm_mux_val; + unsigned int pwm_mux_offset; + unsigned int ch_period_hpr; + unsigned int ch_duty_lpr; + unsigned int ch_crtl; } rk3566_soc_info; /*********** Rockchip RK3566 *************/ @@ -309,24 +431,24 @@ typedef struct { /*********** Rockchip RK3399 *************/ -#define RK3399_GPIO1_BASE 0xff730000U -#define RK3399_GPIO2_BASE 0xff780000U -#define RK3399_GPIO4_BASE 0xff790000U -#define RK3399_GPIO_NUM (0x40) -#define RK3399_GPIO_BIT(x) (1UL << (x)) -#define RK3399_GPIO_SWPORTA_DR_OFFSET 0x00U -#define RK3399_GPIO_SWPORTA_DDR_OFFSET 0x04U -#define RK3399_GPIO_EXT_PORTA_OFFSET 0x50U +#define RK3399_GPIO1_BASE 0xff730000U +#define RK3399_GPIO2_BASE 0xff780000U +#define RK3399_GPIO4_BASE 0xff790000U +#define RK3399_GPIO_NUM (0x40) +#define RK3399_GPIO_BIT(x) (1UL << (x)) +#define RK3399_GPIO_SWPORTA_DR_OFFSET 0x00U +#define RK3399_GPIO_SWPORTA_DDR_OFFSET 0x04U +#define RK3399_GPIO_EXT_PORTA_OFFSET 0x50U -#define RK3399_GRF_GPIO2_3_4_P_OFFSET 0x00040U -#define RK3399_PMUGRF_GPIO0_1_P_OFFSET 0x00040U +#define RK3399_GRF_GPIO2_3_4_P_OFFSET 0x00040U +#define RK3399_PMUGRF_GPIO0_1_P_OFFSET 0x00040U -#define RK3399_PMUGRF_BASE 0xff320000U -#define RK3399_GRF_BASE 0xff77e000U -#define RK3399_CRU_BASE 0xff760000U -#define RK3399_PMUCRU_BASE 0xff750000U -#define RK3399_CRU_CLKGATE_CON31_OFFSET 0x037cU //bit 3 4 5 -#define RK3399_PMUCRU_CLKGATE_CON1_OFFSET 0x0104U +#define RK3399_PMUGRF_BASE 0xff320000U +#define RK3399_GRF_BASE 0xff77e000U +#define RK3399_CRU_BASE 0xff760000U +#define RK3399_PMUCRU_BASE 0xff750000U +#define RK3399_CRU_CLKGATE_CON31_OFFSET 0x037cU //bit 3 4 5 +#define RK3399_PMUCRU_CLKGATE_CON1_OFFSET 0x0104U typedef struct { unsigned int * gpio2_base; @@ -344,15 +466,15 @@ typedef struct { /*********** Rockchip RK3328 *************/ -#define RK3328_GPIO2_BASE 0xff230000 -#define RK3328_GPIO3_BASE 0xff240000 -#define RK3328_GPIO_NUM (0x40) -#define RK3328_GPIO_SWPORTA_DR_OFFSET 0x00 -#define RK3328_GPIO_SWPORTA_DDR_OFFSET 0x04 -#define RK3328_GPIO_EXT_PORTA_OFFSET 0x50 -#define RK3328_GRF_BASE 0xff100000 -#define RK3328_CRU_BASE 0xff440000 -#define RK3328_CRU_CLKGATE_CON16_OFFSET 0x0240 //bit 7 8 9 10 9877 +#define RK3328_GPIO2_BASE 0xff230000 +#define RK3328_GPIO3_BASE 0xff240000 +#define RK3328_GPIO_NUM (0x40) +#define RK3328_GPIO_SWPORTA_DR_OFFSET 0x00 +#define RK3328_GPIO_SWPORTA_DDR_OFFSET 0x04 +#define RK3328_GPIO_EXT_PORTA_OFFSET 0x50 +#define RK3328_GRF_BASE 0xff100000 +#define RK3328_CRU_BASE 0xff440000 +#define RK3328_CRU_CLKGATE_CON16_OFFSET 0x0240 //bit 7 8 9 10 9877 typedef struct { unsigned int * gpio2_base; @@ -364,6 +486,106 @@ typedef struct { /*********** Rockchip RK3328 *************/ +/*************** S905D3 ******************/ + +#define S905D3_GPIO_BASE 0xFF634000 +#define S905D3_GPIO_AO_BASE 0xFF800000 +#define S905D3_GPIO_PWM_BASE 0xFFD19000 +#define S905D3_GPIO_PWM_AO_BASE 0xFF802000 + +//GPIOA +#define S905D3_GPIOA_OUT_EN_REG (S905D3_GPIO_BASE + 0x120) +#define S905D3_GPIOA_OUT_REG (S905D3_GPIO_BASE + 0x121) +#define S905D3_GPIOA_IN_REG (S905D3_GPIO_BASE + 0x122) +#define S905D3_GPIOA_PUPD_REG (S905D3_GPIO_BASE + 0x13F) +#define S905D3_GPIOA_PUEN_REG (S905D3_GPIO_BASE + 0x14D) +#define S905D3_GPIOA_MUX_REG1 (S905D3_GPIO_BASE + 0x1BD) +#define S905D3_GPIOA_MUX_REG2 (S905D3_GPIO_BASE + 0x1BE) + +//GPIOC +#define S905D3_GPIOC_OUT_EN_REG (S905D3_GPIO_BASE + 0x113) +#define S905D3_GPIOC_OUT_REG (S905D3_GPIO_BASE + 0x114) +#define S905D3_GPIOC_IN_REG (S905D3_GPIO_BASE + 0x115) +#define S905D3_GPIOC_PUPD_REG (S905D3_GPIO_BASE + 0x13B) +#define S905D3_GPIOC_PUEN_REG (S905D3_GPIO_BASE + 0x149) +#define S905D3_GPIOC_MUX_REG (S905D3_GPIO_BASE + 0x1B9) + +//GPIOH +#define S905D3_GPIOH_OUT_EN_REG (S905D3_GPIO_BASE + 0x119) +#define S905D3_GPIOH_OUT_REG (S905D3_GPIO_BASE + 0x11A) +#define S905D3_GPIOH_IN_REG (S905D3_GPIO_BASE + 0x11B) +#define S905D3_GPIOH_PUPD_REG (S905D3_GPIO_BASE + 0x13D) +#define S905D3_GPIOH_PUEN_REG (S905D3_GPIO_BASE + 0x14B) +#define S905D3_GPIOH_MUX_REG1 (S905D3_GPIO_BASE + 0x1BB) +#define S905D3_GPIOH_MUX_REG2 (S905D3_GPIO_BASE + 0x1BC) + +//GPIOAO +#define S905D3_GPIOAO_OUT_EN_REG (S905D3_GPIO_AO_BASE + 0x109) +#define S905D3_GPIOAO_OUT_REG (S905D3_GPIO_AO_BASE + 0x10D) +#define S905D3_GPIOAO_IN_REG (S905D3_GPIO_AO_BASE + 0x10A) +#define S905D3_GPIOAO_PUPD_REG (S905D3_GPIO_AO_BASE + 0x10B) +#define S905D3_GPIOAO_PUEN_REG (S905D3_GPIO_AO_BASE + 0x10C) +#define S905D3_GPIOAO_MUX_REG1 (S905D3_GPIO_AO_BASE + 0x105) +#define S905D3_GPIOAO_MUX_REG2 (S905D3_GPIO_AO_BASE + 0x106) + +//for short——gpio +#define S905D3_GPIO_OUT_EN (s905d3_gpio_info_t.gpio_out_en) +#define S905D3_GPIO_OUT (s905d3_gpio_info_t.gpio_out) +#define S905D3_GPIO_IN (s905d3_gpio_info_t.gpio_in) +#define S905D3_GPIO_PUPD (s905d3_gpio_info_t.gpio_pupd) +#define S905D3_GPIO_PUEN (s905d3_gpio_info_t.gpio_puen) +#define S905D3_GPIO_MUX (s905d3_gpio_info_t.gpio_mux) +#define S905D3_GPIO_OUT_EN_OFFSET (s905d3_gpio_info_t.gpio_out_en_offset) +#define S905D3_GPIO_OUT_OFFSET (s905d3_gpio_info_t.gpio_out_offset) +#define S905D3_GPIO_IN_OFFSET (s905d3_gpio_info_t.gpio_in_offset) +#define S905D3_GPIO_PUPD_OFFSET (s905d3_gpio_info_t.gpio_pupd_offset) +#define S905D3_GPIO_PUEN_OFFSET (s905d3_gpio_info_t.gpio_puen_offset) +#define S905D3_GPIO_MUX_OFFSET (s905d3_gpio_info_t.gpio_mux_offset) + +//PWM +#define S905D3_PWM_DUTY_CYCLE_F_REG (S905D3_GPIO_PWM_BASE + 0x01) +#define S905D3_PWM_MISC_EF_REG (S905D3_GPIO_PWM_BASE + 0x02) +#define S905D3_PWM_DUTY_CYCLE_AO_C_REG (S905D3_GPIO_PWM_AO_BASE) +#define S905D3_PWM_MISC_AO_CD_REG (S905D3_GPIO_PWM_AO_BASE + 0x02) + +//for short——pwm +#define S905D3_PWM_DUTY_CYCLE (s905d3_gpio_info_t.pwm_duty_cycle) +#define S905D3_PWM_MISC (s905d3_gpio_info_t.pwm_misc) + +//PWM_MISC_OFFSET +#define S905D3_PWM_CLK_EN_1 (23) +#define S905D3_PWM_CLK_DIV_1 (16) // 22 ~ 16 +#define S905D3_PWM_CLK_EN_0 (15) +#define S905D3_PWM_CLK_DIV_0 (8) // 8 ~ 14 +#define S905D3_PWM_CLK_SEL_1 (6) // 7 ~ 6 +#define S905D3_PWM_CLK_SEL_0 (4) // 5 ~ 4 +#define S905D3_PWM_EN_1 (1) +#define S905D3_PWM_EN_0 (0) + +typedef struct { + unsigned int * gpio_base; + unsigned int * gpio_ao_base; + unsigned int * gpio_pwm_base; + unsigned int * gpio_pwm_ao_base; + unsigned int gpio_out_en; + unsigned int gpio_out; + unsigned int gpio_in; + unsigned int gpio_pupd; + unsigned int gpio_puen; + unsigned int gpio_mux; + unsigned int gpio_out_en_offset; + unsigned int gpio_out_offset; + unsigned int gpio_in_offset; + unsigned int gpio_pupd_offset; + unsigned int gpio_puen_offset; + unsigned int gpio_mux_offset; + unsigned int pwm_duty_cycle; + unsigned int pwm_misc; +} s905d3_gpio_info; + +/*************** S905D3 ******************/ + + // Mask for the bottom 64 pins which belong to the Raspberry Pi // The others are available for the other devices @@ -376,89 +598,92 @@ extern int wiringPiDebug; // wiringPi modes -#define WPI_MODE_PINS 0 -#define WPI_MODE_GPIO 1 -#define WPI_MODE_GPIO_SYS 2 -#define WPI_MODE_PHYS 3 -#define WPI_MODE_PIFACE 4 -#define WPI_MODE_UNINITIALISED -1 +#define WPI_MODE_PINS 0 +#define WPI_MODE_GPIO 1 +#define WPI_MODE_GPIO_SYS 2 +#define WPI_MODE_PHYS 3 +#define WPI_MODE_PIFACE 4 +#define WPI_MODE_UNINITIALISED -1 // Pin modes -#define INPUT 0 -#define OUTPUT 1 -#define PWM_OUTPUT 2 -#define GPIO_CLOCK 3 -#define SOFT_PWM_OUTPUT 4 -#define SOFT_TONE_OUTPUT 5 -#define PWM_TONE_OUTPUT 6 +#define INPUT 0 +#define OUTPUT 1 +#define PWM_OUTPUT 2 +#define GPIO_CLOCK 3 +#define SOFT_PWM_OUTPUT 4 +#define SOFT_TONE_OUTPUT 5 +#define PWM_TONE_OUTPUT 6 -#define LOW 0 -#define HIGH 1 +#define LOW 0 +#define HIGH 1 // Pull up/down/none -#define PUD_OFF 0 -#define PUD_DOWN 1 -#define PUD_UP 2 +#define PUD_OFF 0 +#define PUD_DOWN 1 +#define PUD_UP 2 // PWM -#define PWM_MODE_MS 0 -#define PWM_MODE_BAL 1 +#define PWM_MODE_MS 0 +#define PWM_MODE_BAL 1 // Interrupt levels -#define INT_EDGE_SETUP 0 -#define INT_EDGE_FALLING 1 -#define INT_EDGE_RISING 2 -#define INT_EDGE_BOTH 3 +#define INT_EDGE_SETUP 0 +#define INT_EDGE_FALLING 1 +#define INT_EDGE_RISING 2 +#define INT_EDGE_BOTH 3 // Pi model types and version numbers // Intended for the GPIO program Use at your own risk. /* Allwinner H6 */ -#define PI_MODEL_3 0 -#define PI_MODEL_LTIE_2 1 +#define PI_MODEL_3 0 +#define PI_MODEL_LTIE_2 1 /* Allwinner H2+ */ -#define PI_MODEL_ZERO 2 +#define PI_MODEL_ZERO 2 /* Allwinner H3 */ -#define PI_MODEL_H3 3 -#define PI_MODEL_ZERO_PLUS_2 4 +#define PI_MODEL_H3 3 +#define PI_MODEL_ZERO_PLUS_2 4 /* Allwinner A64 */ -#define PI_MODEL_WIN 5 +#define PI_MODEL_WIN 5 /* Allwinner H5 */ -#define PI_MODEL_PRIME 6 -#define PI_MODEL_PC_2 7 -#define PI_MODEL_ZERO_PLUS 8 +#define PI_MODEL_PRIME 6 +#define PI_MODEL_PC_2 7 +#define PI_MODEL_ZERO_PLUS 8 /* Allwinner H616 */ -#define PI_MODEL_ZERO_2 9 -#define PI_MODEL_ZERO_2_W 10 +#define PI_MODEL_ZERO_2 9 +#define PI_MODEL_ZERO_2_W 10 /* Rockchip RK3399 */ -#define PI_MODEL_800 15 -#define PI_MODEL_4 16 -#define PI_MODEL_4_LTS 17 -#define PI_MODEL_RK3399 18 +#define PI_MODEL_800 15 +#define PI_MODEL_4 16 +#define PI_MODEL_4_LTS 17 +#define PI_MODEL_RK3399 18 /* Rockchip RK3328 */ -#define PI_MODEL_R1_PLUS 22 +#define PI_MODEL_R1_PLUS 22 /* Rockchip RK3588(s) */ -#define PI_MODEL_900 23 -#define PI_MODEL_5 24 -#define PI_MODEL_5B 25 -#define PI_MODEL_5_PLUS 26 +#define PI_MODEL_900 23 +#define PI_MODEL_5 24 +#define PI_MODEL_5B 25 +#define PI_MODEL_5_PLUS 26 /* Rockchip RK3566 */ -#define PI_MODEL_CM4 27 -#define PI_MODEL_3B 28 +#define PI_MODEL_CM4 27 +#define PI_MODEL_3B 28 + +/* S905D3 */ +#define PI_MODEL_3_PLUS 29 extern const char *piModelNames [16] ; @@ -571,21 +796,25 @@ extern int wiringPiSetupPiFaceForGpioProg (void) ; // Don't use this - for gpio // On-Board Raspberry Pi hardware specific stuff -extern void piBoardId (int *model) ; -extern int wpiPinToGpio (int wpiPin) ; -extern int physPinToGpio (int physPin) ; -extern void setPadDrive (int group, int value) ; -extern int getAlt (int pin) ; -extern void H618_set_pwm_reg(int pin,sunxi_gpio_info *sunxi_gpio_info_ptr); -extern void pwmToneWrite (int pin, int freq) ; -extern void pwmSetMode(int pin,int mode) ; -extern void pwmSetRange(int pin,unsigned int range) ; -extern void pwmSetClock(int pin,int divisor) ; -extern void gpioClockSet (int pin, int freq) ; -extern unsigned int digitalReadByte (void) ; -extern unsigned int digitalReadByte2 (void) ; -extern void digitalWriteByte (int value) ; -extern void digitalWriteByte2 (int value) ; +extern void piBoardId(int *model) ; +extern int wpiPinToGpio(int wpiPin) ; +extern int physPinToGpio(int physPin) ; +extern void setPadDrive(int group, int value) ; +extern int getAlt(int pin) ; +extern void H618_set_pwm_reg(int pin,sunxi_gpio_info *sunxi_gpio_info_ptr) ; +extern void s905d3_set_gpio_reg(int pin,s905d3_gpio_info *s905d3_gpio_info_ptr) ; +extern void rk3588_set_pwm_reg(int pin,rk3588_soc_info *rk3588_soc_info_ptr) ; +extern void rk3566_set_pwm_reg(int pin,rk3566_soc_info *rk3566_soc_info_ptr) ; +extern void sunxi_pwm_set_enable(int en) ; +extern void pwmToneWrite(int pin, int freq) ; +extern void pwmSetMode(int pin,int mode) ; +extern void pwmSetRange(int pin,unsigned int range) ; +extern void pwmSetClock(int pin,int divisor) ; +extern void gpioClockSet(int pin, int freq) ; +extern unsigned int digitalReadByte(void) ; +extern unsigned int digitalReadByte2(void) ; +extern void digitalWriteByte(int value) ; +extern void digitalWriteByte2(int value) ; // Interrupts // (Also Pi hardware specific) @@ -618,6 +847,10 @@ extern int OrangePi_digitalRead(int pin); extern int OrangePi_digitalWrite(int pin, int value); extern int OrangePi_set_gpio_alt(int pin, int mode); extern void OrangePi_set_gpio_pullUpDnControl (int pin, int pud); +extern void sunxi_pwm_set_act(int pin,int act_cys); +extern void sunxi_pwm_set_period(int pin,unsigned int period_cys); +extern void sunxi_pwm_set_clk(int pin,int clk); +extern void sunxi_pwm_set_tone(int pin,int freq); void set_soc_info(void);