Shop OBEX P1 Docs P2 Docs Learn Events
TAQOZ - Tachyon Forth for the P2 BOOT ROM - Page 22 — Parallax Forums

TAQOZ - Tachyon Forth for the P2 BOOT ROM

1192022242538

Comments

  • samuellsamuell Posts: 554
    edited 2019-01-30 16:21
    Thanks Publison. Ctrl+W displays "0", and then I have to press Enter to return to the prompt. The chip is not too hot to touch, but the board smells hot.

    Kind regards, Samuel Lourenço
  • samuell wrote: »
    Thanks Publison. Ctrl+W displays "0", and then I have to press Enter to return to the prompt. The chip is not too hot to touch, but the board smells hot.

    Kind regards, Samuel Lourenço

    That does not sound right. CNTL+W should bring an instant response. My board is pretty cool in an enclosure without a fan.
  • dgatelydgately Posts: 1,631
    edited 2019-01-30 16:49
    samuell wrote: »
    Thanks Publison. Ctrl+W displays "0", and then I have to press Enter to return to the prompt. The chip is not too hot to touch, but the board smells hot.
    I had the same result when testing last night (about 12 hours ago). Did the ROM image change in the last 24 hours? I went back to a ROM image that I had from earlier in the day and that one is working fine. Running a checksum on that version of the image and one that was just downloaded, shows a difference, though the size is exactly the same.
    $ cksum _BOOT_P2.BIX
    4258669355 84736 _BOOT_P2.BIX
    $ cksum _BOOT_P2.BIX-WORKING 
    3910082680 84736 _BOOT_P2.BIX-WORKING
    

    The current ROM image seems to have lost it vocabulary :-)

    dgately
  • PublisonPublison Posts: 12,366
    edited 2019-01-30 16:55
    dgately wrote: »
    samuell wrote: »
    Thanks Publison. Ctrl+W displays "0", and then I have to press Enter to return to the prompt. The chip is not too hot to touch, but the board smells hot.
    I had the same result when testing last night (about 12 hours ago). Did the ROM image change in the last 24 hours? I went back to a ROM image that I had from earlier in the day and that one is working fine. Running a checksum on that version of the image and one that was just downloaded, shows a difference, though the size is exactly the same.
    $ cksum _BOOT_P2.BIX
    4258669355 84736 _BOOT_P2.BIX
    $ cksum _BOOT_P2.BIX-WORKING 
    3910082680 84736 _BOOT_P2.BIX-WORKING
    

    The current ROM image seems to have lost it vocabulary :-)

    dgately

    I used the file from DropBox 1_29_2019
    There's a new V2 image in the Dropbox folder you can try which corrects the clock speed problem. I've now also fixed the divider to 1 and any clock frequencies selected will be forced to a multiple of that, just to keep things simple. You can however manually specify the clock settings and you can have a look at the source for CLOCK to get a better idea (i.e. uses 15PF PLLEN 1 XIDIV etc).

    This image starts up at 115200 baud at 80MHz since the SD seems to behave better on the P2-ES board at a lower clock rate but just type CRUISE to switch to 180MHz if you also want to use VGA. The P2-ES seems to work fine at 340MHz otherwise but I need to make some changes so that the VGA frequency will also switch and hopefully the SD will still work.

    Since the link changes when the file changes, here is the folder it's in.
  • Publison wrote: »
    I used the file from DropBox 1_29_2019
    Since the link changes when the file changes, here is the folder it's in.
    Yes, as did I! If you download the file again (now) from the "here is the folder it's in" link, does it work? What is its cksum value? Is it different than what you are using now? What I'm saying is that I used the same link to download both images over an 8 hour time frame and got 2 different ROM images.

  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2019-01-30 23:05
    Yesterday I was experimenting with reclaiming private words and also moving the dictionary back into the end of the first 64k just to make it that little bit easier to compress without having to worry about buffers in-between etc. I still need to make a few small changes and then I will verify that the boot images are correct which they should be since I cycle the power on the board to double-check.
    BTW, the dictionary can be moved anywhere in memory at any time, all it needs is the pointer to the most recent word.

    @FredBlais - pay no heed to my advice! I noticed that I used COG! to modify the code, yet the code is hubexec so you would need:
    CLKHZ 250000 U/ ' WSLED 4 - !
    
    But I will check that out shortly too.


    GOOD NEWS!
    I received a shipment of add-ons yesterday for the P2-ES, feels like I've been to the candy store as a kid!
    First thing I did was plug in the Charlieplexed LED MATRIX and type a couple of one-liners. Later on I will get it reflect the output of an 8 byte buffer or even reflect part of the VGA display and also so we can scroll messages across it or draw an icon etc.

    Then I also unplugged my VGA wires and plugged in the add-on and that works.
  • @FredBlais - pay no heed to my advice! I noticed that I used COG! to modify the code, yet the code is hubexec so you would need:
    CLKHZ 250000 U/ ' WSLED 4 - !
    
    But I will check that out shortly too.

    It's working! But the value was 2,500,000 and not 250,000 :D
  • FredBlaisFredBlais Posts: 375
    edited 2019-01-31 00:28
    samuell wrote: »
    Thanks Publison. Ctrl+W displays "0", and then I have to press Enter to return to the prompt. The chip is not too hot to touch, but the board smells hot.

    Kind regards, Samuel Lourenço

    There are 2 boot image in the boot image directory. The .BIX has the issue.
    I used the .BIY and renamed it to .BIX and this one is working fine.
  • Cluso99Cluso99 Posts: 18,069
    Yesterday I was experimenting with reclaiming private words and also moving the dictionary back into the end of the first 64k just to make it that little bit easier to compress without having to worry about buffers in-between etc. I still need to make a few small changes and then I will verify that the boot images are correct which they should be since I cycle the power on the board to double-check.
    BTW, the dictionary can be moved anywhere in memory at any time, all it needs is the pointer to the most recent word.

    @FredBlais - pay no heed to my advice! I noticed that I used COG! to modify the code, yet the code is hubexec so you would need:
    CLKHZ 250000 U/ ' WSLED 4 - !
    
    But I will check that out shortly too.


    GOOD NEWS!
    I received a shipment of add-ons yesterday for the P2-ES, feels like I've been to the candy store as a kid!
    First thing I did was plug in the Charlieplexed LED MATRIX and type a couple of one-liners. Later on I will get it reflect the output of an 8 byte buffer or even reflect part of the VGA display and also so we can scroll messages across it or draw an icon etc.

    Then I also unplugged my VGA wires and plugged in the add-on and that works.

    Mine arrived yesterday too - actually Tuesday but I wasn't home so it went to the post office :smile:

    You will have to post the one-liner for the led matrix board.
  • FredBlaisFredBlais Posts: 375
    edited 2019-01-31 03:28
    @"Peter Jakacki"
    Something seems wrong with the Switch/Case. ISWITHIN seems never used and referred by CASE>.
    I would expect something like
    ' CASE>< ( from to -- )
    _CASE_WITHIN   word   _WORD,ISWITHIN,COMPW,_IF_+ex
    

    Or maybe there is something I don't understand?
    ' ************** CASE STATEMENTS *********************8
    
    ' SWITCH ( val -- )
    _SWITCH word    rg+uswitch,STOREX+ex
    
    ' SWITCH@ ( -- val )
    SWFETCH word    rg+uswitch,FETCHX+ex
    
    ' SWITCH= ( val -- flg )
    ISEQ
            word    SWFETCH,_EQ,EXIT
    
    ' CASE ( compare -- )
    _CASE   word    _WORD,ISEQ,COMPW,_IF_+ex
    
    ' BREAK
    ISEND   word    w+EXIT,COMPW,_THEN_,ALLOCATED+ex
    
    
    ' SWITCH>< ( from to -- flg )..
    ISWITHIN
            word    SWFETCH,ROT2,WITHIN+ex
    
            byte 6,         "SWITCH"
            word _SWITCH
            byte 5,         "CASE@"
            word SWFETCH
            byte 5,         "CASE="
            word ISEQ
            byte 5,         "CASE>"
            word ISWITHIN
            byte 5+im,      "BREAK"
            word ISEND
            byte 4+im,      "CASE"
            word _CASE
    
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2019-01-31 03:50
    There is a new and tested BIX boot image for the ES which is contained within 64kB. The reasoning being that the code is followed by the dictionary with only blank code space in-between and the area preceding the code is the config block and some system pointers etc, so this memory area can be compressed without having to worry about removing fluff beforehand.

    If in operation as the dictionary grows down toward code which is growing up and more code space is needed, then the dictionary can easily be relocated anywhere and we would use a larger image size for backup.

    @FredBlais - I will look at those structures as I need to think about how I am going to use them. They are quite a bit different from Forth but really quite simple and flexible.
    The CASE> only returns a flag at present but it really needs to be an alternative to CASE like this;
    SWITCH
    $0D CASE <enter> BREAK
    $10 $1F CASE> <$10..$1F> BREAK
    
    In which "case" CASE> needs to be more descriptive with perhaps <CASE> as a possibility. >CASE and <CASE can then become the case for any values greater than or less than the switch.
  • samuellsamuell Posts: 554
    edited 2019-01-31 03:58
    FredBlais wrote: »
    samuell wrote: »
    Thanks Publison. Ctrl+W displays "0", and then I have to press Enter to return to the prompt. The chip is not too hot to touch, but the board smells hot.

    Kind regards, Samuel Lourenço

    There are 2 boot image in the boot image directory. The .BIX has the issue.
    I used the .BIY and renamed it to .BIX and this one is working fine.
    Thanks, that works!

    I can change speed without messing the terminal, except when going to RCFAST or RCSLOW. I guess that is due to the crystal not being used in those configurations. Works good enough for me.

    Kind regards, Samuel Lourenço
  • Cluso99Cluso99 Posts: 18,069
    samuell wrote: »
    FredBlais wrote: »
    samuell wrote: »
    Thanks Publison. Ctrl+W displays "0", and then I have to press Enter to return to the prompt. The chip is not too hot to touch, but the board smells hot.

    Kind regards, Samuel Lourenço

    There are 2 boot image in the boot image directory. The .BIX has the issue.
    I used the .BIY and renamed it to .BIX and this one is working fine.
    Thanks, that works!

    I can change speed without messing the terminal, except when going to RCFAST or RCSLOW. I guess that is due to the crystal not being used in those configurations. Works good enough for me.

    Kind regards, Samuel Lourenço

    When you go to rcslow or rcfast, the autobaud has lost its setting so the serial doesn't know precisely what speed it is running at.
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2019-01-31 05:14
    Yes, RCSLOW and RCFAST are clock modes but not precise clock speeds as we get with the crystal/oscillator. You can however change to them but need to change back again before using the console.

    If however you happen to know the clock speed of RCFAST you can trick CONBAUD before switching to RCFAST like this:
    TAQOZ# 22500000 $14 ! 115200 CONBAUD RCFAST ---  ok
    

    I found out the frequency by connecting the scope to P56 and output a 1/10 frequency. When running at 80MHz I type 58 PIN 8 MHZ and then switch to RCFAST for a few seconds, measure it, and then it flips back with RCFAST 3 s ECO

    EDIT - I've now updated RCFAST (in the next image) to just set the frequency as 22400000 and reset the baud rate before switching to RCFAST. If the RCFAST frequency is too different you may need to set that directly like this (assuming it is 23MHz).
    23,000,000 ' RCFAST 2+ !
    
    Then BACKUP BIX to update your image.
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2019-01-31 08:18
    The 8x7 LED MATRIX add-on for the P2-ES has 7 rows of 8 columns of LEDs charlieplexed from 8 I/O. To turn on just one LED requires a combination of an I/O high and an I/O low with the other I/O floating. This unoptimized demo routine will display a character on the matrix and also treat it as an output device in conjunction with the serial console except you can specify a delay between characters up to 255 ms.

    If you type PLEXLED then character output will be redirected just to the matrix without any character delay so just typing at the keyboard will echo onto here. If you use CONLED then it will output to both the matrix and to the serial console with an adjustable delay.

    It is fairly basic and could probably be optimized a bit and also it could have scrolling added but an 8x7 matrix is a bit limited in that regard :)

    Use the V2 image and paste this code in.
    TAQOZ
    {
    PLEXLED.FTH
    SIMPLE CHARACTER I/O FOR P2-ES LED MATRIX
    
    }
    56 TABLE 8X7
    
    --- CREATE A TABLE BUILDER WORD TO ENCODE AND WRITE COLUMN AND ROW
    : X	8X7 + 7 ADO SWAP 4 << + I C! LOOP ;
    
    6 7	5 6	4 5	3 4	2 3	1 2	0 1	0 X
    7 0	5 7	4 6	3 5	2 4	1 3	0 2	7 X
    7 1	6 0	4 7	3 6	2 5	1 4	0 3	14 X
    7 2	6 1	5 0	3 7 	2 6	1 5	0 4	21 X
    
    7 3	6 2	5 1	4 0	2 7	1 6	0 5 	28 X
    7 4	6 3	5 2	4 1	3 0	1 7	0 6	35 X
    7 5	6 4	5 3	4 2	3 1	2 0	0 7	42 X
    7 6	6 5	5 4	4 3	3 2	2 1	1 0	49 X
    FORGET X ( discard table builder )
    
    : ALED ( n -- )		7 U//
    : XYLED	( x y -- )	0 DIRA COG! 7 * 6 ROT - + 8X7 + C@ DUP 7 AND 16 + LOW 4 >> 16 + HIGH ;
    
    
    7 bytes ledbuf
    : PLEX.TASK		BEGIN 7 0 DO I ledbuf + C@ 8 0 DO DUP I |< AND IF I J XYLED 200 us THEN LOOP DROP LOOP AGAIN ;
    
    --- PLEXLED CHARACTER OUTPUT DEVICE
    : PLEXLED		' PLEX.TASK 1 RUN EMIT:
    : PLEXCH ( ch -- ) 	7 * FONT5X7 + ledbuf 7 CMOVE ;
    
    
    byte spd 100 spd C!
    : CONLED		' PLEX.TASK 1 RUN EMIT: DUP CONEMIT PLEXCH spd C@ ?DUP IF ms THEN ;
    
    END
    
    

    692 x 945 - 85K
    648 x 945 - 101K
  • The simplicity of code is both head-scratching and beautiful, Peter.

    As you mentioned scrolling- that would be nice, as the chars could be centered at least, if not scrolled. (Although not suggesting you burn any time on it!)


    Don't forget this could be 8x7, if you plug to vertical vs horizontal headers. (If that helps character size :)
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2019-01-31 09:42
    VonSzarvas wrote: »
    The simplicity of code is both head-scratching and beautiful, Peter.

    As you mentioned scrolling- that would be nice, as the chars could be centered at least, if not scrolled. (Although not suggesting you burn any time on it!)


    Don't forget this could be 8x7, if you plug to vertical vs horizontal headers. (If that helps character size :)

    Thanks, but I think the code could be simpler again! With it in this orientation there is still room to start squeezing in the next character.
    So when I implement scrolling I will see if I can do more with less :)

    BTW, I decided to look at what code they are using on the Arduino. I'm glad I didn't look at that first off, I'd be turned off and although it is rather verbose and there are extra functions, there is still a lot of code there for such a simple display.
  • A feature request for the next version of TAQOZ: it'd be very handy to have an entry point to allow a PASM program to hand a string to TAQOZ to execute. This could be used to have some PASM code "reboot" into TAQOZ, optionally giving it some code to run. Or, it could be used by PASM code running in one COG to execute a TAQOZ subroutine in another COG. The assumption would be, of course, that TAQOZ would have the whole bottom 64K of RAM and that the PASM code would stay out of that.

    An alternative might be @msrobots suggestion of making the pins to use for TAQOZ I/O easily changable, so that a COG can communicate serially with another COG running TAQOZ and send commands to it.

    Either way, this feature would be a kind of "gateway drug" allowing users of traditional languages (PASM, Spin, BASIC, etc.) to discover the power of Forth. Once they start using a few Forth subroutines, and discover the ease of testing and modification, they may wish to move an increasing amount of their code over to Forth.
  • It'd also be useful for writing MBR bootloaders in TAQOZ bytecode, starting with a PASM stub that has TAQOZ run the rest of the MBR.
  • I'm not sure how TAQOZ operating out of at least the first 64k of RAM will coexist with other code, so I'm thinking aloud here.

    Sure, we could have some fixed entry vectors in ROM, perhaps near the end of it and one of those could be the one that calls the decompress routine to load TAQOZ into RAM as normal but afterwards and not before it would have to disable the serial console and redirect the console I/O to hub locations which could be in the first 256 bytes just after the config block. In fact I suppose that the decompress routine could be called but rather than have it automatically coginit afterwards we could pass control back and then the config block can be modified and then the user code can simply coginit which cog it wants from hub location 0. (cogid <> 0 will vary the behaviour)

    Normally this calls "initsys" which sets the clock and loads up VGA if configured, and then other cogs if their vectors in the config block are set and then finally launches the main TACHYON console using cog 0. However I suppose if we cogid in initsys so that it returns something other than cog 0 we can determine that this was called by a user program and simply load the same cog with TAQOZ running a mailbox console.

    My revised thought is that if we coginit the TAQOZ "loader" which decompresses TAQOZ into the first 64k RAM, we can detect that the cogid is not the boot default of 0 and change the behavior of TAQOZ's init so that it simply runs an instance of TAQOZ albeit with a mailbox console of some sort rather than physical pins. You can though tell it through the mailbox to use some other form of I/O such as serial on other pins.

    How does that sound?


  • That sounds great, Peter! Although rather than relying on cogid it might be nice to have a flag or a slightly different entry vector for the "run subroutine code" version of TAQOZ, if that's not too difficult -- that way even programs with unusual COG configurations will still work properly if the PASM code that calls TAQOZ ends up in COG 0 for some reason.

    As for the coexistence, I think it's OK to force the PASM program to leave the first 64K of HUB RAM alone. Does TAQOZ need any other space in HUB RAM? I don't know if you saw the discussion in the boot rom thread, but we're proposing to reserve a small block of "configuration memory" at the top of HUB RAM to hold things like clock frequency and mode. Would this cause any difficulties for TAQOZ?

    Thanks,
    Eric
  • ersmith wrote: »
    That sounds great, Peter! Although rather than relying on cogid it might be nice to have a flag or a slightly different entry vector for the "run subroutine code" version of TAQOZ, if that's not too difficult -- that way even programs with unusual COG configurations will still work properly if the PASM code that calls TAQOZ ends up in COG 0 for some reason.

    As for the coexistence, I think it's OK to force the PASM program to leave the first 64K of HUB RAM alone. Does TAQOZ need any other space in HUB RAM? I don't know if you saw the discussion in the boot rom thread, but we're proposing to reserve a small block of "configuration memory" at the top of HUB RAM to hold things like clock frequency and mode. Would this cause any difficulties for TAQOZ?

    Thanks,
    Eric

    I've got my configuration block at the very start of memory since it is also easy to address as immediate but I suppose it could be moved up. I have ID strings and pin assignments for device and init vectors as well as clock information. We could also store RCFAST frequency in there too I think.

    This is what I'm using at the moment.
                       DAT	' STAGE 1 - BOOT TIME INITIALIZATION '
                       
    00000              		orgh	0
    00000 000          		org
    00000 000 fd900058 		jmp	#initsys
                       
                       '**************** configuration block **************** '
                       ''
    00004 001 452d3250 		byte	"P2-ES   "		' 8 character ID'
    0000c 003 03       _OPTIONS	byte	%0000_0011		' options    SD,FLASH
    0000d 003 000000   		byte	0,0,0
                       
                       '	*** CLOCK ***	'
    00010 004 01312d00 _XIN		long	XIN			' input freqency'
    00014 005 11e1a300 _CPUHZ		long	CPUHZ			' final clock '
    00018 006 01000ef8 _CLKCFG		long	CLKCFG	''$014CB3FC 'CLKCFG
                       
                       '	*** SERIAL/VGA/KEYBOARD *** '
    0001c 007 0001c200 _BAUD		long	baud_rate
    00020 008 03020100 _VGACFG		long	$03020100		' VRGBH pins '
    00024 009 00000004 		long	4
    00028 00a 00000b8c _VGAINIT	long	@vgainit		' VGA code '
    0002c 00b 0aaaaab0 _VGASET		long	round(fset)
    00030 00c 00000607 _KBCFG		long	$0607
                       '	*** RESET VECTORS *** '
    00034 00d 00000420 _RESET		long	@RESET
    00038 00e 00001f8c _IDLE		long	@IDLE
    0003c 00f 00002044 _TERMINAL	long	@TERMINAL		' COG0 TASK'
    00040 010 00000000 _COG1		long	0			' COG1 TASK ( 0=none )
    00044 011 00000000 _COG2		long	0
    00048 012 00000000 _COG3		long	0
    0004c 013 00000000 _COG4		long	0
    00050 014 00000000 _COG5		long	0
    00054 015 00000000 _COG6		long	0
    00058 016 00000000 _COG7		long	0
    



  • I've got my configuration block at the very start of memory since it is also easy to address as immediate but I suppose it could be moved up. I have ID strings and pin assignments for device and init vectors as well as clock information. We could also store RCFAST frequency in there too I think.
    Actually that looks very good! I'll adopt the same layout (or a subset of it) for fastspin -- input frequency at $10, final clock at $14, mode bits at $18, baud at $1c.

    Are these values overwritten when TAQOZ is decompressed? It'd be nice if we could start TAQOZ in a "pre-configured" state (clock and baud rate set, at least) and have it use the settings that the previous PASM program was using.

    Thanks,
    Eric

  • jmgjmg Posts: 15,175
    I've got my configuration block at the very start of memory since it is also easy to address as immediate but I suppose it could be moved up.

    If you do keep it there, can you do a slight reorder so the most useful config info is first ?

    _CPUHZ long CPUHZ ' final clock '
    _XIN long XIN ' input freqency'
    _CLKCFG long CLKCFG
    _BAUD long baud_rate
    _RCFAST ' good idea. possible calibrated RCFAST location. Could be derived from Autobaud, if initial BAUD is known ?

    I think some have reported issues on Linux with higher baud speeds (Linux only 'knows' some bauds, somewhat archaic), so it could derive RCFAST from a standard initial baud assumption (eg 230400)
    RCFAST precision may be good enough, any binary multiple of 230400 may do ?


    Checking this, it looks like
    230400*4 = 921600
    12M/ans = 13.020833333333333333 USB bridges use mostly 12MHz virtual clocks.
    1-ans/13 = 0.160% error in actual USB Bridge baud rate

    I think Linux is ok with 921600 ?

  • I have never had problems with high baud rates in Linux but 3M is the limit for standard FT232R chips though and my P2 runs very happily at this rate, even on a slow clock. The fact that I default to 115200 baud is more to do with making sure that it works for everyone else and some of those flimsy terminal emulators.

    I've been trying to think of a simple way of calibrating the RCFAST but either way once we know what it is and set that entry in the config then TAQOZ is quite happy to run on RCFAST including the SD but not including VGA obviously.
  • msrobotsmsrobots Posts: 3,709
    edited 2019-02-02 00:05
    Finally some traction!

    I m already doing this with the current ES rom. I compile my program with fastspin, open the pasm2 file and add a stub at the beginning to patch the rom leave 64K for TAQOZ, start my program in COG1and jmp COG0 into the ROM TAQOZ start.

    The patching convices TAQOZ to use two different SPs and reads the sp next to its own so with a serial driver I basically can let 4 spartpins talk to each other without any jumpers needed.

    Works fine, just lsio will destroy my new pinsettings.

    If TAQOZ could be convinced to start with a mailbox as console-io by patching in a mailbox address and then start TAQOS in rom as it get started normally to decompress itself like it normally does, everything would be golden.

    Enjoy!

    Mike
  • FredBlaisFredBlais Posts: 375
    edited 2019-02-02 20:48
    @"Peter Jakacki"

    Today I'm trying to play a wav file through an i2s amp (MAX98357A). The waveform is quite simple to reproduce (see picture). However I'm having trouble to get the timing right with plain TAQOZ code. So far, I can read the WAV file one word at a time and shift the data out with the bit clock but how can I achieve the right timing? Would I have to use one of the smartpin mode? Streamer?

    LRCLK supports 8kHz, 16kHz, 32kHz, 44.1kHz,
    48kHz, 88.2kHz, and 96kHz frequencies.

    Currently my WAV file is encoded with ffmpeg at 16 bit per sample, 16kHz sample rate.
    wave.png
    1079 x 638 - 175K
    wave.png 175.2K
  • @FredBlais - can you post your code?

    You can synchronize the timing if you use an initial WAITX before you enter the loop and then WAITCNT will use that same timing. I will look at the smartpin modes to see if we can use them. I do have some I2S chips I could check it on but the main thing is to get the timing right. If I go that far I may as well output audio direct from the DAC mode too.

    Have you also tried the CLKOUT instructions?
    ' I2C support
    ' CLKOUT ( iobit dat -- iobit dat2 ) REG6=iomask ) Shift msb bit out,  clock high, clock low
    CLKOUT          outl    tos+1              ' ensure output will be active low
                    drvl    clockpins
                    shl     tos,#1 wc
                    dirnc   tos+1                   ' make it an output if it is a low else float
    ' CLOCK ( REG6=iomask ) Toggle multiple bits on the output)
    CLOCK           outnot  clockpins
                    tjz     clkdly,#ckx
                    mov     fx,clkdly
            _ret_   djnz    fx,#$
    ckx             ret
    
                       ' #0027
    0048c 01b 00000000 clockpins       long 0                                  ' I/O mask for CLOCK instruction
    00490 01c 00000000 clkdly          long 0
    

  • With all the delay stuff removed, it looks like this :
    25 := LRCLK
    27 := BCLK
    29 := DIN
    : BIT_LOOP BCLK HIGH BCLK LOW 16 FOR DUP 2* I |< AND IF DIN HIGH BCLK HIGH BCLK LOW ELSE DIN LOW BCLK HIGH BCLK LOW THEN NEXT DROP ;
    : SEND DUP LRCLK LOW BIT_LOOP LRCLK HIGH BIT_LOOP ;
    FOPEN AUDIO.WAV
    : START 44 BEGIN DUP SDW@ SEND 2+ KEY UNTIL ;
    
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2019-02-03 01:26
    @FredBlais - there's trouble with this already. Take a look at a version of your code that would output a precisely timed clock taking into account too that the loop index I in a FOR NEXT only counts down (from 16 bin this case) and never reads a 0.
    : BIT_LOOP
    	BCLK HIGH BCLK LOW
    	CLKHZ 16000 U/ WAITX
    	16 FOR 
    	  DUP I 1- |< AND IF DIN HIGH ELSE DIN LOW THEN
    	  BCLK HIGH BCLK LOW WAITCNT 
    	NEXT 
    	DROP
    	;
    

    Even though this loop can be optimized a couple of different ways it still suffers from one basic problem, that of the BCLK not being continuous which IIRC is required. If it is not then at least this is a starting point for you. Even with a bit bashed loop it is possible to have a continuous clock simply with BCLK 16 KHZ and then have your loop synch to the clock before outputting a data bit. But there are smartpin modes for this although this would be a good learning exercise.

    NOTES:
    If you shift your data then you need a constant mask of $8000 to test the msb then shift, but if you use the index then you should not shift the data as well.
    Re using I as an index in a FOR NEXT loop - I tried this on gforth but there seems to be a bug there because it also included 0 and thus ends up adding one more loop

    EDIT: Here's a slightly modified version of my version that outputs a nice square clock and includes the extra clock as part of the loop.
    : I2S
    	CLKHZ 16000 2* U/ WAITX
    	17 FOR 
    	  DUP I 1- |< AND IF DIN HIGH ELSE DIN LOW THEN
    	  BCLK HIGH WAITCNT BCLK LOW WAITCNT 
    	NEXT 
    	DROP
    	;
    
Sign In or Register to comment.