mirror of
https://github.com/F5OEO/rpitx.git
synced 2026-03-23 16:56:54 +01:00
Working carrier
This commit is contained in:
156
src/gpio.cpp
156
src/gpio.cpp
@@ -4,6 +4,7 @@ extern "C"
|
||||
}
|
||||
#include "gpio.h"
|
||||
#include "raspberry_pi_revision.h"
|
||||
#include "stdio.h"
|
||||
|
||||
gpio::gpio(uint32_t base, uint32_t len)
|
||||
{
|
||||
@@ -49,3 +50,158 @@ uint32_t gpio::GetPeripheralBase()
|
||||
dmagpio::dmagpio():gpio(GetPeripheralBase()+DMA_BASE,DMA_LEN)
|
||||
{
|
||||
}
|
||||
|
||||
// ***************** CLK Registers *****************************************
|
||||
clkgpio::clkgpio():gpio(GetPeripheralBase()+CLK_BASE,CLK_LEN)
|
||||
{
|
||||
}
|
||||
|
||||
int clkgpio::SetPllNumber(int PllNo,int MashType)
|
||||
{
|
||||
if(PllNo<8)
|
||||
pllnumber=PllNo;
|
||||
else
|
||||
pllnumber=clk_pllc;
|
||||
if(MashType<4)
|
||||
Mash=MashType;
|
||||
else
|
||||
Mash=0;
|
||||
gpioreg[GPCLK_CNTL]= 0x5A000000 | (Mash << 9) | pllnumber|(1 << 4) ; //4 is START CLK
|
||||
Pllfrequency=GetPllFrequency(pllnumber);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64_t clkgpio::GetPllFrequency(int PllNo)
|
||||
{
|
||||
uint64_t Freq=0;
|
||||
switch(PllNo)
|
||||
{
|
||||
case clk_plla:Freq=XOSC_FREQUENCY*((uint64_t)gpioreg[PLLA_CTRL]&0x3ff) +XOSC_FREQUENCY*(uint64_t)gpioreg[PLLA_FRAC]/(1<<20);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);break;
|
||||
case clk_plld:Freq=XOSC_FREQUENCY*((uint64_t)gpioreg[PLLD_CTRL]&0x3ff) +(XOSC_FREQUENCY*(uint64_t)gpioreg[PLLD_FRAC])/(1<<20);break;
|
||||
case clk_hdmi:Freq=XOSC_FREQUENCY*((uint64_t)gpioreg[PLLH_CTRL]&0x3ff) +XOSC_FREQUENCY*(uint64_t)gpioreg[PLLH_FRAC]/(1<<20);break;
|
||||
}
|
||||
fprintf(stderr,"Freq = %lld\n",Freq);
|
||||
|
||||
return Freq;
|
||||
}
|
||||
|
||||
int clkgpio::SetFrequency(uint64_t Frequency)
|
||||
{
|
||||
|
||||
double Freqresult=(double)Pllfrequency/(double)Frequency;
|
||||
uint32_t FreqDivider=(uint32_t)Freqresult;
|
||||
uint32_t FreqFractionnal=(uint32_t) (4096*(Freqresult-(double)FreqDivider));
|
||||
|
||||
printf("DIV/FRAC %u/%u \n",FreqDivider,FreqFractionnal);
|
||||
|
||||
gpioreg[GPCLK_DIV] = 0x5A000000 | ((FreqDivider)<<12) | FreqFractionnal;
|
||||
//gpioreg[GPCLK_CNTL]= 0x5A000000 | (Mash << 9) | pllnumber |4 ; //4 is START CLK
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
void clkgpio::print_clock_tree(void)
|
||||
{
|
||||
|
||||
printf("PLLC_DIG0=%08x\n",gpioreg[(0x1020/4)]);
|
||||
printf("PLLC_DIG1=%08x\n",gpioreg[(0x1024/4)]);
|
||||
printf("PLLC_DIG2=%08x\n",gpioreg[(0x1028/4)]);
|
||||
printf("PLLC_DIG3=%08x\n",gpioreg[(0x102c/4)]);
|
||||
printf("PLLC_ANA0=%08x\n",gpioreg[(0x1030/4)]);
|
||||
printf("PLLC_ANA1=%08x\n",gpioreg[(0x1034/4)]);
|
||||
printf("PLLC_ANA2=%08x\n",gpioreg[(0x1038/4)]);
|
||||
printf("PLLC_ANA3=%08x\n",gpioreg[(0x103c/4)]);
|
||||
printf("PLLC_DIG0R=%08x\n",gpioreg[(0x1820/4)]);
|
||||
printf("PLLC_DIG1R=%08x\n",gpioreg[(0x1824/4)]);
|
||||
printf("PLLC_DIG2R=%08x\n",gpioreg[(0x1828/4)]);
|
||||
printf("PLLC_DIG3R=%08x\n",gpioreg[(0x182c/4)]);
|
||||
|
||||
printf("GNRIC CTL=%08x DIV=%8x ",gpioreg[ 0],gpioreg[ 1]);
|
||||
printf("VPU CTL=%08x DIV=%8x\n",gpioreg[ 2],gpioreg[ 3]);
|
||||
printf("SYS CTL=%08x DIV=%8x ",gpioreg[ 4],gpioreg[ 5]);
|
||||
printf("PERIA CTL=%08x DIV=%8x\n",gpioreg[ 6],gpioreg[ 7]);
|
||||
printf("PERII CTL=%08x DIV=%8x ",gpioreg[ 8],gpioreg[ 9]);
|
||||
printf("H264 CTL=%08x DIV=%8x\n",gpioreg[10],gpioreg[11]);
|
||||
printf("ISP CTL=%08x DIV=%8x ",gpioreg[12],gpioreg[13]);
|
||||
printf("V3D CTL=%08x DIV=%8x\n",gpioreg[14],gpioreg[15]);
|
||||
|
||||
printf("CAM0 CTL=%08x DIV=%8x ",gpioreg[16],gpioreg[17]);
|
||||
printf("CAM1 CTL=%08x DIV=%8x\n",gpioreg[18],gpioreg[19]);
|
||||
printf("CCP2 CTL=%08x DIV=%8x ",gpioreg[20],gpioreg[21]);
|
||||
printf("DSI0E CTL=%08x DIV=%8x\n",gpioreg[22],gpioreg[23]);
|
||||
printf("DSI0P CTL=%08x DIV=%8x ",gpioreg[24],gpioreg[25]);
|
||||
printf("DPI CTL=%08x DIV=%8x\n",gpioreg[26],gpioreg[27]);
|
||||
printf("GP0 CTL=%08x DIV=%8x ",gpioreg[28],gpioreg[29]);
|
||||
printf("GP1 CTL=%08x DIV=%8x\n",gpioreg[30],gpioreg[31]);
|
||||
|
||||
printf("GP2 CTL=%08x DIV=%8x ",gpioreg[32],gpioreg[33]);
|
||||
printf("HSM CTL=%08x DIV=%8x\n",gpioreg[34],gpioreg[35]);
|
||||
printf("OTP CTL=%08x DIV=%8x ",gpioreg[36],gpioreg[37]);
|
||||
printf("PCM CTL=%08x DIV=%8x\n",gpioreg[38],gpioreg[39]);
|
||||
printf("PWM CTL=%08x DIV=%8x ",gpioreg[40],gpioreg[41]);
|
||||
printf("SLIM CTL=%08x DIV=%8x\n",gpioreg[42],gpioreg[43]);
|
||||
printf("SMI CTL=%08x DIV=%8x ",gpioreg[44],gpioreg[45]);
|
||||
printf("SMPS CTL=%08x DIV=%8x\n",gpioreg[46],gpioreg[47]);
|
||||
|
||||
printf("TCNT CTL=%08x DIV=%8x ",gpioreg[48],gpioreg[49]);
|
||||
printf("TEC CTL=%08x DIV=%8x\n",gpioreg[50],gpioreg[51]);
|
||||
printf("TD0 CTL=%08x DIV=%8x ",gpioreg[52],gpioreg[53]);
|
||||
printf("TD1 CTL=%08x DIV=%8x\n",gpioreg[54],gpioreg[55]);
|
||||
|
||||
printf("TSENS CTL=%08x DIV=%8x ",gpioreg[56],gpioreg[57]);
|
||||
printf("TIMER CTL=%08x DIV=%8x\n",gpioreg[58],gpioreg[59]);
|
||||
printf("UART CTL=%08x DIV=%8x ",gpioreg[60],gpioreg[61]);
|
||||
printf("VEC CTL=%08x DIV=%8x\n",gpioreg[62],gpioreg[63]);
|
||||
|
||||
printf("PULSE CTL=%08x DIV=%8x ",gpioreg[100],gpioreg[101]);
|
||||
printf("PLLT CTL=%08x DIV=????????\n",gpioreg[76]);
|
||||
|
||||
printf("DSI1E CTL=%08x DIV=%8x ",gpioreg[86],gpioreg[87]);
|
||||
printf("DSI1P CTL=%08x DIV=%8x\n",gpioreg[88],gpioreg[89]);
|
||||
printf("AVE0 CTL=%08x DIV=%8x\n",gpioreg[90],gpioreg[91]);
|
||||
|
||||
printf("SDC CTL=%08x DIV=%8x ",gpioreg[106],gpioreg[107]);
|
||||
printf("ARM CTL=%08x DIV=%8x\n",gpioreg[108],gpioreg[109]);
|
||||
printf("AVE0 CTL=%08x DIV=%8x ",gpioreg[110],gpioreg[111]);
|
||||
printf("EMMC CTL=%08x DIV=%8x\n",gpioreg[112],gpioreg[113]);
|
||||
|
||||
// Sometimes calculated frequencies are off by a factor of 2
|
||||
// ANA1 bit 14 may indicate that a /2 prescaler is active
|
||||
printf("PLLA PDIV=%d NDIV=%d FRAC=%d ",(gpioreg[PLLA_CTRL]>>16) ,gpioreg[PLLA_CTRL]&0x3ff, gpioreg[PLLA_FRAC] );
|
||||
printf(" %f MHz\n",19.2* ((float)(gpioreg[PLLA_CTRL]&0x3ff) + ((float)gpioreg[PLLA_FRAC])/((float)(1<<20))) );
|
||||
printf("DSI0=%d CORE=%d PER=%d CCP2=%d\n\n",gpioreg[PLLA_DSI0],gpioreg[PLLA_CORE],gpioreg[PLLA_PER],gpioreg[PLLA_CCP2]);
|
||||
|
||||
|
||||
printf("PLLB PDIV=%d NDIV=%d FRAC=%d ",(gpioreg[PLLB_CTRL]>>16) ,gpioreg[PLLB_CTRL]&0x3ff, gpioreg[PLLB_FRAC] );
|
||||
printf(" %f MHz\n",19.2* ((float)(gpioreg[PLLB_CTRL]&0x3ff) + ((float)gpioreg[PLLB_FRAC])/((float)(1<<20))) );
|
||||
printf("ARM=%d SP0=%d SP1=%d SP2=%d\n\n",gpioreg[PLLB_ARM],gpioreg[PLLB_SP0],gpioreg[PLLB_SP1],gpioreg[PLLB_SP2]);
|
||||
|
||||
printf("PLLC PDIV=%d NDIV=%d FRAC=%d ",(gpioreg[PLLC_CTRL]>>16) ,gpioreg[PLLC_CTRL]&0x3ff, gpioreg[PLLC_FRAC] );
|
||||
printf(" %f MHz\n",19.2* ((float)(gpioreg[PLLC_CTRL]&0x3ff) + ((float)gpioreg[PLLC_FRAC])/((float)(1<<20))) );
|
||||
printf("CORE2=%d CORE1=%d PER=%d CORE0=%d\n\n",gpioreg[PLLC_CORE2],gpioreg[PLLC_CORE1],gpioreg[PLLC_PER],gpioreg[PLLC_CORE0]);
|
||||
|
||||
printf("PLLD %x PDIV=%d NDIV=%d FRAC=%d ",gpioreg[PLLD_CTRL],(gpioreg[PLLD_CTRL]>>16) ,gpioreg[PLLD_CTRL]&0x3ff, gpioreg[PLLD_FRAC] );
|
||||
printf(" %f MHz\n",19.2* ((float)(gpioreg[PLLD_CTRL]&0x3ff) + ((float)gpioreg[PLLD_FRAC])/((float)(1<<20))) );
|
||||
printf("DSI0=%d CORE=%d PER=%d DSI1=%d\n\n",gpioreg[PLLD_DSI0],gpioreg[PLLD_CORE],gpioreg[PLLD_PER],gpioreg[PLLD_DSI1]);
|
||||
|
||||
printf("PLLH PDIV=%d NDIV=%d FRAC=%d ",(gpioreg[PLLH_CTRL]>>16) ,gpioreg[PLLH_CTRL]&0x3ff, gpioreg[PLLH_FRAC] );
|
||||
printf(" %f MHz\n",19.2* ((float)(gpioreg[PLLH_CTRL]&0x3ff) + ((float)gpioreg[PLLH_FRAC])/((float)(1<<20))) );
|
||||
printf("AUX=%d RCAL=%d PIX=%d STS=%d\n\n",gpioreg[PLLH_AUX],gpioreg[PLLH_RCAL],gpioreg[PLLH_PIX],gpioreg[PLLH_STS]);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
// ************************************** GENERAL GPIO *****************************************************
|
||||
generalgpio::generalgpio():gpio(GetPeripheralBase()+GENERAL_BASE,GENERAL_LEN)
|
||||
{
|
||||
}
|
||||
|
||||
void generalgpio::enableclk()
|
||||
{
|
||||
gpioreg[GPFSEL0] = (gpioreg[GPFSEL0] & ~(7 << 12)) | (4 << 12);
|
||||
}
|
||||
|
||||
|
||||
|
||||
90
src/gpio.h
90
src/gpio.h
@@ -51,4 +51,94 @@ class dmagpio:public gpio
|
||||
};
|
||||
|
||||
|
||||
// Add for PLL frequency CTRL wihout divider
|
||||
// https://github.com/raspberrypi/linux/blob/rpi-4.9.y/drivers/clk/bcm/clk-bcm2835.c
|
||||
// See interesting patch for jitter https://github.com/raspberrypi/linux/commit/76527b4e6a5dbe55e0b2d8ab533c2388b36c86be
|
||||
|
||||
#define CLK_BASE (0x00101000)
|
||||
#define CLK_LEN 0x1300
|
||||
|
||||
#define CORECLK_CNTL (0x08/4)
|
||||
#define CORECLK_DIV (0x0c/4)
|
||||
#define GPCLK_CNTL (0x70/4)
|
||||
#define GPCLK_DIV (0x74/4)
|
||||
#define EMMCCLK_CNTL (0x1C0/4)
|
||||
#define EMMCCLK_DIV (0x1C4/4)
|
||||
|
||||
#define PLLA_CTRL (0x1100/4)
|
||||
#define PLLA_FRAC (0x1200/4)
|
||||
#define PLLA_DSI0 (0x1300/4)
|
||||
#define PLLA_CORE (0x1400/4)
|
||||
#define PLLA_PER (0x1500/4)
|
||||
#define PLLA_CCP2 (0x1600/4)
|
||||
|
||||
#define PLLB_CTRL (0x11e0/4)
|
||||
#define PLLB_FRAC (0x12e0/4)
|
||||
#define PLLB_ARM (0x13e0/4)
|
||||
#define PLLB_SP0 (0x14e0/4)
|
||||
#define PLLB_SP1 (0x15e0/4)
|
||||
#define PLLB_SP2 (0x16e0/4)
|
||||
|
||||
#define PLLC_CTRL (0x1120/4)
|
||||
#define PLLC_FRAC (0x1220/4)
|
||||
#define PLLC_CORE2 (0x1320/4)
|
||||
#define PLLC_CORE1 (0x1420/4)
|
||||
#define PLLC_PER (0x1520/4)
|
||||
#define PLLC_CORE0 (0x1620/4)
|
||||
|
||||
#define PLLD_CTRL (0x1140/4)
|
||||
#define PLLD_FRAC (0x1240/4)
|
||||
#define PLLD_DSI0 (0x1340/4)
|
||||
#define PLLD_CORE (0x1440/4)
|
||||
#define PLLD_PER (0x1540/4)
|
||||
#define PLLD_DSI1 (0x1640/4)
|
||||
|
||||
#define PLLH_CTRL (0x1160/4)
|
||||
#define PLLH_FRAC (0x1260/4)
|
||||
#define PLLH_AUX (0x1360/4)
|
||||
#define PLLH_RCAL (0x1460/4)
|
||||
#define PLLH_PIX (0x1560/4)
|
||||
#define PLLH_STS (0x1660/4)
|
||||
|
||||
#define XOSC_CTRL (0x1190/4)
|
||||
#define XOSC_FREQUENCY 19200000
|
||||
|
||||
enum {clk_gnd,clk_osc,clk_debug0,clk_debug1,clk_plla,clk_pllc,clk_plld,clk_hdmi};
|
||||
|
||||
class clkgpio:public gpio
|
||||
{
|
||||
int pllnumber;
|
||||
int Mash;
|
||||
uint64_t Pllfrequency;
|
||||
|
||||
public:
|
||||
clkgpio();
|
||||
int SetPllNumber(int PllNo,int MashType);
|
||||
uint64_t GetPllFrequency(int PllNo);
|
||||
void print_clock_tree(void);
|
||||
int SetFrequency(uint64_t Frequency);
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
//************************************ GENERAL GPIO ***************************************
|
||||
|
||||
#define GENERAL_BASE (0x00200000)
|
||||
#define GENERAL_LEN 0xB4
|
||||
|
||||
#define GPFSEL0 (0x00/4)
|
||||
#define GPFSEL1 (0x04/4)
|
||||
#define GPFSEL2 (0x08/4)
|
||||
#define GPPUD (0x94/4)
|
||||
#define GPPUDCLK0 (0x9C/4)
|
||||
|
||||
class generalgpio:public gpio
|
||||
{
|
||||
|
||||
public:
|
||||
generalgpio();
|
||||
void enableclk();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,7 +1,18 @@
|
||||
|
||||
#include <unistd.h>
|
||||
#include "dma.h"
|
||||
#include "gpio.h"
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
|
||||
clkgpio clk;
|
||||
//clk.print_clock_tree();
|
||||
clk.SetPllNumber(clk_plld,1);
|
||||
|
||||
generalgpio generalio;
|
||||
generalio.enableclk();
|
||||
for(int i=0;i<100;i++)
|
||||
{
|
||||
usleep(40000);
|
||||
clk.SetFrequency(89000000+i*40);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user