Compact Flash I/O test

Dependencies:   mbed

Committer:
emh203
Date:
Tue Dec 27 02:03:56 2011 +0000
Revision:
0:6b1e6c9e48ba
Child:
1:dc171f34db9b

        

Who changed what in which revision?

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