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.

Codec Engine SPHENC1_process failure

Other Parts Discussed in Thread: OMAP-L138, OMAPL138

Hello

Currently I'm developing an application that uses codec engine. Right now I'm doing something like this:

- main() calls CERuntime_init
- main creates a pthread and goes to sleep
- in pthread i do:
- call Engine_open (succeeds)
- call SPHENC1_create (succeeds)
- call something like:
g711a_encoder.in_buf = (XDAS_Int8 *)Memory_contigAlloc(160*2, Memory_DEFAULTALIGNMENT);
g711a_encoder.out_buf = (XDAS_Int8 *)Memory_contigAlloc(160*1, Memory_DEFAULTALIGNMENT);
To allocate buffers on which I'm going to use the g711 encoder from TI's examples. Both allocs succeed.
- open two Linux named pipes, one for reading, second for writing - they serve to exchange data to encode between processes
- then I go to an infinite while loop that sleeps ona a Linux select call until other side writes data to the pipe
- when something gets written to the pipe, select wakes and I do:
unsigned int read_bytes = read(g711a_encoder.fd_rd, g711a_encoder.in_buf, 320);
This call succeeds without a problem. As you can see I'm reading from the pipe right to he buffer allocated by CMEM. Guessing from the example "speech" provided by TI it's OK.
- I call my function:
dsp_encode(g711a_encoder.g711a_enc, g711a_encoder.in_buf, g711a_encoder.out_buf, 320, 160);

int dsp_encode(SPHENC1_Handle enc, XDAS_Int8 *in_buf, XDAS_Int8 *out_buf, unsigned int in_size, unsigned int out_size) {
    XDM1_SingleBufDesc in_buf_desc;
    XDM1_SingleBufDesc out_buf_desc;
    SPHENC1_InArgs enc_in_args;
    SPHENC1_OutArgs enc_out_args;
    Int32 status;

    in_buf_desc.bufSize = in_size;
    in_buf_desc.buf = in_buf;

    out_buf_desc.bufSize = out_size;
    out_buf_desc.buf = out_buf;

    enc_in_args.size  = sizeof(enc_in_args);
    enc_in_args.data.buf = NULL;

    enc_out_args.size = sizeof(enc_out_args);

    status = SPHENC1_process(enc, &in_buf_desc, &out_buf_desc, &enc_in_args, &enc_out_args);
   
    if (status != SPHENC1_EOK) {
        return -1;
    }
    return 0;
}

But unfortunately SPHENC1_process always fails. By printing the most verbose CE_DEBUG=3 I get:

@19,641,165us: [+0 T:0x41160490 S:0x4115fbec] ti.sdo.ce.speech1.SPHENC1 - SPHENC1_process> Enter (handle=0x43960, inBuf=0x4115fcc8, outBuf=0x4115fcbc, inArg)
@19,641,415us: [+4 T:0x41160490 S:0x4115fb84] CV - VISA_getMaxMsgSize(0x43960): returning 0x1000
@19,641,622us: [+5 T:0x41160490 S:0x4115fb8c] CV - VISA_allocMsg> Allocating message for messageId=0x0000001c
@19,641,830us: [+0 T:0x41160490 S:0x4115fb5c] OM - Memory_getBufferPhysicalAddress> Enter(virtAddr=0x421de000, size=320)
@19,642,030us: [+1 T:0x41160490 S:0x4115fb5c] OM - Memory__getPhysicalAddress> Enter(virtAddr=0x421de000, size=320)
@19,642,227us: [+1 T:0x41160490 S:0x4115fb5c] OM - Memory__getPhysicalAddress> found in cb(Sc=0x421de000, Ec=0x421de140, Ss=0x421de000, Es=0x421de140, PSc=0)
@19,642,494us: [+1 T:0x41160490 S:0x4115fb5c] OM - Memory__getPhysicalAddress> returning physAddr=0xc3bf0000
@19,642,693us: [+0 T:0x41160490 S:0x4115fb5c] OM - Memory_getBufferPhysicalAddress> return (0xc3bf0000)
@19,977,668us: [+0 T:0x41160490 S:0x4115fb5c] OM - Memory_getBufferPhysicalAddress> Enter(virtAddr=0x421ee000, size=160)
@19,977,938us: [+1 T:0x41160490 S:0x4115fb5c] OM - Memory__getPhysicalAddress> Enter(virtAddr=0x421ee000, size=160)
@19,978,145us: [+1 T:0x41160490 S:0x4115fb5c] OM - Memory__getPhysicalAddress> found in cb(Sc=0x421ee000, Ec=0x421ee0a0, Ss=0x421ee000, Es=0x421ee0a0, PSc=0)
@19,978,361us: [+1 T:0x41160490 S:0x4115fb5c] OM - Memory__getPhysicalAddress> returning physAddr=0xc3be0000
@19,978,549us: [+0 T:0x41160490 S:0x4115fb5c] OM - Memory_getBufferPhysicalAddress> return (0xc3be0000)
@19,978,751us: [+0 T:0x41160490 S:0x4115fb94] CV - VISA_call(visa=0x43960, msg=0x4216fc80): messageId=0x0000001c, command=0x0
@19,979,022us: [+0 T:0x41160490 S:0x4115fb5c] OC - Comm_put> Enter(queue=0x2, msg=0x4216fc80)
@19,979,233us: [+0 T:0x41160490 S:0x4115fb5c] OC - Comm_put> return (1)
@19,979,433us: [+0 T:0x41160490 S:0x4115fae4] OC - Comm_put> Enter(queue=0x0, msg=0x4216ec80)
@19,979,721us: [+0 T:0x41160490 S:0x4115fae4] OC - Comm_put> return (1)
@19,979,936us: [+0 T:0x41160490 S:0x4115fb94] CV - VISA_call Completed: messageId=0x0000001c, command=0x0, return(status=-1)
@19,980,171us: [+5 T:0x41160490 S:0x4115fb9c] CV - VISA_freeMsg(0x43960, 0x4216fc80): Freeing message with messageId=0x0000001c
@19,980,438us: [+0 T:0x41160490 S:0x4115fbec] ti.sdo.ce.speech1.SPHENC1 - SPHENC1_process> Exit (handle=0x43960, retVal=0xffffffff)

But sometimes I get this and a kernel backtrace:

@16,722,308us: [+0Unable to handle kernel NULL pointer dereference at virtual address 00000000
 T:0x41160490 S:pgd = c35b0000
0x4115fbec] ti.s[00000000] *pgd=c35e6031do.ce.speech1.SP, *pte=00000000HENC1 - SPHENC1_, *ppte=00000000process> Enter (
handle=0x439d0, Internal error: Oops: 817 [#1] PREEMPT
last sysfs file:
Modules linked in: cmemk dsplinkk
CPU: 0    Not tainted  (2.6.33-rc4 #8)
PC is at IPS_unregister+0x128/0x240 [dsplinkk]
LR is at IPS_unregister+0xdc/0x240 [dsplinkk]
pc : [<bf002f68>]    lr : [<bf002f1c>]    psr: 60000013
sp : c35b7dc8  ip : 00000000  fp : c35b7e14
r10: 00008000  r9 : 00000000  r8 : c4102600
r7 : c4210000  r6 : c4210000  r5 : bf0155c8  r4 : 00000000
r3 : 00000000  r2 : 00000000  r1 : 00000000  r0 : 00000001
Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment user
Control: 0005317f  Table: c35b0000  DAC: 00000015
Process dspd (pid: 360, stack limit = 0xc35b6270)
Stack: (0xc35b7dc8 to 0xc35b8000)
7dc0:                   c35ec0cc 00000000 c35b7fb0 c34f0634 c35b7e0c bf0068e8
7de0: bf015ea8 c4374000 00000000 0000800d bf015ea8 00000000 00000000 c417f900
7e00: c4084000 00000001 c35b7e54 c35b7e18 bf006688 bf002e50 bf015ea8 c35b7e28
7e20: c35b7e44 00000000 c004a6f0 0000800d 00000001 00000000 4115f604 4115f604
7e40: c35b6000 00000001 c35b7e64 c35b7e58 bf005388 bf00664c c35b7e84 c35b7e68
7e60: bf01305c bf005354 4115f604 c018e031 c018e031 4115f604 c35b7ef4 c35b7e88
7e80: bf013840 bf012ff4 00000000 00000000 00000000 4115f6f8 00000008 00000000
7ea0: c35b7ec4 c35b7eb0 c004a6f0 c004871c 00000000 00008000 00000000 00000064
7ec0: 40033da4 4015d5f8 00000000 c35b7fb0 c3510680 c018e031 4115f604 c3510680
7ee0: 4115f604 00000001 c35b7f14 c35b7ef8 c00aa594 bf013340 c35b7e74 c3510680
7f00: 4115f604 00000004 c35b7f7c c35b7f18 c00aac30 c00aa51c c0150bdc 00000002
7f20: 00000000 c3006780 c300e548 0000005e c35b6000 00000000 c35b7f74 c35b7f48
7f40: c009cb68 c00cbb9c 00000000 00000000 0000003d 00000000 00000004 4115f604
7f60: c018e031 c3510680 c0029084 00000001 c35b7fa4 c35b7f80 c00aacd0 c00aa6d0
7f80: c0041e98 00000001 00000165 4216dc80 000420e8 00000036 00000000 c35b7fa8
7fa0: c0028f00 c00aaca0 00000165 4216dc80 00000004 c018e031 4115f604 00000004
7fc0: 00000165 4216dc80 000420e8 00000036 4115fcac 4015d5f8 00000001 4115f5f4
7fe0: 00000000 4115f4d8 0001f0b0 400f8c8c 80000010 00000004 00010000 0000000e
Backtrace:
[<bf002e40>] (IPS_unregister+0x0/0x240 [dsplinkk]) from [<bf006688>] (ZCPYMQT_close+0x4c/0x2ac [dsplinkk])
[<bf00663c>] (ZCPYMQT_close+0x0/0x2ac [dsplinkk]) from [<bf005388>] (LDRV_MSGQ_transportClose+0x44/0x54 [dsplinkk])
[<bf005344>] (LDRV_MSGQ_transportClose+0x0/0x54 [dsplinkk]) from [<bf01305c>] (PMGR_MSGQ_transportClose+0x78/0x98 [dsplinkk])
[<bf012fe4>] (PMGR_MSGQ_transportClose+0x0/0x98 [dsplinkk]) from [<bf013840>] (DRV_Ioctl+0x510/0x7c8 [dsplinkk])
 r6:4115f604 r5:c018e031 r4:c018e031
[<bf013330>] (DRV_Ioctl+0x0/0x7c8 [dsplinkk]) from [<c00aa594>] (vfs_ioctl+0x88/0xb8)
[<c00aa50c>] (vfs_ioctl+0x0/0xb8) from [<c00aac30>] (do_vfs_ioctl+0x570/0x5d0)
 r6:00000004 r5:4115f604 r4:c3510680
[<c00aa6c0>] (do_vfs_ioctl+0x0/0x5d0) from [<c00aacd0>] (sys_ioctl+0x40/0x64)
[<c00aac90>] (sys_ioctl+0x0/0x64) from [<c0028f00>] (ret_fast_syscall+0x0/0x28)
 r7:00000036 r6:000420e8 r5:4216dc80 r4:00000165
Code: e1c33910 e5981008 e3a02000 e5883080 (e7812389)
inBuf=0x4115fcc8---[ end trace a318ec83ba68385c ]---
, outBuf=0x4115fcbc, inArgs=0x4115fcac, outArgs=0x4115fca4)
@16,722,580us: [+4 T:0x41160490 S:0x4115fb84] CV - VISA_getMaxMsgSize(0x439d0): returning 0x1000
@16,722,788us: [+5 T:0x41160490 S:0x4115fb8c] CV - VISA_allocMsg> Allocating message for messageId=0x00000001
@16,722,996us: [+0 T:0x41160490 S:0x4115fb5c] OM - Memory_getBufferPhysicalAddress> Enter(virtAddr=0x421de000, size=320)
@16,723,249us: [+1 T:0x41160490 S:0x4115fb5c] OM - Memory__getPhysicalAddress> Enter(virtAddr=0x421de000, size=320)
@16,723,453us: [+1 T:0x41160490 S:0x4115fb5c] OM - Memory__getPhysicalAddress> found in cb(Sc=0x421de000, Ec=0x421de140, Ss=0x421de000, Es=0x421de140, PSc=0)
@16,723,665us: [+1 T:0x41160490 S:0x4115fb5c] OM - Memory__getPhysicalAddress> returning physAddr=0xc3bf0000
@16,723,856us: [+0 T:0x41160490 S:0x4115fb5c] OM - Memory_getBufferPhysicalAddress> return (0xc3bf0000)
@16,724,051us: [+0 T:0x41160490 S:0x4115fb5c] OM - Memory_getBufferPhysicalAddress> Enter(virtAddr=0x421ee000, size=160)
@16,724,251us: [+1 T:0x41160490 S:0x4115fb5c] OM - Memory__getPhysicalAddress> Enter(virtAddr=0x421ee000, size=160)
@16,724,477us: [+1 T:0x41160490 S:0x4115fb5c] OM - Memory__getPhysicalAddress> found in cb(Sc=0x421ee000, Ec=0x421ee0a0, Ss=0x421ee000, Es=0x421ee0a0, PSc=0)
@16,724,701us: [+1 T:0x41160490 S:0x4115fb5c] OM - Memory__getPhysicalAddress> returning physAddr=0xc3be0000
@16,724,897us: [+0 T:0x41160490 S:0x4115fb5c] OM - Memory_getBufferPhysicalAddress> return (0xc3be0000)
@16,726,453us: [+0 T:0x41160490 S:0x4115fb94] CV - VISA_call(visa=0x439d0, msg=0x42170c80): messageId=0x00000001, command=0x0
@16,726,696us: [+0 T:0x41160490 S:0x4115fb5c] OC - Comm_put> Enter(queue=0x3, msg=0x42170c80)
@16,726,934us: [+0 T:0x41160490 S:0x4115fb5c] OC - Comm_put> return (1)
@16,727,149us: [+0 T:0x41160490 S:0x4115fae4] OC - Comm_put> Enter(queue=0x0, msg=0x4216dc80)

Any idea on what might be going on? I would appreciate any leads.
Thank you.

Szymon

  • Szymon,

    The stack traceback from the kernel "Oops" shows that it was in the process of closing the MSGQ transport:

    Szymon Kuklinski said:

    [<bf002e40>] (IPS_unregister+0x0/0x240 [dsplinkk]) from [<bf006688>] (ZCPYMQT_close+0x4c/0x2ac [dsplinkk])
    [<bf00663c>] (ZCPYMQT_close+0x0/0x2ac [dsplinkk]) from [<bf005388>] (LDRV_MSGQ_transportClose+0x44/0x54 [dsplinkk])
    [<bf005344>] (LDRV_MSGQ_transportClose+0x0/0x54 [dsplinkk]) from [<bf01305c>] (PMGR_MSGQ_transportClose+0x78/0x98 [dsplinkk])
    [<bf012fe4>] (PMGR_MSGQ_transportClose+0x0/0x98 [dsplinkk]) from [<bf013840>] (DRV_Ioctl+0x510/0x7c8 [dsplinkk])
     r6:4115f604 r5:c018e031 r4:c018e031

    The CE_DEBUG messages show that the Comm_put() calls are failing (return of 1 is Comm_EFAIL), probably because the MSGQ transport has already been closed (or is in the process of closing).

    The transport would get closed as a result of stock DSPLink signal handling.  DSPLink has its own tracing capabilities that would show the transport getting closed early, if that's the case.  Would you be able to enable DSPLink tracing and generate the error again?  If so then we could likely see where the transport is being closed.

    DSPLink trace enabling instructions are here: http://processors.wiki.ti.com/index.php/Enabling_trace_in_DSPLink

    Regards,

    - Rob

     

  • Hi

    I recompiled DSPLink with --trace=1, compiled and linked my application with the new dsplink.lib loaded new dsplinkk.ko and here's the output:

    Before select! //MY select() printf
    Reading bytes!//MY select() printf
    Read 320 bytes!//MY select() printf
    @23,822,962us: [+0 T:0x41160490 S:0x4115fbe4] ti.sdo.ce.speech1.SPHENC1 - SPHENC1_process> Enter (handle=0x4b9b0, inBuf=0x4115fcc0, outBuf=0x4115fcb4, inArg)
    @23,823,212us: [+4 T:0x41160490 S:0x4115fb7c] CV - VISA_getMaxMsgSize(0x4b9b0): returning 0x1000
    @23,823,413us: [+5 T:0x41160490 S:0x4115fb84] CV - VISA_allocMsg> Allocating message for messageId=0x0000000f
    @23,823,621us: [+0 T:0x41160490 S:0x4115fb54] OM - Memory_getBufferPhysicalAddress> Enter(virtAddr=0x421de000, size=320)
    @23,823,826us: [+1 T:0x41160490 S:0x4115fb54] OM - Memory__getPhysicalAddress> Enter(virtAddr=0x421de000, size=320)
    @24,158,017us: [+1 T:0x41160490 S:0x4115fb54] OM - Memory__getPhysicalAddress> found in cb(Sc=0x421de000, Ec=0x421de140, Ss=0x421de000, Es=0x421de140, PSc=0)
    @24,158,498us: [+1 T:0x41160490 S:0x4115fb54] OM - Memory__getPhysicalAddress> returning physAddr=0xc3bf0000
    @24,158,731us: [+0 T:0x41160490 S:0x4115fb54] OM - Memory_getBufferPhysicalAddress> return (0xc3bf0000)
    @24,158,940us: [+0 T:0x41160490 S:0x4115fb54] OM - Memory_getBufferPhysicalAddress> Enter(virtAddr=0x421ee000, size=160)
    @24,159,142us: [+1 T:0x41160490 S:0x4115fb54] OM - Memory__getPhysicalAddress> Enter(virtAddr=0x421ee000, size=160)
    @24,159,396us: [+1 T:0x41160490 S:0x4115fb54] OM - Memory__getPhysicalAddress> found in cb(Sc=0x421ee000, Ec=0x421ee0a0, Ss=0x421ee000, Es=0x421ee0a0, PSc=0)
    @24,159,615us: [+1 T:0x41160490 S:0x4115fb54] OM - Memory__getPhysicalAddress> returning physAddr=0xc3be0000
    @24,159,803us: [+0 T:0x41160490 S:0x4115fb54] OM - Memory_getBufferPhysicalAddress> return (0xc3be0000)
    @24,159,999us: [+0 T:0x41160490 S:0x4115fb8c] CV - VISA_call(visa=0x4b9b0, msg=0x42170c80): messageId=0x0000000f, command=0x0
    @24,160,209us: [+0 T:0x41160490 S:0x4115fb54] OC - Comm_put> Enter(queue=0x3, msg=0x42170c80)
    Entered MSGQ_put ()
            msgqQueue       [0x3]
            msg     [0x42170c80]
    Entered DRV_Invoke ()
            drvObj  [0x4b750]
            cmdId   [0xc018e039]
            arg1    [0x4115fb64]
            arg2    [0x0]
    Entered _POOL_xltBuf ()
            poolId  [0x0]
            bufPtr  [0x4115fb6c]
            xltFlag [0x200]
    Leaving _POOL_xltBuf ()         status [0x8000]
    Status: 80008054
    Leaving DRV_Invoke ()   status [0x80008054]
    Leaving MSGQ_put ()     status [0x80008054]
    @24,161,517us: [+0 T:0x41160490 S:0x4115fb54] OC - Comm_put> return (1)
    @24,161,730us: [+0 T:0x41160490 S:0x4115fadc] OC - Comm_put> Enter(queue=0x0, msg=0x4216dc80)
    Entered MSGQ_put ()
            msgqQueue       [0x0]
            msg     [0x4216dc80]
    Entered DRV_Invoke ()
            drvObj  [0x4b750]
            cmdId   [0xc018e039]
            arg1    [0x4115faec]
            arg2    [0x0]
    Entered _POOL_xltBuf ()
            poolId  [0x0]
            bufPtr  [0x4115faf4]
            xltFlag [0x200]
    Leaving _POOL_xltBuf ()         status [0x8000]
    Status: 80008054
    Leaving DRV_Invoke ()   status [0x80008054]
    Leaving MSGQ_put ()     status [0x80008054]
    @24,163,024us: [+0 T:0x41160490 S:0x4115fadc] OC - Comm_put> return (1)
    @24,163,233us: [+0 T:0x41160490 S:0x4115fb8c] CV - VISA_call Completed: messageId=0x0000000f, command=0x0, return(status=-1)
    @24,163,504us: [+5 T:0x41160490 S:0x4115fb94] CV - VISA_freeMsg(0x4b9b0, 0x42170c80): Freeing message with messageId=0x0000000f
    @24,163,730us: [+0 T:0x41160490 S:0x4115fbe4] ti.sdo.ce.speech1.SPHENC1 - SPHENC1_process> Exit (handle=0x4b9b0, retVal=0xffffffff)

    And it just spits out more of the same each time i run dsp_encode.
    According to errbase.h 0x80008054 is DSP_ENOTREADY.

    Let me know if I should turn of any more verbose debug messages (and how shoudl I do that ;) ).

    Thank you
    Szymon

  • The source code for DSPLink should be in your installation, in case you want to dig deep yourself.

    From the source code I see just one function that returns DSP_ENOTREADY - IPS_notify().  The header file comments for IPS_notify() contains:
     *          DSP_ENOTREADY
     *              Event is not registered on the remote processor.

    I'm not sure how much help I can be here, since I'm not very familiar with the internals of DSPLink.  I'm not sure what "event" is in question here, but it seems to me that it could be related to the capabilities available on the DSP side, something to do with the DSP-side DSPLink not being built with MSGQ capabilities.  Have you rebuilt your codec server (the DSP program) with the same installation of DSPLink with which you built your ARM app?

    I'll try to alert DSPLink folks to your issue here, they would be much better to help here.

    Regards,

    - Rob

  • Hello

    Doubting that my problem is a serious bug in CE I started looking at my code and found an interesting fact. When my CE application was running alone in the system all went well. Right after I ran a second (much bigger) program CE started to behave in a random way. I concluded that this must be some kind of configuration problem. The first thing I did was to reduce the memory available to Linux to 32M. This seems to have cured the problem.

    Naturally I would like to use all the free RAM. I'm using Zoom OMAP-L138 eXperimenter kit with 64MB of RAM. In the default configuration DSPLink uses 62M-64M range. I also configured CMEM to use 60M-62M like this:

    insmod /lib/modules/2.6.33-rc4/kernel/cmemk.ko pools=16x65536 phys_start=0xC3C00000 phys_end=0xC3E00000

    I looked at the files OMAP-L138_arm_1_00_00_11/codec_engine_2_25_00_05/packages/ti/sdo/ce/ipc/dsplink/Processor_dsplink_linkcfg_OMAPL138.c and  OMAP-L138_arm_1_00_00_11/dsplink_linux_1_65_00_02/dsplink/config/all/CFG_OMAPL138GEM_SHMEM.c. The configuration seems to be ok

    But then I looked into OMAP-L138_arm_1_00_00_11/codec_engine_2_25_00_05/examples/ti/sdo/ce/examples/servers/all_codecs/all_evmOMAPL138.tci and the config there does not correspond to what's in the two previous files.

    var mem_ext = [
    {
        comment:    "DDRALGHEAP: off-chip memory for dynamic algmem allocation",
        name:       "DDRALGHEAP",
        base:       0xC3000000,
        len:        0x01000000,
        space:      "code/data"
    },
    {
        comment:    "SDRAM: off-chip memory for application code and data",
        name:       "SDRAM",
        base:       0xC2C00000,
        len:        0x00300000,
        space:      "code/data"
    },
    {
        comment:    "DSPLINK: off-chip memory reserved for DSPLINK code and data",
        name:       "DSPLINKMEM",
        base:       0xC2F01000,
        len:        0x00100000 - 0x1000,
        space:      "code/data"
    },
    {
        comment:    "RESET_VECTOR: off-chip memory for the reset vector table",
        name:       "RESET_VECTOR",
        base:       0xC2F00000,
        len:        0x00001000,
        space:      "code/data"
    },
    ];

    As you can see when I had MEM=60M there was a clash between Linux and the codecs. I'll have to correct this one I catch up with my work. This would also explain why setting MEM to 50M did not help in my case - 0xC2C00000 - the lowest memory base taken from the array above corresponds to 44MB of RAM.

    All the examples I ran were working ok, just because they ran alone, with only some kernel processes in the background. Nothing got corrupted along the way since this invalid memory is used directly by the DSP and not the application itself, so there were no segfaults. From what I remember Zoom OMAP-L138 ships with MEM=32M in u-boot, so many people won't see this problem right from the start when they don't care about the performance right from the beginning.

    Regards
    Szymon