got the bootloader->main handoff working
diff --git a/bbb_cape/src/cape/Makefile b/bbb_cape/src/cape/Makefile
index 5046615..d74e700 100644
--- a/bbb_cape/src/cape/Makefile
+++ b/bbb_cape/src/cape/Makefile
@@ -45,6 +45,7 @@
OBJECTS_bootloader := bootloader \
uart_common \
uart_byte \
+ led \
OBJECTS_main_test := $(OBJECTS_main_common) \
robot_test \
diff --git a/bbb_cape/src/cape/analog.c b/bbb_cape/src/cape/analog.c
index 0ccd2f0..58a1563 100644
--- a/bbb_cape/src/cape/analog.c
+++ b/bbb_cape/src/cape/analog.c
@@ -28,7 +28,7 @@
// (100ns+8ns)*120MHz = 12.96
// Clear the CSEL pin to select it.
- for (int i = 0; i < 9; ++i) CSEL_GPIO->BSRRH = 1 << CSEL_NUM;
+ for (int i = 0; i < 9; ++i) CSEL_GPIO->BSRRL = 1 << CSEL_NUM;
current_channel = channel;
uint16_t data = 1 << 8 /* start bit */ |
0 << 7 /* not differential */ |
@@ -43,7 +43,7 @@
// Masking off the high bits is important because there's nothing driving
// the MISO line during the time the MCU receives them.
analog_readings[current_channel] = value & 0x3FF;
- CSEL_GPIO->BSRRL = 1 << CSEL_NUM;
+ CSEL_GPIO->BSRRH = 1 << CSEL_NUM;
TIM->CR1 = TIM_CR1_UDIS;
TIM->CCR1 = 1;
@@ -66,7 +66,7 @@
RCC->APB1ENR |= RCC_APB1ENR_TIMEN;
gpio_setup_out(CSEL_GPIO, CSEL_NUM, 3);
- CSEL_GPIO->BSRRL = 1 << CSEL_NUM; // make sure it's deselected
+ CSEL_GPIO->BSRRH = 1 << CSEL_NUM; // make sure it's deselected
gpio_setup_alt(GPIOB, 13, 5); // SCK
gpio_setup_alt(GPIOB, 14, 5); // MISO
diff --git a/bbb_cape/src/cape/bootloader.c b/bbb_cape/src/cape/bootloader.c
index 1ed6218..3ff86af 100644
--- a/bbb_cape/src/cape/bootloader.c
+++ b/bbb_cape/src/cape/bootloader.c
@@ -3,6 +3,7 @@
#include <STM32F2XX.h>
#include "cape/bootloader_handoff.h"
+#include "cape/led.h"
// Sets everything up and then jumps to the main code.
static void jump_to_main(void) __attribute__((noreturn));
@@ -15,12 +16,58 @@
__builtin_unreachable();
}
-void _start(void) {
- SYSCFG->CMPCR = SYSCFG_CMPCR_CMP_PD; // enable IO compensation cell
- while (!(SYSCFG->CMPCR & SYSCFG_CMPCR_READY)) {} // wait for it to be ready
+static void setup_main_clock(void) {
+ // We set up a couple of registers here separately from the actual register to
+ // avoid having to think about what happens when the value is in some
+ // intermediate state.
+ RCC->CR |= RCC_CR_HSEON; // get the HSE oscillator going
+
+ FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN | FLASH_ACR_DCEN |
+ FLASH_ACR_LATENCY_3WS;
+
+ uint32_t rcc_pllcfgr = 0;
+ rcc_pllcfgr |= RCC_PLLCFGR_PLLSRC; // use the external oscillator
+ // 8MHz * 120 / 4 / 2 = 120MHz
+ rcc_pllcfgr |= 120 << 6; // multiplier
+ rcc_pllcfgr |= 4; // divider
+ rcc_pllcfgr |= 5 << 24; // other stuff divider = 5, just in case
+ RCC->PLLCFGR = rcc_pllcfgr;
+
+ uint32_t rcc_cfgr = 0;
+ rcc_cfgr |= 4 << 13; // APB2 divider = 2
+ rcc_cfgr |= 5 << 10; // APB1 divider = 4
+ rcc_cfgr |= 2; // use the PLL
+
+ // Wait for the HSE oscillator to be stable.
+ while (!(RCC->CR & RCC_CR_HSERDY)) {}
+
+ RCC->CR |= RCC_CR_PLLON;
+ // Wait for the main PLL to be stable.
+ while (!(RCC->CR & RCC_CR_PLLRDY)) {}
+ // Wait until the flash is using 3 wait states.
+ while ((FLASH->ACR & 7) != 3) {}
+ RCC->CFGR = rcc_cfgr;
+ // Wait until we are using the PLL as our main clock source.
+ while ((RCC->CFGR & (3 << 2)) != (2 << 2)) {}
+}
+
+void _start(void) {
+ // Enable the GPIO pin clocks.
// We don't have anything on the 1 port D pin, so don't bother enabling it.
- RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOBEN | RCC_AHB1ENR_GPIOCEN;
+ RCC->AHB1ENR |=
+ RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOBEN | RCC_AHB1ENR_GPIOCEN;
+ led_init();
+ led_set(LED_ERR, 1);
+
+ setup_main_clock();
+
+#if 0
+ SYSCFG->CMPCR |= SYSCFG_CMPCR_CMP_PD; // enable IO compensation cell
+ while (!(SYSCFG->CMPCR & SYSCFG_CMPCR_READY)) {} // wait for it to be ready
+ TODO(brians): Figure out what the story with this is.
+#endif
+ led_set(LED_DB, 1);
jump_to_main();
}
diff --git a/bbb_cape/src/cape/bootloader.ld b/bbb_cape/src/cape/bootloader.ld
index 21aaa00..6751529 100644
--- a/bbb_cape/src/cape/bootloader.ld
+++ b/bbb_cape/src/cape/bootloader.ld
@@ -1,7 +1,7 @@
MEMORY
{
- FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x08000 /* 32k */
- RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x20000 /* 128k */
+ FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 16k
+ RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 128k
}
SECTIONS
diff --git a/bbb_cape/src/cape/bootloader_handoff.h b/bbb_cape/src/cape/bootloader_handoff.h
index d0fcde8..1e48e90 100644
--- a/bbb_cape/src/cape/bootloader_handoff.h
+++ b/bbb_cape/src/cape/bootloader_handoff.h
@@ -5,7 +5,7 @@
// the bootloader and the main code.
// How much flash the bootloader has (starting at address 0).
-#define BOOTLOADER_FLASH_SIZE 0x8000
+#define BOOTLOADER_FLASH_SIZE 0x4000
// Where the main code's flash starts.
#define MAIN_FLASH_START BOOTLOADER_FLASH_SIZE
diff --git a/bbb_cape/src/cape/fill_packet.c b/bbb_cape/src/cape/fill_packet.c
index 700df1d..ad7396e 100644
--- a/bbb_cape/src/cape/fill_packet.c
+++ b/bbb_cape/src/cape/fill_packet.c
@@ -11,7 +11,6 @@
#include "cape/crc.h"
#include "cape/bootloader_handoff.h"
#include "cape/gyro.h"
-#include "cape/led.h"
#include "cape/analog.h"
#include "cape/robot.h"
#include "cape/digital.h"
@@ -73,7 +72,6 @@
TIMESTAMP_TIM->CR1 |= TIM_CR1_CEN;
crc_init();
- led_init();
analog_init();
encoder_init();
gyro_init();
diff --git a/bbb_cape/src/cape/gyro.c b/bbb_cape/src/cape/gyro.c
index 80accb9..43006fd 100644
--- a/bbb_cape/src/cape/gyro.c
+++ b/bbb_cape/src/cape/gyro.c
@@ -97,7 +97,7 @@
// Do it 8 times (9 cycles) to wait for the amount of time the gyro datasheet
// says we need to.
// (1/2/(7.5MHz)+8ns)*120MHz = 8.96
- for (int i = 0; i < 8; ++i) CSEL_GPIO->BSRRH = 1 << CSEL_NUM;
+ for (int i = 0; i < 8; ++i) CSEL_GPIO->BSRRL = 1 << CSEL_NUM;
}
// Blocks until there is space to enqueue data.
@@ -265,7 +265,7 @@
uint32_t full_value = high_value << 16 | value;
// Set the CSEL pin high to deselect it.
// The parity calculation etc took long enough that this is safe now.
- CSEL_GPIO->BSRRL = 1 << CSEL_NUM;
+ CSEL_GPIO->BSRRH = 1 << CSEL_NUM;
reading_received(full_value);
}
}
@@ -364,7 +364,7 @@
// It's is just a GPIO pin because we're the master (it would be special if we
// were a slave).
gpio_setup_out(CSEL_GPIO, CSEL_NUM, 3);
- CSEL_GPIO->BSRRL = 1 << CSEL_NUM; // make sure it's deselected
+ CSEL_GPIO->BSRRH = 1 << CSEL_NUM; // make sure it's deselected
// Set up SCK, MISO, and MOSI.
gpio_setup_alt(GPIOC, 10, 6); // SCK
diff --git a/bbb_cape/src/cape/led.c b/bbb_cape/src/cape/led.c
index 1968f96..97d5a06 100644
--- a/bbb_cape/src/cape/led.c
+++ b/bbb_cape/src/cape/led.c
@@ -13,9 +13,9 @@
static void do_led_set(GPIO_TypeDef *port, int number, int on) {
if (on) {
- port->BSRRL = 1 << number;
- } else {
port->BSRRH = 1 << number;
+ } else {
+ port->BSRRL = 1 << number;
}
}
diff --git a/bbb_cape/src/cape/main.c b/bbb_cape/src/cape/main.c
index 411a734..be97171 100644
--- a/bbb_cape/src/cape/main.c
+++ b/bbb_cape/src/cape/main.c
@@ -1,6 +1,7 @@
#include <STM32F2XX.h>
#include "cape/fill_packet.h"
+#include "cape/led.h"
// The startup asm code defines this to the start of our exception vector table.
extern uint32_t _vectors;
@@ -11,6 +12,7 @@
SCB->VTOR = (uint32_t)&_vectors;
// Data Memory Barrier to make sure it gets the updated vector table.
__asm__ __volatile__("dmb");
+ led_set(LED_DB, 0);
fill_packet_start();
@@ -18,6 +20,9 @@
// decreses ISR latency a little bit because it doesn't have to stack the
// registers for the first one.
SCB->SCR |= SCB_SCR_SLEEPONEXIT_Msk;
+
+ led_set(LED_ERR, 0);
+
// This seems like the perfect place to use WFI, but Brian on 2013-12-13
// couldn't find anything verifying that WFI doesn't increase the latency for
// the first interrupt handled, and we should never actually get here anyways,
diff --git a/bbb_cape/src/cape/main.ld b/bbb_cape/src/cape/main.ld
index ec39b8f..058c2eb 100644
--- a/bbb_cape/src/cape/main.ld
+++ b/bbb_cape/src/cape/main.ld
@@ -1,7 +1,7 @@
MEMORY
{
- FLASH (rx) : ORIGIN = 0x00008000, LENGTH = 0xF8000 /* 1024k - 32k */
- RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x20000 /* 128k */
+ FLASH (rx) : ORIGIN = 16k, LENGTH = 1024k - 16k
+ RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 128k
}
SECTIONS