10-04-2018 04:20 AM - edited 10-04-2018 04:25 AM
Hi,
I am trying to check if Dynamic reconfiguration of clock works. Problem is whenever I check the value of status register (0x04), it is always '1'. When I check the default value of say clock configuration register 2, it does come out
0x0004000a
as mentioned in the clocking wizard guide. So, it means communication with the AXI Lite clocking wizard registers is happening. I do not understand what I am doing wrong. I tried to check this design with a slave AXI lite peripheral to see if the clocks where changing but it was not.
Do I need some special drivers in Linux for clocking wizard? Or if there is problem with the hardware design and the code?
Your input will be appreciated. Thank you!
Below is the code and hardware design used for testing.
//VCO Frequency = (Input Clock Frequency) * (CLKFBOUT_MULT)/DIVCLK_DIVIDE #define CLK_REG0 0x200 //set 0x00000A01 (DIVCLK_DIVIDE[7:0] - 1, CLKFBOUT_MULT[15:8] - 10 (Default - 0x01010A00)) #define CLK_REG2 0x208 //set 0x00000005 (CLKOUT0_DIVIDE[7:0] - 5 (clkout1 = VCO/CLKOUT0_DIVIDE, status reg - 0x1) (Default - 0x0004000a)) #define CLK_REG23 0x25C //set 0x00000003 (BIT2 - SEN, BIT1 - SADDR, BIT0 - LOAD) #define STATUS 0x04 //Status register, BIT[0] - LOCKED void clock_reconfig() { int dh = open("/dev/mem", O_RDWR | O_SYNC); unsigned int* address = mmap(NULL, 65535, PROT_READ | PROT_WRITE, MAP_SHARED, dh, 0x43C00000); address[CLK_REG0>>2] = 0x00000A01; address[CLK_REG2>>2] = 0x00000005; while(address[STATUS>>2] != 1); //Start dynamic reconfiguration state m/c address[CLK_REG23>>2] = 0x00000007; address[CLK_REG23>>2] = 0x00000002; //Wait for locked signal sleep(1); }
10-04-2018 06:12 PM
I had it working with baremetal and started with the example app for the driver. There was a bug in the example app but it was with respect to calculating the fractional divide.
So comparing my stuff to yours (and I'm not looking at the docs) I see:
Below is a snippet of my code, after calculating the mult/div values. In this snippet you will see a led out macro called every once in a while. That's because I used microblaze and this src (without prints) in hardware simulation.
/* Configuring Multiply and Divide values */ *(u32 *)(CfgPtr_Dynamic->BaseAddr + 0x208) = Frac_en | (Frac_divide << 8) | (Divide); *(u32 *)(CfgPtr_Dynamic->BaseAddr + 0x20C) = 0x00; //Phase LED_OUT(0xa); /* Load Clock Configuration Register values */ *(u32 *)(CfgPtr_Dynamic->BaseAddr + 0x25C) = 0x07; LED_OUT(0xb); if(*(u32 *)(CfgPtr_Dynamic->BaseAddr + 0x04) & CLK_LOCK) { LED_OUT(0x83); Error++; xil_printf("\n ERROR: Clock is locked : 0x%x \t expected " "0x00\n\r", *(u32 *)(CfgPtr_Dynamic->BaseAddr + 0x04) & CLK_LOCK); } LED_OUT(0xc); /* Clock Configuration Registers are used for dynamic reconfiguration */ *(u32 *)(CfgPtr_Dynamic->BaseAddr + 0x25C) = 0x02; LED_OUT(0xd); Fail = Wait_For_Lock(CfgPtr_Dynamic); LED_OUT(0xe); if(Fail) { LED_OUT(0x84); Error++; xil_printf("\n ERROR: Clock is not locked : 0x%x \t Expected "\ ": 0x1\n\r", *(u32 *)(CfgPtr_Dynamic->BaseAddr + 0x04) & CLK_LOCK); }