PJRC.COM Offline Archive, February 07, 2004 Visit this page on the live site |
| ||
Shopping Cart Checkout Shipping Cost Download Website |
Home | MP3 Player | 8051 Tools | All Projects | PJRC Store | Site Map |
You are here: MP3 Player Technical Docs Memory Map | Search PJRC |
Address | Allocation | Description |
---|---|---|
0x0000 - 0x4FFF | Static | Static variables (20k) available for the application level code |
0x5000 - 0x7FFF | Dynamic | Three pages (8k) of space available for the application to use
dynamic memory (mapping pages obtained from malloc_blocks ) |
0x8000 - 0x8FFF | Static | Variables for FAT32, IDE, Playback, Memory Manager |
0x9000 - 0x9FFF | Dynamic | Playback DMA buffer |
0xA000 - 0xAFFF | Dynamic | IDE DMA buffer |
0xB000 - 0xBFFF | Dynamic | FAT32 buffer |
0xC000 - 0xCFFF | None | Unused |
0xD000 - 0xDFFF | Static | FAT32 cached FAT sector list |
0xE000 - 0xEFFF | Dynamic | Memory manager buffer (typically maps blocks 0-31, which contain allocation and usage data for all other blocks) |
Name | Data Type* | Address | Status | Description |
---|---|---|---|---|
PAGE_0 | memory | 0x0000 to 0x0FFF | Working | DRAM Memory, may be mapped to any 4k range within the SIMM |
PAGE_1 | memory | 0x1000 to 0x1FFF | Working | DRAM Memory, may be mapped to any 4k range within the SIMM |
PAGE_2 | memory | 0x2000 to 0x2FFF | Working | DRAM Memory, may be mapped to any 4k range within the SIMM |
PAGE_3 | memory | 0x3000 to 0x3FFF | Working | DRAM Memory, may be mapped to any 4k range within the SIMM |
PAGE_4 | memory | 0x4000 to 0x4FFF | Working | DRAM Memory, may be mapped to any 4k range within the SIMM |
PAGE_5 | memory | 0x5000 to 0x5FFF | Working | DRAM Memory, may be mapped to any 4k range within the SIMM |
PAGE_6 | memory | 0x6000 to 0x6FFF | Working | DRAM Memory, may be mapped to any 4k range within the SIMM |
PAGE_7 | memory | 0x7000 to 0x7FFF | Working | DRAM Memory, may be mapped to any 4k range within the SIMM |
PAGE_8 | memory | 0x8000 to 0x8FFF | Working | DRAM Memory, may be mapped to any 4k range within the SIMM
This page is reserved for misc static data structures used by library routines. File descriptor tables, IDE and playback pending request queues, etc. |
PAGE_9 | memory | 0x9000 to 0x9FFF | Working | DRAM Memory, may be mapped to any 4k range within the SIMM
This page is reserved for playback. The playback code maps the currently playing block here, until the DMA transfer to the MP3 decoder is complete. |
PAGE_A | memory | 0xA000 to 0xAFFF | Working | DRAM Memory, may be mapped to any 4k range within the SIMM
This page is reserved for use by the the IDE driver. The IDE driver maps blocks here for DMA transfers. |
PAGE_B | memory | 0xB000 to 0xBFFF | Working | DRAM Memory, may be mapped to any 4k range within the SIMM
This page is reserved for use by the the FAT32 filesystem. Typically, the FAT32 code will map blocks containing FAT sectors when tring to figure out what clusters compose a file, and to copy the data from the cached clusters when the application reads the file. |
PAGE_C | memory | 0xC000 to 0xCFFF | Working | DRAM Memory, may be mapped to any 4k range within the SIMM
This page isn't currently being used. |
PAGE_D | memory | 0xD000 to 0xDFFF | Working | DRAM Memory, may be mapped to any 4k range within the SIMM
This page is reserved for use by the FAT32 filesystem. This page holds an array of block numbers which are being used to cache FAT sector groups. |
PAGE_E | memory | 0xE000 to 0xEFFF | Working | DRAM Memory, may be mapped to any 4k range within the SIMM
This page is reserved for use by the memory manager (malloc, et all). The memory manager will usually map one of the first 32 blocks, which contain a linked list and misc data about all of the 4k blocks (16 bytes per block). |
DRAM_PAGE_CFG | 16 bit INT (15) | 0xFF00 to 0xFF1D | Working | These fifteen integers control which of the 4k pages
of the DRAM is seen in each of the 4k pages in the
processor's 4k pages (PAGE_X above). Each of the
supported SIMM sizes provides the following blocks:
|
DMA_IDE_DEST | 16 bit INT | 0xFF22 to 0xFF23 | Working | Destination address for DMA transfer from the IDE interface to the DRAM. The 16 bit address must be between 0000 to EFFE. The page(s) where the DMA will write data must remain mapped (DRAM_PAGE_CFG) during the entire transfer. Only even addresses should be used. This register is incremented by the hardware as the DMA transfer takes place |
DMA_IDE_COUNT | 16 bit INT | 0xFF24 to 0xFF25 | Working | Specifies the number of 16 bit words to transfer from the IDE interface to DRAM. To transfer a 512 byte sector, this would be initialized to 256. This register is decremented as the transfer takes place and it will read zero when the transfer is complete. An interrupt may also be generated upon completion. |
DMA_MP3_SRC | 16 bit INT | 0xFF28 to 0xFF29 | Working | Source address for DMA transfer from the DRAM to the STA013 MP3 decoder chip. The hardware automatically transfers the data as the STA013 is ready for it. This register is incremented by the hardware as the DMA transfer takes place. The page(s) containing this memory need to remain mapped during the transfer. |
DMA_MP3_COUNT | 16 bit INT | 0xFF2A to 0xFF2B | Working | Specifies the number of 16 bit words to transfer from DRAM to the STA013 MP3 decoder chip. This register is decremented as the transfer takes place and it will read zero when the transfer is complete. An interrupt may also be generated upon completion. |
MEMCPY_DEST | 16 bit INT | 0xFF30 to 0xFF31 | unimplemented | Don't use the fast hardware memcpy yet! |
MEMCPY_SRC | 16 bit INT | 0xFF32 to 0xFF33 | unimplemented | Don't use the fast hardware memcpy yet! |
MEMCPY_COUNT | 16 bit INT | 0xFF34 to 0xFF35 | unimplemented | Don't use the fast hardware memcpy yet! |
IDE_RESET_BIT | 1 bit | 0xFF40 | Working | The LSB at this location controls the IDE reset pin. Write 0 to reset the IDE devices, or write 1 for normal operation. This bit is initialized to zero when the FPGA is configured, and must be written as 1 to allow the IDE devices to operate. The upper 7 bits will read random data, and should always be written as zeros. |
IDE_DATA_BUF_LSB | 8 bit BYTE | 0xFF42 | untested | Reading this regsiter will return the lower 8 bits of data from the previous IDE interface read. Writing will store the lower 8 bits to be written on the next IDE write. Only the buffers within the FPGA are accessed, no IDE activity is generated by accessing this register. Separate buffers are used within the FPGA, so a write to this register followed by a read will not necessarily return the same byte. This register will not normally be needed, as reads and writes to the IDE port at even addresses will read/write the lower byte of the IDE devices. |
IDE_DATA_BUF_MSB | 8 bit BYTE | 0xFF43 | Working | Reading this regsiter will return the upper 8 bits of data from the previous IDE interface read. Writing will store the upper 8 bits to be written on the next IDE write. Only the buffers within the FPGA are accessed, no IDE activity is generated by accessing this register. Separate buffers are used within the FPGA, so a write to this register followed by a read will not necessarily return the same byte. This register will normally be used when transfering data without DMA, where it would be written before a write to the IDE port or read after a read from the IDE port. |
IRQ_IDENT | 8 bit BYTE | 0xFF50 | Working | This read-only register tells which interrupts are
currently pending. Reading it does not clear an interrupt.
This register should be read at the beginning on the
interrupt service routine to determine which actual
interrupt occured.
|
IRQ_MASK | 8 bit BYTE | 0xFF51 | Untested | This write-only register configure which bits in the
interrupt register can assert the 8051's INT0 pin. The
bits are set by completion of a DMA transfer, and cleared
by writing to the "ack" registers, regardless of what is
written here. This register allows the individual interrupt
to be masked from asserting INT0, but they otherwise
function in exactly the same way.
|
DMA_IDE_GO | Flag | 0xFF58 | Working | Writing to this location causes a DMA transfer from the IDE interface to DRAM memory to begin. DMA_IDE_DEST, DMA_IDE_COUNT, and the corresponding page select in DRAM_PAGE_CFG need to be set up, and it also helps if the drive is ready to transfer data from a command written via IDE_PORT. Data is transfered directly from the drive to DRAM. The drive "sees" PIO style access. Data transfer speed should be approx 2.4 Mbytes/sec. |
DMA_MP3_GO | Flag | 0xFF59 | Working |
Writing to this location causes a DMA transfer from the DRAM to MP3 decoder chip. DMA_MP3_SRC and DMA_MP3_COUNT need to be set up before writing here. |
MEMCPY_GO | Flag | 0xFF5A | Unimplemented (may crash if used) |
Don't use the hardware memcpy yet... just do it in code for now. |
IRQ_DMA_IDE_ACK | Flag | 0xFF5C | Working | Writing to this location causes bit 0 in IRQ_IDENT to be cleared. This must be done in the interrupt service routine if bit 0 is set. |
IRQ_DMA_MP3_ACK | Flag | 0xFF5D | Working | Writing to this location causes bit 1 in IRQ_IDENT to be cleared. This must be done in the interrupt service routine if bit 1 is set. |
IRQ_MEMCPY_ACK | Flag | 0xFF5E | Untested | Writing to this location causes bit 2 in IRQ_IDENT to be cleared. This must be done in the interrupt service routine if bit 2 is set. |
IDE_PORT | 8 bit Bytes (see desc) | 0xFF60 to 0xFF7F | Working | This area provides read/write access to the IDE interface.
All reads within this range cause an IDE read cycle, and all
writes cause an IDE write cycle. Access to the even addresses
within this range read/write the lower 8 bits of the IDE port,
and the upper 8 bits are from IDE_DATA_BUF_MSB are used.
Likewise, access to the odd locations read/write the upper 8
bits and IDE_DATA_BUF_LSB is used for the lower 8 bits. The
first 16 bytes access the IDE interface via CS0, and the second
16 access it via CS1.
Normally only some of the even addresses will be used, because the upper data byte of the IDE interface are only used for data transfer, not commands. Most IDE registers are accessed with CS0, only "control" and "alt_status" use CS1. Here's the list of registers that would normally be used.
|
Ethernet see Tom's website for details |
TBD | 0xFF80 to 0xFF8F | Unimplemented | This area is reserved for Tom's Ethernet project.
The tenative register list for a Cirrus CS8900A chip is:
|
DRAM_WR_DIS | Flag | 0xFFC0 | Working | Writing to this location disables writing to the DRAM memory. This is done by the Flash ROM programming code within PAULMON2_MP3, so that the DRAM doesn't "hear" the writes to the flash memory. The code with PM2 also enables DRAM writing after the flash programming. |
DRAM_WR_EN | Flag | 0xFFC1 | Working | Writing to this location enables writing to the DRAM memory. The FPGA is initialized with DRAM writing enabled, so it is not necessary to write here unless DRAM writing has been disabled. |
* Data Type: "16 bit INT" types are also stored as "little endian", where the LSB is stored at the first location and MSB are the second. "Flag" types are special locations that cause an action when written. They do not have data associated with them, so any byte may be written (whatever's in the accumulator at the moment?).
TODO: add memory map for code space.... explain bank swap, normal code goes in bank 0, how to properly call to and return from code in bank 1, how to get code to download to the correct bank, and possibly other issues I missed in this list.
TODO: explain how the DMA works. General process: do setup for that source has data, make sure pages are properly mapped, set up DMA parms, write to go flag, when interrupt happens it's done, clear interrupt with ack flag. All DMA channels are separate and can be used concurrently (sending data to MP3 decoder while also transfering sectors from the drive). DRAM is still accessible during DMA transfers, and it's ok to remap pages that aren't involved in the transfer.
Accessing 16 bit data from the IDE port is tricky. Usually you would read IDE_DATA (0xFF60) first to get the LSB. Reading this register causes all 16 bits to be read into the FPGA's 16-bit buffer for the IDE port, so the upper 8 bits may be read using the IDE_DATA_BUF_MSB (0xFF43) register.
The tricky part is that any 16 bit access to or from the IDE drive or the DRAM will reuse the buffer and overwrite its contents. So, if you have code like this:
It will not work. The first line reads the IDE_DATA port, and then the byte is stored in variable "my_lsb", which is in xdata memory (DRAM), so the writing operation to my_lsb will destroy the contents of the 16 bit buffer that is read in the next line. If you replace this code with something like:xdata unsigned char my_lsb, my_msb; my_lsb = read_fpga_reg(0xFF60); my_msb = read_fpga_reg(0xFF43);
Now the two bytes are allocated in the 8051's internal memory, so the write operation to "my_lsb" will not destroy the 16-bit buffer contents. However, this _still_ won't work, because an interrupt could occur anytime between the two MOVX instructions that will ultimately be executed within the two calls to read_fpga_reg, and nearly all of the interrupt routines will access the DRAM memory. So if you disable interrupts, like this:data unsigned char my_lsb, my_msb; my_lsb = read_fpga_reg(0xFF60); my_msb = read_fpga_reg(0xFF43);
It probably work, but it will still fail if there is a DMA transfer underway, as these DMA transfers also access DRAM and reuse that 16-bit buffer.data unsigned char my_lsb, my_msb; EA = 0; my_lsb = read_fpga_reg(0xFF60); my_msb = read_fpga_reg(0xFF43); EA = 1;
I don't currently have a reasonable way to work around the DMA access... so this is a pretty serious limitation which will need to be addressed in the hardware to enable you to make use of 16 bit PIO access to the IDE interface.
One thing that might make you life a bit easier is using some C syntax to directly access the registers, instead of having to call assembly language helper functions. You can declare the FPGA registers like this:
and then you can access them just like C variables. Be sure to use the "volatile" keyword, so that the C compiler doesn't try to optimize out your accesses to the registers.volatile xdata unsigned char at 0xFF60 reg_ide_data; volatile xdata unsigned char at 0xFF43 reg_ide_buf_msb;
Bank | Begin | End | Usage |
---|---|---|---|
0 | 2000 | 2FFF | Interrupt Routines |
0 | 3000 | DFFF | C Code |
0 | E000 | ECFF | Utility Programs (non-essential) |
0 | ED00 | EFFF | Utility Programs (the 'X', 'Y' erase and auto-start) |
0 | F000 | FFFF | Firmware Rev is 0.1.3 (which is run if there is no simm) |
1 | 2000 | 2FFF | Interrupt Routines (must be in both banks) |
1 | 3000 | 7FFF | Device Drivers |
1 | 8000 | 8FFF | Non-Volatile Params |
1 | 9000 | 9FFF | STA013 Config Data |
1 | A000 | CEFF | FPGA Config For 0.6.x |
1 | CF00 | CFFF | Unused (256 bytes) |
1 | D000 | FEFF | FPGA Config For 0.1.3 |
1 | FF00 | FFFF | Helper code for the 'X' and 'Y' erase |