#include "general.h"
#include "platform.h"
#include "usb.h"
#include "aux_serial.h"
#include "gdb_if.h"
#include <libopencm3/stm32/rcc.h>
#include <libopencm3/cm3/scb.h>
#include <libopencm3/cm3/scs.h>
#include <libopencm3/cm3/nvic.h>
#include <libopencm3/stm32/usart.h>
#include <libopencm3/usb/usbd.h>
#include <libopencm3/stm32/adc.h>
#include <libopencm3/stm32/spi.h>
#include <libopencm3/stm32/adc.h>
#include <libopencm3/stm32/syscfg.h>
uint16_t srst_pin;
static uint32_t hw_version;
#define SCB_CCR_IC_SHIFT 17U
#define SCB_CCR_IC_MASK (1UL << SCB_CCR_IC_SHIFT)
#define SCB_CCR_DC_SHIFT 16U
#define SCB_CCR_DC_MASK (1UL << SCB_CCR_DC_SHIFT)
#define SCB_CCSIDR_NUMSETS_MASK (0x7fffUL << SCB_CCSIDR_NUMSETS_SHIFT)
#define SCB_CCSIDR_NUMSETS_SHIFT 13U
#define SCB_CCSIDR_ASSOCIATIVITY_SHIFT 3U
#define SCB_CCSIDR_ASSOCIATIVITY_MASK (0x3ffUL << SCB_CCSIDR_ASSOCIATIVITY_SHIFT)
#define CCSIDR_WAYS(x) (((x)&SCB_CCSIDR_ASSOCIATIVITY_MASK) >> SCB_CCSIDR_ASSOCIATIVITY_SHIFT)
#define CCSIDR_SETS(x) (((x)&SCB_CCSIDR_NUMSETS_MASK) >> SCB_CCSIDR_NUMSETS_SHIFT)
#define SCB_DCISW_SET_SHIFT 5U
#define SCB_DCISW_SET_MASK (0x1ffUL << SCB_DCISW_SET_SHIFT)
#define SCB_DCISW_WAY_SHIFT 30U
#define SCB_DCISW_WAY_MASK (3UL << SCB_DCISW_WAY_SHIFT)
static void cm_dsb(void)
{
__asm__ volatile("dsb 0xf" ::: "memory");
}
static void cm_isb(void)
{
__asm__ volatile("isb 0xf" ::: "memory");
}
static void scb_enable_i_cache(void)
{
cm_dsb();
cm_isb();
SCB_ICIALLU = 0UL;
cm_dsb();
cm_isb();
SCB_CCR |= SCB_CCR_IC_MASK;
cm_dsb();
cm_isb();
}
static void scb_enable_d_cache(void)
{
SCB_CCSELR = 0U;
cm_dsb();
uint32_t ccsidr = SCB_CCSIDR;
const uint32_t sets = CCSIDR_SETS(ccsidr);
const uint32_t ways = CCSIDR_WAYS(ccsidr);
for (uint32_t set = 0; set <= sets; ++set) {
for (uint32_t way = 0; way <= ways; ++way) {
SCB_DCISW = ((set << SCB_DCISW_SET_SHIFT) & SCB_DCISW_SET_MASK) |
((way << SCB_DCISW_WAY_SHIFT) & SCB_DCISW_WAY_MASK);
}
}
cm_dsb();
SCB_CCR |= SCB_CCR_DC_MASK;
cm_dsb();
cm_isb();
}
int platform_hwversion(void)
{
return hw_version;
}
void platform_nrst_set_val(bool assert)
{
gpio_set_val(SRST_PORT, SRST_PIN, !assert);
if (assert) {
for (volatile size_t i = 0; i < 10000; i++)
continue;
}
}
bool platform_nrst_get_val()
{
return gpio_get(SRST_PORT, SRST_PIN) == 0;
}
const char *platform_target_voltage(void)
{
static char ret[] = "0.0V";
uint8_t channel = ADC_CHANNEL0;
adc_set_regular_sequence(ADC1, 1, &channel);
adc_start_conversion_regular(ADC1);
while (!adc_eoc(ADC1))
continue;
uint32_t value = adc_read_regular(ADC1);
value *= 3379;
value += 104858;
ret[0] = (value >> 21) + '0';
value &= (1 << 21) - 1;
value *= 10;
ret[2] = (value >> 21) + '0';
return ret;
}
void platform_request_boot(void)
{
volatile uint32_t *magic = (volatile uint32_t *)0x3ff8;
magic[0] = BOOTMAGIC0;
magic[1] = BOOTMAGIC1;
scb_reset_system();
}
void platform_init(void)
{
rcc_periph_clock_enable(RCC_APB2ENR_SYSCFGEN);
rcc_clock_setup_hse(rcc_3v3 + RCC_CLOCK_3V3_216MHZ, 25);
scb_enable_i_cache();
scb_enable_d_cache();
rcc_periph_clock_enable(RCC_GPIOA);
rcc_periph_clock_enable(RCC_GPIOB);
rcc_periph_clock_enable(RCC_GPIOD);
rcc_periph_clock_enable(RCC_GPIOH);
rcc_periph_clock_enable(RCC_GPIOF);
rcc_periph_clock_enable(RCC_GPIOG);
gpio_mode_setup(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO0);
rcc_periph_clock_enable(RCC_ADC1);
adc_power_off(ADC1);
adc_disable_scan_mode(ADC1);
adc_set_sample_time(ADC1, ADC_CHANNEL0, ADC_SMPR_SMP_3CYC);
adc_power_on(ADC1);
gpio_set_output_options(SRST_PORT, GPIO_OTYPE_OD, GPIO_OSPEED_2MHZ, SRST_PIN);
gpio_mode_setup(SRST_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, SRST_PIN);
gpio_set(SRST_PORT, SRST_PIN);
gpio_mode_setup(TMS_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, TMS_PIN);
gpio_set_output_options(TMS_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, TMS_PIN);
gpio_mode_setup(SWDIO_IN_PORT, GPIO_MODE_INPUT, GPIO_PUPD_PULLUP, SWDIO_IN_PIN);
gpio_mode_setup(TDI_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, TDI_PIN);
gpio_set_output_options(TDI_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, TDI_PIN);
gpio_mode_setup(TCK_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, TCK_PIN);
gpio_set_output_options(TCK_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, TCK_PIN);
gpio_mode_setup(TMS_DRIVE_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, TMS_DRIVE_PIN);
gpio_set_output_options(TMS_DRIVE_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, TMS_DRIVE_PIN);
gpio_set(TMS_DRIVE_PORT, TMS_DRIVE_PIN);
gpio_mode_setup(PWR_EN_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, PWR_EN_PIN);
gpio_set_output_options(PWR_EN_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, PWR_EN_PIN);
gpio_set(PWR_EN_PORT, PWR_EN_PIN);
gpio_set_af(MCO1_PORT, MCO1_AF, MCO1_PIN);
gpio_mode_setup(MCO1_PORT, GPIO_MODE_AF, GPIO_PUPD_NONE, MCO1_PIN);
gpio_set_output_options(MCO1_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_25MHZ, MCO1_PIN);
RCC_CR |= RCC_CR_HSION;
RCC_CFGR &= ~(0x3 << RCC_CFGR_MCO1_SHIFT);
RCC_CFGR |= RCC_CFGR_MCO1_HSI << RCC_CFGR_MCO1_SHIFT;
RCC_CFGR &= ~(0x7 << RCC_CFGR_MCO1PRE_SHIFT);
RCC_CFGR |= RCC_CFGR_MCOPRE_DIV_2 << RCC_CFGR_MCO1PRE_SHIFT;
rcc_periph_clock_enable(RCC_GPIOB);
gpio_mode_setup(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO14 | GPIO15);
gpio_set_output_options(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_100MHZ, GPIO14 | GPIO15);
gpio_set_af(GPIOB, GPIO_AF12, GPIO14 | GPIO15);
gpio_mode_setup(LED_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED_PIN);
gpio_set_output_options(LED_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, LED_PIN);
extern int vector_table;
SCB_VTOR = (uintptr_t)&vector_table;
platform_timing_init();
blackmagic_usb_init();
aux_serial_init();
platform_max_frequency_set(6000000);
}
void platform_target_clk_output_enable(bool enable)
{
(void)enable;
}
bool platform_spi_init(const spi_bus_e bus)
{
(void)bus;
return false;
}
bool platform_spi_deinit(const spi_bus_e bus)
{
(void)bus;
return false;
}
bool platform_spi_chip_select(const uint8_t device_select)
{
(void)device_select;
return false;
}
uint8_t platform_spi_xfer(const spi_bus_e bus, const uint8_t value)
{
(void)bus;
return value;
}