diff --git a/wiringPi/wiringPi.c b/wiringPi/wiringPi.c index 38d7a8f..eb2090e 100644 --- a/wiringPi/wiringPi.c +++ b/wiringPi/wiringPi.c @@ -118,14 +118,20 @@ struct wiringPiNodeStruct *wiringPiNodes = NULL ; // Port function select bits -#define FSEL_INPT 0b000 -#define FSEL_OUTP 0b001 -#define FSEL_ALT0 0b100 -#define FSEL_ALT1 0b101 -#define FSEL_ALT2 0b110 -#define FSEL_ALT3 0b111 -#define FSEL_ALT4 0b011 -#define FSEL_ALT5 0b010 +#define FSEL_INPT 0b000 //0 +#define FSEL_OUTP 0b001 //1 +#define FSEL_ALT0 0b100 //4 +#define FSEL_ALT1 0b101 //5 +#define FSEL_ALT2 0b110 //6 +#define FSEL_ALT3 0b111 //7 +#define FSEL_ALT4 0b011 //3 +#define FSEL_ALT5 0b010 //2 +//RP1 defines +#define FSEL_ALT6 8 +#define FSEL_ALT7 9 +#define FSEL_ALT8 10 +#define FSEL_ALT9 11 + //RP1 chip (@Pi5) - 3.1.1. Function select #define RP1_FSEL_ALT0 0x00 @@ -166,10 +172,40 @@ const unsigned int RP1_PAD_IC_DEFAULT_FROM9 = 0x96; //pull-down, Schmitt const unsigned int RP1_PAD_DRIVE_MASK = 0x00000030; const unsigned int RP1_INV_PAD_DRIVE_MASK = ~(RP1_PAD_DRIVE_MASK); +const unsigned int RP1_PWM0_GLOBAL_CTRL = 0; +const unsigned int RP1_PWM0_FIFO_CTRL = 1; +const unsigned int RP1_PWM0_COMMON_RANGE= 2; +const unsigned int RP1_PWM0_COMMON_DUTY = 3; +const unsigned int RP1_PWM0_DUTY_FIFO = 4; +const unsigned int RP1_PWM0_CHAN_START = 5; +//offset channel +const unsigned int RP1_PWM0_CHAN_CTRL = 0; +const unsigned int RP1_PWM0_CHAN_RANGE = 1; +const unsigned int RP1_PWM0_CHAN_PHASE = 2; +const unsigned int RP1_PWM0_CHAN_DUTY = 3; +const unsigned int RP1_PWM0_CHAN_OFFSET= 4; + +const unsigned int RP1_PWM0_CHAN0_RANGE = RP1_PWM0_CHAN_START+RP1_PWM0_CHAN_OFFSET*0+RP1_PWM0_CHAN_RANGE; +const unsigned int RP1_PWM0_CHAN1_RANGE = RP1_PWM0_CHAN_START+RP1_PWM0_CHAN_OFFSET*1+RP1_PWM0_CHAN_RANGE; +const unsigned int RP1_PWM0_CHAN2_RANGE = RP1_PWM0_CHAN_START+RP1_PWM0_CHAN_OFFSET*2+RP1_PWM0_CHAN_RANGE; +const unsigned int RP1_PWM0_CHAN3_RANGE = RP1_PWM0_CHAN_START+RP1_PWM0_CHAN_OFFSET*3+RP1_PWM0_CHAN_RANGE; + +const unsigned int RP1_PWM_CTRL_SETUPDATE = 0x80000000; // Bit 32 +const unsigned int RP1_PWM_TRAIL_EDGE_MS = 0x1; +const unsigned int RP1_PWM_FIFO_POP_MASK = 0x100; // Bit 8 +const unsigned int RP1_CLK_PWM0_CTRL_DISABLE_MAGIC = 0x10000000; // Default after boot +const unsigned int RP1_CLK_PWM0_CTRL_ENABLE_MAGIC = 0x11000840; // Reverse engineered, because of missing documentation, don't known meaning of of bits + +const unsigned int CLK_PWM0_CTRL = (0x00074/4); +const unsigned int CLK_PWM0_DIV_INT = (0x00078/4); +const unsigned int CLK_PWM0_DIV_FRAC = (0x0007C/4); +const unsigned int CLK_PWM0_SEL = (0x00080/4); + //RP1 chip (@Pi5) address const unsigned long long RP1_64_BASE_Addr = 0x1f000d0000; const unsigned int RP1_BASE_Addr = 0x40000000; -const unsigned int RP1_PWM0_Addr = 0x40098000; // Adress is not mapped to gpiomem device! +const unsigned int RP1_CLOCK_Addr = 0x40018000; // Adress is not mapped to gpiomem device, lower than RP1_IO0_Addr +const unsigned int RP1_PWM0_Addr = 0x40098000; // Adress is not mapped to gpiomem device, lower than RP1_IO0_Addr const unsigned int RP1_IO0_Addr = 0x400d0000; const unsigned int RP1_SYS_RIO0_Addr = 0x400e0000; const unsigned int RP1_PADS0_Addr = 0x400f0000; @@ -195,7 +231,7 @@ const unsigned short pciemem_RP1_Ventor= 0x1de4; const unsigned short pciemem_RP1_Device= 0x0001; static volatile unsigned int GPIO_PADS ; -static volatile unsigned int GPIO_CLOCK_BASE ; +static volatile unsigned int GPIO_CLOCK_ADR ; static volatile unsigned int GPIO_BASE ; static volatile unsigned int GPIO_TIMER ; static volatile unsigned int GPIO_PWM ; @@ -241,6 +277,7 @@ static int wiringPiSetuped = FALSE ; const int PWMCLK_DIVI_MAX = 0xFFF; // 3 Byte max size for Clock devider const int OSC_FREQ_DEFAULT = 192; // x100kHz OSC const int OSC_FREQ_BCM2711 = 540; // x100kHz OSC +const int OSC_FREQ_BCM2712 = 500; // x100kHz OSC - cat /sys/kernel/debug/clk/clk_summary | grep pwm0 // Timer // Word offsets @@ -589,10 +626,10 @@ int GetMaxPin() { #define RETURN_ON_MODEL5 if (PI_MODEL_5 == RaspberryPiModel) { if (wiringPiDebug) printf("Function not supported on Pi5\n"); return; } -int FailOnModel5() { +int FailOnModel5(const char *function) { if (PI_MODEL_5 == RaspberryPiModel) { - return wiringPiFailure (WPI_ALMOST, "Function not supported on Raspberry Pi 5.\n" - " Unable to continue. Keep an eye of new versions at https://github.com/wiringpi/wiringpi\n") ; + return wiringPiFailure (WPI_ALMOST, "Function '%s' not supported on Raspberry Pi 5.\n" + " Unable to continue. Keep an eye of new versions at https://github.com/wiringpi/wiringpi\n", function) ; } return 0; } @@ -715,8 +752,8 @@ static uint8_t gpioToPUDCLK [] = static uint8_t gpioToPwmALT [] = { 0, 0, 0, 0, 0, 0, 0, 0, // 0 -> 7 - 0, 0, 0, 0, FSEL_ALT0, FSEL_ALT0, 0, 0, // 8 -> 15 - 0, 0, FSEL_ALT5, FSEL_ALT5, 0, 0, 0, 0, // 16 -> 23 + 0, 0, 0, 0, FSEL_ALT0, FSEL_ALT0, 0, 0, // 8 -> 15 + 0, 0, FSEL_ALT5, FSEL_ALT5, 0, 0, 0, 0, // 16 -> 23 0, 0, 0, 0, 0, 0, 0, 0, // 24 -> 31 0, 0, 0, 0, 0, 0, 0, 0, // 32 -> 39 FSEL_ALT0, FSEL_ALT0, 0, 0, 0, FSEL_ALT0, 0, 0, // 40 -> 47 @@ -731,8 +768,8 @@ static uint8_t gpioToPwmALT [] = static uint8_t gpioToPwmPort [] = { 0, 0, 0, 0, 0, 0, 0, 0, // 0 -> 7 - 0, 0, 0, 0, PWM0_DATA, PWM1_DATA, 0, 0, // 8 -> 15 - 0, 0, PWM0_DATA, PWM1_DATA, 0, 0, 0, 0, // 16 -> 23 + 0, 0, 0, 0, PWM0_DATA, PWM1_DATA, 0, 0, // 8 -> 15 + 0, 0, PWM0_DATA, PWM1_DATA, 0, 0, 0, 0, // 16 -> 23 0, 0, 0, 0, 0, 0, 0, 0, // 24 -> 31 0, 0, 0, 0, 0, 0, 0, 0, // 32 -> 39 PWM0_DATA, PWM1_DATA, 0, 0, 0, PWM1_DATA, 0, 0, // 40 -> 47 @@ -1287,7 +1324,7 @@ void setPadDrive (int group, int value) int getAlt (int pin) { - int fSel, shift, alt ; + int alt; pin &= 63 ; @@ -1318,29 +1355,28 @@ int getAlt (int pin) 11 = alternate function 9 */ switch(alt) { - case 0: return 4; - case 1: return 5; - case 2: return 6; - case 3: return 7; - case 4: return 3; + case 0: return FSEL_ALT0; + case 1: return FSEL_ALT1; + case 2: return FSEL_ALT2; + case 3: return FSEL_ALT3; + case 4: return FSEL_ALT4; case RP1_FSEL_GPIO: { unsigned int outputmask = gpio[2*pin] & 0x3000; //Bit13-OETOPAD + Bit12-OEFROMPERI - return (outputmask==0x3000) ? 1 : 0; //1=OUT 0=IN + return (outputmask==0x3000) ? FSEL_OUTP : FSEL_INPT; } - case 6: return 8; - case 7: return 9; - case 8: return 10; - case 9: return 11; + case 6: return FSEL_ALT6; + case 7: return FSEL_ALT7; + case 8: return FSEL_ALT8; + case RP1_FSEL_NONE: return FSEL_ALT9; default:return alt; } - } else { - fSel = gpioToGPFSEL [pin] ; - shift = gpioToShift [pin] ; + int fSel = gpioToGPFSEL [pin] ; + int shift = gpioToShift [pin] ; alt = (*(gpio + fSel) >> shift) & 7 ; } - return alt ; + return alt; } @@ -1359,7 +1395,12 @@ void pwmSetMode (int mode) { if ((wiringPiMode == WPI_MODE_PINS) || (wiringPiMode == WPI_MODE_PHYS) || (wiringPiMode == WPI_MODE_GPIO)) { - FailOnModel5(); + if (PI_MODEL_5 == RaspberryPiModel) { + if(mode != PWM_MODE_MS) { + fprintf(stderr, "pwmSetMode: Raspberry Pi 5 missing feature PWM BAL mode\n"); + } + return; + } if (mode == PWM_MODE_MS) { *(pwm + PWM_CONTROL) = PWM0_ENABLE | PWM1_ENABLE | PWM0_MS_MODE | PWM1_MS_MODE ; } else { @@ -1381,7 +1422,6 @@ void pwmSetMode (int mode) void pwmSetRange (unsigned int range) { - FailOnModel5(); if ((wiringPiMode == WPI_MODE_PINS) || (wiringPiMode == WPI_MODE_PHYS) || (wiringPiMode == WPI_MODE_GPIO)) { /* would be possible on ms mode but not on bal, deactivated, use pwmc modify instead @@ -1389,10 +1429,24 @@ void pwmSetRange (unsigned int range) range = (OSC_FREQ_BCM2711*range)/OSC_FREQ_DEFAULT; } */ - *(pwm + PWM0_RANGE) = range ; delayMicroseconds (10) ; - *(pwm + PWM1_RANGE) = range ; delayMicroseconds (10) ; + if (!pwm) { + fprintf(stderr, "wiringPi: pwmSetRange but no pwm memory available, ignoring\n"); + return; + } + int readback = 0x00; + if (PI_MODEL_5 == RaspberryPiModel) { + pwm[RP1_PWM0_CHAN0_RANGE] = range; + pwm[RP1_PWM0_CHAN1_RANGE] = range; + pwm[RP1_PWM0_CHAN2_RANGE] = range; + pwm[RP1_PWM0_CHAN3_RANGE] = range; + readback = pwm[RP1_PWM0_CHAN0_RANGE]; + } else { + *(pwm + PWM0_RANGE) = range ; delayMicroseconds (10) ; + *(pwm + PWM1_RANGE) = range ; delayMicroseconds (10) ; + readback = *(pwm + PWM0_RANGE); + } if (wiringPiDebug) { - printf ("PWM range: %u. Current register: 0x%08X\n", range, *(pwm + PWM0_RANGE)); + printf ("PWM range: %u. Current register: 0x%08X\n", range, readback); } } } @@ -1409,20 +1463,40 @@ void pwmSetRange (unsigned int range) void pwmSetClock (int divisor) { uint32_t pwm_control ; + if (!clk) { + fprintf(stderr, "wiringPi: pwmSetClock but no clk memory available, ignoring\n"); + return; + } - FailOnModel5(); + if (divisor > PWMCLK_DIVI_MAX) { + divisor = PWMCLK_DIVI_MAX; // even on Pi5 4095 is OK + } + if (PI_MODEL_5 == RaspberryPiModel) { + if (divisor < 1) { + if (wiringPiDebug) { printf("Disable PWM0 clock"); } + clk[CLK_PWM0_CTRL] = RP1_CLK_PWM0_CTRL_DISABLE_MAGIC; // 0 = disable on Pi5 + } else { + divisor = (OSC_FREQ_BCM2712*divisor)/OSC_FREQ_DEFAULT; + if (wiringPiDebug) { + printf ("PWM clock divisor: %d\n", divisor) ; + } + //clk[CLK_PWM0_CTRL] = RP1_CLK_PWM0_CTRL_DISABLE_MAGIC; + //delayMicroseconds(100); + clk[CLK_PWM0_DIV_INT] = divisor; + clk[CLK_PWM0_DIV_FRAC] = 0; + clk[CLK_PWM0_SEL] = 1; + clk[CLK_PWM0_CTRL] = RP1_CLK_PWM0_CTRL_ENABLE_MAGIC; + } + return; + } if (piGpioBase == GPIO_PERI_BASE_2711) { //calculate value for OSC 54MHz -> 19.2MHz // Pi 4 max divisor is 1456, Pi0-3 is 4095 (0xFFF) divisor = (OSC_FREQ_BCM2711*divisor)/OSC_FREQ_DEFAULT; } - if (divisor > PWMCLK_DIVI_MAX) { - divisor = PWMCLK_DIVI_MAX; - } if (divisor < 1) { divisor = 1; } - if ((wiringPiMode == WPI_MODE_PINS) || (wiringPiMode == WPI_MODE_PHYS) || (wiringPiMode == WPI_MODE_GPIO)) { if (wiringPiDebug) { @@ -1469,7 +1543,7 @@ void gpioClockSet (int pin, int freq) { int divi, divr, divf ; - FailOnModel5(); + FailOnModel5("gpioClockSet"); pin &= 63 ; /**/ if (wiringPiMode == WPI_MODE_PINS) @@ -1658,9 +1732,6 @@ int requestLine(int pin, unsigned int lineRequestFlags) { void pinModeAlt (int pin, int mode) { - int fSel, shift ; - - RETURN_ON_MODEL5 setupCheck ("pinModeAlt") ; if ((pin & PI_GPIO_MASK) == 0) // On-board pin @@ -1673,20 +1744,49 @@ void pinModeAlt (int pin, int mode) return ; if (PI_MODEL_5 == RaspberryPiModel) { - //confusion! diffrent to to BCM! this is taking directly the value for the register - /* - "alt0" 0b100 - "alt1" 0b101 - "alt2" 0b110 - "alt3" 0b111 - "alt4" 0b011 - "alt5" 0b010 - */ - gpio[2*pin+1] = (mode & RP1_FSEL_NONE_HW) | RP1_DEBOUNCE_DEFAULT; //0-4 function, 5-11 debounce time + int modeRP1; + switch(mode) { + case FSEL_ALT0: + modeRP1 = 0; + break; + case FSEL_ALT1: + modeRP1 = 1; + break; + case FSEL_ALT2: + modeRP1 = 2; + break; + case FSEL_ALT3: + modeRP1 = 3; + break; + case FSEL_ALT4: + modeRP1 = 4; + break; + case FSEL_ALT5: + modeRP1 = 5; + break; + case FSEL_ALT6: + modeRP1 = 6; + break; + case FSEL_ALT7: + modeRP1 = 7; + break; + case FSEL_ALT8: + modeRP1 = 8; + break; + case FSEL_OUTP: + case FSEL_INPT: + modeRP1 = RP1_FSEL_GPIO; + break; + default: + fprintf(stderr, "pinModeAlt: invalid mode %d\n", mode); + return; + } + //printf("pinModeAlt: Pi5 alt pin %d to %d\n", pin, modeRP1); + gpio[2*pin+1] = (modeRP1 & RP1_FSEL_NONE_HW) | RP1_DEBOUNCE_DEFAULT; //0-4 function, 5-11 debounce time } else { - fSel = gpioToGPFSEL [pin] ; - shift = gpioToShift [pin] ; + int fSel = gpioToGPFSEL [pin] ; + int shift = gpioToShift [pin] ; *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | ((mode & 0x7) << shift) ; } @@ -1794,8 +1894,14 @@ void pinMode (int pin, int mode) } else { *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) ; // Sets bits to zero = input } - if (PM_OFF==mode && !usingGpioMem && pwm && PI_MODEL_5!=RaspberryPiModel && gpioToPwmALT[pin]>0) { //PWM pin -> reset + if (PM_OFF==mode && !usingGpioMem && pwm && gpioToPwmALT[pin]>0) { //PWM pin -> reset pwmWrite(origPin, 0); + int channel = gpioToPwmPort[pin]; + if (channel>=0 && channel<=3 && PI_MODEL_5 == RaspberryPiModel) { + unsigned int ctrl = pwm[RP1_PWM0_GLOBAL_CTRL]; + pwm[RP1_PWM0_GLOBAL_CTRL] = (ctrl & ~(1<0x%08X)\n", channel, ctrl, pwm[RP1_PWM0_GLOBAL_CTRL]); + } } } else if (mode == OUTPUT) { if (PI_MODEL_5 == RaspberryPiModel) { @@ -1815,20 +1921,35 @@ void pinMode (int pin, int mode) pwmSetMode (PWM_MODE_MS) ; } else if (PWM_OUTPUT==mode || PWM_MS_OUTPUT==mode || PWM_BAL_OUTPUT==mode) { - RETURN_ON_MODEL5 - if ((alt = gpioToPwmALT [pin]) == 0) // Not a hardware capable PWM pin - return ; usingGpioMemCheck("pinMode PWM") ; // exit on error! - - // Set pin to PWM mode - *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (alt << shift) ; - delayMicroseconds (110) ; // See comments in pwmSetClockWPi - - if (PWM_OUTPUT==mode || PWM_BAL_OUTPUT==mode) { - pwmSetMode(PWM_MODE_BAL); // Pi default mode + alt = gpioToPwmALT[pin]; + if (0==alt) { // Not a hardware capable PWM pin + return; + } + int channel = gpioToPwmPort[pin]; + if (PI_MODEL_5 == RaspberryPiModel) { + if (channel>=0 && channel<=3) { + // enable channel pwm m:s mode + pwm[RP1_PWM0_CHAN_START+RP1_PWM0_CHAN_OFFSET*channel+RP1_PWM0_CHAN_CTRL] = (RP1_PWM_TRAIL_EDGE_MS | RP1_PWM_FIFO_POP_MASK); + // enable pwm global + unsigned int ctrl = pwm[RP1_PWM0_GLOBAL_CTRL]; + pwm[RP1_PWM0_GLOBAL_CTRL] = ctrl | (1<0x%08X)\n", channel, ctrl, pwm[RP1_PWM0_GLOBAL_CTRL]); + //change GPIO mode + pads[1+pin] = RP1_PAD_DEFAULT_FROM9; // enable output + pinModeAlt(origPin, alt); //switch to PWM mode + } } else { - pwmSetMode(PWM_MODE_MS); + // Set pin to PWM mode + *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (alt << shift) ; + delayMicroseconds (110) ; // See comments in pwmSetClockWPi + + if (PWM_OUTPUT==mode || PWM_BAL_OUTPUT==mode) { + pwmSetMode(PWM_MODE_BAL); // Pi default mode + } else { + pwmSetMode(PWM_MODE_MS); + } } if (PWM_OUTPUT==mode) { // predefine pwmSetRange (1024) ; // Default range of 1024 @@ -2173,7 +2294,6 @@ void pwmWrite (int pin, int value) { struct wiringPiNodeStruct *node = wiringPiNodes ; - FailOnModel5(); setupCheck ("pwmWrite") ; if ((pin & PI_GPIO_MASK) == 0) // On-Board Pin @@ -2191,9 +2311,22 @@ void pwmWrite (int pin, int value) } */ usingGpioMemCheck ("pwmWrite") ; - *(pwm + gpioToPwmPort [pin]) = value ; + int channel = gpioToPwmPort[pin]; + int readback = 0x00; + if (PI_MODEL_5 == RaspberryPiModel ) { + if (channel>=0 && channel<=3) { + unsigned int addr = RP1_PWM0_CHAN_START+RP1_PWM0_CHAN_OFFSET*channel+RP1_PWM0_CHAN_DUTY; + pwm[addr] = value; + readback = pwm[addr]; + } else { + fprintf(stderr, "pwmWrite: invalid channel at GPIO pin %d \n", pin); + } + } else { + *(pwm + channel) = value ; + readback = *(pwm + channel); + } if (wiringPiDebug) { - printf ("PWM value: %u. Current register: 0x%08X\n", value, *(pwm + gpioToPwmPort[pin])); + printf ("PWM value(duty): %u. Current register: 0x%08X\n", value, readback); } } else @@ -2251,8 +2384,6 @@ void analogWrite (int pin, int value) void pwmToneWrite (int pin, int freq) { - FailOnModel5(); - setupCheck ("pwmToneWrite") ; if (freq == 0) @@ -2290,7 +2421,7 @@ void digitalWriteByte (const int value) int mask = 1 ; int pin ; - FailOnModel5(); + FailOnModel5("digitalWriteByte"); if (wiringPiMode == WPI_MODE_GPIO_SYS) { @@ -2319,7 +2450,7 @@ unsigned int digitalReadByte (void) uint32_t raw ; uint32_t data = 0 ; - FailOnModel5(); + FailOnModel5("digitalReadByte"); if (wiringPiMode == WPI_MODE_GPIO_SYS) { @@ -2350,7 +2481,7 @@ unsigned int digitalReadByte (void) void digitalWriteByte2 (const int value) { - FailOnModel5(); + FailOnModel5("digitalWriteByte2"); if (wiringPiMode == WPI_MODE_GPIO_SYS) { @@ -2366,7 +2497,7 @@ unsigned int digitalReadByte2 (void) { uint32_t data = 0 ; - FailOnModel5(); + FailOnModel5("digitalReadByte2"); if (wiringPiMode == WPI_MODE_GPIO_SYS) { @@ -2937,6 +3068,17 @@ int wiringPiSetup (void) if (PI_MODEL_5 == model) { gpiomemGlobal = pciemem_RP1; gpiomemModule = gpiomem_RP1; + + // PWM alt pins @RP1 - need to be translated to RP1_FSEL with pinModeAlt + gpioToPwmALT[12] = FSEL_ALT0; + gpioToPwmALT[13] = FSEL_ALT0; + gpioToPwmALT[18] = FSEL_ALT3; + gpioToPwmALT[19] = FSEL_ALT3; + //PWM0 channel @RP1 + gpioToPwmPort[12] = 0; + gpioToPwmPort[13] = 1; + gpioToPwmPort[18] = 2; + gpioToPwmPort[19] = 3; } usingGpioMem = FALSE; @@ -2963,10 +3105,10 @@ int wiringPiSetup (void) if (PI_MODEL_5 != model) { //Set the offsets into the memory interface. - GPIO_PADS = piGpioBase + 0x00100000 ; - GPIO_CLOCK_BASE = piGpioBase + 0x00101000 ; + GPIO_PADS = piGpioBase + 0x00100000 ; + GPIO_CLOCK_ADR = piGpioBase + 0x00101000 ; GPIO_BASE = piGpioBase + 0x00200000 ; - GPIO_TIMER = piGpioBase + 0x0000B000 ; + GPIO_TIMER = piGpioBase + 0x0000B000 ; GPIO_PWM = piGpioBase + 0x0020C000 ; GPIO_RIO = 0x00 ; @@ -2986,7 +3128,7 @@ int wiringPiSetup (void) // Clock control (needed for PWM) - clk = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_CLOCK_BASE) ; + clk = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_CLOCK_ADR) ; if (clk == MAP_FAILED) return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: mmap (CLOCK) failed: %s\n", strerror (errno)) ; @@ -3022,7 +3164,7 @@ int wiringPiSetup (void) unsigned int MMAP_size = (usingGpioMem) ? gpiomem_RP1_Size : pciemem_RP1_Size; GPIO_PADS = (RP1_PADS0_Addr-RP1_IO0_Addr) ; - GPIO_CLOCK_BASE = 0x00; + GPIO_CLOCK_ADR = (RP1_CLOCK_Addr-RP1_BASE_Addr); GPIO_BASE = (RP1_IO0_Addr-RP1_BASE_Addr) ; GPIO_TIMER = 0x00; GPIO_PWM = RP1_PWM0_Addr-RP1_BASE_Addr; @@ -3034,8 +3176,12 @@ int wiringPiSetup (void) return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: mmap failed: %s\n", strerror (errno)) ; if (usingGpioMem) { gpio = base; // RP1 start adress of map memory for gpio (same as module memory) + pwm = NULL; // outside of mapped memory, PWM not available from none root + clk = NULL; // outside of mapped memory, CLK main not available from none root } else { - gpio = &base[GPIO_BASE/4];// RP1 start adress of map memory for gpio + gpio = &base[GPIO_BASE/4]; // RP1 start adress of map memory for gpio + pwm = &base[GPIO_PWM/4]; // RP1 start adress of map memory for pwm0 + clk = &base[GPIO_CLOCK_ADR/4]; // RP1 start adress of map memory for clocks_main } pads = &gpio[GPIO_PADS/4]; // RP1 start adress of map memory for pads rio = &gpio[GPIO_RIO/4]; // RP1 start adress of map memory for rio @@ -3045,19 +3191,19 @@ int wiringPiSetup (void) // Export the base addresses for any external software that might need them _wiringPiBase = base ; _wiringPiGpio = gpio ; - _wiringPiPwm = NULL ; - _wiringPiClk = NULL ; + _wiringPiPwm = pwm ; + _wiringPiClk = clk ; _wiringPiPads = pads ; _wiringPiTimer = NULL ; _wiringPiRio = rio ; } if (wiringPiDebug) { - printf ("wiringPi: memory map gpio 0x%x %s\n", GPIO_BASE , _wiringPiGpio ? "valid" : "invalid"); - printf ("wiringPi: memory map pads 0x%x %s\n", GPIO_PADS , _wiringPiPads ? "valid" : "invalid"); - printf ("wiringPi: memory map rio 0x%x %s\n", GPIO_RIO , _wiringPiRio ? "valid" : "invalid"); - printf ("wiringPi: memory map pwm 0x%x %s\n", GPIO_PWM , _wiringPiPwm ? "valid" : "invalid"); - printf ("wiringPi: memory map clk 0x%x %s\n", GPIO_CLOCK_BASE, _wiringPiClk ? "valid" : "invalid"); - printf ("wiringPi: memory map timer 0x%x %s\n", GPIO_TIMER,_wiringPiTimer ? "valid" : "invalid"); + printf ("wiringPi: memory map gpio 0x%x %s\n", GPIO_BASE , _wiringPiGpio ? "valid" : "invalid"); + printf ("wiringPi: memory map pads 0x%x %s\n", GPIO_PADS , _wiringPiPads ? "valid" : "invalid"); + printf ("wiringPi: memory map rio 0x%x %s\n", GPIO_RIO , _wiringPiRio ? "valid" : "invalid"); + printf ("wiringPi: memory map pwm0 0x%x %s\n", GPIO_PWM , _wiringPiPwm ? "valid" : "invalid"); + printf ("wiringPi: memory map clocks 0x%x %s\n", GPIO_CLOCK_ADR, _wiringPiClk ? "valid" : "invalid"); + printf ("wiringPi: memory map timer 0x%x %s\n", GPIO_TIMER ,_wiringPiTimer ? "valid" : "invalid"); } initialiseEpoch () ;