board.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. /*
  2. * f7/board.c
  3. *
  4. * Board-specific setup and management.
  5. *
  6. * Written & released by Keir Fraser <keir.xen@gmail.com>
  7. *
  8. * This is free and unencumbered software released into the public domain.
  9. * See the file COPYING for more details, or visit <http://unlicense.org>.
  10. */
  11. #define gpio_led gpiob
  12. #define pin_led 13
  13. #define gpio_led2 gpioe
  14. #define pin_led2 1
  15. #define gpio_led3 gpioe
  16. #define pin_led3 2
  17. #define gpio_tr43 gpioe
  18. #define pin_tr43_0 12
  19. #define pin_tr43_1 11
  20. const static struct pin_mapping _msel_pins_std[] = {
  21. { 10, _B, 1 },
  22. { 12, _B, 0 },
  23. { 14, _B, 11 },
  24. { 16, _B, 10 },
  25. { 0, 0, 0 }
  26. };
  27. const static struct pin_mapping _msel_pins_f7_slim[] = {
  28. { 10, _B, 1 },
  29. { 14, _B, 11 },
  30. { 0, 0, 0 }
  31. };
  32. const static struct pin_mapping _user_pins_F7SM_v1[] = {
  33. { 2, _B, 12, _OD },
  34. { 0, 0, 0, _OD } };
  35. const static struct pin_mapping _user_pins_F7SM_ant_goffart_f7_plus_v1[] = {
  36. { 2, _B, 12, _OD }, /* board bug: B12 isn't buffered */
  37. { 4, _C, 6, _PP },
  38. { 0, 0, 0, _PP } };
  39. const static struct pin_mapping _user_pins_F7SM_lightning[] = {
  40. { 2, _B, 12, _PP },
  41. { 4, _E, 15, _PP },
  42. { 6, _E, 14, _PP },
  43. { 0, 0, 0, _PP } };
  44. const static struct pin_mapping _user_pins_F7SM_v2[] = {
  45. { 2, _B, 12, _OD },
  46. { 4, _C, 8, _OD },
  47. { 6, _C, 7, _OD },
  48. { 0, 0, 0, _OD } };
  49. const static struct pin_mapping _user_pins_F7SM_ant_goffart_f7_plus_v2[] = {
  50. { 2, _B, 12, _PP },
  51. { 4, _C, 8, _PP },
  52. { 6, _C, 7, _PP },
  53. { 0, 0, 0, _PP } };
  54. const static struct pin_mapping _user_pins_F7SM_lightning_plus[] = {
  55. { 2, _B, 12, _PP },
  56. { 4, _E, 15, _PP },
  57. { 6, _E, 14, _PP },
  58. { 0, 0, 0, _PP } };
  59. const static struct pin_mapping _user_pins_F7SM_slim[] = {
  60. { 0, 0, 0, _PP } };
  61. const static struct pin_mapping _user_pins_F7SM_v3[] = {
  62. { 2, _B, 12, _PP },
  63. { 4, _C, 8, _PP },
  64. { 6, _C, 7, _PP },
  65. { 0, 0, 0, _PP } };
  66. const static struct board_config _board_config[] = {
  67. [F7SM_v1] = {
  68. .hse_mhz = 8,
  69. .user_pins = _user_pins_F7SM_v1,
  70. .msel_pins = _msel_pins_std },
  71. [F7SM_ant_goffart_f7_plus_v1] = {
  72. .hse_mhz = 8,
  73. .user_pins = _user_pins_F7SM_ant_goffart_f7_plus_v1,
  74. .msel_pins = _msel_pins_std },
  75. [F7SM_lightning] = {
  76. .hse_mhz = 16,
  77. .hs_usb = TRUE,
  78. .user_pins = _user_pins_F7SM_lightning,
  79. .msel_pins = _msel_pins_std },
  80. [F7SM_v2] = {
  81. .hse_mhz = 8,
  82. .user_pins = _user_pins_F7SM_v2,
  83. .msel_pins = _msel_pins_std },
  84. [F7SM_ant_goffart_f7_plus_v2] = {
  85. .hse_mhz = 8,
  86. .user_pins = _user_pins_F7SM_ant_goffart_f7_plus_v2,
  87. .msel_pins = _msel_pins_std },
  88. [F7SM_lightning_plus] = {
  89. .hse_mhz = 16,
  90. .hse_byp = TRUE,
  91. .hs_usb = TRUE,
  92. .flippy = TRUE,
  93. .user_pins = _user_pins_F7SM_lightning_plus,
  94. .msel_pins = _msel_pins_std },
  95. [F7SM_slim] = {
  96. .hse_mhz = 16,
  97. .hse_byp = TRUE,
  98. .user_pins = _user_pins_F7SM_slim,
  99. .msel_pins = _msel_pins_f7_slim },
  100. [F7SM_v3] = {
  101. .hse_mhz = 8,
  102. .flippy = TRUE,
  103. .user_pins = _user_pins_F7SM_v3,
  104. .msel_pins = _msel_pins_std },
  105. };
  106. /* Blink the activity LED to indicate fatal error. */
  107. void early_fatal(int blinks)
  108. {
  109. int i;
  110. rcc->ahb1enr |= RCC_AHB1ENR_GPIOBEN;
  111. delay_ticks(10);
  112. gpio_configure_pin(gpio_led, pin_led, GPO_pushpull(IOSPD_LOW, HIGH));
  113. for (;;) {
  114. for (i = 0; i < blinks; i++) {
  115. gpio_write_pin(gpio_led, pin_led, LOW);
  116. early_delay_ms(150);
  117. gpio_write_pin(gpio_led, pin_led, HIGH);
  118. early_delay_ms(150);
  119. }
  120. early_delay_ms(2000);
  121. }
  122. }
  123. void identify_board_config(void)
  124. {
  125. uint16_t low, high;
  126. uint8_t id = 0;
  127. int i;
  128. rcc->ahb1enr |= RCC_AHB1ENR_GPIOCEN;
  129. early_delay_us(2);
  130. /* Pull PC[15:13] low, and check which are tied HIGH. */
  131. for (i = 0; i < 3; i++)
  132. gpio_configure_pin(gpioc, 13+i, GPI_pull_down);
  133. early_delay_us(10);
  134. high = (gpioc->idr >> 13) & 7;
  135. /* Pull PC[15:13] high, and check which are tied LOW. */
  136. for (i = 0; i < 3; i++)
  137. gpio_configure_pin(gpioc, 13+i, GPI_pull_up);
  138. early_delay_us(10);
  139. low = (~gpioc->idr >> 13) & 7;
  140. /* Setup input pins for TR43 more fixes below needed */
  141. gpio_configure_pin(gpio_tr43, pin_tr43_0, GPI_pull_up);
  142. gpio_configure_pin(gpio_tr43, pin_tr43_1, GPI_pull_up);
  143. /* Each PCx pin defines a 'trit': 0=float, 1=low, 2=high.
  144. * We build a 3^3 ID space from the resulting three-trit ID. */
  145. for (i = 0; i < 3; i++) {
  146. id *= 3;
  147. switch ((high>>1&2) | (low>>2&1)) {
  148. case 0: break; /* float = 0 */
  149. case 1: id += 1; break; /* LOW = 1 */
  150. case 2: id += 2; break; /* HIGH = 2 */
  151. case 3: early_fatal(1); /* cannot be tied HIGH *and* LOW! */
  152. }
  153. high <<= 1;
  154. low <<= 1;
  155. }
  156. /* Panic if the ID is unrecognised. */
  157. if (id >= ARRAY_SIZE(_board_config))
  158. early_fatal(2);
  159. gw_info.hw_submodel = id;
  160. board_config = &_board_config[id];
  161. gw_info.mcu_mhz = SYSCLK_MHZ;
  162. gw_info.mcu_sram_kb = 256;
  163. }
  164. static void mcu_board_init(void)
  165. {
  166. uint16_t pu[] = {
  167. [_A] = 0x9930, /* PA4-5,8,11-12,15 */
  168. [_B] = 0x2ffb, /* PB0-1,3-11,13 */
  169. [_C] = 0xffe7, /* PC0-2,5-15 */
  170. [_D] = 0xffff, /* PD0-15 */
  171. [_E] = 0xffff, /* PE0-15 */
  172. [_F] = 0xffff, /* PF0-15 */
  173. [_G] = 0xffff, /* PG0-15 */
  174. [_H] = 0xffff, /* PH0-15 */
  175. [_I] = 0xffff, /* PI0-15 */
  176. };
  177. uint32_t ahb1enr = rcc->ahb1enr;
  178. const struct pin_mapping *mpin;
  179. const struct pin_mapping *upin;
  180. /* Enable all GPIO bank register clocks to configure unused pins. */
  181. rcc->ahb1enr |= (RCC_AHB1ENR_GPIOAEN |
  182. RCC_AHB1ENR_GPIOBEN |
  183. RCC_AHB1ENR_GPIOCEN |
  184. RCC_AHB1ENR_GPIODEN |
  185. RCC_AHB1ENR_GPIOEEN |
  186. RCC_AHB1ENR_GPIOFEN |
  187. RCC_AHB1ENR_GPIOGEN |
  188. RCC_AHB1ENR_GPIOHEN |
  189. RCC_AHB1ENR_GPIOIEN);
  190. peripheral_clock_delay();
  191. /* MSEL pins: do not default these pins to pull-up mode. */
  192. for (mpin = board_config->msel_pins; mpin->pin_id != 0; mpin++)
  193. pu[mpin->gpio_bank] &= ~(1u << mpin->gpio_pin);
  194. /* Keep clock enabled for all banks containing user-modifiable pins.
  195. * Also do not default these pins to pull-up mode. */
  196. for (upin = board_config->user_pins; upin->pin_id != 0; upin++) {
  197. ahb1enr |= 1u << upin->gpio_bank;
  198. pu[upin->gpio_bank] &= ~(1u << upin->gpio_pin);
  199. }
  200. /* Flippy TRK0_DISABLE output: Set inactive (LOW). */
  201. if (board_config->flippy) {
  202. gpio_configure_pin(gpioc, 1, GPO_pushpull(IOSPD_LOW, LOW));
  203. pu[_C] &= ~(1u << 1); /* PC1 */
  204. }
  205. switch (gw_info.hw_submodel) {
  206. case F7SM_slim:
  207. /* Extra pins should float in case they are inputs (drive->GW). */
  208. pu[_B] &= ~((1u << 0) | (1u << 12)); /* PB0, PB12 */
  209. pu[_C] &= ~((1u << 7) | ~(1u << 8)); /* PC7, PC8 */
  210. break;
  211. case F7SM_v3:
  212. case F7SM_lightning_plus:
  213. /* Floppy pin 34 input line is externally pulled up. */
  214. pu[_C] &= ~(1u << 2); /* PC2 */
  215. break;
  216. }
  217. gpio_pull_up_pins(gpioa, pu[_A]);
  218. gpio_pull_up_pins(gpiob, pu[_B]);
  219. gpio_pull_up_pins(gpioc, pu[_C]);
  220. gpio_pull_up_pins(gpiod, pu[_D]);
  221. gpio_pull_up_pins(gpioe, pu[_E]);
  222. gpio_pull_up_pins(gpiof, pu[_F]);
  223. gpio_pull_up_pins(gpiog, pu[_G]);
  224. gpio_pull_up_pins(gpioh, pu[_H]);
  225. gpio_pull_up_pins(gpioi, pu[_I]);
  226. /* Unused GPIO banks can have their clocks disabled again. They will
  227. * statically hold their configuration state. */
  228. peripheral_clock_delay();
  229. rcc->ahb1enr = ahb1enr;
  230. }
  231. /*
  232. * Local variables:
  233. * mode: C
  234. * c-file-style: "Linux"
  235. * c-basic-offset: 4
  236. * tab-width: 4
  237. * indent-tabs-mode: nil
  238. * End:
  239. */