ide.c 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. #include "main.h"
  2. #include "cmsis_os.h"
  3. #include "ide.h"
  4. /* register addresses are in format CS0 CS1 A2 A1 A0 */
  5. #define REG_DATA 0b01000
  6. #define REG_ERROR_FEATURES 0b01001
  7. #define REG_SECTOR_COUNT 0b01010
  8. #define REG_SECTOR 0b01011
  9. #define REG_CYL_LOW 0b01100
  10. #define REG_CYL_HIGH 0b01101
  11. #define REG_HEAD_DEVICE 0b01110
  12. #define REG_STATUS_COMMAND 0b01111
  13. #define BYTE_COUNT_LOW 0b10100
  14. #define BYTE_COUNT_HIGH 0b10101
  15. #define REG_CS0_MASK 0b00010000
  16. #define REG_CS1_MASK 0b00001000
  17. #define REG_DA2_MASK 0b00000100
  18. #define REG_DA1_MASK 0b00000010
  19. #define REG_DA0_MASK 0b00000001
  20. static uint32_t ide_current_bus_mode = GPIO_MODE_INPUT;
  21. static inline void ide_set_bus_mode(uint32_t mode) {
  22. if (ide_current_bus_mode == mode) {
  23. return; // already in requested mode
  24. }
  25. ide_current_bus_mode = mode;
  26. GPIO_InitTypeDef GPIO_InitStruct = {0};
  27. /*Configure GPIO pins : IDE_DD4_Pin IDE_DD5_Pin IDE_DD6_Pin IDE_DD7_Pin
  28. IDE_DD8_Pin IDE_DD9_Pin IDE_DD10_Pin IDE_DD11_Pin
  29. IDE_DD12_Pin IDE_DD13_Pin IDE_DD14_Pin IDE_DD15_Pin */
  30. GPIO_InitStruct.Pin = IDE_DD4_Pin|IDE_DD5_Pin|IDE_DD6_Pin|IDE_DD7_Pin
  31. |IDE_DD8_Pin|IDE_DD9_Pin|IDE_DD10_Pin|IDE_DD11_Pin
  32. |IDE_DD12_Pin|IDE_DD13_Pin|IDE_DD14_Pin|IDE_DD15_Pin;
  33. GPIO_InitStruct.Mode = mode;
  34. GPIO_InitStruct.Pull = GPIO_NOPULL;
  35. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  36. HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
  37. /*Configure GPIO pins : IDE_DD0_Pin IDE_DD1_Pin IDE_DD2_Pin IDE_DD3_Pin */
  38. GPIO_InitStruct.Pin = IDE_DD0_Pin|IDE_DD1_Pin|IDE_DD2_Pin|IDE_DD3_Pin;
  39. GPIO_InitStruct.Mode = mode;
  40. GPIO_InitStruct.Pull = GPIO_NOPULL;
  41. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  42. HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
  43. }
  44. #define PORTD_BUS_IDR_MASK 0b00000000000000000000000000001111
  45. #define PORTE_BUS_IDR_MASK 0b00000000000000001111111111110000
  46. #define PORTD_BUS_BSRR_MASK 0b0000000000001111
  47. #define PORTE_BUS_BSRR_MASK 0b1111111111110000
  48. #define CORE_CLOCK_HZ 218E6 // 168 MHz
  49. #define CORE_CYCLE_TIME_S (1 / CORE_CLOCK_HZ)
  50. #define CORE_CYCLE_TIME_NS ((int)(CORE_CYCLE_TIME_S * 1E9 + 1)) // 6ns
  51. #define NDELAY_CYCLES_PER_ITERATION 3
  52. static inline void ide_ndelay(unsigned int ns) {
  53. unsigned int iterations = (ns / CORE_CYCLE_TIME_NS) / NDELAY_CYCLES_PER_ITERATION + 1;
  54. asm volatile (
  55. "0: subs %[i], 1;"
  56. "bne 0b;"
  57. : [i] "+r" (iterations)
  58. );
  59. }
  60. static void ide_select_register(uint8_t reg) {
  61. HAL_GPIO_WritePin(IDE_CS0_GPIO_Port, IDE_CS0_Pin, reg & REG_CS0_MASK ? GPIO_PIN_SET : GPIO_PIN_RESET);
  62. HAL_GPIO_WritePin(IDE_CS1_GPIO_Port, IDE_CS1_Pin, reg & REG_CS1_MASK ? GPIO_PIN_SET : GPIO_PIN_RESET);
  63. HAL_GPIO_WritePin(IDE_DA0_GPIO_Port, IDE_DA0_Pin, reg & REG_DA0_MASK ? GPIO_PIN_SET : GPIO_PIN_RESET);
  64. HAL_GPIO_WritePin(IDE_DA1_GPIO_Port, IDE_DA1_Pin, reg & REG_DA1_MASK ? GPIO_PIN_SET : GPIO_PIN_RESET);
  65. HAL_GPIO_WritePin(IDE_DA2_GPIO_Port, IDE_DA2_Pin, reg & REG_DA2_MASK ? GPIO_PIN_SET : GPIO_PIN_RESET);
  66. }
  67. static uint16_t ide_register_read(uint8_t reg) {
  68. ide_set_bus_mode(GPIO_MODE_INPUT);
  69. ide_select_register(reg);
  70. ide_ndelay(70);
  71. HAL_GPIO_WritePin(IDE_DIOR_GPIO_Port, IDE_DIOR_Pin, GPIO_PIN_RESET); // flash read strobe (active low)
  72. ide_ndelay(290);
  73. uint16_t result = (uint16_t)((GPIOD->IDR & PORTD_BUS_IDR_MASK) | (GPIOE->IDR & PORTE_BUS_IDR_MASK));
  74. HAL_GPIO_WritePin(IDE_DIOR_GPIO_Port, IDE_DIOR_Pin, GPIO_PIN_SET); // release read strobe
  75. return result;
  76. }
  77. static void ide_register_write(uint8_t reg, uint16_t word) {
  78. ide_set_bus_mode(GPIO_MODE_OUTPUT_PP);
  79. ide_select_register(reg);
  80. GPIOD->BSRR = ((~word & PORTD_BUS_BSRR_MASK) << 16) | (word & PORTD_BUS_BSRR_MASK);
  81. GPIOE->BSRR = ((~word & PORTE_BUS_BSRR_MASK) << 16) | (word & PORTE_BUS_BSRR_MASK);
  82. ide_ndelay(70);
  83. HAL_GPIO_WritePin(IDE_DIOW_GPIO_Port, IDE_DIOW_Pin, GPIO_PIN_RESET); // flash write strobe (active low)
  84. ide_ndelay(290);
  85. HAL_GPIO_WritePin(IDE_DIOW_GPIO_Port, IDE_DIOW_Pin, GPIO_PIN_SET); // release write strobe
  86. ide_ndelay(60);
  87. ide_set_bus_mode(GPIO_MODE_INPUT);
  88. }
  89. static void ide_error() {
  90. /*uint16_t error = ide_register_read_once(REG_ERROR_FEATURES);
  91. int amnf = error & 0b00000001;
  92. int tk0nf = error & 0b00000010;
  93. int abrt = error & 0b00000100;
  94. int mcr = error & 0b00001000;
  95. int idnf = error & 0b00010000;
  96. int mc = error & 0b00100000;
  97. int unc = error & 0b01000000;*/
  98. HAL_GPIO_WritePin(IDE_RESET_GPIO_Port, IDE_RESET_Pin, GPIO_PIN_RESET);
  99. while(1) {
  100. HAL_GPIO_TogglePin(LED_2_GPIO_Port, LED_2_Pin);
  101. osDelay(100);
  102. }
  103. }
  104. int ide_ready() {
  105. uint16_t status = ide_register_read(REG_STATUS_COMMAND);
  106. if (status & 1) ide_error();
  107. int ready = status & 0b0000000001000000;
  108. int busy = status & 0b0000000010000000;
  109. return ready && !busy;
  110. }
  111. static int ide_drq() {
  112. uint16_t status = ide_register_read(REG_STATUS_COMMAND);
  113. if (status & 1) ide_error();
  114. return status & 0b0000000000001000;
  115. }
  116. static void ide_set_lba(uint32_t lba, uint16_t sector_count) { // 28 bit lba
  117. ide_register_write(REG_HEAD_DEVICE, (uint8_t)((lba & 0x0F000000) >> 24) | 0b11100000); // master device, LBA mode, lba most significant 4 bits
  118. ide_register_write(REG_CYL_HIGH, (uint8_t)((lba & 0x00FF0000) >> 16));
  119. ide_register_write(REG_CYL_LOW, (uint8_t)((lba & 0x0000FF00) >> 8));
  120. ide_register_write(REG_SECTOR, (uint8_t)((lba & 0x000000FF)));
  121. ide_register_write(REG_SECTOR_COUNT, sector_count);
  122. }
  123. static void ide_reset() {
  124. // never drive the bus unless when actually writing
  125. ide_set_bus_mode(GPIO_MODE_INPUT);
  126. // read/write strobes are active low -> normally keep them pulled high
  127. HAL_GPIO_WritePin(IDE_DIOR_GPIO_Port, IDE_DIOR_Pin, GPIO_PIN_SET);
  128. HAL_GPIO_WritePin(IDE_DIOW_GPIO_Port, IDE_DIOW_Pin, GPIO_PIN_SET);
  129. // now enable the level shifters, connecting the MCU and the IDE device
  130. HAL_GPIO_WritePin(TXS0108E_OE_GPIO_Port, TXS0108E_OE_Pin, GPIO_PIN_SET);
  131. // start device reset
  132. HAL_GPIO_WritePin(IDE_RESET_GPIO_Port, IDE_RESET_Pin, GPIO_PIN_RESET);
  133. // wait for the device to reset
  134. osDelay(1);
  135. HAL_GPIO_WritePin(IDE_RESET_GPIO_Port, IDE_RESET_Pin, GPIO_PIN_SET);
  136. osDelay(4);
  137. ide_register_write(REG_HEAD_DEVICE, 0b11100000); // select master device and LBA mode
  138. // set PIO default mode without IORDY
  139. ide_register_write(REG_SECTOR_COUNT, 0x01); // PIO default mode, disable IORDY (ACS-4 7.43.4)
  140. ide_register_write(REG_ERROR_FEATURES, 0x03); // "Set transfer mode" (ACS-4 7.43.2)
  141. ide_register_write(REG_STATUS_COMMAND, 0xEF); // SET FEATURES (ACS-4 7.43)
  142. while(!ide_ready());
  143. }
  144. void ide_read_next_sector(uint8_t* buf) {
  145. uint16_t* buf16 = (uint16_t*) buf;
  146. while(!ide_drq());
  147. ide_set_bus_mode(GPIO_MODE_INPUT);
  148. ide_select_register(REG_DATA);
  149. ide_ndelay(70);
  150. for (int i = 0; i < 256; i++) {
  151. HAL_GPIO_WritePin(IDE_DIOR_GPIO_Port, IDE_DIOR_Pin, GPIO_PIN_RESET); // flash read strobe (active low)
  152. ide_ndelay(165);
  153. buf16[i] = (uint16_t)((GPIOD->IDR & PORTD_BUS_IDR_MASK) | (GPIOE->IDR & PORTE_BUS_IDR_MASK));
  154. HAL_GPIO_WritePin(IDE_DIOR_GPIO_Port, IDE_DIOR_Pin, GPIO_PIN_SET); // release read strobe
  155. }
  156. ide_ndelay(600);
  157. }
  158. static void ide_identify_device(uint8_t* buf) {
  159. while(!ide_ready());
  160. ide_register_write(REG_STATUS_COMMAND, 0xEC);
  161. ide_read_next_sector(buf);
  162. }
  163. void ide_init() {
  164. ide_reset();
  165. }
  166. int ide_get_num_sectors() {
  167. uint16_t buf[256];
  168. ide_identify_device((uint8_t*) buf);
  169. return ((uint32_t)(buf[61]) << 16) | ((uint32_t)(buf[60]));
  170. }
  171. void ide_begin_read_sectors(uint32_t lba, uint16_t num_sectors) {
  172. while(!ide_ready());
  173. ide_set_lba(lba, num_sectors);
  174. ide_register_write(REG_STATUS_COMMAND, 0x20);
  175. }
  176. void ide_write_next_sector(uint8_t* buf) {
  177. uint16_t* buf16 = (uint16_t*) buf;
  178. while(!ide_drq());
  179. ide_set_bus_mode(GPIO_MODE_OUTPUT_PP);
  180. ide_select_register(REG_DATA);
  181. ide_ndelay(70);
  182. for (int i = 0; i < 256; i++) {
  183. uint16_t word = buf16[i];
  184. GPIOD->BSRR = ((~word & PORTD_BUS_BSRR_MASK) << 16) | (word & PORTD_BUS_BSRR_MASK);
  185. GPIOE->BSRR = ((~word & PORTE_BUS_BSRR_MASK) << 16) | (word & PORTE_BUS_BSRR_MASK);
  186. ide_ndelay(60);
  187. HAL_GPIO_WritePin(IDE_DIOW_GPIO_Port, IDE_DIOW_Pin, GPIO_PIN_RESET); // flash write strobe (active low)
  188. ide_ndelay(165);
  189. HAL_GPIO_WritePin(IDE_DIOW_GPIO_Port, IDE_DIOW_Pin, GPIO_PIN_SET); // release write strobe
  190. }
  191. ide_ndelay(600);
  192. ide_set_bus_mode(GPIO_MODE_INPUT);
  193. }
  194. void ide_begin_write_sectors(uint32_t lba, uint16_t num_sectors) {
  195. while(!ide_ready());
  196. ide_set_lba(lba, num_sectors);
  197. ide_register_write(REG_STATUS_COMMAND, 0x30);
  198. }