Shop OBEX P1 Docs P2 Docs Learn Events
4-bit GUI (testing) Now with WS2812B RGB LED test example - Page 3 — Parallax Forums

4-bit GUI (testing) Now with WS2812B RGB LED test example

135

Comments

  • cgraceycgracey Posts: 14,133
    Yes, this is neat. I'll be trying this out, hopefully, tomorrow.

    It would be neat if the world could rediscover the fun of programming on and for a system which is both fully understandable and totally controllable.
  • ErNaErNa Posts: 1,738
    Hi Chip, I believe, that is what you and many in the forum are working for. It will happen. LEGO once were simple blocks. Then special functions appeared, like roof stones. Then complete stories existed, like pirates or star wars. But in the end the children will create their own stuff from bricks.
    If HP had offered the scientific calculators in a low price version, UPN would be common. If you take a look at Peters progress in Tachyon, I imagine the moment, PII is available, a self contained IDE is in existence!
  • RaymanRayman Posts: 13,800
    Just found a bug so bad, I'm amazed the code worked!

    The draw object loop was incrementing by bytes instead of longs:
    'Draw Form objects
                  mov       mo,ptrb
                  add       mo,#9'8 +1 for font
    mFormObjectLoop              
                  rdlong    ptrb,mo
                  cmp       ptrb,#0 wz,wc
           if_z   RET
                  call      #mDrawFormObject
                  add       mo,#1
                  jmp       #mFormObjectLoop
    

    The #9 should be #9*4 and the #1 should be #4.
  • T ChapT Chap Posts: 4,198
    edited 2016-12-20 14:35
    Some buttons would be nice. Up, down, while clicked. One day that will be fun to create. I like the free app Pixleformer, works great to export to bmp, import in your 1bit app, export as .dat
  • RaymanRayman Posts: 13,800
    Got basic button working.
    It highlights red on mouse over and yellow on mouse down...
    1632 x 1224 - 987K
  • T ChapT Chap Posts: 4,198
    edited 2016-12-21 04:03
    So USB mouse will be easy on the real chip with no usb interface?
  • jmgjmg Posts: 15,140
    T Chap wrote: »
    So USB mouse will be easy on the real chip with no usb interface?

    For certain values of 'USB mouse' and 'easy', yup, a SW +Smart Pin solution looks do-able.

  • cgraceycgracey Posts: 14,133
    T Chap wrote: »
    So USB mouse will be easy on the real chip with no usb interface?

    The real chip has USB pin sets on every odd-even pair of pins.
  • jmgjmg Posts: 15,140
    cgracey wrote: »
    T Chap wrote: »
    So USB mouse will be easy on the real chip with no usb interface?

    The real chip has USB pin sets on every odd-even pair of pins.

    I wonder how many of those pairs, a P2 could realistically drive ?
    As a Host talking to Keyboard or Mouse type peripherals, the P2 can choose the payload and phase, so it comes down to just how many bytes are needed per 1ms frame (or even groups of frames).
    eg a single COG could sequentially phase multiple USB pairs, up to what ? 3?,4?,?


  • RaymanRayman Posts: 13,800
    Just got to testing out something...
    Made last entry in button object (located in hub) the address of a hubexec routine.
    When button clicked main cog just jumps to that address.
    Seems weird, but appears to work:
    Form1Button1
                  long      1       '0 type=button
                  long      80      '1 left
                  long      200     '2 top
                  long      80      '3 width
                  long      50      '4 height
                  long      black   '5 border color
                  long      sForm1Text4 '6 string
                  long      black    '7 text fore color
                  long      gray  '8 text back color
                  long      VarFont'FontData     '9 font pointer
                  long      red '10 mouse over border color
                  long      yellow '11 mouse down border color
                  long      mOnForm1Button1  '12 on-click code
    
    DAT 'Form exec1
    mOnForm1Button1
                  wrlong    #20,ptra[2] 'x1
                  wrlong    #50,ptra[6] 'x2
                  wrlong    #10,ptra[3] 'y1             
                  wrlong    #30,ptra[7] 'y2
                  wrlong    #red,ptra[4]   'color
                  mov       PA,#DrawFilledRectangle_
                  call      #MainGraphicsCmd
                  RET
    
  • RaymanRayman Posts: 13,800
    also just thinking about setq and communications between cogs through the hub...

    I'm thinking that if, for example, the usb code is repeatedly using setq to write 3 longs of status and another cog is using setq to read 3 longs then you don't have to worry about reading in an incomplete update.

    What I mean is that you won't get a new x value with an old y value.
    At least, I'm thinking this is true...
  • Did the P2 get opcodes for doing fast CRC for USB and Ethernet?
  • pedward wrote: »
    Did the P2 get opcodes for doing fast CRC for USB and Ethernet?
    No specific opcodes for CRC. For USB low/full speed, using pre-calculated lookup tables can get the job done.
  • I've been advocating for builtin CRC instructions for a good long while now. It's dumb to waste memory and/or cycles on CRC when it can be done so easily in Verilog.
  • jmgjmg Posts: 15,140
    pedward wrote: »
    I've been advocating for builtin CRC instructions for a good long while now. It's dumb to waste memory and/or cycles on CRC when it can be done so easily in Verilog.
    I think one of the issues here, was that there is not one single, universal CRC, but instead there are many....
  • IIRC, USB and Ethernet use the same algorithm, with simply a different modulus value. My original thought was to simply allow the program to specify the starting modulus, then it would be applicable to many uses.
  • jmgjmg Posts: 15,140
    pedward wrote: »
    IIRC, USB and Ethernet use the same algorithm, with simply a different modulus value. My original thought was to simply allow the program to specify the starting modulus, then it would be applicable to many uses.
    https://en.wikipedia.org/wiki/Cyclic_redundancy_check
    Shows both 5b and 16b needed for USB and 32b for Ethernet ....

  • RaymanRayman Posts: 13,800
    edited 2016-12-22 02:14
    As an aside...

    I've started copying what I've seen others do and do a JMP instead of a CALL to a subroutine that ends in RET. Seems like it saves an instruction (RET) in a lot of cases...
    I don't think we could do this with P1, right?

    Also...

    When things go wrong I wonder if I've hit the 5-deep (right?) CALL stack limit. Hasn't been the actual problem so far though...
  • jmgjmg Posts: 15,140
    Rayman wrote: »
    As an aside...
    I've started copying what I've seen others do and do a JMP instead of a CALL to a subroutine that ends in RET.

    You mean where you have a final call, immediately before a return ?
    ThisFunction:
      ...
      CALL  FunctionName
      RET
    
    instead it becomes
    ThisFunction:
     ...
      JMP  FunctionName    ' saves 1 stack level and one opcode.
    ' RET 
    

  • RaymanRayman Posts: 13,800
    exactly...
  • Rayman wrote: »
    When things go wrong I wonder if I've hit the 5-deep (right?) CALL stack limit. Hasn't been the actual problem so far though...
    The hardware stack is 8 levels deep.

  • jmg wrote: »
    Rayman wrote: »
    As an aside...
    I've started copying what I've seen others do and do a JMP instead of a CALL to a subroutine that ends in RET.

    You mean where you have a final call, immediately before a return ?
    ThisFunction:
      ...
      CALL  FunctionName
      RET
    
    instead it becomes
    ThisFunction:
     ...
      JMP  FunctionName    ' saves 1 stack level and one opcode.
    ' RET 
    

    Seems like you couldn't reuse FunctionName in other parts of code if you JMP to it. How would it know where to return to? Am I missing something?
  • Think of it as a head/tail thing. If you are using a series of subroutines to complete a task, and you're at the end of a routine where you know you want to eventually return to the "head" routine, that would be the "tail" routine that uses the jmp. The jmp target could be a subroutine that does some cleanup task, which could include calling other subroutines. When the cleanup routine encounters its exit ret, the stack address will be that of the "head" routine.
  • RaymanRayman Posts: 13,800
    edited 2016-12-22 19:21
    Just got option buttons working.
    Ran out of room in main cog and had to push some mouse up event handling out to the hub.

    It's really remarkable how you can just cut and paste code between cog and hub and it works.
    I know there are some things that don't work in hub.
    I forgot what they are, but I must not be using them cause it seems to work...

    This might lead to less optimized code though...
    I was in the process of reducing code size when I just decided to move it to hub.
    Don't feel the need to optimize hub code as much...
  • RaymanRayman Posts: 13,800
    Here's the latest version, now with option buttons and check boxes.
    1632 x 1224 - 780K
  • RaymanRayman Posts: 13,800
    Speaking of call and ret... I was just trying to remember...

    Can the return value of a subroutine be in the carry flag?

    I was going to try that but then think remembered that flags also get pushed and popped from stack..
  • I see you have a push button, but do you have a pull button too? That way you can have "push me" and "pull me".
  • jmgjmg Posts: 15,140
    Rayman wrote: »
    Speaking of call and ret... I was just trying to remember...

    Can the return value of a subroutine be in the carry flag?

    I was going to try that but then think remembered that flags also get pushed and popped from stack..

    It would be unusual to save flags on the stack, as it is common to return with values in the flags.

  • jmgjmg Posts: 15,140
    edited 2016-12-22 23:31
    ke4pjw wrote: »
    Seems like you couldn't reuse FunctionName in other parts of code if you JMP to it. How would it know where to return to? Am I missing something?
    There are strict caveats in the use. (which is why I keep a commented RET in code where this is done)

    In the example above, ThisFunction is called from somewhere, and then only where you have a CALL immediately followed by a RET, you have a choice to JMP and use the RET in FunctionName, to return to the caller of ThisFunction. You do have CALL-RET balance.

    Both ThisFunction & FunctionName can be called from anywhere in main code, like normal.

    There are enough caveats to bite novices here, & this trick is not edit / cut-paste friendly, so I tend to favour an assembler/compiler that do this an option optimize.
    ( even that has issues, as someone right on the stack limit, with opt-on, would have stack issues with opt-off, yet most expect opt-off to be safer and less bug exposed... )
  • Rayman wrote: »
    Speaking of call and ret... I was just trying to remember...

    Can the return value of a subroutine be in the carry flag?

    I was going to try that but then think remembered that flags also get pushed and popped from stack..
    A CALL also saves the C & Z flags on the stack.
    If you want to restore the flags on return simply add WC and/or WZ effects to the RET instruction
       ret wc   'return to address on stack and restore c flag
    

Sign In or Register to comment.