{"id":713,"date":"2020-06-05T17:16:58","date_gmt":"2020-06-05T15:16:58","guid":{"rendered":"https:\/\/next-hack.com\/?p=713"},"modified":"2020-06-05T22:10:12","modified_gmt":"2020-06-05T20:10:12","slug":"vga-library-for-uchip-with-usb-host-support-and-uchip-simple-vga-console","status":"publish","type":"post","link":"https:\/\/next-hack.com\/index.php\/2020\/06\/05\/vga-library-for-uchip-with-usb-host-support-and-uchip-simple-vga-console\/","title":{"rendered":"VGA library for uChip with USB host support and uChip Simple VGA Console"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Introduction<\/h2>\n\n\n\n<p>A VGA\noutput might come in handy for a number of applications, such as a\nterminal\/monitor or, why not, a videogame console, which is, by the way, the\nfinal goal of this library : &#8211; )<\/p>\n\n\n\n<p>So far,\nthere have already been several successful attempts to generate a VGA signal by\nsoftware using a \u201csmall\u201d microcontroller. In the simplest VGA implementations,\nthere is only one bit per color, i.e, the red, green, and blue signals are\nconnected to one general-purpose input-output (GPIO) pin. This means that the\nmaximum number of colors is 8.<\/p>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1912\" height=\"1165\" src=\"https:\/\/next-hack.com\/wp-content\/uploads\/2020\/06\/8-color-vga.png\" alt=\"\" class=\"wp-image-749\"\/><figcaption>Fig. 1. A single bit per color connection allows to create 8 color images.<\/figcaption><\/figure>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<p>More advanced software-based \u201ccontrollers\u201d use more than one bit per signal. The most common configurations are 2 bit per each color signal (6 bits per pixel, i.e. 64 colors) or 3, 3, and 2 bits for red, green, and blue respectively (8 bits per pixel, i.e. 256 colors).<\/p>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1719\" height=\"1125\" src=\"https:\/\/next-hack.com\/wp-content\/uploads\/2020\/06\/256-color-VGA.png\" alt=\"\" class=\"wp-image-746\"\/><figcaption>Fig. 2. RGB &#8220;332&#8221; resistor DAC connection. 256 colors can be displayed.<\/figcaption><\/figure>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<p>The digital\nsignals are connected to resistor-based digital-to-analog converters (DAC),\nwhich allow to convert the 0\u20263.3V digital signals to the corresponding 0\u20260.7 V\nanalog values.<\/p>\n\n\n\n<p>While there\nare some VGA shields and examples for Arduino and, in general, for AVR\nmicrocontrollers, on Arduino Zero and ATSAMD21 microcontrollers instead there\nare none, at least to our knowledge. That\u2019s really a pity, because one could\nexploit the larger memory and computing power either to perform more advanced\ntasks (beside showing the VGA image), or to provide better graphics\ncapabilities.<\/p>\n\n\n\n<p>In fact,\ntypical AVR microcontrollers have only few kBs of RAM (between 2 and 8 kB),\nwhich strongly limit the maximum number of onscreen colors or the available\nresolution. Furthermore, the ATSAMD21 features an integrated USB Host, which would\nallow to use standard USB devices such as a keyboard or a gamepad as input.<\/p>\n\n\n\n<p>There are many\nATSAMD21-based development boards, but many of them are quite bulky. However,\nthe smaller ones, like uChip, feature the 32-pin ATSAMD21E, which has only one contiguous\n8-bit port, PA00-PA07 (not all the remaining PA08 to PA31 pins are available). &nbsp;Unluckily, pins PA00 and PA01 are typically\nused by the 32768 Hz crystal, hence they are not available as an output signal.\nuChip makes no exception as it was designed to have the best compatibility to\nthe Arduino Zero.<\/p>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1018\" height=\"664\" src=\"https:\/\/next-hack.com\/wp-content\/uploads\/2020\/02\/uChip.png\" alt=\"\" class=\"wp-image-645\"\/><figcaption>Fig. 3. uChip, an ATSAMD21 board on which this project will be based. <a href=\"https:\/\/shop.itaca-innovation.com\/epages\/186543.sf\/en_US\/?ObjectPath=\/Shops\/186543\/Products\/UCHIP-SH\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\"You can get uChip here! (opens in a new tab)\">You can get uChip here!<\/a><\/figcaption><\/figure>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<p>This\nrequires to connect the various red, green, blue signals in non-contiguous\npins, meaning that for each pixel we need to perform some on-the-fly\ncalculations or processing. <\/p>\n\n\n\n<p>To add insult to the injury, the 32768-Hz crystal oscillator is useless for this project. In fact we verified that the DFLL and DPLL of the ATSAMD21 introduce quite noticeable jitter\/instability on the generated waveform if the input clock frequency is low (&lt; 1MHz), therefore the aforementioned oscillator cannot be used as clock source. The amount of introduced jitter is totally unacceptable, as shown by the picture below:<\/p>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"929\" height=\"901\" src=\"https:\/\/next-hack.com\/wp-content\/uploads\/2020\/06\/VGA-jitter.png\" alt=\"\" class=\"wp-image-753\"\/><figcaption>Fig. 4. Closeup of an SXGA monitor, showing noticeable jitter if the internal 32768 Hz oscillator is used to feed the DPLL or DFLL of the ATSAMD21.<\/figcaption><\/figure>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<p>The figure above is a detailed photograph of part of an LCDn SXGA monitor (128&#215;1024 pixels), which shows the effects of jitter produced if the 32k crystal oscillator is fed to the DPLL. Similar results occur using the DFLL. We verified that such jitter is totally absent when using a 4-16 MHz external crystal oscillator. By the way, this might also explain why Microchip suggests using the DPLL with high input clock frequency when using the USB in host mode:<\/p>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"764\" height=\"518\" src=\"https:\/\/next-hack.com\/wp-content\/uploads\/2020\/06\/SAMD21-USB-CLOCK.png\" alt=\"\" class=\"wp-image-752\"\/><figcaption>Fig. 5. Extract of the SAMD21&#8217;s datasheet: the suggested clock source for USB Host is the FDPLL96M driven by an external clock source, at high frequency (&gt;1MHz).<\/figcaption><\/figure>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<p>This prevents the straightforward resistor-only implementation of a shield for ATSAMD21-based boards: an external crystal oscillator is required.<\/p>\n\n\n\n<p>All that said, we must also face with the memory limitation. Yes, 32kB is much more with respect to 2 to 8 kB, and 48 MHz is much more than 16-20 MHz. Still we need to remember that we will require some per-pixel on-the-fly processing.<\/p>\n\n\n\n<p>Since there are already some AVR-based applications that allow an 8-bpp palette, we want to have a 256-color space too. We cannot go much higher due to pin and memory limitation. We also want to achieve a QVGA resolution, i.e. 320&#215;240. Actually, we will use only 200 vertical pixels, to save on RAM and to avoid the CPU starvation. After all, nowadays the 16:10 is a much more common format than 4:3, and many monitors allow 4:3 adaption to 16:10.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Timings<\/strong><\/h3>\n\n\n\n<p>How much time do we have? Very little. With a visible horizontal resolution of 320 pixel, at 48MHz we have only 4 CPU clock cycles for each pixel (we assume 525 vertical lines and \u201cabout\u201d 60 Hz). Also, note that:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Flash accesses require 1 wait state, i.e. we would require one more cycle per instruction. The internal SAMD21 cache is a double-edged sword because, on one hand it reduces the average fetch time, on the other, the time required to fetch each instruction is not constant, so the execution time from flash is not deterministic. That\u2019s why we will place our function in RAM (of course, the function is in flash, but it is copied to RAM at startup).<\/li><li>Data accesses to RAM (LDR instructions) require two clock cycles.<\/li><li>Branches, if taken, take two clock cycles. For this reason, for the most complex graphics modes we will have to avoid creating a 320-iteration loop: we will create a long sequence of instructions.<\/li><li>Unlike the AVR, there are no nibble based instructions (like SWAP) on the Cortex M0. These could have been useful for 4-bpp video modes. There are also no immediate-operand AND and OR instructions.<\/li><li>Even if there are sixteen 32-bit registers, only eight of them (r0-r7) have access to the full instruction set. Some of the registers are special purpose (r13 through r15 like SP, LR and PC), therefore only the remaining r8-r12 high registers are available as general purpose. However, these registers are used by a very limited set of instructions (mainly: BX, CMP and ADD, with no immediate-operand support).&nbsp; <br> By comparison, there are thirty-two 8-bit registers on the AVR. (Even in this case, many instructions work only with some registers. For instance, there are only three pointer registers \u2013 which take six 8-bit registers \u2013 and immediate-operand instructions mostly work with r16-31 only). The availability of 8- instead of 32-bit registers is a penalty when doing general data processing, however they would have been very useful for VGA signal generation, as the data width is 8-bit. In this sense, having 4 bytes stored on a single register is quite painful, when it comes to quickly separate them. Yes, there is the UXTB (unsigned byte extend) for the least significant byte, and LSR (logical shift right) for the most significant byte. However, we cannot extract with a single instruction the central bytes: we need to use REV16, so that the central bytes can be later separated with UXTB and LSR. On the bright side, four pixels can be loaded at once, with only a 2-cycle instruction.<\/li><\/ul>\n\n\n\n<p>Luckily enough,\nthe ATSAMD21 feature a local bus for the I\/O ports, allowing for a single-cycle\naccess. This means that for each pixel we have on average 3 cycles left. In\nthese three average cycles per pixel we must perform all the decoding or\npre-processing required to calculate the actual value to write to the port.<\/p>\n\n\n\n<p>The VGA\nsynchronization signals are generated by two ATSAMD21 timers, so no CPU\nintervention is required. The VGA signal generation routine is entered by an\ninterrupt having the second highest priority (i.e. 1), generated by the\nhorizontal sync timer. In that interrupt, we check which line we are currently\ndrawing, and if it is in the visible area, the actual drawing procedure is\nexecuted. <\/p>\n\n\n\n<p>Interrupts might have some variable latency therefore, to ensure a precise start-of-line, another timer is configured. This timer generates an event at a fixed delay with respect to the horizontal sync signal. The event, in turn, generates the higher priority interrupt (i.e. numerically 0). If we did not disable interrupts, once the event is triggered, the CPU would jump to the relative interrupt handler: we do not want this, therefore we disable the interrupts as soon as we enter the first handler. Instead, at a certain point, i.e. right before where the actual line drawing should occur, we put a \u201cWait For Interrupt\u201d instruction. I.e. the CPU will sit there, until the event is triggered. Such solution allows for deterministic and very fast interrupt detection, therefore the lines are drawn at the same horizontal position, which can be adjusted by the delay with which we generate the event.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">The current state of the art<\/h3>\n\n\n\n<p>So far, we\nhave squeezed out the following operating modes.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Bitmapped mode<\/strong><\/h4>\n\n\n\n<p>The first\none is a bitmapped mode. A bitmapped mode is when one pixel is mapped to one or\nmore bits on memory. <\/p>\n\n\n\n<p>Let\u2019s make some calculations: A 320&#215;200 screen has 64k pixels. This means that we cannot use 8 bits per pixel, as we have no enough memory. Even 4 bits per pixel would leave too few bytes on our microcontroller, especially if USB has to be used.<\/p>\n\n\n\n<p>This means\nthat either we need to lower the resolution, or we need to reduce the number of\ncolors.<\/p>\n\n\n\n<p>In our\nbitmapped mode, we have 2 bits per pixels. This means that each pixel can\nassume 4 different values. Each value is mapped \u2013 via an array called Palette \u2013\nto a specific user selectable color. In this way we have 4 colors onscreen. <\/p>\n\n\n\n<p>But, we\nhave a couple of tricks, which might come in handy. In fact, the palette is not\nfixed, but instead is optionally indexed on an 8-pixel basis, allowing almost\nto fully exploit the 256-color palette (of course with some limitations). <\/p>\n\n\n\n<p>Another\ntrick is that, to save on memory accesses, we compute two pixels (4 bits) at\nonce. By carefully choosing the palette, one can halve the horizontal\nresolution, and join two pixels. This has the effect of actually having a\nresolution of 160&#215;200, with 4 bits per pixel (16 color). Again, the palette can\nbe changed every eight pixels. <\/p>\n\n\n\n<p>Furthermore,\none can choose the palette so that two colors work in \u201chigh resolution mode\u201d \u2013\n320&#215;200 \u2013 and the other remaining colors work as usual, 160&#215;200 pixel. This is\nuseful if you need to write text and display some color graphics.<\/p>\n\n\n\n<p>The\nfeatures are as follows:<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>Up to 320&#215;200 pixels.<\/li><li>The palette is 4 colors per pixel\n(or 16\/32 per double-pixel). The palette can be changed every eight horizontal pixels.\n<\/li><li>The palette determines the actual horizontal\npixel size (1 or 2 QVGA pixels).<\/li><li>No scroll, no sprites, for now.<\/li><li>Small RAM footprint of the\nVGA-signal generation function, because it uses a loop (unlike tile mode1 and 2,\nsee below)<\/li><\/ol>\n\n\n\n<p>Below you find a preview of this bitmapped mode.<\/p>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1992\" height=\"1536\" src=\"https:\/\/next-hack.com\/wp-content\/uploads\/2020\/06\/tetris.jpg\" alt=\"\" class=\"wp-image-758\"\/><figcaption>Fig. 6. Tetris game we programmed to show the bitmapped mode features. Despite the mode has only 2 bits per pixel, the number of on-screen color is much larger, due to the 8-pixel palette remapping.<\/figcaption><\/figure>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Tile Mode 1<\/strong><\/h4>\n\n\n\n<p>As we saw in the <a rel=\"noreferrer noopener\" aria-label=\"handheld platform game article (opens in a new tab)\" href=\"https:\/\/next-hack.com\/index.php\/2019\/04\/07\/lets-build-an-handheld-platform-game-with-a-cortex-m0-microcontroller\/\" target=\"_blank\">handheld platform game article<\/a>, 2D games usually are tile based, i.e. they repeat the same few graphics elements (tiles), while they superimpose sprites for bonuses, enemies, player, etc.<\/p>\n\n\n\n<p>We can do the\nsame thing also for the VGA. With respect to the hand held platform, we need to\nradically change the way the image is created. In fact, instead of creating the\nimage on per horizontal-slice basis, we must have the image \u201cready\u201d before each\nframe begins. For \u201cready\u201d of course we do not mean that the full bitmap image\nis already rendered on memory: we already know that this is impossible, due to\nmemory limitation. We simply need that the image can be outputted with\n\u201cminimal\u201d per pixel processing. <\/p>\n\n\n\n<p>For this\nreason, we store in a table (the vram, i.e. video ram) the references<a href=\"#_ftn1\">[1]<\/a>\nto the tiles to be drawn on screen. <\/p>\n\n\n\n<p>The\nfeatures are as follows:<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>320 x 200 tiled mode. Each tile is 8 by 8 pixels. The vram size is configurable, but the minimum is 40 x 25 entries, each one storing 2 bytes, which Is the lower part of the tile address (the higher part is 0x20000000, being all the tiles in RAM). <\/li><li>Up to 400 different tiles on-screen (actual number of tiles depends on how much ram is available). <\/li><li>X and Y smooth scroll. <\/li><li>Optional per-line and per-tile X scrolll, allowing to produce some nice effects, like water deformation or parallax.<\/li><li>Optional fixed top or bottom static zone to display score, or other information.<\/li><li>Optional row remapping, allowing for instance split screen, or other effects like mirroring or upside down display (e.g. as a temporary screen-reversal malus like in Apidya on the Amiga). <\/li><li>256-color palette for tiles and sprites<a href=\"#_ftn2\">[2]<\/a>.<\/li><li>\u201cUnlimited\u201d number of sprites. Actual sprite number depends on how many free tiles are available for the sprites, the sprite size, position and alignment. &nbsp;The sprite drawing routine automatically handles \u201cany\u201d size of sprite (i.e. no needs of splitting larger sprites in smaller ones).<\/li><li>Sprite rotation (90, 180, 270), horizontal-vertical mirror and x-y swap.<\/li><li>Different sprite handling positions.<\/li><li>Custom sprite\/background blend modes for special effects such as lights, semitransparent explosions, etc.<\/li><li>Tiles on screen must reside in ram. However, you can copy tiles from the Flash to the ram at very high speed during the game, so animated tiles are easy to implement.<\/li><li>Optional sprite and tile priority.<\/li><\/ol>\n\n\n\n<p>This is a\npreview of the tile mode 1.<\/p>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1600\" height=\"1200\" src=\"https:\/\/next-hack.com\/wp-content\/uploads\/2020\/06\/fairplay-race-2.jpg\" alt=\"\" class=\"wp-image-754\"\/><figcaption>Fig. 7. A top-down racing game programmed with the Tile Mode 1 (256 colors). Two transparent explosions are shown.<\/figcaption><\/figure>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Tile Mode 2&nbsp; <\/strong><\/h4>\n\n\n\n<p>It is the\nsame of Tile Mode 1, but it uses a 16-color remappable palette (allowing up-to\n256 onscreen colors). This has the following advantages:<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>The tile occupation is 32 bytes instead of 64, therefore the maximum number of tiles is almost doubled (around 700). <\/li><li>Per row color changing palette engine, that allows on per low-res (200) or high-res (400) line basis:<ul><li>To switch to another palette, i.e. changing all the 16 colors in a single row (useful for water effect)<\/li><li>To change a selected color of a palette, to any color value (useful for creating background shades).<\/li><\/ul><\/li><\/ol>\n\n\n\n<p>The color changing engine however requires 1kB of RAM per additional\npalette.<\/p>\n\n\n\n<p>Tile mode 2\nhas one disadvantage: it does not allow 90\u00b0 and 270\u00b0 sprite-rotation. Only\nvertical and horizontal mirroring are supported for now. It also does not\nsupport custom sprite-background blending for now.<\/p>\n\n\n\n<p>Furthermore\nTile Mode 2 also allows high-res (400-lines) row remapping (this feature will\nbe implemented also for tile mode 1 in the future, as it is currently low res \u2013\nQVGA- only).<\/p>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1500\" height=\"1126\" src=\"https:\/\/next-hack.com\/wp-content\/uploads\/2020\/06\/4bpp-combined.jpg\" alt=\"\" class=\"wp-image-747\"\/><figcaption>Fig. 8. Example pictures of the 4-bpp Tile Mode 2, showing the most interesting effects.<\/figcaption><\/figure>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Tile Mode Boot<\/strong><\/h4>\n\n\n\n<p>This mode\nhas been developed to be used for the bootloader only, with the exclusive goal\nof having the smallest flash memory footprint, while providing 256 onscreen\ncolors, for the game preview. To achieve this, tiles must be stored in RAM in a\n128-byte uncompressed format (i.e. signals ready to be outputted).<\/p>\n\n\n\n<p>This mode\nalso supports vertical row remapping.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Notes for all the modes<\/strong><\/h4>\n\n\n\n<p>Actually,\nwith minor modifications all the video mode could support up to 320&#215;240 or even\n320&#215;400\/320&#215;480 pixels. However when using 400\/480 lines, the pixels will have\na 1:2 aspect ratio. Furthermore, using 240\/480 lines, there will be very few\ntime left for the CPU! More CPU cycles can be achieved by drawing only the odd\nor only the even scanlines, emulating the classic CRT effect. However during\nthese spare lines, the CPU should not draw sprites, otherwise flickering might\noccur.<\/p>\n\n\n\n<p>There is an\nadditional mode, which is work-in-progress, and can also work together with the\nprevious tiled and bitmapped modes, but requires an external 74AHC245, the SPI\nMode.<\/p>\n\n\n\n<p>This mode\nis totally hardware-driven, and it leaves plenty of time to the CPU, as almost\nno intervention is required.<\/p>\n\n\n\n<p>It features\nthese specs:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>2 colors, of which one is black.<\/li><li>Works either as standalone or with all the previous modes.<\/li><li>Up to 640 pixels per line.<\/li><li>Up to 480 vertical lines.<\/li><\/ul>\n\n\n\n<p>This is\nbest suited for text modes, or to display score or other useful things.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Conclusion<\/h3>\n\n\n\n<p>In the next\nposts we will talk more specifically about uSVC, uChip Simple VGA Console, how\nmodes work, and, more importantly, how to build your own games!<br><\/p>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<p><a href=\"#_ftnref1\">[1]<\/a> We actually store the lower\npart (16 bit) of the address of the tiles to be drawn. The higher part is fixed\nto 0x2000, which points to the RAM region.<\/p>\n\n\n\n<p><a href=\"#_ftnref2\">[2]<\/a> Actuallly sprites have 255 colors (black is transparent).<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction A VGA output might come in handy for a number of applications, such as a terminal\/monitor or, why not, a videogame console, which is, by the way, the final goal of this library : &#8211; ) So far, there&#8230; <a class=\"read-more-button\" href=\"https:\/\/next-hack.com\/index.php\/2020\/06\/05\/vga-library-for-uchip-with-usb-host-support-and-uchip-simple-vga-console\/\">(READ MORE)<\/a><\/p>\n","protected":false},"author":2,"featured_media":758,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[32,27],"tags":[],"class_list":["post-713","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-all-projects","category-usvc"],"_links":{"self":[{"href":"https:\/\/next-hack.com\/index.php\/wp-json\/wp\/v2\/posts\/713"}],"collection":[{"href":"https:\/\/next-hack.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/next-hack.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/next-hack.com\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/next-hack.com\/index.php\/wp-json\/wp\/v2\/comments?post=713"}],"version-history":[{"count":6,"href":"https:\/\/next-hack.com\/index.php\/wp-json\/wp\/v2\/posts\/713\/revisions"}],"predecessor-version":[{"id":786,"href":"https:\/\/next-hack.com\/index.php\/wp-json\/wp\/v2\/posts\/713\/revisions\/786"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/next-hack.com\/index.php\/wp-json\/wp\/v2\/media\/758"}],"wp:attachment":[{"href":"https:\/\/next-hack.com\/index.php\/wp-json\/wp\/v2\/media?parent=713"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/next-hack.com\/index.php\/wp-json\/wp\/v2\/categories?post=713"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/next-hack.com\/index.php\/wp-json\/wp\/v2\/tags?post=713"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}