cn9130 hrm document \\10.10.2.210\IPD Data\Project_研發專案文件區\Checkpoint\Marvell\CN9130\MV-S111692-00A_CN9130_functional.pdf cn96xx hrm D:\cn96xx\Manuals\CN96XX-HM-0.95E.pdf # CP_MPP[22] as pwm ### In uboot -------------- Step1: ![](https://i.imgur.com/zPsxJ3V.png) DONT CONFUSE WITH **FIELD** IN TABLE W.R.T GPIO NUMBERING. CP0 HAS GPIO NUMBERING FROM 0-31 AND CP1 HAS GPIO NUMBERING FROM 32 TO 63 SO CP_MPP[22] MEANS WE NEED TO SET 22ND BIT OF REGISTER CONTENT 0XF2440100. AS TABLE SHOWS **n=0-1, which just means gpio group cp0 and cp1 not gpio 0 to 63**. NOTE: By default md command will print out word length data. If you want to print out byte then used md.b and for half word md.w and double word which is 16bytes md.l To avoid confusion just print memory contents by "md gpio_reg_address 1" ![](https://i.imgur.com/CNHZNuF.png) Marvell>> md f2440100 1 f2440100: 00000000 .... to change 22nd bit of "f2440100: **00000000**" left shift 1 by 22 times to change 22nd gpio ![](https://i.imgur.com/WHgxo4a.png) 400000 bitwise OR with 00000000 to set 22nd gpio now write back 400000 to set cpp_mpp[22] dataout register f2440100 ![](https://i.imgur.com/2ISTdUJ.png) Step2: ![](https://i.imgur.com/dvEaQUF.png) Marvell>> md f2440104 f2440104: **ffffffff** 00000000 00000000 7cabffff ...............| to set gpio 22 = ~(40000) AND ffffffff = fbffffff ![](https://i.imgur.com/3zwrtO8.png) ![](https://i.imgur.com/7TcEvcE.png) Step3: ![](https://i.imgur.com/I08Qw5E.png) Marvell>> md f2440108 1 f2440108: 00000000 .... to set gpio 22 = 40000 OR 00000000 = 400000 ![](https://i.imgur.com/7gx4aA0.png) step4: ![](https://i.imgur.com/1OXQ0uQ.png) Marvell>> md f2440120 f2440120: **00000000** 00000000 00000000 00000000 ................ default value is 0 which means counter A is selected by defualt. If you want to change it to blink counter B then we have to set 22nd bit which is again write 0x400000 to register f2440120 step5: ![](https://i.imgur.com/dNlP6el.png) ![](https://i.imgur.com/DtjTK0T.png) this is trail and error method, keep on writing random values and measure signal at oscilloscope at the same time. for 300k and 600k finally found values 65000 and 32500 so just write these values to ON/OFF duration registers **300hz Marvell>> mw f24401f4 65000 Marvell>> mw f24401f0 65000** **600Hz Marvell>> mw f24401f4 32500 Marvell>> mw f24401f0 32500** /* *all commands together* *mw f2440100 400000 mw f2440104 ffbfffff mw f2440108 400000* *120hz Marvell>> mw f24401f0 100000 Marvell>> mw f24401f4 100000* *490khz Marvell>> mw f24401f0 100 Marvell>> mw f24401f4 100* *300hz Marvell>> mw f24401f4 65000 Marvell>> mw f24401f0 65000* *600Hz Marvell>> mw f24401f4 32500 Marvell>> mw f24401f0 32500* */ final ------------- ### In kernel **1.** ![](https://i.imgur.com/HTWxzkZ.png) **devmem2 0xf2440100 w 0x1400000** **2.** ![](https://i.imgur.com/dvEaQUF.png) 0xf2440104 - instead of reading or writing 0x7C2DFFFF, write halfword 0XFFFF on 0xf2440104 and next halfword 0x7C2D on 0xf2440106 memory layout in byte memory - 0xf2440104 | 0xf2440105 | 0xf2440106 | 0xf2440107 data - 0xff | 0xff | 0x2d | 0x7c memory layout in halfword memory - 0xf2440104 | 0xf2440106 data - 0xffff | 0x7c2d **to avoid bus error write in half words** **devmem2 0xf2440104 h 0xFFFF devmem2 0xf2440106 h 0x7C2D** **3.** ![](https://i.imgur.com/I08Qw5E.png) **devmem2 0xf2440108 w 0x400000** **4.** ![](https://i.imgur.com/1OXQ0uQ.png) By **default** counter A is selected already so not changing this register **5.** ![](https://i.imgur.com/dNlP6el.png) **devmem2 0xf24401f0 w 0x32500** (write on 0xf24401f0 **first**, if we write value on 0xf24401f4 first then we will loose **data** written on 0xf24401f0) - Counter A ON duration Above one is for 600k, for 300k execute below command **devmem2 0xf24401f0 w 0x65000** **6.** ![](https://i.imgur.com/DsD1FbV.png) 0xf24401f4 - instead of reading or writing 0x32500, write halfword 0X2500 on 0xf24401f4 and next halfword 0x3 on 0xf24401f6 (here 0x3 means 0x0003) - Counter B OFF duration memory layout in byte memory - 0xf24401f4 | 0xf24401f5 | 0xf24401f6 | 0xf24401f7 data - 0x0 | 0x25 | 0x3 | 0x0 memory layout in halfword memory - 0xf24401f4 | 0xf24401f6 data - 0x2500 | 0x3 **to avoid bus error, write in half words** **devmem2 0xf24401f4 h 0x2500 devmem2 0xf24401f6 h 0x3** Above one is for 600k, for 300k execute below command **devmem2 0xf24401f4 h 0x5000 devmem2 0xf24401f6 h 0x6** ***NOTE : All above steps are hacked first writing gpio registers in uboot then boot to kernel without resetting device and read gpio registers. Then reboot device and directly modify gpio registers in kernel.*** ***In future same can be used to backtrack gpio register address contents and decide what to write at that address.*** /* *all steps together except counter A selection as default is already coutner A selected devmem2 0xf2440100 w 0x1400000 devmem2 0xf2440104 h 0xFFFF devmem2 0xf2440106 h 0x7C2D devmem2 0xf2440108 w 0x400000* *600k devmem2 0xf24401f0 w 0x32500 devmem2 0xf24401f4 h 0x2500 devmem2 0xf24401f6 h 0x3* *300k devmem2 0xf24401f0 w 0x65000 devmem2 0xf24401f4 h 0x5000 devmem2 0xf24401f6 h 0x6* */ ---------- Links: If devmem2 is not part of the rootfs then download it from below link and install on device using dpkg -i command. https://launchpad.net/ubuntu/+source/devmem2/0.0-0ubuntu2/+build/14525249