Merge branch 'kconfig' of https://github.com/RetroBSD/retrobsd into kconfig.

This commit is contained in:
Serge Vakulenko
2015-09-04 16:45:00 -07:00
8 changed files with 31 additions and 1102 deletions

View File

@@ -2,7 +2,7 @@
# Programs that live in subdirectories, and have makefiles of their own. # Programs that live in subdirectories, and have makefiles of their own.
# #
SUBDIR = baremetal duinomite duinomite-emega explorer16 \ SUBDIR = baremetal duinomite duinomite-emega explorer16 \
fubarino max32 maximite maximite-color meb mmb-mx7 \ fubarino max32 maximite maximite-color mmb-mx7 \
picadillo pinguino-micro sdxl starter-kit ubw32 wf32 picadillo pinguino-micro sdxl starter-kit ubw32 wf32
default: default:

View File

@@ -1,22 +1,39 @@
Build directories: Build directories:
max32 - chipKIT Max32 board. 32mxsdram-uart/ - 32MXSDRAM custom board with external SDRAM
used as a volatile disk storage (swap).
ubw32 - Sparkfun UBW32 board, USB console. baremetal/ - PIC32MX processor on a custom board.
ubw32-uart - Sparkfun UBW32 board, UART console. duinomite/ - Olimex Duinomite or Duinomite-Mega board.
maximite - Maximite computer. duinomite-emega/ - Olimex Duinomite-eMega board.
explorer16 - Microchip Explorer 16 board, with explorer16/ - Microchip Explorer 16 board,
PIC32 CAN-USB plug-in module and SD & MMC pictail. with PIC32MX plug-in module
and SD & MMC pictail.
starter-kit - Microchip PIC32 USB or Ethernet Starter Kit, fubarino/ - Fubarino SD board.
with I/O Expansion board and SD & MMC pictail.
dip - eflightworks.net PIC32-on-DIP board. max32/ - chipKIT Max32 board.
(work in progress)
meb - Microchip Multimedia Expansion board with maximite/ - Maximite computer.
Microchip PIC32 USB or Ethernet Starter Kit.
(work in progress) maximite-color/ - The Colour Maximite computer.
mmb-mx7/ - MikroElektronika MultiMedia Board for PIC32MX7.
picadillo/ - 4D Systems Picadillo-35T board.
pinguino-micro/ - Olimex Pinguino-Micro board equipped
with pic32mx795 processor.
sdxl/ - Majenko SDXL board.
starter-kit/ - Microchip PIC32MX USB or Ethernet Starter Kit,
with I/O Expansion board and SD & MMC pictail.
ubw32/ - Sparkfun UBW32 board.
wf32/ - ChipKIT WF32 board with
2.4" LCD TFT display shield.

View File

@@ -1,9 +0,0 @@
.compileversion
.deps/
.oldversion
machine
sys
unix.bin
unix.map
usbboot.map
vers.c

View File

@@ -1,17 +0,0 @@
core pic32mx7
linker bootloader
mapping generic
device kernel cpu_khz=80000 bus_khz=80000 led=D2
device console device=ttyUSB0 led=D0
device uartusb
device rdisk led=D1
device sd0 port=1 cs=A9
device gpio
#device adc

View File

@@ -1,46 +0,0 @@
BUILDPATH = ../../../tools/configsys/../../sys/pic32
H = ../../../tools/configsys/../../sys/include
M = ../../../tools/configsys/../../sys/pic32
S = ../../../tools/configsys/../../sys/kernel
vpath %.c $(M):$(S)
vpath %.S $(M):$(S)
KERNOBJ += clock.o cons.o devsw.o exception.o exec_aout.o exec_conf.o exec_elf.o exec_script.o exec_subr.o gpio.o init_main.o init_sysent.o kern_clock.o kern_descrip.o kern_exec.o kern_exit.o kern_fork.o kern_mman.o kern_proc.o kern_prot.o kern_prot2.o kern_resource.o kern_sig.o kern_sig2.o kern_subr.o kern_synch.o kern_sysctl.o kern_time.o machdep.o mem.o rd_sd.o rdisk.o signal.o spi_bus.o startup.o subr_prf.o subr_rmap.o swap.o sys_generic.o sys_inode.o sys_pipe.o sys_process.o syscalls.o sysctl.o tty.o tty_subr.o tty_tty.o ufs_alloc.o ufs_bio.o ufs_bmap.o ufs_dsort.o ufs_fio.o ufs_inode.o ufs_mount.o ufs_namei.o ufs_subr.o ufs_syscalls.o ufs_syscalls2.o usb_device.o usb_function_cdc.o usb_uart.o vers.o vfs_vnops.o vm_sched.o vm_swap.o vm_swp.o
EXTRA_TARGETS =
DEFS += -DBUS_DIV=1
DEFS += -DBUS_KHZ=80000
DEFS += -DCONSOLE_DEVICE=ttyUSB0
DEFS += -DCPU_IDIV=2
DEFS += -DCPU_KHZ=80000
DEFS += -DCPU_MUL=20
DEFS += -DCPU_ODIV=1
DEFS += -DCRYSTAL=8
DEFS += -DEXEC_AOUT
DEFS += -DEXEC_ELF
DEFS += -DEXEC_SCRIPT
DEFS += -DGPIO_ENABLED=YES
DEFS += -DKERNEL
DEFS += -DLED_DISK_PIN=1
DEFS += -DLED_DISK_PORT=TRISD
DEFS += -DLED_KERNEL_PIN=2
DEFS += -DLED_KERNEL_PORT=TRISD
DEFS += -DLED_TTY_PIN=0
DEFS += -DLED_TTY_PORT=TRISD
DEFS += -DPIC32MX7
DEFS += -DSD0_CS_PIN=9
DEFS += -DSD0_CS_PORT=TRISA
DEFS += -DSD0_PORT=1
DEFS += -DUARTUSB_ENABLED=YES
DEFS += -DUCB_METER
DEFS += -DUSB_MAX_EP_NUMBER=3
DEFS += -DUSB_NUM_STRING_DESCRIPTORS=3
LDSCRIPT = ../../../tools/configsys/../../sys/pic32/cfg/bootloader.ld
CONFIG = MEB
CONFIGPATH = ../../../tools/configsys
include ../../../tools/configsys/../../sys/pic32/kernel-post.mk

View File

@@ -1,5 +0,0 @@
NOTE
====
This device configuration is not currently supported by the
rdisk system. A new driver is needed for the SD card chip.

View File

@@ -1,854 +0,0 @@
/*
* SSD1926 hardware SD card driver
*
* Copyright (C) 2008 Microchip Technology Inc. All rights reserved.
* Microchip licenses to you the right to use, modify, copy and distribute
* Software only when embedded on a Microchip microcontroller or digital
* signal controller, which is integrated into your product or third party
* product (pursuant to the sublicense terms in the accompanying license
* agreement).
*
* You should refer to the license agreement accompanying this Software
* for additional information regarding your rights and obligations.
*
* SOFTWARE AND DOCUMENTATION ARE PROVIDED 'AS IS' WITHOUT WARRANTY OF ANY
* KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY WARRANTY
* OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR
* PURPOSE. IN NO EVENT SHALL MICROCHIP OR ITS LICENSORS BE LIABLE OR
* OBLIGATED UNDER CONTRACT, NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION,
* BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT
* DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL,
* INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA,
* COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY
* CLAIMS BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF),
* OR OTHER SIMILAR COSTS.
*
* Author Date Comments
* -----------------------------------------------------
* Sean Justice 15_Sept-2008 First release
* Anton Alkhimenok 06_Jun-2009 Ported to PIC24
*/
#include <machine/ssd1926.h>
/*
* Helper Macros
*/
#define CheckDataInhibit() while(GetReg(0x1124) & 0x02)
#define CheckCommandInhibit() while(GetReg(0x1124) & 0x01)
#define GetDataPortReg0() GetReg(0x1120)
#define SetDataPortReg0(data) SetReg(0x1120, data)
#define SetTransferMode(mode) SetReg(0x110C, mode)
/*
* Set graphics controller register (byte access)
*/
void SetReg(WORD index, BYTE value)
{
DisplaySetCommand(); // set RS line to low for command
DisplayEnable(); // enable SSD1926
DeviceWrite(((WORD_VAL) index).v[1]);
DeviceWrite(index << 8);
DisplaySetData(); // set RS line to high for data
if(index & 0x0001)
DeviceWrite(value);
else
DeviceWrite(value << 8);
DisplayDisable(); // disable SSD1926
}
/*
* Read graphics controller register value (byte access)
*/
BYTE GetReg(WORD index)
{
WORD value;
DisplaySetCommand(); // set RS line to low for command
DisplayEnable(); // enable SSD1926
DeviceWrite(((WORD_VAL) index).v[1]);
DeviceWrite(index << 8);
DisplaySetData(); // set RS line to high for data
value = DeviceRead();
value = DeviceRead();
DisplayDisable(); // disable SSD1926
if(index & 0x0001)
value &= 0x00ff;
else
value = (value >> 8) & 0x00ff;
return (value);
}
/*
* Helper Functions
*/
inline void __attribute__ ((always_inline))
SetCommandArgument(DWORD arg)
{
SetReg(0x110B, ((DWORD_VAL) arg).v[3]);
SetReg(0x110A, ((DWORD_VAL) arg).v[2]);
SetReg(0x1109, ((DWORD_VAL) arg).v[1]);
SetReg(0x1108, ((DWORD_VAL) arg).v[0]);
}
inline void __attribute__ ((always_inline))
SetCommand(BYTE idx, BYTE flags)
{
SetReg(0x110E, flags); //set response type
SetReg(0x110F, idx); //command index
}
inline volatile DWORD __attribute__ ((always_inline))
GetCommandResponse(BYTE idx)
{
DWORD_VAL rsp;
idx <<= 2;
rsp.v[0] = GetReg(0x1110 + idx);
rsp.v[1] = GetReg(0x1111 + idx);
rsp.v[2] = GetReg(0x1112 + idx);
rsp.v[3] = GetReg(0x1113 + idx);
return (rsp.Val);
}
void ReadCmdResponse(DWORD *rsp, UINT size)
{
DWORD idx;
for(idx = 0; idx < size; idx++)
{
*rsp = GetCommandResponse(idx);
rsp++;
}
}
/*
* Global Variables
*/
DWORD finalLBA;
WORD sectorSize;
DWORD maxBusClock;
BYTE hcMode;
MEDIA_INFORMATION mediaInformation;
/*
* Local Prototypes
*/
BYTE SDInit(void);
BYTE SDSetClock(DWORD clockMax);
BYTE SDSendCommand(BYTE cmd_idx, BYTE flags, DWORD arg);
BYTE SDSendAppCommand(BYTE cmd_idx, BYTE flags, DWORD arg1, DWORD arg2);
void SDReset(BYTE type);
/*
* Function:
* BYTE SDSetClock(DWORD clockMax)
* Input:
* clockMax - SD card maximum frequency,
* Output:
* returns non-zero if the operation is successfull.
* Overview:
* Sets the SD card clock frequency close to clockMax
*/
BYTE SDSetClock(DWORD clockMax)
{
DWORD mclk;
BYTE reg;
BYTE div;
mclk = SSD_SYS_CLOCK * GetReg(SSD_REG_PLL_CONFIG1);
mclk /= (GetReg(SSD_REG_PLL_CONFIG0) & 0x1F);
mclk /= ((GetReg(SSD_REG_MCLK_CONIG) & 0x1F) + 1);
if(GetReg(SSD_REG_MCLK_CONIG) & 0x01)
mclk /= 2;
reg = GetReg(SSD_SDCARD_REG_CLK_CNTL);
reg = reg &~((BYTE) SSD_SD_CLK_ENABLE);
SetReg(SSD_SDCARD_REG_CLK_CNTL, reg);
reg |= SSD_SD_INT_CLK_ENABLE;
SetReg(SSD_SDCARD_REG_CLK_CNTL, reg);
DelayMs(1);
if(!(GetReg(SSD_SDCARD_REG_CLK_CNTL) & SSD_SD_INT_CLK_STABLE))
return (FALSE);
div = 0;
while(mclk > clockMax)
{
mclk >>= 1;
div++;
}
div = 1 << (div - 1);
SetReg(SSD_SDCARD_REG_CLK_DIV, div);
reg |= SSD_SD_CLK_ENABLE;
SetReg(SSD_SDCARD_REG_CLK_CNTL, reg);
return (TRUE);
}
/*
* Function:
* BYTE SDSendCommand(BYTE cmd_idx, BYTE flags, DWORD arg)
* Input:
* cmd_idx - command start index,
* flags - command flags,
* arg - command arguments.
* Output:
* Returns non-zero if the operation is successful
* Overview:
* Send SD card command.
*/
BYTE SDSendCommand(BYTE cmd_idx, BYTE flags, DWORD arg)
{
DWORD timeout;
SetReg(0x112E, 0x0E); // Data Timeout Counter Value = MCLK x 2^27
CheckCommandInhibit();
// Clear interrupt flags
SetReg(0x1130, 0xff);
// Enable command complete interrupt
SetReg(0x1134, GetReg(0x1134) | 0x01);
// Clear error interrupt flags
SetReg(0x1132, 0xff);
SetReg(0x1133, 0xff);
// Enable all interrupts
SetReg(0x1136, 0xff);
SetReg(0x1137, 0xff);
SetCommandArgument(arg);
SetCommand(cmd_idx, flags);
timeout = SD_TIMEOUT;
while(1)
{
if(GetReg(0x1130) & 0x01)
{
break;
}
if(!timeout--)
{
return (FALSE);
}
}
return (TRUE);
}
/*
* Function:
* BYTE SDSendAppCommand(BYTE cmd_idx, BYTE flags, DWORD arg1, DWORD arg2)
* Input:
* cmd_idx - command start index,
* flags - command flags,
* arg1 - application command arguments 1
* arg2 - application command arguments 2
* Output:
* Returns non-zero if the operation is successful
* Overview:
* Send SD card application command.
*/
BYTE SDSendAppCommand(BYTE cmd_idx, BYTE flags, DWORD arg1, DWORD arg2)
{
if(!SDSendCommand(CMD_APP_CMD, SSD_RESPONSE_48, arg1))
return (FALSE);
if(!SDSendCommand(cmd_idx, flags, arg2))
return (FALSE);
return (TRUE);
}
/*
* Function:
* void SDReset(BYTE type)
* Input:
* type - type of reset.
* Overview:
* Resets the SD card module
*/
void SDReset(BYTE type)
{
DWORD timeout;
SetReg(SSD_SDCARD_REG_SW_RESET, type);
timeout = SD_TIMEOUT;
while(1)
{
if(!timeout--)
return;
if(!(GetReg(SSD_SDCARD_REG_SW_RESET) & type))
return;
}
}
/*
* Function:
* void SDPower(BYTE on)
* Input:
* on - '0' means off, '1' means on.
* Overview:
* Powers on the SD card.
*/
void SDPower(BYTE on)
{
if(on)
SetReg(SSD_SDCARD_REG_PWR_CNTL, 0x0F);
else
SetReg(SSD_SDCARD_REG_PWR_CNTL, 0x0E);
}
/*
* Function:
* BYTE SDDetect(void)
* Output:
* TRUE - card detected,
* FALSE - no card detected.
* Overview:
* Detects if the SD card is inserted.
*/
BYTE SDDetect(void)
{
BYTE reg;
reg = GetReg(SSD_SDCARD_REG_PRSNT_STATE_2);
if(!(reg & SSD_CARD_DETECT))
return (FALSE);
if(reg & SSD_CARD_INSERTED)
{
DWORD timeout;
timeout = SD_TIMEOUT;
while(1)
{
if(!timeout--)
return (FALSE);
if(GetReg(SSD_SDCARD_REG_PRSNT_STATE_2) & SSD_CARD_STABLE)
break;
}
}
else
return (FALSE);
return (TRUE);
}
/*
* Function:
* BYTE SDWriteProtectState(void)
* Output:
* Returns the status of the "write enabled" pin.
* Overview:
* Determines if the card is write-protected.
*/
BYTE SDWriteProtectState(void)
{
return (GetReg(SSD_SDCARD_REG_PRSNT_STATE_2) & SSD_WRITE_PROTECT);
}
/*
* Function:
* BYTE SDInit(void)
* Output:
* Returns TRUE if media is initialized, FALSE otherwise.
* Overview:
* MediaInitialize initializes the media card and supporting variables.
*/
BYTE SDInit(void)
{
DWORD timeout;
DWORD response;
DWORD voltage;
DWORD CSD_C_SIZE;
DWORD CSD_C_SIZE_MULT;
DWORD CSD_RD_BL_LEN;
DWORD RCA;
DWORD CSD[4];
if(!SDSendCommand(CMD_RESET, SSD_NO_RESPONSE, 0xFFFFFFFF))
return (FALSE);
if(!SDSendCommand(CMD_SEND_IF_COND, SSD_RESPONSE_48 | SSD_CMD_CRC_CHK | SSD_CMD_IDX_CHK, 0x000001AA))
return (FALSE);
response = GetCommandResponse(0);
if(response == 0x000001AA)
{
voltage = 0x40200000;
hcMode = 1;
}else{
voltage = 0x00200000;
hcMode = 0;
}
timeout = 10;
do
{
if(!timeout--)
{
return (FALSE);
}
SDReset(SSD_RESET_DATA|SSD_RESET_CMD);
if(!SDSendAppCommand(ACMD_SEND_OCR, SSD_RESPONSE_48, 0, voltage))
return (FALSE); // ask card send OCR back
DelayMs(150);
response = GetCommandResponse(0);
} while((response&0x80000000) == 0);
if((response&0x40000000L) == 0){
hcMode = 0;
}
if(!SDSendCommand(CMD_SEND_ALL_CID, SSD_RESPONSE_136 | SSD_CMD_CRC_CHK, 0xFFFFFFFF))
return (FALSE);
DelayMs(150);
if(!SDSendCommand(CMD_SEND_RCA, SSD_RESPONSE_48 | SSD_CMD_CRC_CHK | SSD_CMD_IDX_CHK, 0xFFFFFFFF))
return (FALSE);
RCA = GetCommandResponse(0);
RCA |= 0x0000ffff;
//CMD9 - Request CSD from SD Card
if(!SDSendCommand(CMD_SEND_CSD, SSD_CMD_IDX_CHK | SSD_CMD_CRC_CHK | SSD_RESPONSE_136, RCA))
return (FALSE);
ReadCmdResponse(CSD, 4);
CSD_C_SIZE = ((CSD[2] & 0x00000003) << 10) | ((CSD[1] & 0xFFC00000) >> 22); //CSD Bit[73:62] => Bit[65:54] (Deduct CRC-7 as CRC-7 is not stored in response register)
CSD_C_SIZE_MULT = ((CSD[1] & 0x00000380) >> 7); //CSD Bit[49:47] =? Bit[41:39]
CSD_RD_BL_LEN = (CSD[2] & 0x00000F00) >> 8; //CSD Bit[83:80] -> Bit[75:72]
finalLBA = (CSD_C_SIZE + 1) * (1 << (CSD_C_SIZE_MULT + 2));
sectorSize = (1 << CSD_RD_BL_LEN);
if((CSD[3] & 0x000000FF) == 0x32)
maxBusClock = 25000000; // 25MHz
else
maxBusClock = 25000000; // 50MHz
SDReset(SSD_RESET_CMD);
//CMD7 Select Card
if(!SDSendCommand(CMD_SELECT_CARD, SSD_RESPONSE_48_BUSY | SSD_CMD_CRC_CHK | SSD_CMD_IDX_CHK, RCA))
return (FALSE);
sectorSize = 512L;
//CMD16 Set the block size.
if(!SDSendCommand(CMD_SET_BLKLEN, SSD_RESPONSE_48 | SSD_CMD_CRC_CHK | SSD_CMD_IDX_CHK, sectorSize))
return (FALSE);
//CMD55 + ACMD6 Set bus width = 4 Bit
if(!SDSendAppCommand(ACMD_SET_BUS_WIDTH, SSD_RESPONSE_48 | SSD_CMD_CRC_CHK | SSD_CMD_IDX_CHK, RCA, 0xFFFFFFFE))
return (FALSE);
//Data width 4bits
SetReg(0x1128, 0x02);
return (TRUE);
}
/*
* Function:
* INT32 SDGetStatus(void)
* Output:
* SD card status.
* Overview:
* Returns SD card status. If the returned value is -1 the there's an error.
*/
INT32 SDGetStatus(void)
{
DWORD status;
DWORD RCA;
SDReset(SSD_RESET_CMD);
//Normal interrupt handling
SetReg(0x1134, GetReg(0x1134) | 0x01); //enable read interrupt
SetReg(0x1130, 0x01); //clear previous interrupt
//Error interrupt handling
SetReg(0x1136, GetReg(0x1136) | 0x8F); //enable error interrupt
SetReg(0x1137, GetReg(0x1137) | 0x71); //enable error interrupt
SetReg(0x1132, 0x8F); //enable error interrupt
SetReg(0x1133, 0x71); //enable error interrupt
if(!SDSendCommand(CMD_SEND_RCA, SSD_RESPONSE_48 | SSD_CMD_CRC_CHK | SSD_CMD_IDX_CHK, 0xFFFFFFFF))
return (DWORD) (-1);
RCA = GetCommandResponse(0);
RCA |= 0x0000ffff;
if(!SDSendCommand(CMD_SEND_STATUS, SSD_RESPONSE_48 | SSD_CMD_CRC_CHK | SSD_CMD_IDX_CHK, RCA))
return (DWORD) (-1);
while(!(GetReg(0x1130) & 0x01));
//check cmd complt int
SetReg(0x1130, 0x01); //clear previous int
while((GetReg(0x1132) & 0x8F) || (GetReg(0x1133) & 0x71));
SetReg(0x1132, 0x8F); //enable error interrupt
SetReg(0x1133, 0x71); //enable error interrupt
ReadCmdResponse(&status, 1);
return (status);
}
/*
* Function:
* MEDIA_INFORMATION* SDInitialize(void)
* Output:
* Returns a pointer to the media inforamtion structure.
* Overview:
* SDInitialize initializes the media card and supporting variables.
* Sets maximum clock frequency for the SD card.
*/
MEDIA_INFORMATION *SDInitialize(void)
{
DWORD timeout;
SDReset(SSD_RESET_DATA | SSD_RESET_CMD | SSD_RESET_ALL);
SDPower(TRUE);
mediaInformation.errorCode = MEDIA_NO_ERROR;
mediaInformation.validityFlags.value = 0;
if(!SDSetClock(SSD_SD_CLK_INIT))
{
mediaInformation.errorCode = MEDIA_DEVICE_NOT_PRESENT;
return (&mediaInformation);
}
timeout = 10;
while(!SDInit())
{
if(!timeout--)
{
mediaInformation.errorCode = MEDIA_DEVICE_NOT_PRESENT;
return (&mediaInformation);
}
}
mediaInformation.validityFlags.bits.sectorSize = 1;
mediaInformation.sectorSize = sectorSize;
if(!SDSetClock(maxBusClock>>1))
mediaInformation.errorCode = MEDIA_DEVICE_NOT_PRESENT;
return (&mediaInformation);
}
/*
* Function: BYTE SDSectorRead(DWORD sector_addr, BYTE *buffer)
*
* Input: sector_addr - Sector address
* buffer - Buffer where data will be stored, see
* 'ram_acs.h' for 'block' definition.
* 'Block' is dependent on whether internal or
* external memory is used
*
* Output: Returns TRUE if read successful, false otherwise
*
* Overview: SectorRead reads data from the card starting
* at the sector address specified by sector_addr and stores
* them in the location pointed to by 'buffer'.
*
* Note: The device expects the address field in the command packet
* to be byte address. Therefore the sector_addr must first
* be converted to byte address.
*/
BYTE SDSectorRead(DWORD sector_addr, BYTE *buffer)
{
if(!hcMode)
{
sector_addr *= sectorSize;
}
CheckDataInhibit();
SDReset(SSD_RESET_DATA);
SetTransferMode(0x10);
// Block size is one sector
SetReg(0x1104, ((WORD_VAL) sectorSize).v[0]); // write block size
SetReg(0x1105, ((WORD_VAL) sectorSize).v[1]); // write block size
//Clear error interrupt flags
SetReg(0x1136, 0xff);
SetReg(0x1137, 0xff);
SetReg(0x1132, 0xff);
SetReg(0x1133, 0xff);
// Buffer Read Ready, Transfer Complete, Command Complete interrupts enable
SetReg(0x1134, 0x23);
// Clear previous interrupt flags
SetReg(0x1130, 0x23);
// Send command
if
(
!SDSendCommand
(
CMD_RD_SINGLE,
SSD_RESPONSE_48 | SSD_DATA_PRESENT | SSD_CMD_CRC_CHK | SSD_CMD_IDX_CHK,
sector_addr
)
) return (FALSE);
// Wait for transfer complete
while(!(GetReg(0x1130) & 0x20));
// Clear transfer complete flag
SetReg(0x1130, 0x20);
// Read data
WORD counter = 0;
while(GetReg(0x1125) & 0x08)
{
if(counter < sectorSize)
*buffer++ = GetDataPortReg0();
counter++;
}
if(counter > sectorSize)
return (FALSE);
return (TRUE);
}
/*
* Function:
* BYTE SDSectorDMARead(DWORD sector_addr, DWORD dma_addr, UINT16 num_blk)
* Input:
* sector_addr - Sector address
* buffer - Buffer where data will be stored, see
* 'ram_acs.h' for 'block' definition.
* 'Block' is dependent on whether internal or
* external memory is used
*
* Output:
* Returns TRUE if read successful, false otherwise.
* Overview: SectorRead reads data from the card starting
* at the sector address specified by sector_addr and stores
* them in the location pointed to by 'buffer'.
*
* Note: The device expects the address field in the command packet
* to be byte address. Therefore the sector_addr must first
* be converted to byte address.
*/
BYTE SDSectorDMARead(DWORD sector_addr, DWORD dma_addr, UINT16 num_blk)
{
DWORD dma_size;
BYTE boundary;
if(!hcMode)
{
sector_addr *= sectorSize;
}
CheckDataInhibit();
SDReset(SSD_RESET_DATA);
// set up the DMA address
SetReg(0x1100, ((DWORD_VAL) dma_addr).v[0]);
SetReg(0x1101, ((DWORD_VAL) dma_addr).v[1]);
SetReg(0x1102, ((DWORD_VAL) dma_addr).v[2]);
SetReg(0x1103, ((DWORD_VAL) dma_addr).v[3]);
// set up the transefer mode (Multi-Blk, Read, Blk Cnt, DMA)
SetTransferMode(0x33);
// set up the DMA buffer size (4k) and sector block size
dma_size = (DWORD) num_blk * sectorSize;
dma_size >>= 12;
boundary = 0;
while(dma_size)
{
dma_size >>= 1;
boundary++;
}
boundary <<= 4;
boundary |= ((WORD_VAL) sectorSize).v[1] & 0x0F;
SetReg(0x1104, ((WORD_VAL) sectorSize).v[0]); // write block size
SetReg(0x1105, boundary); // write block size
// Set the number of blocks to read
SetReg(0x1106, (BYTE) (num_blk & 0xFF)); // write block size
SetReg(0x1107, (BYTE) (num_blk >> 8)); // write block size
// set up the normal status register 0
SetReg(0x1134, 0x0B); // enable read interrupt
SetReg(0x1130, GetReg(0x1130) | 0x0B); // clear previous interrupt
// set up the error status register
SetReg(0x1136, 0xFF); // clear previous interrupt
SetReg(0x1132, 0xFF); // clear previous interrupt
SetReg(0x1133, 0x01); // clear previous interrupt
SetReg(0x1130, 0x08); // clear previous interrupt
// set the command to read multiple blocks
if
(
!SDSendCommand
(
CMD_RD_MULTIPLE,
SSD_RESPONSE_48 | SSD_DATA_PRESENT | SSD_CMD_CRC_CHK | SSD_CMD_IDX_CHK,
sector_addr
)
) return (FALSE);
// wait until the dma transfer is done
while(!(GetReg(0x1130) & 0x08) && (GetReg(0x1125) & 0x02));
SetReg(0x1130, 0x08);
// stop the transmission
if
(
!SDSendCommand
(
CMD_STOP_TRANSMISSION,
SSD_CMD_TYPE_ABORT | SSD_RESPONSE_48_BUSY | SSD_CMD_CRC_CHK | SSD_CMD_IDX_CHK,
0xFFFFFFFF
)
) return (FALSE);
SetReg(0x1130, 0x01); //clear previous interrupt
SetReg(0x1106, 0); // write block size
SetReg(0x1107, 0); // write block size
// disable the transfer mode
SetTransferMode(0);
return (TRUE);
}
/*
* Function: BYTE SDSectorWrite(DWORD sector_addr, BYTE *buffer, BYTE allowWriteToZero)
*
* Input: sector_addr - Sector address
* buffer - Buffer where data will be read
* allowWriteToZero - If true, writes to the MBR will be valid
*
* Output: Returns TRUE if write successful, FALSE otherwise
*
* Overview: SectorWrite sends data from the location
* pointed to by 'buffer' to the card starting
* at the sector address specified by sector_addr.
*
* Note: The sample device expects the address field in the command packet
* to be byte address. Therefore the sector_addr must first
* be converted to byte address.
*/
BYTE SDSectorWrite(DWORD sector_addr, BYTE *buffer, BYTE allowWriteToZero)
{
UINT16 i;
if(!hcMode)
{
sector_addr *= sectorSize;
}
CheckDataInhibit();
SDReset(SSD_RESET_DATA);
SetTransferMode(0);
SetReg(0x1104, ((WORD_VAL) sectorSize).v[0]); // write block size
SetReg(0x1105, ((WORD_VAL) sectorSize).v[1]); // write block size
//Clear error interrupt flags
SetReg(0x1136, 0xff);
SetReg(0x1137, 0xff);
SetReg(0x1132, 0xff);
SetReg(0x1133, 0xff);
//Normal interrupt handling
SetReg(0x1134, 0x13); //enable write interrupt
SetReg(0x1130, 0x13); //clear all type of normal interrupt
if
(
!SDSendCommand
(
CMD_WR_SINGLE,
SSD_RESPONSE_48 | SSD_DATA_PRESENT | SSD_CMD_CRC_CHK | SSD_CMD_IDX_CHK,
sector_addr
)
) return (FALSE);
SetReg(0x1130, 0x01); //clear previous interrupt
while(!(GetReg(0x1130)&0x10) && !(GetReg(0x1125) & 0x04)); //check Buffer write int
SetReg(0x1130, 0x10); //clear previous interrupt
for(i = 0; i < sectorSize; i++)
{
//check if Write Enable bit set, which mean buffer is free for new data
while(!(GetReg(0x1125) & 0x04));
//put data that need be written into SSD1928 buffers
SetDataPortReg0(*buffer++);
}
SetReg(0x1130, 0x10); //clear previous interrupt
while(!(GetReg(0x1130)&0x02)); //check Transfer complt int
SetReg(0x1130, 0x02); // clear previous interrupt
return (TRUE);
}
/*
* Function:
* WORD SDReadSectorSize(void)
* PreCondition:
* MediaInitialize() is complete
* Output:
* Size of the sectors for this physical media.
* Overview:
* Returns size of the sectors for this physical media.
*/
WORD SDReadSectorSize(void)
{
return (sectorSize);
}
/*
* Function:
* DWORD SDReadCapacity(void)
* PreCondition:
* MediaInitialize() is complete
* Output:
* Number of sectors.
* Overview:
* Returns number of sectors.
*/
DWORD SDReadCapacity(void)
{
return (finalLBA);
}

View File

@@ -1,157 +0,0 @@
/*
* SSD1926 hardware definitions
*
* Copyright (C) 2008 Microchip Technology Inc. All rights reserved.
* Microchip licenses to you the right to use, modify, copy and distribute
* Software only when embedded on a Microchip microcontroller or digital
* signal controller, which is integrated into your product or third party
* product (pursuant to the sublicense terms in the accompanying license
* agreement).
*
* You should refer to the license agreement accompanying this Software
* for additional information regarding your rights and obligations.
*
* SOFTWARE AND DOCUMENTATION ARE PROVIDED 'AS IS' WITHOUT WARRANTY OF ANY
* KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY WARRANTY
* OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR
* PURPOSE. IN NO EVENT SHALL MICROCHIP OR ITS LICENSORS BE LIABLE OR
* OBLIGATED UNDER CONTRACT, NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION,
* BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT
* DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL,
* INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA,
* COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY
* CLAIMS BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF),
* OR OTHER SIMILAR COSTS.
*
* Author Date Comments
* -----------------------------------------------------
* Sean Justice 15_Sept-2008 First release
* Anton Alkhimenok 06_Jun-2009 Ported to PIC24
*/
#ifndef _SSD1926_H
#define _SSD1926_H
/*
* User Defines
*/
#define SSD_SYS_CLOCK (DWORD) (4000000) /* SSD1926 crystal frequncy */
#define SSD_SD_CLK_INIT (DWORD) (400000)
#define SD_TIMEOUT (DWORD) (3000000)
/*
* Registers
*/
#define SSD_REG_PLL_CONFIG0 0x0126
#define SSD_REG_PLL_CONFIG1 0x0127
#define SSD_REG_MCLK_CONIG 0x0004
#define SSD_SDCARD_SD_CLK 0x1001
#define SSD_SDCARD_REG_DMA_ADDR 0x1100
#define SSD_SDCARD_REG_BLK_SIZE 0x1104
#define SSD_SDCARD_REG_BLK_CNT 0x1106
#define SSD_SDCARD_REG_ARG_32BIT 0x1108
#define SSD_SDCARD_REG_XFR_MODE 0x110c
#define SSD_SDCARD_REG_CMD 0x110e
#define SSD_SDCARD_REG_RSP 0x1110
#define SSD_SDCARD_REG_DATA_PORT 0x1120
#define SSD_SDCARD_REG_RSVD1 0x1121
#define SSD_SDCARD_REG_PRSNT_STATE_0 0x1124
#define SSD_SDCARD_REG_PRSNT_STATE_1 0x1125
#define SSD_SDCARD_REG_PRSNT_STATE_2 0x1126
#define SSD_SDCARD_REG_PRSNT_STATE_3 0x1127
#define SSD_SDCARD_REG_HST_CNTL 0x1128
#define SSD_SDCARD_REG_PWR_CNTL 0x1129
#define SSD_SDCARD_REG_BLK_GAP_CNTL 0x112a
#define SSD_SDCARD_REG_WKUP_CNTL 0x112b
#define SSD_SDCARD_REG_CLK_CNTL 0x112c
#define SSD_SDCARD_REG_CLK_DIV 0x112d
#define SSD_SDCARD_REG_TOUT_CNTL 0x112e
#define SSD_SDCARD_REG_SW_RESET 0x112f
#define SSD_SDCARD_REG_NRM_INTR_STATUS 0x1130
#define SSD_SDCARD_REG_ERR_INTR_STATUS 0x1132
#define SSD_SDCARD_REG_NRM_INTR_STATUS_EN 0x1134
#define SSD_SDCARD_REG_ERR_INTR_STATUS_EN 0x1136
#define SSD_SDCARD_REG_NRM_INTR_SIG_EN 0x1138
#define SSD_SDCARD_REG_ERR_INTR_SIG_EN 0x113a
#define SSD_SDCARD_REG_ACMD12_ERR_STATUS 0x113c
#define SSD_SDCARD_REG_RSVD2 0x113e
#define SSD_SDCARD_REG_CAPABILITIES 0x1140
#define SSD_SDCARD_REG_CAP_RSVD 0x1144
#define SSD_SDCARD_REG_MAX_CURR_CAP 0x1148
#define SSD_SDCARD_REG_MAX_CURR_CAP_RSVD 0x114c
#define SSD_SDCARD_REG_RSVD3 0x1150
#define SSD_SDCARD_REG_SLOT_INTR_STATUS 0x11fc
#define SSD_SDCARD_REG_HCVER 0x11fe
/*
* SD Commands
*/
#define CMD_RESET 0
#define CMD_SEND_OCR 1 // used exclusively in MMC
#define CMD_SEND_ALL_CID 2 // R2: R136
#define CMD_SEND_RCA 3 // R1 (MMC) or R6(SDMEM)
#define CMD_SET_DSR 4
#define CMD_IO_SEND_OCR 5 // R4, unique to IO cards
#define CMD_SELECT_CARD 7 // R1, arg=rca[31..16] or 0
#define CMD_SEND_IF_COND 8
#define CMD_SEND_CSD 9 // R2: R136
#define CMD_SEND_CID 10 // R2: R136
#define CMD_STOP_TRANSMISSION 12 // R1b: arg=stuff bits
#define CMD_SEND_STATUS 13 // R1
#define CMD_GO_INACTIVE 15 // None, arg=rca[31..16], stuff[15..0]
#define CMD_SET_BLKLEN 16 // R1, arg=block len[31..0]
#define CMD_RD_SINGLE 17 // R1, arg=block address[31..0]
#define CMD_RD_MULTIPLE 18 // R1, arg=block address[31..0]
#define CMD_WR_SINGLE 24 // R1, arg=block address[31..0]
#define CMD_WR_MULTIPLE 25 // R1, arg=block address[31..0]
#define CMD_SET_WP 28 // R1b, arg=wp address[31..0]
#define CMD_CLR_WP 29 // R1b, arg=wp address[31..0]
#define CMD_SEND_WP 30 // R1, DATA, arg=wp address[31..0]
#define CMD_ERASE_SADDR 32 // R1, arg=block address[31..0]
#define CMD_ERASE_EADDR 33 // R1, arg=block address[31..0]
#define CMD_ERASE_GRP_SADDR 35 // R1, arg=block address[31..0]
#define CMD_ERASE_GRP_EADDR 36 // R1, arg=block address[31..0]
#define CMD_ERASE 38 // R1b, arg=stuff bits[31..0]
#define CMD_IO_RW_DIRECT 52 // R5
#define CMD_IO_RW_EXTENDED 53 // R1, data transfer
#define CMD_APP_CMD 55 // R1, arg=rca[31..16], stuff[15..0]
#define CMD_GEN_CMD 56 // R1, data, arg=stuff[31..1], RD/WR[0]
#define ACMD_SET_BUS_WIDTH 6 // R1, arg=[1..0] = bus width, [31:2] stuff bits
#define ACMD_SEND_STATUS 13 // R1, DATA, arg=stuff bits [31..0]
#define ACMD_SEND_NUM_WR_BLK 22 // R1, DATA, arg=stuff bits [31..0]
#define ACMD_SEND_OCR 41
#define ACMD_SEND_SCR 51 // R1, arg=stuff bits[31..0]
/*
* Flags
*/
#define SSD_SD_CLK_CTRL_ON (DWORD) 0x80000000
#define SSD_SD_CLK_ENABLE (DWORD) 0x00000004
#define SSD_SD_INT_CLK_STABLE (DWORD) 0x00000002
#define SSD_SD_INT_CLK_ENABLE (DWORD) 0x00000001
#define SSD_SD_CLK_FLAGS (SSD_SD_CLK_CTRL_ON | SSD_SD_CLK_ENABLE | SSD_SD_INT_CLK_ENABLE)
#define SSD_CMD_TYPE_ABORT 0xC0
#define SDD_CMD_TYPE_RESUME 0x80
#define SDD_CMD_TYPE_SUSPEND 0x40
#define SDD_CMD_TYPE_NORMAL 0x00
#define SSD_DATA_PRESENT 0x20
#define SSD_CMD_IDX_CHK 0x10
#define SSD_CMD_CRC_CHK 0x08
#define SSD_NO_RESPONSE 0x00
#define SSD_RESPONSE_136 0x01
#define SSD_RESPONSE_48 0x02
#define SSD_RESPONSE_48_BUSY 0x03
#define SSD_CARD_DETECT 0x04
#define SSD_CARD_STABLE 0x02
#define SSD_CARD_INSERTED 0x01
#define SSD_WRITE_PROTECT 0x08
#define SSD_RESET_ALL 0x01
#define SSD_RESET_CMD 0x02
#define SSD_RESET_DATA 0x04
#define WAIT_CNT (DWORD) 10000000l
#endif /* _SSD1926_H */