This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

pwm-ecap in capture mode for AM335x -- how to get value to sysfs to userspace from kernel driver

Hi ,

I am facing small issue while reading data for the ecap.  my question how to get the captured value to userspace from kernel. i tried in many ways like :

#1:  sending a pointer  from sys.c to core.c to the pwm-tiecap.c    -- if i am sending pointer as argument to the driver to get value , i am getting kernel panic  

#2: then i changed to take the value in return value -- but the frame work is throwing :

root@am335x-evm:/sys/class/pwm/pwmchip0/pwm0# cat ecap_get_value_periodns
[ 90.451326] ecap_pwm_get_value:
[ 90.454888] cap1 :46353; cap2 :42418; cap3 :44730; cap4 :46347;
[ 90.461257] dev_attr_show: pwm_ecap_get_value_periodns_show+0x0/0x20 returned bad count
[ 90.469682] fill_read_buffer: dev_attr_show+0x0/0x50 returned bad count

kernel panic:

root@am335x-evm:~# cd /sys/class/pwm/pwmchip0/pwm0/
root@am335x-evm:/sys/class/pwm/pwmchip0/pwm0# ls
duty_cycle enable polarity
ecap_get_value_duty_cycle mode power
ecap_get_value_periodns period uevent
root@am335x-evm:/sys/class/pwm/pwmchip0/pwm0# cat ecap_get_value_periodns
[ 57.812218] ecap_pwm_get_value:
[ 57.815876] cap1 :0; cap2 :0; cap3 :0; cap4 :0;
[ 57.820677] Unable to handle kernel NULL pointer dereference at virtual address 00000000
[ 57.829280] pgd = cf754000
[ 57.832165] [00000000] *pgd=8c247831, *pte=00000000, *ppte=00000000
[ 57.838796] Internal error: Oops: 817 [#1] ARM
[ 57.843469] Modules linked in: cryptodev(O) musb_dsps musb_hdrc pvrsrvkm(O) musb_am335x
[ 57.851949] CPU: 0 PID: 1527 Comm: cat Tainted: G O 3.14.26-g2489c02-dirty #167
[ 57.860545] task: cc398400 ti: cf520000 task.ti: cf520000
[ 57.866240] PC is at ecap_pwm_get_value+0xd4/0xec
[ 57.871207] LR is at wake_up_klogd+0x3c/0x48
[ 57.875707] pc : [<c0293708>] lr : [<c00623a0>] psr: 00000013
[ 57.875707] sp : cf521e08 ip : cf521d28 fp : cf521e2c
[ 57.887763] r10: c05f6ebc r9 : cc0b0000 r8 : 00001000
[ 57.893254] r7 : 00000000 r6 : 00000000 r5 : cf23a710 r4 : c08886e4
[ 57.900112] r3 : 00000000 r2 : 00000007 r1 : 00000000 r0 : 00000000
[ 57.906975] Flags: nzcv IRQs on FIQs on Mode SVC_32 ISA ARM Segment user
[ 57.914469] Control: 10c5387d Table: 8f754019 DAC: 00000015
[ 57.920511] Process cat (pid: 1527, stack limit = 0xcf520238)
[ 57.926550] Stack: (0xcf521e08 to 0xcf522000)
[ 57.931141] 1e00: 00000000 00000000 cf2423c0 00000000 00000000 00000fff
[ 57.939744] 1e20: cf521e4c cf521e30 c0291d8c c0293640 c02930fc cc0a0780 c0833720 cf7fbc00
[ 57.948355] 1e40: cf521e5c cf521e50 c0293118 c0291d60 cf521e74 cf521e60 c0355c44 c0293108
[ 57.956959] 1e60: cc0a0780 cf5d9408 cf521ea4 cf521e78 c0126f24 c0355c2c c0126e90 cf7fbc00
[ 57.965554] 1e80: 00000001 cc0a0780 cf521ec8 cf3f3a40 00000000 00000001 cf521eb4 cf521ea8
[ 57.974159] 1ea0: c0129cdc c0126e9c cf521f04 cf521eb8 c00e92bc c0129cbc cc0a07b0 be91fbd4
[ 57.982762] 1ec0: 00001000 cf521f78 00000000 00000000 cf521f04 cf521ee0 c022e4c4 cf7fbc00
[ 57.991369] 1ee0: 00001000 be91fbd4 cf521f78 00001000 00001000 be91fbd4 cf521f44 cf521f08
[ 57.999968] 1f00: c012a65c c00e9100 c00e3db0 cf3f3a48 00000001 00000020 c081833c cf3f3a40
[ 58.008583] 1f20: 00001000 be91fbd4 cf521f78 00001000 cf520000 be91fbd4 cf521f74 cf521f48
[ 58.017185] 1f40: c00cb748 c012a554 c00e3734 c00e36b4 00000000 00000000 cf3f3a40 cf3f3a40
[ 58.025796] 1f60: 00001000 be91fbd4 cf521fa4 cf521f78 c00cb920 c00cb6bc 00000000 00000000
[ 58.034405] 1f80: 00001000 be91fbd4 00000003 00000003 c000e964 00000000 00000000 cf521fa8
[ 58.043016] 1fa0: c000e7e0 c00cb8e8 00001000 be91fbd4 00000003 be91fbd4 00001000 00000000
[ 58.051614] 1fc0: 00001000 be91fbd4 00000003 00000003 0009c798 00000001 00000000 00000003
[ 58.060210] 1fe0: 00000000 be91fbb4 00013820 470665bc 40000010 00000003 00000000 00000000
[ 58.068788] Backtrace:
[ 58.071410] [<c0293634>] (ecap_pwm_get_value) from [<c0291d8c>] (pwm_ecap_get_value+0x38/0x58)
[ 58.080452] r7:00000fff r6:00000000 r5:00000000 r4:cf2423c0
[ 58.086456] [<c0291d54>] (pwm_ecap_get_value) from [<c0293118>] (pwm_ecap_get_value_periodns_show+0x1c/0x28)
[ 58.096771] r6:cf7fbc00 r5:c0833720 r4:cc0a0780 r3:c02930fc
[ 58.102779] [<c02930fc>] (pwm_ecap_get_value_periodns_show) from [<c0355c44>] (dev_attr_show+0x24/0x50)
[ 58.112665] [<c0355c20>] (dev_attr_show) from [<c0126f24>] (sysfs_kf_seq_show+0x94/0x110)
[ 58.121251] r5:cf5d9408 r4:cc0a0780
[ 58.125045] [<c0126e90>] (sysfs_kf_seq_show) from [<c0129cdc>] (kernfs_seq_show+0x2c/0x30)
[ 58.133724] r10:00000001 r9:00000000 r8:cf3f3a40 r7:cf521ec8 r6:cc0a0780 r5:00000001
[ 58.141989] r4:cf7fbc00 r3:c0126e90
[ 58.145786] [<c0129cb0>] (kernfs_seq_show) from [<c00e92bc>] (seq_read+0x1c8/0x4a0)
[ 58.153840] [<c00e90f4>] (seq_read) from [<c012a65c>] (kernfs_fop_read+0x114/0x15c)
[ 58.161878] r10:be91fbd4 r9:00001000 r8:00001000 r7:cf521f78 r6:be91fbd4 r5:00001000
[ 58.170143] r4:cf7fbc00
[ 58.172842] [<c012a548>] (kernfs_fop_read) from [<c00cb748>] (vfs_read+0x98/0x138)
[ 58.180789] r10:be91fbd4 r9:cf520000 r8:00001000 r7:cf521f78 r6:be91fbd4 r5:00001000
[ 58.189052] r4:cf3f3a40
[ 58.191740] [<c00cb6b0>] (vfs_read) from [<c00cb920>] (SyS_read+0x44/0x90)
[ 58.198953] r10:be91fbd4 r8:00001000 r7:cf3f3a40 r6:cf3f3a40 r5:00000000 r4:00000000
[ 58.207258] [<c00cb8dc>] (SyS_read) from [<c000e7e0>] (ret_fast_syscall+0x0/0x30)
[ 58.215112] r10:00000000 r8:c000e964 r7:00000003 r6:00000003 r5:be91fbd4 r4:00001000
[ 58.223391] Code: e58dc000 eb0c5728 e5943008 e3a00000 (e5873000)
[ 58.229877] ---[ end trace f955019e121d8d02 ]---
Segmentation fault

regards,

Viswanath K

  • Hi Viswanath,

    Which SDK are you using?
    Have you configured your driver as described here: processors.wiki.ti.com/.../Linux_Core_PWM_User%27s_Guide ?

    Best Regards,
    Yordan
  • Thank you for the reply. Weblink you given and in linux also pwm-ecap is configured for pwm generation only. pwm capture is not given.
    So we implemented completely -- but unable to send the values to the user-space those values.

    we are able to capture , which the cap register values -- here we are facing another problem --
    #1:
    we are using this pwm capture to read the fan speed -- here i am having few quest/doubts
    1. we are not enabled the interrupts in pwm-tiecap.c. we like to use the one shot mode
    2. how can we calculate the fan speed in terms of RPM with CAP1-CAP4 register values.

    can you please guide us.

    regards,
    Viswanath K
  • Hi Viswanath,

    I too have a similar problem with eCAP for capture.....

    I have been following the technical reference for am335x to configure eCAP registers for capture.
    I have assigned customized functions to ecap_pwm_ops in pwm-tiecap.c, which will configure the eCAP registers for Capture. So that We have sysfs access to call these functions and to execute.
    I confirmed capture operation by randomly reading the CAP1-4 registers(counter value is incrementing when feeding pulse inputs.)

    But i have been stuck to read CAP1-4 registers at the instant of interrupt ECINT(CEVT4).
    How should i get the interrupt (particularly 31 and 47) and handle my interrupt routine in pwm driver.

    Also i tried,

    request_irq (irq_num, (irq_handler_t)pulse_handlers, 0, pulse_input_name, NULL)

    my handler is not executing ..

    Pls suggest

    regards,

    Abishek

  • Sure. I will help u.
    #1: are u able to send the data to user space from kernel space.??
    #2: did u implemented the sysfs interface -to user ??
    #3: Do u have any alternative option to read the signal.. ??

    if u you want the 31 and 47 interrupt , u need to add those in dtsi file. then only u can able to get the interrupt number and can able to register.
    might u have to use devm_request_irq

    if u need any thing more, mail me at viswa.kondapalli@gmail.com.
    post here too, so that it will help to others also.

    regards,
    Viswanath K
  • Hi Viswanath,

    Thank you for your support.

    #1 Currently i am not using, But i created one attribute, which has show operation. Later i will use to show the period.

    #2 I replaced ecap_pwm_config()  in pwm-tiecap.c, so that if i write any values on attributes in userspace, Those specific functions assigned to ecap_pwm_ops will get called. (attached console logs)

    #3 By using one of the attributes(say, polarity), i have advantage to read the current cap register value and printing for testing.

    I have attached device tree entries also. Interrupts entries added .

    ISR Problem: Requesting irq through devm_request_irq:

    I have devm_request_irq in ecap_pwm_probe() func,
    devm_request_irq(&pdev->dev, irq_num, (irq_handler_t)pulse_handler, 0, pulse_input_name, &pdev->id )

    where irq_num = 31. 

    Still my routine is not getting executed, Is any changes required in that func like flags...

    tipost.txt
    Fullscreen
    1
    2
    3
    4
    5
    Device tree entries:
    epwmss0: epwmss@48300000 {
    status = "okay";
    ecap0: ecap@48300100 {
    compatible = "ti,am33xx-ecap";
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    Best regards,
    Abishek