From 2d2d854280d57569f3b072d09a771a6142fc9aa6 Mon Sep 17 00:00:00 2001 From: F5OEO Date: Sun, 18 Aug 2019 13:32:09 +0100 Subject: [PATCH] pi4 detection and CLKOSC according --- app/testrpitx.cpp | 34 +++++++++++- src/gpio.cpp | 128 +++++++++++++++++++++++++++++++------------ src/gpio.h | 17 ++++-- src/phasedmasync.cpp | 2 +- 4 files changed, 140 insertions(+), 41 deletions(-) diff --git a/app/testrpitx.cpp b/app/testrpitx.cpp index 95edf55..d72c15d 100644 --- a/app/testrpitx.cpp +++ b/app/testrpitx.cpp @@ -701,10 +701,40 @@ void SimpleTestAtv(uint64_t Freq) } } -void info(void) +void info(uint64_t Freq) { + generalgpio genpio; + fprintf(stderr, "GPIOPULL =%x\n", genpio.gpioreg[GPPUDCLK0]); + +#define PULL_OFF 0 +#define PULL_DOWN 1 +#define PULL_UP 2 + /*genpio.gpioreg[GPPUD] = 0; //PULL_DOWN; + usleep(150); + genpio.gpioreg[GPPUDCLK0] = (1 << 4); //GPIO CLK is GPIO 4 + usleep(150); + genpio.gpioreg[GPPUDCLK0] = (0); //GPIO CLK is GPIO 4 + */ + //genpio.setpulloff(4); + + padgpio pad; + pad.setlevel(7); + clkgpio clk; clk.print_clock_tree(); + clk.SetPllNumber(clk_plld, 2); + clk.enableclk(4); + //clk.SetAdvancedPllMode(true); + //clk.SetPLLMasterLoop(0,4,0); + //clk.Setppm(+7.7); + clk.SetCenterFrequency(Freq, 1000); + double freqresolution = clk.GetFrequencyResolution(); + double RealFreq = clk.GetRealFrequency(0); + fprintf(stderr, "Frequency resolution=%f Error freq=%f\n", freqresolution, RealFreq); + int Deviation = 0; + clk.SetFrequency(000); + sleep(10); + clk.disableclk(4); } @@ -744,5 +774,5 @@ int main(int argc, char *argv[]) //SimpleTestbpsk(Freq); //SimpleTestAtv(Freq); - info(); + info(Freq); } diff --git a/src/gpio.cpp b/src/gpio.cpp index 67d5a8c..d625f09 100644 --- a/src/gpio.cpp +++ b/src/gpio.cpp @@ -31,7 +31,8 @@ extern "C" { gpio::gpio(uint32_t base, uint32_t len) { - gpioreg = (uint32_t *)mapmem(base, len); + + gpioreg = (uint32_t *)mapmem(GetPeripheralBase()+base, len); gpiolen=len; } @@ -41,40 +42,84 @@ gpio::~gpio() unmapmem((void*)gpioreg,gpiolen); } + +uint32_t get_hwbase(void) +{ + const char *ranges_file = "/proc/device-tree/soc/ranges"; + uint8_t ranges[12]; + FILE *fd; + uint32_t ret = 0; + + memset(ranges, 0, sizeof(ranges)); + + if ((fd = fopen(ranges_file, "rb")) == NULL) + { + printf("Can't open '%s'\n", ranges_file); + } + else if (fread(ranges, 1, sizeof(ranges), fd) >= 8) + { + ret = (ranges[4] << 24) | + (ranges[5] << 16) | + (ranges[6] << 8) | + (ranges[7] << 0); + if (!ret) + ret = (ranges[8] << 24) | + (ranges[9] << 16) | + (ranges[10] << 8) | + (ranges[11] << 0); + if ((ranges[0] != 0x7e) || + (ranges[1] != 0x00) || + (ranges[2] != 0x00) || + (ranges[3] != 0x00) || + ((ret != 0x20000000) && (ret != 0x3f000000) && (ret != 0xfe000000))) + { + printf("Unexpected ranges data (%02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x)\n", + ranges[0], ranges[1], ranges[2], ranges[3], + ranges[4], ranges[5], ranges[6], ranges[7], + ranges[8], ranges[9], ranges[10], ranges[11]); + ret = 0; + } + } + else + { + printf("Ranges data too short\n"); + } + + fclose(fd); + + return ret; +} + uint32_t gpio::GetPeripheralBase() { RASPBERRY_PI_INFO_T info; - uint32_t BCM2708_PERI_BASE = bcm_host_get_peripheral_address(); - dbg_printf(1,"Peri Base = %x SDRAM %x\n",bcm_host_get_peripheral_address(),bcm_host_get_sdram_address()); + uint32_t BCM2708_PERI_BASE =bcm_host_get_peripheral_address(); + dbg_printf(1,"Peri Base = %x SDRAM %x\n",/*get_hwbase()*/bcm_host_get_peripheral_address(),bcm_host_get_sdram_address()); + if(BCM2708_PERI_BASE==0xFE000000) // Fixme , could be inspect without this hardcoded value + { + pi_is_2711=true; //Rpi4 + XOSC_FREQUENCY=54000000; + } if(BCM2708_PERI_BASE==0) { dbg_printf(0,"Unknown peripheral base, swith to PI4 \n"); - BCM2708_PERI_BASE=0xfe000000; + BCM2708_PERI_BASE=0xfe000000; + XOSC_FREQUENCY=54000000; + pi_is_2711=true; } - /* - if (getRaspberryPiInformation(&info) > 0) - { - if (info.peripheralBase == RPI_BROADCOM_2835_PERIPHERAL_BASE) - { - BCM2708_PERI_BASE = info.peripheralBase; - } - - if ((info.peripheralBase == RPI_BROADCOM_2836_PERIPHERAL_BASE) || (info.peripheralBase == RPI_BROADCOM_2837_PERIPHERAL_BASE)) - { - BCM2708_PERI_BASE = info.peripheralBase; - } - }*/ + if(pi_is_2711) + dbg_printf(1,"Running on Pi4\n"); return BCM2708_PERI_BASE; } //******************** DMA Registers *************************************** -dmagpio::dmagpio() : gpio(GetPeripheralBase() + DMA_BASE, DMA_LEN) +dmagpio::dmagpio() : gpio( DMA_BASE, DMA_LEN) { } // ***************** CLK Registers ***************************************** -clkgpio::clkgpio() : gpio(GetPeripheralBase() + CLK_BASE, CLK_LEN) +clkgpio::clkgpio() : gpio(CLK_BASE, CLK_LEN) { SetppmFromNTP(); padgpio level; @@ -118,21 +163,21 @@ uint64_t clkgpio::GetPllFrequency(int PllNo) Freq = XOSC_FREQUENCY; break; case clk_plla: - Freq = XOSC_FREQUENCY * ((uint64_t)gpioreg[PLLA_CTRL] & 0x3ff) + XOSC_FREQUENCY * (uint64_t)gpioreg[PLLA_FRAC] / (1 << 20); + Freq = (XOSC_FREQUENCY * ((uint64_t)gpioreg[PLLA_CTRL] & 0x3ff) + XOSC_FREQUENCY * (uint64_t)gpioreg[PLLA_FRAC] / (1 << 20))/(2*(gpioreg[PLLA_CTRL] >> 12)&0x7); break; //case clk_pllb:Freq=XOSC_FREQUENCY*((uint64_t)gpioreg[PLLB_CTRL]&0x3ff) +XOSC_FREQUENCY*(uint64_t)gpioreg[PLLB_FRAC]/(1<<20);break; case clk_pllc: - Freq = XOSC_FREQUENCY * ((uint64_t)gpioreg[PLLC_CTRL] & 0x3ff) + XOSC_FREQUENCY * (uint64_t)gpioreg[PLLC_FRAC] / (1 << 20); + Freq = (XOSC_FREQUENCY * ((uint64_t)gpioreg[PLLC_CTRL] & 0x3ff) + XOSC_FREQUENCY * (uint64_t)gpioreg[PLLC_FRAC] / (1 << 20))/(2*(gpioreg[PLLC_CTRL] >> 12)&0x7) ; break; case clk_plld: - Freq = (XOSC_FREQUENCY * ((uint64_t)gpioreg[PLLD_CTRL] & 0x3ff) + (XOSC_FREQUENCY * (uint64_t)gpioreg[PLLD_FRAC]) / (1 << 20)) / (gpioreg[PLLD_PER] >> 1); + Freq =( (XOSC_FREQUENCY * ((uint64_t)gpioreg[PLLD_CTRL] & 0x3ff) + (XOSC_FREQUENCY * (uint64_t)gpioreg[PLLD_FRAC]) / (1 << 20)) / (2*gpioreg[PLLD_PER] >> 1))/((gpioreg[PLLD_CTRL] >> 12)&0x7) ; break; case clk_hdmi: - Freq = XOSC_FREQUENCY * ((uint64_t)gpioreg[PLLH_CTRL] & 0x3ff) + XOSC_FREQUENCY * (uint64_t)gpioreg[PLLH_FRAC] / (1 << 20); + Freq =( XOSC_FREQUENCY * ((uint64_t)gpioreg[PLLH_CTRL] & 0x3ff) + XOSC_FREQUENCY * (uint64_t)gpioreg[PLLH_FRAC] / (1 << 20))/(2*(gpioreg[PLLH_CTRL] >> 12)&0x7) ; break; } Freq=Freq*(1.0-clk_ppm*1e-6); - dbg_printf(1, "Freq PLL no %d= %llu\n",PllNo, Freq); + dbg_printf(1, "Pi4=%d Xosc = %llu Freq PLL no %d= %llu\n",pi_is_2711,XOSC_FREQUENCY,PllNo, Freq); return Freq; } @@ -221,7 +266,8 @@ int clkgpio::ComputeBestLO(uint64_t Frequency, int Bandwidth) #define MIN_PLL_RATE 200e6 #define MIN_PLL_RATE_USE_PDIV 1500e6 //1700 works but some ticky breaks in clock..PLL should be at limit #define MAX_PLL_RATE 4e9 - #define XTAL_RATE 19.2e6 + #define XTAL_RATE XOSC_FREQUENCY + //Pi4 seems 54Mhz double xtal_freq_recip = 1.0 / XTAL_RATE; // todo PPM correction int best_divider = 0; @@ -631,7 +677,7 @@ void clkgpio::SetppmFromNTP() // ************************************** GENERAL GPIO ***************************************************** -generalgpio::generalgpio() : gpio(GetPeripheralBase() + GENERAL_BASE, GENERAL_LEN) +generalgpio::generalgpio() : gpio(/*GetPeripheralBase() + */GENERAL_BASE, GENERAL_LEN) { } @@ -653,18 +699,32 @@ int generalgpio::setmode(uint32_t gpio, uint32_t mode) int generalgpio::setpulloff(uint32_t gpio) { - gpioreg[GPPUD]=0; - usleep(150); - gpioreg[GPPUDCLK0]=1<>4)]; + bits &= ~(3 << shift); + bits |= (pull << shift); + gpioreg[GPPUPPDN0 + (gpio>>4)] = bits; + } + return 0; } // ********************************** PWM GPIO ********************************** -pwmgpio::pwmgpio() : gpio(GetPeripheralBase() + PWM_BASE, PWM_LEN) +pwmgpio::pwmgpio() : gpio(/*GetPeripheralBase() + */PWM_BASE, PWM_LEN) { gpioreg[PWM_CTL] = 0; @@ -814,7 +874,7 @@ int pwmgpio::SetPrediv(int predivisor) //Mode should be only for SYNC or a Data // ********************************** PCM GPIO (I2S) ********************************** -pcmgpio::pcmgpio() : gpio(GetPeripheralBase() + PCM_BASE, PCM_LEN) +pcmgpio::pcmgpio() : gpio(PCM_BASE, PCM_LEN) { gpioreg[PCM_CS_A] = 1; // Disable Rx+Tx, Enable PCM block } @@ -899,7 +959,7 @@ int pcmgpio::SetPrediv(int predivisor) //Carefull we use a 10 fixe divisor for n // ********************************** PADGPIO (Amplitude) ********************************** -padgpio::padgpio() : gpio(GetPeripheralBase() + PADS_GPIO, PADS_GPIO_LEN) +padgpio::padgpio() : gpio(PADS_GPIO, PADS_GPIO_LEN) { } diff --git a/src/gpio.h b/src/gpio.h index d703a11..746c495 100644 --- a/src/gpio.h +++ b/src/gpio.h @@ -7,7 +7,9 @@ class gpio { - + public: + bool pi_is_2711=false; + uint64_t XOSC_FREQUENCY=19200000; public: volatile uint32_t *gpioreg = NULL; uint32_t gpiolen; @@ -57,7 +59,7 @@ class dmagpio : public gpio //************************************ GENERAL GPIO *************************************** #define GENERAL_BASE (0x00200000) -#define GENERAL_LEN 0xB4 +#define GENERAL_LEN 0xD0 #define GPFSEL0 (0x00 / 4) #define GPFSEL1 (0x04 / 4) @@ -66,6 +68,11 @@ class dmagpio : public gpio #define GPPUDCLK0 (0x98 / 4) #define GPPUDCLK1 (0x9C / 4) +#define GPPUPPDN0 (0xBC/4) +#define GPPUPPDN1 (0xC0/4) +#define GPPUPPDN2 (0xC4/4) +#define GPPUPPDN3 (0xC8/4) + enum { fsel_input, @@ -104,6 +111,8 @@ class generalgpio : public gpio #define GPCLK_DIV_2 (0x84 / 4) #define EMMCCLK_CNTL (0x1C0 / 4) #define EMMCCLK_DIV (0x1C4 / 4) +#define CM_EMMC2CTL (0x1d0/4) +#define CM_EMMC2DIV (0x1d4/4) #define CM_VPUCTL 0x008 #define CM_VPUDIV 0x00c @@ -246,8 +255,8 @@ class generalgpio : public gpio #define PLLH_STS (0x1660 / 4) #define XOSC_CTRL (0x1190 / 4) -#define XOSC_FREQUENCY 19200000 - +//#define XOSC_FREQUENCY 19200000 +//#define XOSC_FREQUENCY 54000000 //Parent PLL enum { diff --git a/src/phasedmasync.cpp b/src/phasedmasync.cpp index 1acc601..cac2db2 100644 --- a/src/phasedmasync.cpp +++ b/src/phasedmasync.cpp @@ -41,7 +41,7 @@ phasedmasync::phasedmasync(uint64_t TuneFrequency,uint32_t SampleRateIn,int Numb clkgpio::SetAdvancedPllMode(true); clkgpio::ComputeBestLO(tunefreq,0); // compute PWM divider according to MasterPLL clkgpio::PllFixDivider - double FloatMult=((double)(tunefreq)*clkgpio::PllFixDivider)/(double)(XOSC_FREQUENCY); + double FloatMult=((double)(tunefreq)*clkgpio::PllFixDivider)/(double)(pwmgpio::XOSC_FREQUENCY); uint32_t freqctl = FloatMult*((double)(1<<20)) ; int IntMultiply= freqctl>>20; // Need to be calculated to have a center frequency freqctl&=0xFFFFF; // Fractionnal is 20bits