|
@@ -9,6 +9,71 @@
|
|
|
* See the file COPYING for more details, or visit <http://unlicense.org>.
|
|
|
*/
|
|
|
|
|
|
+uint8_t board_id;
|
|
|
+
|
|
|
+#define early_delay_ms(ms) (delay_ticks((ms)*2000))
|
|
|
+#define early_delay_us(ms) (delay_ticks((ms)*2))
|
|
|
+
|
|
|
+/* Blink the activity LED to indicate fatal error. */
|
|
|
+static void early_fatal(int blinks) __attribute__((noreturn));
|
|
|
+static void early_fatal(int blinks)
|
|
|
+{
|
|
|
+ int i;
|
|
|
+ rcc->ahb1enr |= RCC_AHB1ENR_GPIOBEN;
|
|
|
+ delay_ticks(10);
|
|
|
+ gpio_configure_pin(gpiob, 13, GPO_pushpull(IOSPD_LOW, HIGH));
|
|
|
+ for (;;) {
|
|
|
+ for (i = 0; i < blinks; i++) {
|
|
|
+ gpio_write_pin(gpiob, 13, LOW);
|
|
|
+ early_delay_ms(150);
|
|
|
+ gpio_write_pin(gpiob, 13, HIGH);
|
|
|
+ early_delay_ms(150);
|
|
|
+ }
|
|
|
+ early_delay_ms(2000);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static void board_id_init(void)
|
|
|
+{
|
|
|
+ uint16_t low, high;
|
|
|
+ uint8_t id = 0;
|
|
|
+ int i;
|
|
|
+
|
|
|
+ rcc->ahb1enr |= RCC_AHB1ENR_GPIOCEN;
|
|
|
+ early_delay_us(2);
|
|
|
+
|
|
|
+ /* Pull PC[15:13] low, and check which are tied HIGH. */
|
|
|
+ for (i = 0; i < 3; i++)
|
|
|
+ gpio_configure_pin(gpioc, 13+i, GPI_pull_down);
|
|
|
+ early_delay_us(10);
|
|
|
+ high = (gpioc->idr >> 13) & 7;
|
|
|
+
|
|
|
+ /* Pull PC[15:13] high, and check which are tied LOW. */
|
|
|
+ for (i = 0; i < 3; i++)
|
|
|
+ gpio_configure_pin(gpioc, 13+i, GPI_pull_up);
|
|
|
+ early_delay_us(10);
|
|
|
+ low = (~gpioc->idr >> 13) & 7;
|
|
|
+
|
|
|
+ /* Each PCx pin defines a 'trit': 0=float, 1=low, 2=high.
|
|
|
+ * We build a 3^3 ID space from the resulting three-trit ID. */
|
|
|
+ for (i = 0; i < 3; i++) {
|
|
|
+ id *= 3;
|
|
|
+ switch ((high>>1&2) | (low>>2&1)) {
|
|
|
+ case 0: break; /* float = 0 */
|
|
|
+ case 1: id += 1; break; /* LOW = 1 */
|
|
|
+ case 2: id += 2; break; /* HIGH = 2 */
|
|
|
+ case 3: early_fatal(1); /* cannot be tied HIGH *and* LOW! */
|
|
|
+ }
|
|
|
+ high <<= 1;
|
|
|
+ low <<= 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Panic if the ID is unrecognised. */
|
|
|
+ board_id = id;
|
|
|
+ if (board_id != 0)
|
|
|
+ early_fatal(2);
|
|
|
+}
|
|
|
+
|
|
|
static void clock_init(void)
|
|
|
{
|
|
|
/* Flash controller: reads require 7 wait states at 216MHz. */
|
|
@@ -46,10 +111,6 @@ static void clock_init(void)
|
|
|
|
|
|
/* Internal oscillator no longer needed. */
|
|
|
rcc->cr &= ~RCC_CR_HSION;
|
|
|
-
|
|
|
- /* Enable SysTick counter at 216MHz/8 = 27MHz. */
|
|
|
- stk->load = STK_MASK;
|
|
|
- stk->ctrl = STK_CTRL_ENABLE;
|
|
|
}
|
|
|
|
|
|
void peripheral_clock_delay(void)
|
|
@@ -78,6 +139,7 @@ static void peripheral_init(void)
|
|
|
void stm32_init(void)
|
|
|
{
|
|
|
cortex_init();
|
|
|
+ board_id_init();
|
|
|
clock_init();
|
|
|
icache_enable();
|
|
|
dcache_enable();
|