Eli Hughes
/
COMPACT_FLASH_2
FAT_FS/diskio.c@0:76427232f435, 2012-02-16 (annotated)
- Committer:
- emh203
- Date:
- Thu Feb 16 00:41:26 2012 +0000
- Revision:
- 0:76427232f435
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
emh203 | 0:76427232f435 | 1 | #include "mbed.h" |
emh203 | 0:76427232f435 | 2 | #include "LPC17xx.h" |
emh203 | 0:76427232f435 | 3 | #include "integer.h" |
emh203 | 0:76427232f435 | 4 | #include "diskio.h" |
emh203 | 0:76427232f435 | 5 | #include "stdarg.h" |
emh203 | 0:76427232f435 | 6 | #include "USBHost.h" |
emh203 | 0:76427232f435 | 7 | #include "Terminal.h" |
emh203 | 0:76427232f435 | 8 | |
emh203 | 0:76427232f435 | 9 | /*-------------------------------------------------------------------------- |
emh203 | 0:76427232f435 | 10 | |
emh203 | 0:76427232f435 | 11 | Module Private Functions |
emh203 | 0:76427232f435 | 12 | |
emh203 | 0:76427232f435 | 13 | ---------------------------------------------------------------------------*/ |
emh203 | 0:76427232f435 | 14 | |
emh203 | 0:76427232f435 | 15 | static volatile DSTATUS Stat[3] = {STA_NOINIT | STA_NODISK}; /* Disk status */ |
emh203 | 0:76427232f435 | 16 | static volatile BYTE DiskProcTimer[3]={0}; /* 100Hz decrement timer */ |
emh203 | 0:76427232f435 | 17 | |
emh203 | 0:76427232f435 | 18 | |
emh203 | 0:76427232f435 | 19 | |
emh203 | 0:76427232f435 | 20 | |
emh203 | 0:76427232f435 | 21 | |
emh203 | 0:76427232f435 | 22 | BYTE RAM_DISK[512]; |
emh203 | 0:76427232f435 | 23 | |
emh203 | 0:76427232f435 | 24 | DWORD BlockSize; |
emh203 | 0:76427232f435 | 25 | DWORD BlockCount; |
emh203 | 0:76427232f435 | 26 | |
emh203 | 0:76427232f435 | 27 | //#define _CF_DEBUG_MESSAGES |
emh203 | 0:76427232f435 | 28 | //#define _CF_DEBUG_READ_ATA |
emh203 | 0:76427232f435 | 29 | |
emh203 | 0:76427232f435 | 30 | #ifdef _CF_DEBUG_MESSAGES |
emh203 | 0:76427232f435 | 31 | #define CF_DEBUG(...) printf(__VA_ARGS__) |
emh203 | 0:76427232f435 | 32 | #else |
emh203 | 0:76427232f435 | 33 | #define CF_DEBUG do{}while(0); |
emh203 | 0:76427232f435 | 34 | #endif |
emh203 | 0:76427232f435 | 35 | |
emh203 | 0:76427232f435 | 36 | void disk_timerproc (void); |
emh203 | 0:76427232f435 | 37 | |
emh203 | 0:76427232f435 | 38 | #define LED1_MASK (uint32_t )(1<<18) |
emh203 | 0:76427232f435 | 39 | #define LED2_MASK (uint32_t )(1<<20) |
emh203 | 0:76427232f435 | 40 | #define LED3_MASK (uint32_t )(1<<21) |
emh203 | 0:76427232f435 | 41 | #define LED4_MASK (uint32_t )(1<<23) |
emh203 | 0:76427232f435 | 42 | |
emh203 | 0:76427232f435 | 43 | |
emh203 | 0:76427232f435 | 44 | #define LED1_ON LPC_GPIO1->FIOSET=LED1_MASK |
emh203 | 0:76427232f435 | 45 | #define LED1_OFF LPC_GPIO1->FIOCLR=LED1_MASK |
emh203 | 0:76427232f435 | 46 | #define LED1_TOGGLE LPC_GPIO1->FIOPIN^=LED1_MASK |
emh203 | 0:76427232f435 | 47 | |
emh203 | 0:76427232f435 | 48 | #define LED2_ON LPC_GPIO1->FIOSET=LED2_MASK |
emh203 | 0:76427232f435 | 49 | #define LED2_OFF LPC_GPIO1->FIOCLR=LED2_MASK |
emh203 | 0:76427232f435 | 50 | #define LED2_TOGGLE LPC_GPIO1->FIOPIN^=LED2_MASK |
emh203 | 0:76427232f435 | 51 | |
emh203 | 0:76427232f435 | 52 | #define LED3_ON LPC_GPIO1->FIOSET=LED3_MASK |
emh203 | 0:76427232f435 | 53 | #define LED3_OFF LPC_GPIO1->FIOCLR=LED3_MASK |
emh203 | 0:76427232f435 | 54 | #define LED3_TOGGLE LPC_GPIO1->FIOPIN^=LED3_MASK |
emh203 | 0:76427232f435 | 55 | |
emh203 | 0:76427232f435 | 56 | #define LED4_ON LPC_GPIO1->FIOSET=LED4_MASK |
emh203 | 0:76427232f435 | 57 | #define LED4_OFF LPC_GPIO1->FIOCLR=LED4_MASK |
emh203 | 0:76427232f435 | 58 | #define LED4_TOGGLE LPC_GPIO1->FIOPIN^=LED4_MASK |
emh203 | 0:76427232f435 | 59 | |
emh203 | 0:76427232f435 | 60 | |
emh203 | 0:76427232f435 | 61 | |
emh203 | 0:76427232f435 | 62 | //8-bit Data Bus is on Pins P0.4 - P0.11 |
emh203 | 0:76427232f435 | 63 | #define DATA_BUS_MASK (uint32_t )((0xFF)<<4) |
emh203 | 0:76427232f435 | 64 | |
emh203 | 0:76427232f435 | 65 | //3 bit address is on Port 2.0 - 2.2 |
emh203 | 0:76427232f435 | 66 | #define ADDRESS_BUS_MASK (uint32_t )(0x7) |
emh203 | 0:76427232f435 | 67 | |
emh203 | 0:76427232f435 | 68 | //ChipSelects are on port 2 |
emh203 | 0:76427232f435 | 69 | #define CS0_MASK (uint32_t )(1<<3) |
emh203 | 0:76427232f435 | 70 | #define CS1_MASK (uint32_t )(1<<4) |
emh203 | 0:76427232f435 | 71 | |
emh203 | 0:76427232f435 | 72 | //IORD and IOWR are on port 0 |
emh203 | 0:76427232f435 | 73 | #define IORD_MASK (uint32_t )(1<<24) |
emh203 | 0:76427232f435 | 74 | #define IOWR_MASK (uint32_t )(1<<23) |
emh203 | 0:76427232f435 | 75 | |
emh203 | 0:76427232f435 | 76 | |
emh203 | 0:76427232f435 | 77 | //Reset and power enable are on port 1 |
emh203 | 0:76427232f435 | 78 | #define COMPACT_FLASH_RESET_MASK (uint32_t )(1<<30) |
emh203 | 0:76427232f435 | 79 | #define COMPACT_FLASH_POWER_ENABLE_MASK (uint32_t )(0x80000000) |
emh203 | 0:76427232f435 | 80 | //Card Detect is on Port 2 |
emh203 | 0:76427232f435 | 81 | #define COMPACT_FLASH_CARD_DETECT_MASK (uint32_t )(1<<5) |
emh203 | 0:76427232f435 | 82 | |
emh203 | 0:76427232f435 | 83 | //Low Level Bus Operation Macros |
emh203 | 0:76427232f435 | 84 | //Note: LPC 176x have dedicate set and clear registers |
emh203 | 0:76427232f435 | 85 | |
emh203 | 0:76427232f435 | 86 | #define SET_DATA_BUS_TO_INPUTS LPC_GPIO0->FIODIR &= ~(DATA_BUS_MASK); |
emh203 | 0:76427232f435 | 87 | #define SET_DATA_BUS_TO_OUTPUT LPC_GPIO0->FIODIR |= (DATA_BUS_MASK); |
emh203 | 0:76427232f435 | 88 | |
emh203 | 0:76427232f435 | 89 | #define CS0_ACTIVE LPC_GPIO2->FIOCLR = CS0_MASK |
emh203 | 0:76427232f435 | 90 | #define CS0_INACTIVE LPC_GPIO2->FIOSET = CS0_MASK |
emh203 | 0:76427232f435 | 91 | #define CS1_ACTIVE LPC_GPIO2->FIOCLR = CS1_MASK |
emh203 | 0:76427232f435 | 92 | #define CS1_INACTIVE LPC_GPIO2->FIOSET = CS1_MASK |
emh203 | 0:76427232f435 | 93 | |
emh203 | 0:76427232f435 | 94 | #define IORD_ACTIVE LPC_GPIO0->FIOCLR = IORD_MASK |
emh203 | 0:76427232f435 | 95 | #define IORD_INACTIVE LPC_GPIO0->FIOSET = IORD_MASK |
emh203 | 0:76427232f435 | 96 | |
emh203 | 0:76427232f435 | 97 | #define IOWR_ACTIVE LPC_GPIO0->FIOCLR = IOWR_MASK |
emh203 | 0:76427232f435 | 98 | #define IOWR_INACTIVE LPC_GPIO0->FIOSET = IOWR_MASK |
emh203 | 0:76427232f435 | 99 | |
emh203 | 0:76427232f435 | 100 | #define COMPACT_FLASH_RESET_ACTIVE LPC_GPIO1->FIOCLR = COMPACT_FLASH_RESET_MASK |
emh203 | 0:76427232f435 | 101 | #define COMPACT_FLASH_RESET_INACTIVE LPC_GPIO1->FIOSET = COMPACT_FLASH_RESET_MASK |
emh203 | 0:76427232f435 | 102 | |
emh203 | 0:76427232f435 | 103 | #define COMPACT_FLASH_POWER_ENABLE LPC_GPIO1->FIOCLR = COMPACT_FLASH_POWER_ENABLE_MASK |
emh203 | 0:76427232f435 | 104 | #define COMPACT_FLASH_POWER_DISABLE LPC_GPIO1->FIOSET = COMPACT_FLASH_POWER_ENABLE_MASK |
emh203 | 0:76427232f435 | 105 | |
emh203 | 0:76427232f435 | 106 | #define COMPACT_FLASH_CARD_DETECTED (!((LPC_GPIO2->FIOPIN)&COMPACT_FLASH_CARD_DETECT_MASK)) |
emh203 | 0:76427232f435 | 107 | |
emh203 | 0:76427232f435 | 108 | //To set the Address and Data Bus Lines we will use the convient Mask register in the Port I/O modules |
emh203 | 0:76427232f435 | 109 | //The Hardware will mask out pins that are set to 1 in the MASK register |
emh203 | 0:76427232f435 | 110 | |
emh203 | 0:76427232f435 | 111 | #define SET_CF_ADDRESS(ADDRESS) LPC_GPIO2->FIOMASK=~(ADDRESS_BUS_MASK); \ |
emh203 | 0:76427232f435 | 112 | LPC_GPIO2->FIOPIN=ADDRESS; \ |
emh203 | 0:76427232f435 | 113 | LPC_GPIO2->FIOMASK=0 //Always remember to reset the mask for other operations to complete correctly |
emh203 | 0:76427232f435 | 114 | |
emh203 | 0:76427232f435 | 115 | |
emh203 | 0:76427232f435 | 116 | #define SET_CF_DATA(DATA) LPC_GPIO0->FIOMASK=~(DATA_BUS_MASK); \ |
emh203 | 0:76427232f435 | 117 | LPC_GPIO0->FIOPIN=(((uint32_t)DATA)<<4); \ |
emh203 | 0:76427232f435 | 118 | LPC_GPIO0->FIOMASK=0 //Always remember to reset the mask for other operations to complete correctly |
emh203 | 0:76427232f435 | 119 | |
emh203 | 0:76427232f435 | 120 | #define GET_CF_DATA(DATA) LPC_GPIO0->FIOMASK=~(DATA_BUS_MASK); \ |
emh203 | 0:76427232f435 | 121 | (DATA) = (LPC_GPIO0->FIOPIN)>>4; \ |
emh203 | 0:76427232f435 | 122 | LPC_GPIO0->FIOMASK=0 //Always remember to reset the mask for other operations to complete correctly |
emh203 | 0:76427232f435 | 123 | |
emh203 | 0:76427232f435 | 124 | #define SET_DATA_BUS_AS_OUTPUTS LPC_GPIO0->FIODIR|=DATA_BUS_MASK |
emh203 | 0:76427232f435 | 125 | #define SET_DATA_BUS_AS_INPUTS LPC_GPIO0->FIODIR&=~DATA_BUS_MASK |
emh203 | 0:76427232f435 | 126 | |
emh203 | 0:76427232f435 | 127 | /* ATA command */ |
emh203 | 0:76427232f435 | 128 | #define CMD_RESET 0x08 /* DEVICE RESET */ |
emh203 | 0:76427232f435 | 129 | #define CMD_READ 0x20 /* READ SECTOR(S) */ |
emh203 | 0:76427232f435 | 130 | #define CMD_WRITE 0x30 /* WRITE SECTOR(S) */ |
emh203 | 0:76427232f435 | 131 | #define CMD_IDENTIFY 0xEC /* DEVICE IDENTIFY */ |
emh203 | 0:76427232f435 | 132 | #define CMD_SETFEATURES 0xEF /* SET FEATURES */ |
emh203 | 0:76427232f435 | 133 | |
emh203 | 0:76427232f435 | 134 | /* ATA register bit definitions */ |
emh203 | 0:76427232f435 | 135 | #define LBA 0xE0 |
emh203 | 0:76427232f435 | 136 | #define BUSY 0x80 |
emh203 | 0:76427232f435 | 137 | #define DRDY 0x40 |
emh203 | 0:76427232f435 | 138 | #define DF 0x20 |
emh203 | 0:76427232f435 | 139 | #define DRQ 0x08 |
emh203 | 0:76427232f435 | 140 | #define ERR 0x01 |
emh203 | 0:76427232f435 | 141 | #define SRST 0x40 |
emh203 | 0:76427232f435 | 142 | #define nIEN 0x20 |
emh203 | 0:76427232f435 | 143 | |
emh203 | 0:76427232f435 | 144 | /* Bit definitions for Control Port */ |
emh203 | 0:76427232f435 | 145 | #define CTL_READ 0x20 |
emh203 | 0:76427232f435 | 146 | #define CTL_WRITE 0x40 |
emh203 | 0:76427232f435 | 147 | #define CTL_RESET 0x80 |
emh203 | 0:76427232f435 | 148 | #define REG_DATA 0x0 |
emh203 | 0:76427232f435 | 149 | #define REG_ERROR 0x1 |
emh203 | 0:76427232f435 | 150 | #define REG_FEATURES 0x1 |
emh203 | 0:76427232f435 | 151 | #define REG_COUNT 0x2 |
emh203 | 0:76427232f435 | 152 | #define REG_SECTOR 0x3 |
emh203 | 0:76427232f435 | 153 | #define REG_CYLL 0x4 |
emh203 | 0:76427232f435 | 154 | #define REG_CYLH 0x5 |
emh203 | 0:76427232f435 | 155 | #define REG_DEV 0x6 |
emh203 | 0:76427232f435 | 156 | #define REG_COMMAND 0x7 |
emh203 | 0:76427232f435 | 157 | #define REG_STATUS 0x7 |
emh203 | 0:76427232f435 | 158 | #define REG_DEVCTRL 0xE |
emh203 | 0:76427232f435 | 159 | #define REG_ALTSTAT 0xE |
emh203 | 0:76427232f435 | 160 | |
emh203 | 0:76427232f435 | 161 | void InitCompactFlashInterface() |
emh203 | 0:76427232f435 | 162 | { |
emh203 | 0:76427232f435 | 163 | SET_DATA_BUS_AS_INPUTS; |
emh203 | 0:76427232f435 | 164 | |
emh203 | 0:76427232f435 | 165 | LPC_GPIO2->FIODIR |= ADDRESS_BUS_MASK | CS0_MASK | CS1_MASK; |
emh203 | 0:76427232f435 | 166 | LPC_GPIO2->FIODIR &=~(COMPACT_FLASH_CARD_DETECT_MASK); |
emh203 | 0:76427232f435 | 167 | LPC_GPIO1->FIODIR |= COMPACT_FLASH_RESET_MASK | COMPACT_FLASH_POWER_ENABLE_MASK | LED1_MASK | LED2_MASK | LED3_MASK | LED4_MASK; |
emh203 | 0:76427232f435 | 168 | LPC_GPIO0->FIODIR |= IORD_MASK | IOWR_MASK ; |
emh203 | 0:76427232f435 | 169 | |
emh203 | 0:76427232f435 | 170 | COMPACT_FLASH_RESET_ACTIVE; |
emh203 | 0:76427232f435 | 171 | COMPACT_FLASH_POWER_DISABLE; |
emh203 | 0:76427232f435 | 172 | CS0_INACTIVE; |
emh203 | 0:76427232f435 | 173 | CS1_INACTIVE; |
emh203 | 0:76427232f435 | 174 | |
emh203 | 0:76427232f435 | 175 | SysTick_Config(SystemCoreClock/100); |
emh203 | 0:76427232f435 | 176 | NVIC_SetVector(SysTick_IRQn, (uint32_t)(&disk_timerproc)); |
emh203 | 0:76427232f435 | 177 | } |
emh203 | 0:76427232f435 | 178 | |
emh203 | 0:76427232f435 | 179 | /*-----------------------------------------------------------------------*/ |
emh203 | 0:76427232f435 | 180 | /* Read an ATA register */ |
emh203 | 0:76427232f435 | 181 | /*-----------------------------------------------------------------------*/ |
emh203 | 0:76427232f435 | 182 | |
emh203 | 0:76427232f435 | 183 | static |
emh203 | 0:76427232f435 | 184 | BYTE read_ata ( |
emh203 | 0:76427232f435 | 185 | BYTE reg /* Register to be read */ |
emh203 | 0:76427232f435 | 186 | ) |
emh203 | 0:76427232f435 | 187 | { |
emh203 | 0:76427232f435 | 188 | BYTE rd; |
emh203 | 0:76427232f435 | 189 | |
emh203 | 0:76427232f435 | 190 | CS0_ACTIVE; |
emh203 | 0:76427232f435 | 191 | SET_DATA_BUS_AS_INPUTS; |
emh203 | 0:76427232f435 | 192 | SET_CF_ADDRESS(reg); |
emh203 | 0:76427232f435 | 193 | IORD_ACTIVE; |
emh203 | 0:76427232f435 | 194 | __nop(); |
emh203 | 0:76427232f435 | 195 | __nop(); |
emh203 | 0:76427232f435 | 196 | __nop(); |
emh203 | 0:76427232f435 | 197 | __nop(); |
emh203 | 0:76427232f435 | 198 | |
emh203 | 0:76427232f435 | 199 | GET_CF_DATA(rd); |
emh203 | 0:76427232f435 | 200 | __nop(); |
emh203 | 0:76427232f435 | 201 | __nop(); |
emh203 | 0:76427232f435 | 202 | __nop(); |
emh203 | 0:76427232f435 | 203 | __nop(); |
emh203 | 0:76427232f435 | 204 | IORD_INACTIVE; |
emh203 | 0:76427232f435 | 205 | CS0_INACTIVE; |
emh203 | 0:76427232f435 | 206 | #ifdef _CF_DEBUG_READ_ATA |
emh203 | 0:76427232f435 | 207 | CF_DEBUG("rd 0x%2x\r\n",rd); |
emh203 | 0:76427232f435 | 208 | #endif |
emh203 | 0:76427232f435 | 209 | return rd; |
emh203 | 0:76427232f435 | 210 | } |
emh203 | 0:76427232f435 | 211 | |
emh203 | 0:76427232f435 | 212 | |
emh203 | 0:76427232f435 | 213 | |
emh203 | 0:76427232f435 | 214 | /*-----------------------------------------------------------------------*/ |
emh203 | 0:76427232f435 | 215 | /* Write a byte to an ATA register */ |
emh203 | 0:76427232f435 | 216 | /*-----------------------------------------------------------------------*/ |
emh203 | 0:76427232f435 | 217 | |
emh203 | 0:76427232f435 | 218 | static |
emh203 | 0:76427232f435 | 219 | void write_ata ( |
emh203 | 0:76427232f435 | 220 | BYTE reg, /* Register to be written */ |
emh203 | 0:76427232f435 | 221 | BYTE dat /* Data to be written */ |
emh203 | 0:76427232f435 | 222 | ) |
emh203 | 0:76427232f435 | 223 | { |
emh203 | 0:76427232f435 | 224 | |
emh203 | 0:76427232f435 | 225 | __nop(); |
emh203 | 0:76427232f435 | 226 | CS0_ACTIVE; |
emh203 | 0:76427232f435 | 227 | SET_DATA_BUS_AS_OUTPUTS; |
emh203 | 0:76427232f435 | 228 | SET_CF_ADDRESS(reg); |
emh203 | 0:76427232f435 | 229 | SET_CF_DATA(dat); |
emh203 | 0:76427232f435 | 230 | IOWR_ACTIVE; |
emh203 | 0:76427232f435 | 231 | __nop(); |
emh203 | 0:76427232f435 | 232 | __nop(); |
emh203 | 0:76427232f435 | 233 | __nop(); |
emh203 | 0:76427232f435 | 234 | __nop(); |
emh203 | 0:76427232f435 | 235 | IOWR_INACTIVE; |
emh203 | 0:76427232f435 | 236 | __nop(); |
emh203 | 0:76427232f435 | 237 | __nop(); |
emh203 | 0:76427232f435 | 238 | __nop(); |
emh203 | 0:76427232f435 | 239 | __nop(); |
emh203 | 0:76427232f435 | 240 | CS0_INACTIVE; |
emh203 | 0:76427232f435 | 241 | SET_DATA_BUS_AS_INPUTS; |
emh203 | 0:76427232f435 | 242 | } |
emh203 | 0:76427232f435 | 243 | |
emh203 | 0:76427232f435 | 244 | |
emh203 | 0:76427232f435 | 245 | |
emh203 | 0:76427232f435 | 246 | /*-----------------------------------------------------------------------*/ |
emh203 | 0:76427232f435 | 247 | /* Read a part of data block */ |
emh203 | 0:76427232f435 | 248 | /*-----------------------------------------------------------------------*/ |
emh203 | 0:76427232f435 | 249 | |
emh203 | 0:76427232f435 | 250 | static |
emh203 | 0:76427232f435 | 251 | void read_part ( |
emh203 | 0:76427232f435 | 252 | BYTE *buff, /* Data buffer to store read data */ |
emh203 | 0:76427232f435 | 253 | BYTE ofs, /* Offset of the part of data in unit of word */ |
emh203 | 0:76427232f435 | 254 | BYTE count /* Number of word to pick up */ |
emh203 | 0:76427232f435 | 255 | ) |
emh203 | 0:76427232f435 | 256 | { |
emh203 | 0:76427232f435 | 257 | BYTE c = 0, dl, dh; |
emh203 | 0:76427232f435 | 258 | |
emh203 | 0:76427232f435 | 259 | SET_CF_ADDRESS(REG_DATA); /* Select Data register */ |
emh203 | 0:76427232f435 | 260 | __nop(); |
emh203 | 0:76427232f435 | 261 | __nop(); |
emh203 | 0:76427232f435 | 262 | |
emh203 | 0:76427232f435 | 263 | SET_DATA_BUS_AS_INPUTS; |
emh203 | 0:76427232f435 | 264 | CS0_ACTIVE; |
emh203 | 0:76427232f435 | 265 | __nop(); |
emh203 | 0:76427232f435 | 266 | __nop(); |
emh203 | 0:76427232f435 | 267 | do { |
emh203 | 0:76427232f435 | 268 | IORD_ACTIVE; /* IORD = L */ |
emh203 | 0:76427232f435 | 269 | __nop(); |
emh203 | 0:76427232f435 | 270 | __nop(); |
emh203 | 0:76427232f435 | 271 | __nop(); |
emh203 | 0:76427232f435 | 272 | __nop(); |
emh203 | 0:76427232f435 | 273 | GET_CF_DATA(dl); /* Read Even data */ |
emh203 | 0:76427232f435 | 274 | IORD_INACTIVE; /* IORD = H */ |
emh203 | 0:76427232f435 | 275 | __nop(); |
emh203 | 0:76427232f435 | 276 | __nop(); |
emh203 | 0:76427232f435 | 277 | __nop(); |
emh203 | 0:76427232f435 | 278 | __nop(); |
emh203 | 0:76427232f435 | 279 | IORD_ACTIVE; /* IORD = L */ |
emh203 | 0:76427232f435 | 280 | __nop(); |
emh203 | 0:76427232f435 | 281 | __nop(); |
emh203 | 0:76427232f435 | 282 | __nop(); |
emh203 | 0:76427232f435 | 283 | __nop(); |
emh203 | 0:76427232f435 | 284 | GET_CF_DATA(dh); /* Read Odd data */ |
emh203 | 0:76427232f435 | 285 | IORD_INACTIVE; /* IORD = H */ |
emh203 | 0:76427232f435 | 286 | __nop(); |
emh203 | 0:76427232f435 | 287 | __nop(); |
emh203 | 0:76427232f435 | 288 | __nop(); |
emh203 | 0:76427232f435 | 289 | __nop(); |
emh203 | 0:76427232f435 | 290 | if (count && (c >= ofs)) { /* Pick up a part of block */ |
emh203 | 0:76427232f435 | 291 | *buff++ = dl; |
emh203 | 0:76427232f435 | 292 | *buff++ = dh; |
emh203 | 0:76427232f435 | 293 | count--; |
emh203 | 0:76427232f435 | 294 | } |
emh203 | 0:76427232f435 | 295 | } while (++c); |
emh203 | 0:76427232f435 | 296 | CS0_INACTIVE; |
emh203 | 0:76427232f435 | 297 | |
emh203 | 0:76427232f435 | 298 | read_ata(REG_ALTSTAT); |
emh203 | 0:76427232f435 | 299 | read_ata(REG_STATUS); |
emh203 | 0:76427232f435 | 300 | } |
emh203 | 0:76427232f435 | 301 | |
emh203 | 0:76427232f435 | 302 | |
emh203 | 0:76427232f435 | 303 | /*-----------------------------------------------------------------------*/ |
emh203 | 0:76427232f435 | 304 | /* Wait for Data Ready */ |
emh203 | 0:76427232f435 | 305 | /*-----------------------------------------------------------------------*/ |
emh203 | 0:76427232f435 | 306 | |
emh203 | 0:76427232f435 | 307 | static |
emh203 | 0:76427232f435 | 308 | int wait_data (void) |
emh203 | 0:76427232f435 | 309 | { |
emh203 | 0:76427232f435 | 310 | BYTE s; |
emh203 | 0:76427232f435 | 311 | |
emh203 | 0:76427232f435 | 312 | DiskProcTimer[CF] = 100; /* Time out = 1 sec */ |
emh203 | 0:76427232f435 | 313 | do { |
emh203 | 0:76427232f435 | 314 | if (!DiskProcTimer[CF]) return 0; /* Abort when timeout occured */ |
emh203 | 0:76427232f435 | 315 | s = read_ata(REG_STATUS); /* Get status */ |
emh203 | 0:76427232f435 | 316 | } while ((s & (BUSY|DRQ)) != DRQ); /* Wait for BUSY goes low and DRQ goes high */ |
emh203 | 0:76427232f435 | 317 | |
emh203 | 0:76427232f435 | 318 | read_ata(REG_ALTSTAT); |
emh203 | 0:76427232f435 | 319 | return 1; |
emh203 | 0:76427232f435 | 320 | } |
emh203 | 0:76427232f435 | 321 | |
emh203 | 0:76427232f435 | 322 | |
emh203 | 0:76427232f435 | 323 | |
emh203 | 0:76427232f435 | 324 | |
emh203 | 0:76427232f435 | 325 | /*-----------------------------------------------------------------------*/ |
emh203 | 0:76427232f435 | 326 | /* Initialize Disk Drive */ |
emh203 | 0:76427232f435 | 327 | /*-----------------------------------------------------------------------*/ |
emh203 | 0:76427232f435 | 328 | |
emh203 | 0:76427232f435 | 329 | DSTATUS disk_initialize ( |
emh203 | 0:76427232f435 | 330 | BYTE drv /* Physical drive number (0) */ |
emh203 | 0:76427232f435 | 331 | ) |
emh203 | 0:76427232f435 | 332 | { |
emh203 | 0:76427232f435 | 333 | DSTATUS RetVal; |
emh203 | 0:76427232f435 | 334 | |
emh203 | 0:76427232f435 | 335 | switch(drv) |
emh203 | 0:76427232f435 | 336 | { |
emh203 | 0:76427232f435 | 337 | case COMPACT_FLASH: |
emh203 | 0:76427232f435 | 338 | |
emh203 | 0:76427232f435 | 339 | Stat[CF] |= STA_NOINIT; |
emh203 | 0:76427232f435 | 340 | for (DiskProcTimer[CF] = 10; DiskProcTimer[CF]; ); /* 100ms */ |
emh203 | 0:76427232f435 | 341 | if (Stat[CF] & STA_NODISK) return Stat[CF]; /* Exit when socket is empty */ |
emh203 | 0:76427232f435 | 342 | COMPACT_FLASH_POWER_ENABLE; /* Initialize CFC control port */ |
emh203 | 0:76427232f435 | 343 | for (DiskProcTimer[CF] = 1;DiskProcTimer[CF]; ); /* 10ms */ |
emh203 | 0:76427232f435 | 344 | |
emh203 | 0:76427232f435 | 345 | SET_DATA_BUS_AS_INPUTS; |
emh203 | 0:76427232f435 | 346 | for (DiskProcTimer[CF] = 5; DiskProcTimer[CF]; ); /* 50ms */ |
emh203 | 0:76427232f435 | 347 | COMPACT_FLASH_RESET_INACTIVE; |
emh203 | 0:76427232f435 | 348 | for (DiskProcTimer[CF] = 5; DiskProcTimer[CF]; ); /* 50ms */ |
emh203 | 0:76427232f435 | 349 | write_ata(REG_DEV, LBA); /* Select Device 0 */ |
emh203 | 0:76427232f435 | 350 | DiskProcTimer[CF] = 200; |
emh203 | 0:76427232f435 | 351 | |
emh203 | 0:76427232f435 | 352 | do { /* Wait for card goes ready */ |
emh203 | 0:76427232f435 | 353 | if (!DiskProcTimer[CF]) |
emh203 | 0:76427232f435 | 354 | { |
emh203 | 0:76427232f435 | 355 | CF_DEBUG("Timeout waiting for card BUSY to go inactive\r\n"); |
emh203 | 0:76427232f435 | 356 | return Stat[CF]; |
emh203 | 0:76427232f435 | 357 | } |
emh203 | 0:76427232f435 | 358 | } while (read_ata(REG_STATUS) & BUSY); |
emh203 | 0:76427232f435 | 359 | |
emh203 | 0:76427232f435 | 360 | |
emh203 | 0:76427232f435 | 361 | write_ata(REG_DEVCTRL, SRST | nIEN); /* Software reset */ |
emh203 | 0:76427232f435 | 362 | for (DiskProcTimer[CF] = 2; DiskProcTimer[CF]; ); /* 20ms */ |
emh203 | 0:76427232f435 | 363 | |
emh203 | 0:76427232f435 | 364 | write_ata(REG_DEVCTRL, nIEN); /* Release software reset */ |
emh203 | 0:76427232f435 | 365 | |
emh203 | 0:76427232f435 | 366 | for (DiskProcTimer[CF] = 2; DiskProcTimer[CF]; ); /* 20ms */ |
emh203 | 0:76427232f435 | 367 | |
emh203 | 0:76427232f435 | 368 | DiskProcTimer[CF] = 200; |
emh203 | 0:76427232f435 | 369 | do { /* Wait for card goes ready */ |
emh203 | 0:76427232f435 | 370 | if (!DiskProcTimer[CF]) |
emh203 | 0:76427232f435 | 371 | { |
emh203 | 0:76427232f435 | 372 | CF_DEBUG("Timeout waiting for card DRDY\r\n"); |
emh203 | 0:76427232f435 | 373 | return Stat[CF]; |
emh203 | 0:76427232f435 | 374 | } |
emh203 | 0:76427232f435 | 375 | } while ((read_ata(REG_STATUS) & (DRDY|BUSY)) != DRDY); |
emh203 | 0:76427232f435 | 376 | |
emh203 | 0:76427232f435 | 377 | CF_DEBUG("Setting to 8-bit PIO MOD\r\n"); |
emh203 | 0:76427232f435 | 378 | write_ata(REG_FEATURES, 0x01); /* Select 8-bit PIO transfer mode */ |
emh203 | 0:76427232f435 | 379 | write_ata(REG_COMMAND, CMD_SETFEATURES); |
emh203 | 0:76427232f435 | 380 | DiskProcTimer[CF] = 200; |
emh203 | 0:76427232f435 | 381 | do { |
emh203 | 0:76427232f435 | 382 | if (!DiskProcTimer[CF]) |
emh203 | 0:76427232f435 | 383 | { |
emh203 | 0:76427232f435 | 384 | CF_DEBUG("Timeout waiting after trying to call the SETFEATURES command\r\n"); |
emh203 | 0:76427232f435 | 385 | return Stat[CF]; |
emh203 | 0:76427232f435 | 386 | } |
emh203 | 0:76427232f435 | 387 | |
emh203 | 0:76427232f435 | 388 | } while (read_ata(REG_STATUS) & (BUSY | ERR)); |
emh203 | 0:76427232f435 | 389 | |
emh203 | 0:76427232f435 | 390 | Stat[CF] &= ~STA_NOINIT; /* When device goes ready, clear STA_NOINIT */ |
emh203 | 0:76427232f435 | 391 | |
emh203 | 0:76427232f435 | 392 | RetVal = Stat[CF]; |
emh203 | 0:76427232f435 | 393 | |
emh203 | 0:76427232f435 | 394 | break; |
emh203 | 0:76427232f435 | 395 | |
emh203 | 0:76427232f435 | 396 | case USB: |
emh203 | 0:76427232f435 | 397 | |
emh203 | 0:76427232f435 | 398 | if(USB_Disk_Detected) |
emh203 | 0:76427232f435 | 399 | { |
emh203 | 0:76427232f435 | 400 | TERMINAL_PRINTF("USB Disk Detected.\r\n"); |
emh203 | 0:76427232f435 | 401 | Stat[USB] &= ~(STA_NOINIT | STA_NODISK); |
emh203 | 0:76427232f435 | 402 | } |
emh203 | 0:76427232f435 | 403 | else |
emh203 | 0:76427232f435 | 404 | { |
emh203 | 0:76427232f435 | 405 | TERMINAL_PRINTF("USB Disk not attached.\r\n"); |
emh203 | 0:76427232f435 | 406 | Stat[USB] |= STA_NOINIT | STA_NODISK; |
emh203 | 0:76427232f435 | 407 | } |
emh203 | 0:76427232f435 | 408 | |
emh203 | 0:76427232f435 | 409 | RetVal = Stat[USB]; |
emh203 | 0:76427232f435 | 410 | break; |
emh203 | 0:76427232f435 | 411 | |
emh203 | 0:76427232f435 | 412 | |
emh203 | 0:76427232f435 | 413 | case RAM: |
emh203 | 0:76427232f435 | 414 | Stat[RAM] &= ~STA_NOINIT; |
emh203 | 0:76427232f435 | 415 | RetVal = Stat[RAM]; |
emh203 | 0:76427232f435 | 416 | break; |
emh203 | 0:76427232f435 | 417 | |
emh203 | 0:76427232f435 | 418 | default: |
emh203 | 0:76427232f435 | 419 | RetVal = STA_NOINIT; |
emh203 | 0:76427232f435 | 420 | break; |
emh203 | 0:76427232f435 | 421 | } |
emh203 | 0:76427232f435 | 422 | |
emh203 | 0:76427232f435 | 423 | return RetVal; |
emh203 | 0:76427232f435 | 424 | } |
emh203 | 0:76427232f435 | 425 | |
emh203 | 0:76427232f435 | 426 | |
emh203 | 0:76427232f435 | 427 | |
emh203 | 0:76427232f435 | 428 | /*-----------------------------------------------------------------------*/ |
emh203 | 0:76427232f435 | 429 | /* Return Disk Status */ |
emh203 | 0:76427232f435 | 430 | /*-----------------------------------------------------------------------*/ |
emh203 | 0:76427232f435 | 431 | |
emh203 | 0:76427232f435 | 432 | DSTATUS disk_status ( |
emh203 | 0:76427232f435 | 433 | BYTE drv |
emh203 | 0:76427232f435 | 434 | ) |
emh203 | 0:76427232f435 | 435 | { |
emh203 | 0:76427232f435 | 436 | DSTATUS RetVal; |
emh203 | 0:76427232f435 | 437 | |
emh203 | 0:76427232f435 | 438 | switch(drv) |
emh203 | 0:76427232f435 | 439 | { |
emh203 | 0:76427232f435 | 440 | case CF: |
emh203 | 0:76427232f435 | 441 | RetVal = Stat[CF]; |
emh203 | 0:76427232f435 | 442 | break; |
emh203 | 0:76427232f435 | 443 | |
emh203 | 0:76427232f435 | 444 | |
emh203 | 0:76427232f435 | 445 | case USB: |
emh203 | 0:76427232f435 | 446 | RetVal = Stat[USB]; |
emh203 | 0:76427232f435 | 447 | break; |
emh203 | 0:76427232f435 | 448 | |
emh203 | 0:76427232f435 | 449 | case RAM: |
emh203 | 0:76427232f435 | 450 | RetVal = Stat[RAM]; |
emh203 | 0:76427232f435 | 451 | break; |
emh203 | 0:76427232f435 | 452 | |
emh203 | 0:76427232f435 | 453 | default: |
emh203 | 0:76427232f435 | 454 | RetVal = STA_NOINIT; |
emh203 | 0:76427232f435 | 455 | break; |
emh203 | 0:76427232f435 | 456 | } |
emh203 | 0:76427232f435 | 457 | |
emh203 | 0:76427232f435 | 458 | return RetVal; |
emh203 | 0:76427232f435 | 459 | } |
emh203 | 0:76427232f435 | 460 | |
emh203 | 0:76427232f435 | 461 | |
emh203 | 0:76427232f435 | 462 | |
emh203 | 0:76427232f435 | 463 | /*-----------------------------------------------------------------------*/ |
emh203 | 0:76427232f435 | 464 | /* Read Sector(s) */ |
emh203 | 0:76427232f435 | 465 | /*-----------------------------------------------------------------------*/ |
emh203 | 0:76427232f435 | 466 | |
emh203 | 0:76427232f435 | 467 | DRESULT disk_read ( |
emh203 | 0:76427232f435 | 468 | BYTE drv, /* Physical drive nmuber (0) */ |
emh203 | 0:76427232f435 | 469 | BYTE *buff, /* Data buffer to store read data */ |
emh203 | 0:76427232f435 | 470 | DWORD sector, /* Sector number (LBA) */ |
emh203 | 0:76427232f435 | 471 | BYTE count /* Sector count (1..255) */ |
emh203 | 0:76427232f435 | 472 | ) |
emh203 | 0:76427232f435 | 473 | { |
emh203 | 0:76427232f435 | 474 | BYTE c; |
emh203 | 0:76427232f435 | 475 | DWORD i; |
emh203 | 0:76427232f435 | 476 | |
emh203 | 0:76427232f435 | 477 | switch(drv) |
emh203 | 0:76427232f435 | 478 | { |
emh203 | 0:76427232f435 | 479 | case CF: |
emh203 | 0:76427232f435 | 480 | if (Stat[CF] & STA_NOINIT) return RES_NOTRDY; |
emh203 | 0:76427232f435 | 481 | |
emh203 | 0:76427232f435 | 482 | /* Issue Read Setor(s) command */ |
emh203 | 0:76427232f435 | 483 | write_ata(REG_COUNT, count); |
emh203 | 0:76427232f435 | 484 | write_ata(REG_SECTOR, (BYTE)sector); |
emh203 | 0:76427232f435 | 485 | write_ata(REG_CYLL, (BYTE)(sector >> 8)); |
emh203 | 0:76427232f435 | 486 | write_ata(REG_CYLH, (BYTE)(sector >> 16)); |
emh203 | 0:76427232f435 | 487 | write_ata(REG_DEV, ((BYTE)(sector >> 24) & 0x0F) | LBA); |
emh203 | 0:76427232f435 | 488 | write_ata(REG_COMMAND, CMD_READ); |
emh203 | 0:76427232f435 | 489 | |
emh203 | 0:76427232f435 | 490 | do { |
emh203 | 0:76427232f435 | 491 | if (!wait_data()) return RES_ERROR; /* Wait data ready */ |
emh203 | 0:76427232f435 | 492 | |
emh203 | 0:76427232f435 | 493 | SET_CF_ADDRESS(REG_DATA); |
emh203 | 0:76427232f435 | 494 | __nop(); |
emh203 | 0:76427232f435 | 495 | __nop(); |
emh203 | 0:76427232f435 | 496 | __nop(); |
emh203 | 0:76427232f435 | 497 | __nop(); |
emh203 | 0:76427232f435 | 498 | CS0_ACTIVE; |
emh203 | 0:76427232f435 | 499 | c = 0; |
emh203 | 0:76427232f435 | 500 | |
emh203 | 0:76427232f435 | 501 | __nop(); |
emh203 | 0:76427232f435 | 502 | __nop(); |
emh203 | 0:76427232f435 | 503 | __nop(); |
emh203 | 0:76427232f435 | 504 | |
emh203 | 0:76427232f435 | 505 | SET_DATA_BUS_AS_INPUTS; |
emh203 | 0:76427232f435 | 506 | do { |
emh203 | 0:76427232f435 | 507 | IORD_ACTIVE; /* IORD = L */ |
emh203 | 0:76427232f435 | 508 | __nop(); |
emh203 | 0:76427232f435 | 509 | __nop(); |
emh203 | 0:76427232f435 | 510 | __nop(); |
emh203 | 0:76427232f435 | 511 | GET_CF_DATA(*buff++); /* Get even data */ |
emh203 | 0:76427232f435 | 512 | __nop(); |
emh203 | 0:76427232f435 | 513 | __nop(); |
emh203 | 0:76427232f435 | 514 | __nop(); |
emh203 | 0:76427232f435 | 515 | |
emh203 | 0:76427232f435 | 516 | __nop(); |
emh203 | 0:76427232f435 | 517 | __nop(); |
emh203 | 0:76427232f435 | 518 | __nop(); |
emh203 | 0:76427232f435 | 519 | |
emh203 | 0:76427232f435 | 520 | IORD_INACTIVE; /* IORD = H */ |
emh203 | 0:76427232f435 | 521 | __nop(); |
emh203 | 0:76427232f435 | 522 | __nop(); |
emh203 | 0:76427232f435 | 523 | __nop(); |
emh203 | 0:76427232f435 | 524 | |
emh203 | 0:76427232f435 | 525 | IORD_ACTIVE; /* IORD = L */ |
emh203 | 0:76427232f435 | 526 | __nop(); |
emh203 | 0:76427232f435 | 527 | __nop(); |
emh203 | 0:76427232f435 | 528 | __nop(); |
emh203 | 0:76427232f435 | 529 | |
emh203 | 0:76427232f435 | 530 | GET_CF_DATA(*buff++); /* Get Odd data */ |
emh203 | 0:76427232f435 | 531 | __nop(); |
emh203 | 0:76427232f435 | 532 | __nop(); |
emh203 | 0:76427232f435 | 533 | __nop(); |
emh203 | 0:76427232f435 | 534 | |
emh203 | 0:76427232f435 | 535 | __nop(); |
emh203 | 0:76427232f435 | 536 | IORD_INACTIVE; /* IORD = H */ |
emh203 | 0:76427232f435 | 537 | __nop(); |
emh203 | 0:76427232f435 | 538 | __nop(); |
emh203 | 0:76427232f435 | 539 | __nop(); |
emh203 | 0:76427232f435 | 540 | |
emh203 | 0:76427232f435 | 541 | |
emh203 | 0:76427232f435 | 542 | } while (--c); |
emh203 | 0:76427232f435 | 543 | } while (--count); |
emh203 | 0:76427232f435 | 544 | |
emh203 | 0:76427232f435 | 545 | CS0_INACTIVE; |
emh203 | 0:76427232f435 | 546 | read_ata(REG_ALTSTAT); |
emh203 | 0:76427232f435 | 547 | read_ata(REG_STATUS); |
emh203 | 0:76427232f435 | 548 | |
emh203 | 0:76427232f435 | 549 | return RES_OK; |
emh203 | 0:76427232f435 | 550 | break; |
emh203 | 0:76427232f435 | 551 | |
emh203 | 0:76427232f435 | 552 | |
emh203 | 0:76427232f435 | 553 | case USB: |
emh203 | 0:76427232f435 | 554 | |
emh203 | 0:76427232f435 | 555 | if(MassStorage_Read(sector, 1,(u8 *) buff, 512) == 0) |
emh203 | 0:76427232f435 | 556 | return RES_OK; |
emh203 | 0:76427232f435 | 557 | else |
emh203 | 0:76427232f435 | 558 | return RES_NOTRDY; |
emh203 | 0:76427232f435 | 559 | |
emh203 | 0:76427232f435 | 560 | break; |
emh203 | 0:76427232f435 | 561 | |
emh203 | 0:76427232f435 | 562 | case RAM: |
emh203 | 0:76427232f435 | 563 | for(i=0;i<512;i++) |
emh203 | 0:76427232f435 | 564 | { |
emh203 | 0:76427232f435 | 565 | buff[i] = RAM_DISK[i]; |
emh203 | 0:76427232f435 | 566 | } |
emh203 | 0:76427232f435 | 567 | return RES_OK; |
emh203 | 0:76427232f435 | 568 | break; |
emh203 | 0:76427232f435 | 569 | |
emh203 | 0:76427232f435 | 570 | default: |
emh203 | 0:76427232f435 | 571 | return RES_PARERR; |
emh203 | 0:76427232f435 | 572 | break; |
emh203 | 0:76427232f435 | 573 | } |
emh203 | 0:76427232f435 | 574 | } |
emh203 | 0:76427232f435 | 575 | |
emh203 | 0:76427232f435 | 576 | |
emh203 | 0:76427232f435 | 577 | /*-----------------------------------------------------------------------*/ |
emh203 | 0:76427232f435 | 578 | /* Write Sector(s) */ |
emh203 | 0:76427232f435 | 579 | /*-----------------------------------------------------------------------*/ |
emh203 | 0:76427232f435 | 580 | |
emh203 | 0:76427232f435 | 581 | DRESULT disk_write ( |
emh203 | 0:76427232f435 | 582 | BYTE drv, /* Physical drive number (0) */ |
emh203 | 0:76427232f435 | 583 | const BYTE *buff, /* Data to be written */ |
emh203 | 0:76427232f435 | 584 | DWORD sector, /* Sector number (LBA) */ |
emh203 | 0:76427232f435 | 585 | BYTE count /* Sector count (1..255) */ |
emh203 | 0:76427232f435 | 586 | ) |
emh203 | 0:76427232f435 | 587 | { |
emh203 | 0:76427232f435 | 588 | BYTE s, c; |
emh203 | 0:76427232f435 | 589 | DWORD i; |
emh203 | 0:76427232f435 | 590 | DRESULT RetVal; |
emh203 | 0:76427232f435 | 591 | |
emh203 | 0:76427232f435 | 592 | switch(drv) |
emh203 | 0:76427232f435 | 593 | { |
emh203 | 0:76427232f435 | 594 | case CF: |
emh203 | 0:76427232f435 | 595 | /* Issue Write Setor(s) command */ |
emh203 | 0:76427232f435 | 596 | write_ata(REG_COUNT, count); |
emh203 | 0:76427232f435 | 597 | write_ata(REG_SECTOR, (BYTE)sector); |
emh203 | 0:76427232f435 | 598 | write_ata(REG_CYLL, (BYTE)(sector >> 8)); |
emh203 | 0:76427232f435 | 599 | write_ata(REG_CYLH, (BYTE)(sector >> 16)); |
emh203 | 0:76427232f435 | 600 | write_ata(REG_DEV, ((BYTE)(sector >> 24) & 0x0F) | LBA); |
emh203 | 0:76427232f435 | 601 | write_ata(REG_COMMAND, CMD_WRITE); |
emh203 | 0:76427232f435 | 602 | |
emh203 | 0:76427232f435 | 603 | do { |
emh203 | 0:76427232f435 | 604 | if (!wait_data()) return RES_ERROR; |
emh203 | 0:76427232f435 | 605 | |
emh203 | 0:76427232f435 | 606 | SET_CF_ADDRESS(REG_DATA); |
emh203 | 0:76427232f435 | 607 | __nop(); |
emh203 | 0:76427232f435 | 608 | __nop(); |
emh203 | 0:76427232f435 | 609 | __nop(); |
emh203 | 0:76427232f435 | 610 | CS0_ACTIVE; |
emh203 | 0:76427232f435 | 611 | __nop(); |
emh203 | 0:76427232f435 | 612 | __nop(); |
emh203 | 0:76427232f435 | 613 | __nop(); |
emh203 | 0:76427232f435 | 614 | |
emh203 | 0:76427232f435 | 615 | SET_DATA_BUS_AS_OUTPUTS; |
emh203 | 0:76427232f435 | 616 | c = 0; |
emh203 | 0:76427232f435 | 617 | do { |
emh203 | 0:76427232f435 | 618 | SET_CF_DATA(*buff++); /* Set even data */ |
emh203 | 0:76427232f435 | 619 | __nop(); |
emh203 | 0:76427232f435 | 620 | __nop(); |
emh203 | 0:76427232f435 | 621 | __nop(); |
emh203 | 0:76427232f435 | 622 | |
emh203 | 0:76427232f435 | 623 | IOWR_ACTIVE; /* IOWR = L */ |
emh203 | 0:76427232f435 | 624 | __nop(); |
emh203 | 0:76427232f435 | 625 | __nop(); |
emh203 | 0:76427232f435 | 626 | __nop(); |
emh203 | 0:76427232f435 | 627 | |
emh203 | 0:76427232f435 | 628 | IOWR_INACTIVE; /* IOWR = H */ |
emh203 | 0:76427232f435 | 629 | __nop(); |
emh203 | 0:76427232f435 | 630 | __nop(); |
emh203 | 0:76427232f435 | 631 | __nop(); |
emh203 | 0:76427232f435 | 632 | |
emh203 | 0:76427232f435 | 633 | SET_CF_DATA(*buff++); /* Set odd data */ |
emh203 | 0:76427232f435 | 634 | __nop(); |
emh203 | 0:76427232f435 | 635 | __nop(); |
emh203 | 0:76427232f435 | 636 | __nop(); |
emh203 | 0:76427232f435 | 637 | |
emh203 | 0:76427232f435 | 638 | IOWR_ACTIVE; /* IOWR = L */ |
emh203 | 0:76427232f435 | 639 | __nop(); |
emh203 | 0:76427232f435 | 640 | __nop(); |
emh203 | 0:76427232f435 | 641 | __nop(); |
emh203 | 0:76427232f435 | 642 | |
emh203 | 0:76427232f435 | 643 | IOWR_INACTIVE; /* IOWR = H */ |
emh203 | 0:76427232f435 | 644 | __nop(); |
emh203 | 0:76427232f435 | 645 | __nop(); |
emh203 | 0:76427232f435 | 646 | __nop(); |
emh203 | 0:76427232f435 | 647 | } while (--c); |
emh203 | 0:76427232f435 | 648 | |
emh203 | 0:76427232f435 | 649 | } while (--count); |
emh203 | 0:76427232f435 | 650 | |
emh203 | 0:76427232f435 | 651 | SET_DATA_BUS_AS_INPUTS; |
emh203 | 0:76427232f435 | 652 | CS0_INACTIVE; |
emh203 | 0:76427232f435 | 653 | |
emh203 | 0:76427232f435 | 654 | DiskProcTimer[CF] = 100; |
emh203 | 0:76427232f435 | 655 | do { |
emh203 | 0:76427232f435 | 656 | if (!DiskProcTimer[CF]) return RES_ERROR; |
emh203 | 0:76427232f435 | 657 | s = read_ata(REG_STATUS); |
emh203 | 0:76427232f435 | 658 | } while (s & BUSY); |
emh203 | 0:76427232f435 | 659 | if (s & ERR) return RES_ERROR; |
emh203 | 0:76427232f435 | 660 | |
emh203 | 0:76427232f435 | 661 | read_ata(REG_ALTSTAT); |
emh203 | 0:76427232f435 | 662 | read_ata(REG_STATUS); |
emh203 | 0:76427232f435 | 663 | |
emh203 | 0:76427232f435 | 664 | RetVal = RES_OK; |
emh203 | 0:76427232f435 | 665 | break; |
emh203 | 0:76427232f435 | 666 | |
emh203 | 0:76427232f435 | 667 | |
emh203 | 0:76427232f435 | 668 | case USB: |
emh203 | 0:76427232f435 | 669 | |
emh203 | 0:76427232f435 | 670 | if( MassStorage_Write(sector, 1, (u8 *)buff, 512) == 0) |
emh203 | 0:76427232f435 | 671 | RetVal = RES_OK; |
emh203 | 0:76427232f435 | 672 | else |
emh203 | 0:76427232f435 | 673 | RetVal = RES_NOTRDY; |
emh203 | 0:76427232f435 | 674 | |
emh203 | 0:76427232f435 | 675 | break; |
emh203 | 0:76427232f435 | 676 | |
emh203 | 0:76427232f435 | 677 | case RAM: |
emh203 | 0:76427232f435 | 678 | |
emh203 | 0:76427232f435 | 679 | for(i=0;i<512;i++) |
emh203 | 0:76427232f435 | 680 | { |
emh203 | 0:76427232f435 | 681 | RAM_DISK[i] = buff[i]; |
emh203 | 0:76427232f435 | 682 | } |
emh203 | 0:76427232f435 | 683 | RetVal = RES_OK; |
emh203 | 0:76427232f435 | 684 | |
emh203 | 0:76427232f435 | 685 | break; |
emh203 | 0:76427232f435 | 686 | |
emh203 | 0:76427232f435 | 687 | default: |
emh203 | 0:76427232f435 | 688 | RetVal = RES_PARERR; |
emh203 | 0:76427232f435 | 689 | break; |
emh203 | 0:76427232f435 | 690 | |
emh203 | 0:76427232f435 | 691 | } |
emh203 | 0:76427232f435 | 692 | return RetVal; |
emh203 | 0:76427232f435 | 693 | } |
emh203 | 0:76427232f435 | 694 | |
emh203 | 0:76427232f435 | 695 | |
emh203 | 0:76427232f435 | 696 | |
emh203 | 0:76427232f435 | 697 | /*-----------------------------------------------------------------------*/ |
emh203 | 0:76427232f435 | 698 | /* Miscellaneous Functions */ |
emh203 | 0:76427232f435 | 699 | /*-----------------------------------------------------------------------*/ |
emh203 | 0:76427232f435 | 700 | |
emh203 | 0:76427232f435 | 701 | DRESULT disk_ioctl ( |
emh203 | 0:76427232f435 | 702 | BYTE drv, /* Physical drive nmuber (0) */ |
emh203 | 0:76427232f435 | 703 | BYTE ctrl, /* Control code */ |
emh203 | 0:76427232f435 | 704 | void *buff /* Buffer to send/receive data block */ |
emh203 | 0:76427232f435 | 705 | ) |
emh203 | 0:76427232f435 | 706 | { |
emh203 | 0:76427232f435 | 707 | BYTE n, w, ofs, dl, dh, *ptr = (BYTE *)buff; |
emh203 | 0:76427232f435 | 708 | |
emh203 | 0:76427232f435 | 709 | switch(drv) |
emh203 | 0:76427232f435 | 710 | { |
emh203 | 0:76427232f435 | 711 | case CF: |
emh203 | 0:76427232f435 | 712 | switch (ctrl) |
emh203 | 0:76427232f435 | 713 | { |
emh203 | 0:76427232f435 | 714 | case GET_SECTOR_COUNT : /* Get number of sectors on the disk (DWORD) */ |
emh203 | 0:76427232f435 | 715 | ofs = 60; w = 2; n = 0; |
emh203 | 0:76427232f435 | 716 | break; |
emh203 | 0:76427232f435 | 717 | |
emh203 | 0:76427232f435 | 718 | case GET_BLOCK_SIZE : /* Get erase block size in sectors (DWORD) */ |
emh203 | 0:76427232f435 | 719 | *(DWORD*)buff = 32; |
emh203 | 0:76427232f435 | 720 | return RES_OK; |
emh203 | 0:76427232f435 | 721 | break; |
emh203 | 0:76427232f435 | 722 | case CTRL_SYNC : /* Nothing to do */ |
emh203 | 0:76427232f435 | 723 | return RES_OK; |
emh203 | 0:76427232f435 | 724 | break; |
emh203 | 0:76427232f435 | 725 | case ATA_GET_REV : /* Get firmware revision (8 chars) */ |
emh203 | 0:76427232f435 | 726 | ofs = 23; w = 4; n = 4; |
emh203 | 0:76427232f435 | 727 | break; |
emh203 | 0:76427232f435 | 728 | |
emh203 | 0:76427232f435 | 729 | case ATA_GET_MODEL : /* Get model name (40 chars) */ |
emh203 | 0:76427232f435 | 730 | ofs = 27; w = 20; n = 20; |
emh203 | 0:76427232f435 | 731 | break; |
emh203 | 0:76427232f435 | 732 | |
emh203 | 0:76427232f435 | 733 | case ATA_GET_SN : /* Get serial number (20 chars) */ |
emh203 | 0:76427232f435 | 734 | ofs = 10; w = 10; n = 10; |
emh203 | 0:76427232f435 | 735 | break; |
emh203 | 0:76427232f435 | 736 | |
emh203 | 0:76427232f435 | 737 | default: |
emh203 | 0:76427232f435 | 738 | return RES_PARERR; |
emh203 | 0:76427232f435 | 739 | } |
emh203 | 0:76427232f435 | 740 | |
emh203 | 0:76427232f435 | 741 | write_ata(REG_COMMAND, CMD_IDENTIFY); |
emh203 | 0:76427232f435 | 742 | |
emh203 | 0:76427232f435 | 743 | if (!wait_data()) return RES_ERROR; |
emh203 | 0:76427232f435 | 744 | |
emh203 | 0:76427232f435 | 745 | read_part(ptr, ofs, w); |
emh203 | 0:76427232f435 | 746 | |
emh203 | 0:76427232f435 | 747 | while (n--) |
emh203 | 0:76427232f435 | 748 | { |
emh203 | 0:76427232f435 | 749 | dl = *ptr; dh = *(ptr+1); |
emh203 | 0:76427232f435 | 750 | *ptr++ = dh; *ptr++ = dl; |
emh203 | 0:76427232f435 | 751 | } |
emh203 | 0:76427232f435 | 752 | |
emh203 | 0:76427232f435 | 753 | return RES_OK; |
emh203 | 0:76427232f435 | 754 | break; |
emh203 | 0:76427232f435 | 755 | |
emh203 | 0:76427232f435 | 756 | |
emh203 | 0:76427232f435 | 757 | case USB: |
emh203 | 0:76427232f435 | 758 | if (USB_Disk_Detected == 0) |
emh203 | 0:76427232f435 | 759 | { |
emh203 | 0:76427232f435 | 760 | // TERMINAL_PRINTF("USB Disk not attached\r\n"); |
emh203 | 0:76427232f435 | 761 | return RES_ERROR; |
emh203 | 0:76427232f435 | 762 | } |
emh203 | 0:76427232f435 | 763 | else |
emh203 | 0:76427232f435 | 764 | { |
emh203 | 0:76427232f435 | 765 | Stat[USB] &= ~STA_NOINIT; |
emh203 | 0:76427232f435 | 766 | switch (ctrl) |
emh203 | 0:76427232f435 | 767 | { |
emh203 | 0:76427232f435 | 768 | |
emh203 | 0:76427232f435 | 769 | case GET_SECTOR_COUNT: |
emh203 | 0:76427232f435 | 770 | /* if(MassStorage_ReadCapacity(USB_Disk_Device, &BlockCount, &BlockSize) == 0) |
emh203 | 0:76427232f435 | 771 | { |
emh203 | 0:76427232f435 | 772 | |
emh203 | 0:76427232f435 | 773 | *(DWORD *)(buff) = BlockCount; |
emh203 | 0:76427232f435 | 774 | |
emh203 | 0:76427232f435 | 775 | |
emh203 | 0:76427232f435 | 776 | } |
emh203 | 0:76427232f435 | 777 | else |
emh203 | 0:76427232f435 | 778 | { |
emh203 | 0:76427232f435 | 779 | return RES_ERROR; |
emh203 | 0:76427232f435 | 780 | }*/ |
emh203 | 0:76427232f435 | 781 | return RES_OK; |
emh203 | 0:76427232f435 | 782 | break; |
emh203 | 0:76427232f435 | 783 | |
emh203 | 0:76427232f435 | 784 | case GET_BLOCK_SIZE : |
emh203 | 0:76427232f435 | 785 | |
emh203 | 0:76427232f435 | 786 | /* if(MassStorage_ReadCapacity(USB_Disk_Device, &BlockCount, &BlockSize) == 0) |
emh203 | 0:76427232f435 | 787 | { |
emh203 | 0:76427232f435 | 788 | *(DWORD *)(buff) = BlockSize; |
emh203 | 0:76427232f435 | 789 | return RES_OK; |
emh203 | 0:76427232f435 | 790 | } |
emh203 | 0:76427232f435 | 791 | else |
emh203 | 0:76427232f435 | 792 | { |
emh203 | 0:76427232f435 | 793 | return RES_ERROR; |
emh203 | 0:76427232f435 | 794 | }*/ |
emh203 | 0:76427232f435 | 795 | return RES_OK; |
emh203 | 0:76427232f435 | 796 | |
emh203 | 0:76427232f435 | 797 | break; |
emh203 | 0:76427232f435 | 798 | |
emh203 | 0:76427232f435 | 799 | case CTRL_SYNC : |
emh203 | 0:76427232f435 | 800 | return RES_OK; |
emh203 | 0:76427232f435 | 801 | break; |
emh203 | 0:76427232f435 | 802 | |
emh203 | 0:76427232f435 | 803 | case ATA_GET_REV : |
emh203 | 0:76427232f435 | 804 | strcpy ((CHAR *)buff,"00000"); |
emh203 | 0:76427232f435 | 805 | return RES_OK; |
emh203 | 0:76427232f435 | 806 | break; |
emh203 | 0:76427232f435 | 807 | |
emh203 | 0:76427232f435 | 808 | case ATA_GET_MODEL : |
emh203 | 0:76427232f435 | 809 | strcpy ((CHAR *)buff, "000000"); |
emh203 | 0:76427232f435 | 810 | return RES_OK; |
emh203 | 0:76427232f435 | 811 | break; |
emh203 | 0:76427232f435 | 812 | |
emh203 | 0:76427232f435 | 813 | case ATA_GET_SN : |
emh203 | 0:76427232f435 | 814 | strcpy ((CHAR *)buff,"00000000"); |
emh203 | 0:76427232f435 | 815 | return RES_OK; |
emh203 | 0:76427232f435 | 816 | break; |
emh203 | 0:76427232f435 | 817 | |
emh203 | 0:76427232f435 | 818 | default: |
emh203 | 0:76427232f435 | 819 | return RES_PARERR; |
emh203 | 0:76427232f435 | 820 | } |
emh203 | 0:76427232f435 | 821 | } |
emh203 | 0:76427232f435 | 822 | |
emh203 | 0:76427232f435 | 823 | break; |
emh203 | 0:76427232f435 | 824 | |
emh203 | 0:76427232f435 | 825 | case RAM: |
emh203 | 0:76427232f435 | 826 | switch (ctrl) |
emh203 | 0:76427232f435 | 827 | |
emh203 | 0:76427232f435 | 828 | { |
emh203 | 0:76427232f435 | 829 | case GET_SECTOR_COUNT : /* Get number of sectors on the disk (DWORD) */ |
emh203 | 0:76427232f435 | 830 | *(DWORD *)(buff) = 1; |
emh203 | 0:76427232f435 | 831 | break; |
emh203 | 0:76427232f435 | 832 | |
emh203 | 0:76427232f435 | 833 | case GET_BLOCK_SIZE : /* Get erase block size in sectors (DWORD) */ |
emh203 | 0:76427232f435 | 834 | *(DWORD *)(buff) = 1; |
emh203 | 0:76427232f435 | 835 | return RES_OK; |
emh203 | 0:76427232f435 | 836 | break; |
emh203 | 0:76427232f435 | 837 | case CTRL_SYNC : /* Nothing to do */ |
emh203 | 0:76427232f435 | 838 | return RES_OK; |
emh203 | 0:76427232f435 | 839 | break; |
emh203 | 0:76427232f435 | 840 | |
emh203 | 0:76427232f435 | 841 | case ATA_GET_REV : /* Get firmware revision (8 chars) */ |
emh203 | 0:76427232f435 | 842 | strcpy ((CHAR *)buff,"Rev 0.01"); |
emh203 | 0:76427232f435 | 843 | break; |
emh203 | 0:76427232f435 | 844 | |
emh203 | 0:76427232f435 | 845 | case ATA_GET_MODEL : /* Get model name (40 chars) */ |
emh203 | 0:76427232f435 | 846 | strcpy ((CHAR *)buff,"Wavenumber RAM Drive"); |
emh203 | 0:76427232f435 | 847 | break; |
emh203 | 0:76427232f435 | 848 | |
emh203 | 0:76427232f435 | 849 | case ATA_GET_SN : /* Get serial number (20 chars) */ |
emh203 | 0:76427232f435 | 850 | strcpy ((CHAR *)buff,"12345"); |
emh203 | 0:76427232f435 | 851 | break; |
emh203 | 0:76427232f435 | 852 | default: |
emh203 | 0:76427232f435 | 853 | return RES_PARERR; |
emh203 | 0:76427232f435 | 854 | } |
emh203 | 0:76427232f435 | 855 | return RES_OK; |
emh203 | 0:76427232f435 | 856 | break; |
emh203 | 0:76427232f435 | 857 | |
emh203 | 0:76427232f435 | 858 | default: |
emh203 | 0:76427232f435 | 859 | return RES_PARERR; |
emh203 | 0:76427232f435 | 860 | break; |
emh203 | 0:76427232f435 | 861 | } |
emh203 | 0:76427232f435 | 862 | |
emh203 | 0:76427232f435 | 863 | return RES_OK; |
emh203 | 0:76427232f435 | 864 | } |
emh203 | 0:76427232f435 | 865 | |
emh203 | 0:76427232f435 | 866 | |
emh203 | 0:76427232f435 | 867 | /*-----------------------------------------------------------------------*/ |
emh203 | 0:76427232f435 | 868 | /* Device timer interrupt procedure */ |
emh203 | 0:76427232f435 | 869 | /*-----------------------------------------------------------------------*/ |
emh203 | 0:76427232f435 | 870 | /* This function must be called in period of 10ms */ |
emh203 | 0:76427232f435 | 871 | |
emh203 | 0:76427232f435 | 872 | void disk_timerproc (void) |
emh203 | 0:76427232f435 | 873 | { |
emh203 | 0:76427232f435 | 874 | static BYTE pv; |
emh203 | 0:76427232f435 | 875 | BYTE n; |
emh203 | 0:76427232f435 | 876 | |
emh203 | 0:76427232f435 | 877 | n = DiskProcTimer[CF]; /* 100Hz decrement timer */ |
emh203 | 0:76427232f435 | 878 | if (n) DiskProcTimer[CF] = --n; |
emh203 | 0:76427232f435 | 879 | |
emh203 | 0:76427232f435 | 880 | n = DiskProcTimer[USB]; /* 100Hz decrement timer */ |
emh203 | 0:76427232f435 | 881 | if (n) DiskProcTimer[USB] = --n; |
emh203 | 0:76427232f435 | 882 | |
emh203 | 0:76427232f435 | 883 | n = DiskProcTimer[RAM]; /* 100Hz decrement timer */ |
emh203 | 0:76427232f435 | 884 | if (n) DiskProcTimer[RAM] = --n; |
emh203 | 0:76427232f435 | 885 | |
emh203 | 0:76427232f435 | 886 | n = pv; |
emh203 | 0:76427232f435 | 887 | pv = COMPACT_FLASH_CARD_DETECTED ; /* Sapmle socket switch */ |
emh203 | 0:76427232f435 | 888 | |
emh203 | 0:76427232f435 | 889 | |
emh203 | 0:76427232f435 | 890 | //Check Compact Flash Card Detect |
emh203 | 0:76427232f435 | 891 | if (n == pv) { /* Have contacts stabled? */ |
emh203 | 0:76427232f435 | 892 | if (!COMPACT_FLASH_CARD_DETECTED ) |
emh203 | 0:76427232f435 | 893 | { /* CD1 or CD2 is high (Socket empty) */ |
emh203 | 0:76427232f435 | 894 | Stat[CF] |= (STA_NODISK | STA_NOINIT); |
emh203 | 0:76427232f435 | 895 | SET_DATA_BUS_TO_INPUTS; /* Float D0-D7 */ |
emh203 | 0:76427232f435 | 896 | COMPACT_FLASH_RESET_ACTIVE; /* Assert RESET# */ |
emh203 | 0:76427232f435 | 897 | COMPACT_FLASH_POWER_DISABLE; /* Power OFF */ |
emh203 | 0:76427232f435 | 898 | LED1_OFF; |
emh203 | 0:76427232f435 | 899 | } |
emh203 | 0:76427232f435 | 900 | else |
emh203 | 0:76427232f435 | 901 | { /* CD1 and CD2 are low (Card inserted) */ |
emh203 | 0:76427232f435 | 902 | Stat[CF] &= ~STA_NODISK; |
emh203 | 0:76427232f435 | 903 | LED1_ON; |
emh203 | 0:76427232f435 | 904 | } |
emh203 | 0:76427232f435 | 905 | } |
emh203 | 0:76427232f435 | 906 | |
emh203 | 0:76427232f435 | 907 | //Check to see if a USB drive is connected |
emh203 | 0:76427232f435 | 908 | if(USB_Disk_Detected>0) |
emh203 | 0:76427232f435 | 909 | LED2_ON; |
emh203 | 0:76427232f435 | 910 | else |
emh203 | 0:76427232f435 | 911 | LED2_OFF; |
emh203 | 0:76427232f435 | 912 | |
emh203 | 0:76427232f435 | 913 | } |
emh203 | 0:76427232f435 | 914 | |
emh203 | 0:76427232f435 | 915 | |
emh203 | 0:76427232f435 | 916 | DWORD get_fattime(void) |
emh203 | 0:76427232f435 | 917 | { |
emh203 | 0:76427232f435 | 918 | time_t CurrentTimeStamp; |
emh203 | 0:76427232f435 | 919 | tm *CurrentLocalTime; |
emh203 | 0:76427232f435 | 920 | DWORD FATFSTimeCode; |
emh203 | 0:76427232f435 | 921 | |
emh203 | 0:76427232f435 | 922 | CurrentTimeStamp = time(NULL); |
emh203 | 0:76427232f435 | 923 | CurrentLocalTime = localtime(&CurrentTimeStamp); |
emh203 | 0:76427232f435 | 924 | |
emh203 | 0:76427232f435 | 925 | //Map the tm struct time into the FatFs time code |
emh203 | 0:76427232f435 | 926 | FATFSTimeCode = ((CurrentLocalTime->tm_year-80)<<25) | |
emh203 | 0:76427232f435 | 927 | ((CurrentLocalTime->tm_mon+1)<<21) | |
emh203 | 0:76427232f435 | 928 | ((CurrentLocalTime->tm_mday)<<16) | |
emh203 | 0:76427232f435 | 929 | ((CurrentLocalTime->tm_hour)<<11) | |
emh203 | 0:76427232f435 | 930 | ((CurrentLocalTime->tm_min)<<5) | |
emh203 | 0:76427232f435 | 931 | ((CurrentLocalTime->tm_sec)); |
emh203 | 0:76427232f435 | 932 | |
emh203 | 0:76427232f435 | 933 | return FATFSTimeCode; |
emh203 | 0:76427232f435 | 934 | } |