Videopac G7000
Last changed: 2007-08-31

The FlashCART

The FlashCART is a version of the MegaCART with flash ROM. Its main purpose is to act as a simple development environment for the MegaCART. You can upload a program from a PC through a RS-232C port and store it on the FlashCART. It is also possible to use the serial port in your own programs, for example in my Videopac+ graphics editor. The communication protocol is designed to work with USB to serial converters without much speed loss.

The hardware

The FlashCART is a MegaCART with a flash ROM instead of the EPROM. Additionally there is a firmware EPROM which handles the communication protocol. Which one is used is decided by a switch. There is also a RS-232C port with level translator. Command packets are read on the T0 line of the 8048 processor. The answers are sent on one of the I/O ports. The communication parameters are 38400 bps, 8 bits, 1 stop bit, no parity. It is possible to use this port in your own programs. My VPP graphics editor example program uses it to save and load the VPP screens.

This is a picture of a FlashCART. Click on it for a bigger picture. This is version 1.1, the version you can download below. I left out the EEPROM on this one to play with the expansion port.


Using the FlashCART

The FlashCART has 1 Mbyte of non-volatile flash ROM. That means that it keeps its data even without power. So you can copy a program onto it at home and take the FlashCART to a friend to show your latest programming efforts without having to take your PC with you.

How to connect PC and FlashCART

The FlashCART has a normal 9 pin female RS-232C COM port connector. You need a normal serial 1:1 extension cable to connect it to a PC with a serial port. This cable is a different one than the cable for my RAM cart.

If your PC does no longer have a serial port or they are already in use you can also get a USB to serial converter. I recommend one with a cable already attached, so you don't have to get another cable to connect the converter to the FlashCART. I personally like converters built with FTDI chips, since their drivers allow some fine tuning, but it is not always mentioned which chips are inside the converters.

It is also possible to use a Bluetooth to serial converter. The one I tested is much slower than a real cable and has a higher error rate. To get it to work I had to change the MTU to 136 to avoid packet fragmentation in the air.

Switching between communication and run mode

The FlashCART has a switch to change between communication mode and run mode. In communication mode the FlashCART talks to the PC and gets its memory filled. In run mode the program you sent to the FlashCART runs on the Videopac. You can switch between modes with the switch connected to the SWITCH1 connector. To change modes hold RESET, toggle the switch and release RESET. It is safe to toggle the switch without pressing RESET if you are in communication mode and have sent the --endcomm command. You will see the message "READY FOR RESET" on the Videopac screen. You still need to press RESET to start your program after you changed the switch.

Communication mode

In communication mode the firmware in the EPROM is active. Press any key after RESET to start. You will see a black screen with the version number of the firmware and a P for PAL or N for NTSC in the top right corner. The Videopac is listening for commands on the serial port. Use the g7kflash program to talk to it. A full program upload to the FlashCART takes between 10 and 11 minutes. If you finished uploading use the --endcomm command, toggle the switch, press RESET and the program you sent to the FlashCART starts at 0400h in bank 0ffh, flash address 0xff400.

The communication software

The communication program that I have written is a simple command line tool. It should not be difficult to create a GUI for it or even integrate it into a development environment. The program is portable to different Operation Systems, I provide ports to Linux, Windows, AmigaOS and NetBSD.

Parameters

G7kflash takes one command and several parameters. Here are the possible parameters and what they mean:

--device <dev>, -d <dev>

This is the device where the FlashCART is connected to. The exact name depends on the OS you use, examples are /dev/ttyS0 or /dev/ttyUSB0 for Linux, COM1 or \\.\COM10 for Windows, serial.device/0 for AmigaOS or /dev/dty00 for NetBSD.

--start <adr>, -s <adr>

This is the first address for the flash and EEPROM access commands that is used.

--end <adr>, -e <adr>

This is the last address for the flash and EEPROM access commands that is used.

--filestart <pos>

This is the position of the first byte that is read/written to in the file for the flash and EEPROM access commands. This is not fully supported on all Operation Systems.

--quiet

Suppress the progress information for the EEPROM and flash commands.

--verbose

Prints some more information about what is going on for the --linetest command.

--debug

Dump all the communication between PC and FlashCART, only useful for debugging the protocol.

Commands

And here are the commands for g7kflash:

--help

Prints a short explanation of all parameters and commands.

--linetest <num>

Tests the communication between PC and FlashCART by sending num NOP data packets and checking the answers. It can be used to check the stability of the communication, although its main use was to help porting and debugging the low-level communication routines.

--endcomm

Sends a special command to end all communication between PC and FlashCART. The normal firmware jumps to an endless loop in the BIOS so you can switch to the program without holding down RESET. Integrated firmware can react different, the VPP editor uses it to jump back from communication mode into main mode.

--info

Identifies the flash and EEPROM chips. The EEPROM identification can't distinguish the 93C56/93C66 and the 93C76/93C86 because they are nearly identical in use.

--eraseflash <adr>

Erase the flash sector at adr or the whole chip if adr is 0xffffff. This operation can take a lot of time, the timeout chosen by g7kflash is displayed on screen. The timeout depends on the flash chip used. The exact sector layout depends on the flash chip used, please look into the datasheet for the flash chip you have.

--writeflash <file>

Write the file file to flash ROM. Use a filename of - for the standard input. To change the address to write to in flash ROM use the --start parameter. You can only change 1 bits to 0 bits when writing to flash ROM, so if there is already data there you need to erase it first.

--readflash <file>

Read from flash ROM to the file file. Use a filename of - for the standard output. To change the address to read from in flash ROM use the --start parameter.

--eraseeeprom

Erase the whole EEPROM.

--writeeeprom <file>

Write the file file to EEPROM. Use a filename of - for the standard input. To change the address to write to in EEPROM use the --start parameter. The EEPROM can be overwritten without erasing.

--readeeprom <file>

Read from EEPROM to the file file. Use a filename of - for the standard output. To change the address to read from in EEPROM use the --start parameter.

--readvpp <file>

Read from the VPP screen to the file file. All char, attribute and slice data are copied. The resulting file is identical to the result from the savevpp command in O2EM's debugger (note that the savevpp command is broken in O2EM 1.17.3 and 1.18): First there are 25 lines starting with line 0 and ending with the service row. Then there are 960 bytes for slice data without background and another 960 bytes of slice data with background change. This command is mostly useful for saving the screens from the VPP screen editor.

--writevpp <file>

Write back the file file saved with --readvpp to the VPP screen. This command is mostly useful for the VPP screen editor.

Notes to the different ports

Linux/i386

The normal serial ports are called /dev/ttySX on Linux/i386. The USB converters usually show up as /dev/ttyUSBX. You may need special rights to access these devices as normal user, see the manual of your distribution for details. You either need to add your user id to a specific group or change the udev configuration to allow access. You can fine tune some of the FTDI converters by changing the latency setting via the /sys filesystem to 1. This only works on kernel 2.6.22 or newer.

The binary was compiled on a Debian 4.0 etch distribution.

Windows

The normal serial ports and the USB converters both show up as COMX. For X>=10 you need to use the full resource path to access it: "\\.\COM10". You can fine-tune USB converters by setting the latency to 1ms and changing the buffer sizes to the smallest number >=136.

The binary was cross-compiled with mingw-gcc 3.4.1.

AmigaOS

The normal serial port is serial.device/0. The --filestart parameter only works on writing if the file is already big enough.

The binary was compiled on AmigaOS 3.1 with dice 3.16 on an Amiga 4000 with 68030. It is also tested on AmigaOS 2.0 on a plain Amiga 2000.

NetBSD/i386

The normal serial ports are called /dev/dty0X. The USB converters show up as /dev/ttyUX.

The binary was compiled on NetBSD 3.1.

The communication protocol

The communication protocol is based on a standard serial communication with 38400 bits per second, 8 bits, no parity, one stop bit. It is packet-based with 8 header bytes and up to 128 bytes of data. The FlashCART is completely passive, it waits for a command packet, executes the command and returns an answer packet, it never sends any data without being asked.

The header

iram_hd_lenLength of data field
iram_hd_cmdCommand to execute
iram_hd_adrhHigh byte of the address
iram_hd_adrmMiddle byte of the address
iram_hd_adrlLow byte of the address
iram_hd_hsumHeader checksum: add first 5 byte of header without carry
iram_hd_dsumhHigh byte of data checksum: add iram_hd_len bytes of data without carry
iram_hd_dsumlLow byte of data checksum: add iram_hd_len bytes of data without carry

Most of the commands need an address as parameter, so there is a 24 bit address in the header. The checksums are just a sum without carry bit of all relevant bytes in 8 bit for the header and 16 bit for the data. Better checksums take much longer to compute on the FlashCART side, so I had to choose simple ones.

The possible commands

Error handling

All commands have the highest bit 7 cleared. When answering the FlashCART sets this bit. If any of the checksums do not match in the answer packet a reception error occurred. Try to repeat the offending command to make sure it is executed correctly. If the checksums are ok, the highest bit of the command is set and the lower 7 bits still contain the command then the command was executed successfully.

The FlashCART can return several error codes, all have the highest bit set without a matching command:

0F6hCMD_ERR_NOCMDThe command is not known to the FlashCART
0F7hCMD_ERR_NOEEPNo EEPROM was found
0F8hCMD_ERR_REFUSEThe FlashCART refuses to execute this command
0F9hCMD_ERR_NOVPPThis command only works on a Videopac+ machine
0FAhCMD_ERR_ERASEAn erase did not complete
0FBhCMD_ERR_VRFYA byte was not written correctly
0FChCMD_ERR_WRITEA write failed
0FDhCMD_ERR_HSUMThe header checksum did not match
0FEhCMD_ERR_DSUMThe data checksum did not match
0FFhCMD_ERR_TIMETimeout while receiving data on the FlashCART

Although the CMD_ERR_VRFY and CMD_ERR_WRITE sound similar they have a different meaning. CMD_ERR_WRITE means that the flash ROM chip returned an error while writing. CMD_ERR_VRFY means that the flash ROM chip thinks the write was ok, but that the FlashCART found a different byte than expected.

Commands

00h, CMD_NOP: do nothing

This command just sends all data it receives back to the PC. It is used for presence detection and for --linetest.

01h, CMD_FIRMWARE: return firmware version

This command returns 2 bytes of data: The major and the minor version number. They are the same as with the commapi_version API call.

02h, CMD_END: end the communication

This command is used to end the communication. On the FlashCART it prints "READY FOR RESET" and jumps to an endless loop. If you insert the firmware into one of your own projects you should replace this with something that makes more sense for you. This command is used for --endcomm.

010h, CMD_FLS_RD: read from the flash ROM

This command reads a block from flash ROM starting at the supplied address and sends it to the PC. It takes the number of bytes to read as an additional parameter in the first data byte. The number of bytes has to be <=128. The whole block has to be in the same page.

011h, CMD_FLS_WR: write to the flash ROM

This command writes iram_hd_len bytes into the flash ROM starting at the address in the header. The number of bytes has to be <=128. The whole block has to be in the same page. This command handles the full write cycle with flash ROM unlocking, writing and data polling for every byte. You can't use this command if you insert the firmware into your own programs.

012h, CMD_FLS_ER: erase a sector or all of the flash ROM

This commands erases the flash sector at the header address or the whole chip when the address is 0xffffff. This command handles the full erase cycle with flash ROM unlocking, erasing and data polling. It can take a long time to execute, especially as the flash ROM chip ages. See the datasheet of the flash ROM in your FlashCART for details. You can't use this command if you insert the firmware into your own programs.

013h, CMD_FLS_ID: return the flash ROM id

Every modern flash chip has a manufacturer and a device id. This command returns both in the data field, first the manufacturer then the device id. See datasheets of flash ROM chips for the possible ids. You can't use this command if you insert the firmware into your own programs.

014h, CMD_FLS_DWR: direct write

This command allows you to send write commands directly to the flash ROM. There will be no unlock cycles, just writes to the flash ROM. So you can use all commands the flash ROM allows. Usually these commands will be single byte writes. The parameters are the same as for CMD_FLS_WR. This command is not used by g7kflash. You can't use this command if you insert the firmware into your own programs.

020h, CMD_EEP_RD: read from EEPROM

This command reads a block from the EEPROM and sends it to the PC. The number of bytes to read is in the first data byte. It has to be <=128. Only up to 16 bits of the address are used. The biggest EEPROM only has 11 active address bits, so this is not a really a restriction.

021h, CMD_EEP_WR: write to EEPROM

This command writes iram_hd_len bytes into the EEPROM starting at the address in the header. The number of bytes has to be <=128. Only up to 16 bits of the address are used.

022h, CMD_EEP_ER: erase EEPROM

This command erases the whole EEPROM. Since any byte can be written directly there is no byte erase implemented.

023h, CMD_EEP_ID: return the EEPROM address length

This commands return in one data byte the number of address bits the EEPROM has.

030h, CMD_VDC_WR: write to VDC

This command writes a data block into the VDC starting with the address in the header. Only the lowest 8 bits of the address are used. This command is not used by g7kflash. There is no corresponding read command.

031h, CMD_VPP_RD: read from VPP screen

This command reads char and attribute data from the Videopac+ screen. The addresses are not linear, the position is encoded into the middle and low address byte. The middle address byte contains the line number as used by the Videopac+, so the service row is 31. Only 5 bits of the line number are used. The lowest address byte contains the X position in bits 7-1, bit 0 is unused. This encoding makes sense since there are two byte for every position: the char and the attribute byte. The length in the first data byte is still in bytes, not number of char positions. All data to read should be in the same line.

032h, CMD_VPP_WR: write to VPP screen

This command write char and attribute data to the Videopac+ screen. The addresses are not linear, the position is encoded into the middle and low address byte. The middle address byte contains the line number as used by the Videopac+, so the service row is 31. Only 5 bits of the line number are used. The lowest address byte contains the X position in bits 7-1, bit 0 is unused. This encoding makes sense since there are two byte for every position: the char and the attribute byte. The length in the header is the number of bytes to write, not the number of char positions. All data to read should be in the same line.

033h, CMD_VPP_RDSL: read VPP slice data

This commands reads from the Videopac+ redefined chars. The lowest address byte contains the first char to read. The lowest bit of the middle address byte contains a flag which set of redefined chars is used: 0 for the normal set and 1 for the chars with background as parallel attribute. The length byte in the first data byte contains the number of bytes to read. You should only read complete chars, the length should be multiplies of 10 bytes of slice data. The length has to be <=128.

034h, CMD_VPP_WRSL: write VPP slice data

This commands writes to the Videopac+ redefined chars. The lowest address byte contains the first char to write to. The lowest bit of the middle address byte contains a flag which set of redefined chars is used: 0 for the normal set and 1 for the chars with background as parallel attribute. The length byte in the header contains the number of bytes to write. You should only write complete chars, the length should be multiplies of 10 bytes of slice data. The length has to be <=128.

035h, CMD_VPP_MODE: call plusmode

This command sets the VPP mode. It calls plusmode with the first data byte as transparency and the second data byte as luminance. This command is not used in g7kflash.

036h, CMD_VPP_CMD: call pluscmd

This command sends any command to the VPP. It calls pluscmd with the first data byte as command and the second data byte as parameter. This command is not used in g7kflash.

Extensions

If you want to add your own commands please use the range from 060h-06fh. If you think your extensions are useful for other people, too, then contact me so I can reserve some commands for you and add them officially to the protocol.

Firmware API

The firmware which handles all the communication can also be used in your own programs. To be able to do that you have to include a copy of the firmware into your own program, there is no way to access the EPROM used for running the firmware in download mode. This also means that you can't do any write accesses to the flash ROM since the code is running from there. The firmware contains routines for initialisation, for communication with a PC and EEPROM routines.

The firmware needs addresses 0500h-0fffh in any code bank. The page from 0400h-04ffh is free to allow you to interface the rest of the program with the firmware. Try to use the interface documented here whenever possible, this makes it easier to update the firmware when I release updates. Don't rely on anything that I don't document here, for example preserved registers.

Some of my example programs use the firmware API. The most complex one is the VPP screen editor. A much simpler program is the EEPROM editor.

Resources used by the firmware

You can download an include file with all symbolic names used, it is called the flashdefs.h include file.

Internal RAM

All routines expect that bits 0, 1 and 2 of address 03Fh are set to the correct machine type, see commapi_init for explanations. The routines commapi_readblock and commapi_execcmd use internal RAM from 020h-027h:

03Fhiram_modeSome flags for the firmware
03Fh:0iram_mode_plus1=Machine is a Videopac+
03Fh:1iram_mode_pal1=Machine has PAL timings
03Fh:2iram_mode_local1=Command is locally created
020hiram_hd_lenLength of data field
021hiram_hd_cmdCommand to execute
022hiram_hd_adrhHighest byte of address
023hiram_hd_adrmMiddle byte of address
024hiram_hd_adrlLowest byte of address
025hiram_hd_hsumHeader checksum
026hiram_hd_dsumhHigh byte of data checksum
027hiram_hd_dsumlLow byte of data checksum

External RAM

The routines commapi_readblock and the commapi_execcmd may overwrite any external RAM.

The routines

All routines have fixed entry points at the beginning of the firmware code. When finished all use ret to return to the caller with sel mb0 active.

0500h: commapi_init

This routine initialises the firmware: It disables the EEPROM, resets the flash ROM chip, turns off XROM and sets the iram_mode_plus and iram_mode_pal bits. When assembled for debugging it will also print a version number on the Videopac+ screen. It does not touch the code bank switching. The reason is simple: In most cases you have already used it to get to the firmware bank.

InputIRQ chain with a working waitvsync
Outputiram_mode is set to the detected machine type
 EEPROM and flash ROM are in a defined state
 The TX line is ready for communication
 The external RAM is enabled
AltersEverything

The machine type bit iram_mode_pal is set when the machine runs with PAL timings. The iram_mode_plus is set when the machine has a Videopac+ BIOS. Both bit definitions define the bit number, not a bit mask, use (1 << iram_mode_X) to get the bit mask for testing if a bit is set. All other bits in iram_mode except the two highest bits are cleared.

0502h: commapi_version

This routine returns two version numbers for the firmware itself. Both are BCD coded numbers. All changes to the API defined here will change the major version number. The minor version number will change with every release I make.

InputNone
OutputR6: major version number
 R7: minor version number

0504h: commapi_readblock

This routines waits until the PC sends data. Once a data block is complete the checksums are checked and a return code is generated. The command received is not executed. This allows protocol extensions and redefinitions, you will quite likely redefine the CMD_END command to return to the program into which you include this firmware.

Inputextramenable
OutputA=RET_OK data block ok
 A=RET_TIMEOUT data block incomplete
 A=RET_HSUM header checksum mismatch
 A=RET_DSUM data checksum mismatch
 iram(020h-027h): header
 extram: data
 interrupts enabled
AltersEverything

0506h: commapi_execcmd

This routine executes a command received by commapi_readblock and sends an answer to the PC. In the case of reception errors it sends the correct error code back to the PC, the command is not executed.

It is also possible to execute a command locally without a PC present. You have to set the iram_mode_local bit for that. You also have to prepare a header and the data as if they were sent from a PC except the checksums.

This routine is special, it returns with interrupts disabled. This is needed to reliably receive the next command after the current one is answered. The PC expects that the firmware is ready to receive immediately after the PC got the answer from a command. Any interrupt running at that time will lead to lost bytes. So use en i if you return to your normal program after running commapi_execcmd.

Inputextramenable
 A: return code from commapi_readblock
 iram(020h-027h): header
 extram: data
Outputinterrupts disabled
 iram(020h-027h): answer header
 extram: answer data
AltersEverything

0508h: commapi_eepromsize

This routine returns the number of address bits used by the EEPROM. For some EEPROMs (93C56, 93C76) the highest address bit is a don't care bit. The only way to detect that is to write different data to two locations differing only on the highest address bit and to read back from the first location to see if it has changed by the second write.

Inputextramenable
OutputA: number of address bits, 0 for no EEPROM
AltersR0 R2 R3 R6 R7

050ah: commapi_eepromread

This routines reads one byte from the EEPROM. To read lots of bytes at once use commapi_execcmd with the CMD_EEP_RD command.

Inputextramenable
 R5: high byte of address
 R6: low byte of address
OutputA: byte read from EEPROM
AltersA R0 R2 R5 R6 R7

050ch: commapi_eepromwrite

This routine writes one byte to the EEPROM. To write lots of bytes at once use commapi_execcmd with the CMD_EEP_WR command.

Inputextramenable
 R5: high byte of address
 R6: low byte of address
 A: data byte to write
OutputA=0 ok
 A=0ffh write error
AltersA R0 R2 R3 R5 R6 R7

The registers

The MegaCART has 4 hardware registers accessible as external RAM starting at 080h. Although they are mirrored every 4 bytes I suggest to only use the copies from 080h-083h, future hardware may have more registers. The code bank switch method for code is based on the one used for 12K and 16K Videopac+ games. The data bank switch is similar to the one used on Videopac 31 and 40, Musician and 4 in 1 Row.

All three read/write registers return the last value written to them when read.

080h, ereg_codebank

This read/write register stores the current code bank. This sets the address line A12-A19 for program code if P1.0 is 0. If P1.0 is set address lines A12-A19 are all ones, so after reset bank 0ffh is active. The ereg_codebank contains 0 after the BIOS routine init is run. So it makes sense to first write 0ffh into ereg_codebank and then clear P1.0 as part of an early initialisation. In all banks the BIOS is still at 0-03ffh.

The way the code bank switch works is not compatible with the automatic Videopac+ detection used by plusselectgame. If you use the firmware you can check the iram_mode_plus bit, or check the BIOS by a direct read like in the following example:


        ; detect videopac+
        ; The bank-switch of the MegaCART is not compatible with the usual
        ; way to detect VP+, so I check one of the two easily readable
        ; differences in the BIOS. (The other one is 0394h=0bbh for VP+)
        section plusdetect
        mov     a,#07eh
        movp3   a,@a                    ; read 037eh, 020h=std, 039h=VP+
        xrl     a,#039h
        jz      .ok
        jmp     normal                  ; no videopac+
.ok     endsection plusdetect

081h, ereg_databank

This read/write register stores the current data bank. This sets the address line A12-A19 for data reads if P1.1 is 0. Additionally A8-A11 have to be set by the lowest nibble of P2. Then the XROM read of the EPROM is activated by a movx read. All the other read sources have to be turned off: VDC, VPP and external RAM. Since the BIOS knows P1.1 only as address line for its own bank switching, P1.1 has to be set manually before using any other of the movx sources, the BIOS routines don't do it.

This XROM read allows reading all bytes of the EPROM from any code location. It simplifies the handling of big data structures like Videopac+ data. The BIOS interrupt routines do not know about the XROM access, so you have to disable the interrupts while P1.1 is cleared.

Some example macros for XROM data read

Here are some macros I wrote to enable and disable XROM data read. More code can be found in my G7000 BIOS document. A full example program is on the demo program page.


; Enable XROM (read and write)
;  P16=0 (enable cart signal), P11=0 (enable XROM), P15=1, P14=1, P13=1, P12=1
m_xromenable macro
        orl     P1,#03ch
        anl     P1,#0bdh
        endm

; Disable XROM reading: P11=1
; This is needed because the BIOS extram/vdcenable routines don't touch P10/P11
m_xromdisable macro
        orl     P1,#002h
        endm

; Switch from XROM to XRAM
m_xromtoram macro
        orl     P1,#0beh
        anl     P1,#0afh
        endm

082h, ereg_io_out

This read/write register is used to control some pins on the CPLD. Three of them are connected to the EEPROM, one is used on the FlashCART for communication. I strongly suggest that you insert the FlashCART firmware into your program if your want to use the EEPROM or talk to a PC.

Bit 0eout_tx This bit is used on the FlashCART as TX line. It is inverted, so that the BIOS initialises it to the correct level on the serial port.
Bit 1eout_eecs This bit controls the chip select pin of the EEPROM.
Bit 2eout_eeclk This bit controls the clock pin of the EEPROM.
Bit 3eout_eedi This bit controls the data in pin of the EEPROM.

All the eout_ definitions are bit masks, not bit numbers.

083h, ereg_io_in

This is a read only register which contains the level on some of the CPLD pins. Currently only one bit is used, the rest returns 0.

Bit 0ein_eedo This bit reads the data out pin of the EEPROM.

Expansion port

The FlashCART has a 10 pin connector to allow future expansions. It has all the EEPROM signals on it, so you can leave the EEPROM on the FlashCART empty and plug in different EEPROMs for testing. It also has other signals that can be useful, one idea I have is to connect another SPI device besides the EEPROM which uses the TX signal for select. Or make the EEPROM outputs open-collector and use TWI/I2C peripherals.

Pinout

5V1o o23.3V
ROMSWITCH3o o4TX
EEDO5o o6EEDI
EECLK7o o8EECS
GND9o o10GND

The downloads

The first released version of the hardware is 1.1. For the rest the first released version is 1.0.

For a complete package you need the hardware, firmware and communication software.

Other useful pages