aboutsummaryrefslogtreecommitdiff
path: root/driver_fw/main.c
diff options
context:
space:
mode:
authorjaseg <git@jaseg.net>2019-03-04 23:16:42 +0900
committerjaseg <git@jaseg.net>2019-03-04 23:16:42 +0900
commitd48b92b93507f46ba2623284d8a0841e22e9a09b (patch)
tree902491412a82f8e1d0ddf0fcdcf65bd33477414e /driver_fw/main.c
parentca0439cb8ea63e2e1fbd19873b1540b177e31df7 (diff)
download8seg-d48b92b93507f46ba2623284d8a0841e22e9a09b.tar.gz
8seg-d48b92b93507f46ba2623284d8a0841e22e9a09b.tar.bz2
8seg-d48b92b93507f46ba2623284d8a0841e22e9a09b.zip
driver/fw: Beginnings of a firmware
This code starts up and blinks a led. This means RCC, GPIO and SPI1 are working.
Diffstat (limited to 'driver_fw/main.c')
-rw-r--r--driver_fw/main.c155
1 files changed, 109 insertions, 46 deletions
diff --git a/driver_fw/main.c b/driver_fw/main.c
index 730065c..c16d200 100644
--- a/driver_fw/main.c
+++ b/driver_fw/main.c
@@ -2,10 +2,11 @@
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
-#include <stm32f1xx.h>
+#include <stm32f0xx.h>
#pragma GCC diagnostic pop
-#include <system_stm32f1xx.h>
+#include <system_stm32f0xx.h>
+#include <stm32f0xx_ll_spi.h>
#include <stdint.h>
#include <stdbool.h>
@@ -29,48 +30,120 @@ static volatile struct {
#define NO_SYMBOL (DECODER_RETURN_CODE_LAST + 1)
+unsigned char random() {
+ static unsigned char x, a, b, c;
+ x++; //x is incremented every round and is not affected by any other variable
+ a = (a ^ c ^ x); //note the mix of addition and XOR
+ b = (b + a); //And the use of very few instructions
+ c = ((c + ((b >> 1) ^ a))); // the AES S-Box Operation ensures an even distributon of entropy
+ return c;
+}
+
+enum STATUS_LEDS {
+ STATUS_LED_COMM = 1,
+ STATUS_LED_ERROR = 2,
+ STATUS_LED_LOAD = 4,
+ STATUS_LED_OPERATION = 8,
+ STATUS_LED_J5_GREEN = 16,
+ STATUS_LED_J5_YELLOW = 32,
+ STATUS_LED_J4_GREEN = 64,
+ STATUS_LED_J4_YELLOW = 128
+};
+
+static void set_status_leds(uint8_t val) {
+ /* Workaround for *nasty* hardware behavior: If SPI data width is configured as 8 bit but DR is written as 16
+ * bit, SPI actually sends 16 clock cycles. Thus, we have to make sure the compiler emits a 8-bit write here.
+ * Thanks, TI! */
+ *((volatile uint8_t *)&(SPI1->DR)) = val ^ 0x0f; /* Invert LEDs connected to VCC instead of GND */
+}
+
+
int main(void) {
- /* External crystal: 8MHz */
RCC->CR |= RCC_CR_HSEON;
while (!(RCC->CR&RCC_CR_HSERDY));
-
- /* Sysclk = HCLK = 48MHz */
- RCC->CFGR = (RCC->CFGR & (~RCC_CFGR_PLLMULL_Msk & ~RCC_CFGR_SW_Msk & ~RCC_CFGR_PPRE1_Msk & ~RCC_CFGR_PPRE2_Msk &
- ~RCC_CFGR_HPRE_Msk))
- | (10<<RCC_CFGR_PLLMULL_Pos) | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | (4<<RCC_CFGR_PPRE1_Pos) |
- (4<<RCC_CFGR_PPRE2_Pos);
-
+ RCC->CFGR &= ~RCC_CFGR_PLLMUL_Msk & ~RCC_CFGR_SW_Msk & ~RCC_CFGR_PPRE_Msk & ~RCC_CFGR_HPRE_Msk;
+ RCC->CFGR |= ((6-2)<<RCC_CFGR_PLLMUL_Pos) | RCC_CFGR_PLLSRC_HSE_PREDIV; /* PLL x6 -> 48.0MHz */
RCC->CR |= RCC_CR_PLLON;
while (!(RCC->CR&RCC_CR_PLLRDY));
-
- /* Switch to PLL */
RCC->CFGR |= (2<<RCC_CFGR_SW_Pos);
- //RCC->CFGR = (RCC->CFGR & (~RCC_CFGR_PPRE1_Msk & ~RCC_CFGR_PPRE2_Msk))
- // | (4<<RCC_CFGR_PPRE1_Pos) | (4<<RCC_CFGR_PPRE2_Pos);
- SystemCoreClockUpdate();
-
- RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | RCC_APB2ENR_IOPCEN | RCC_APB2ENR_TIM1EN;
+ RCC->AHBENR |= RCC_AHBENR_DMAEN | RCC_AHBENR_GPIOAEN | RCC_AHBENR_GPIOBEN | RCC_AHBENR_FLITFEN;
+ RCC->APB1ENR |= RCC_APB1ENR_TIM3EN | RCC_APB1ENR_PWREN | RCC_APB1ENR_I2C1EN;
+ RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN | RCC_APB2ENR_ADCEN| RCC_APB2ENR_DBGMCUEN | RCC_APB2ENR_USART1EN | RCC_APB2ENR_SPI1EN;
- GPIOA->CRH =
- (2<<GPIO_CRH_CNF8_Pos) | (1<<GPIO_CRH_MODE8_Pos); /* PA8 - low side */
-
- GPIOB->CRH =
- (2<<GPIO_CRH_CNF13_Pos) | (1<<GPIO_CRH_MODE13_Pos); /* PB13 - high side */
-
- GPIOC->CRH =
- (0<<GPIO_CRH_CNF13_Pos) | (1<<GPIO_CRH_MODE13_Pos); /* PC13 - LED */
-
- /* TIM1 running off 24MHz APB2 clk, T=41.667ns */
- TIM1->CR1 = 0; /* Disable ARR preload (double-buffering) */
- TIM1->PSC = 24-1; /* Prescaler 24 -> f=1MHz/T=1us */
- TIM1->DIER = TIM_DIER_UIE; /* Enable update (overflow) interrupt */
- TIM1->CCMR1 = 6<<TIM_CCMR1_OC1M_Pos | TIM_CCMR1_OC1PE; /* Configure output compare unit 1 to PWM mode 1, enable CCR1
+ SystemCoreClockUpdate();
+ SysTick_Config(SystemCoreClock/100); /* 10ms interval */
+ NVIC_EnableIRQ(SysTick_IRQn);
+ NVIC_SetPriority(SysTick_IRQn, 3<<5);
+
+ GPIOA->MODER |=
+ (3<<GPIO_MODER_MODER0_Pos) /* PA0 - Vboot to ADC */
+ | (2<<GPIO_MODER_MODER1_Pos) /* PA1 - RS485 DE */
+ | (2<<GPIO_MODER_MODER2_Pos) /* PA2 - RS485 TX */
+ | (2<<GPIO_MODER_MODER3_Pos) /* PA3 - RS485 RX */
+ | (1<<GPIO_MODER_MODER4_Pos) /* PA4 - Strobe/Vin to ADC. CAUTION: This pin is dual-use */
+ | (2<<GPIO_MODER_MODER5_Pos) /* PA5 - SCK */
+ | (2<<GPIO_MODER_MODER6_Pos) /* PA6 - CTRL_A to TIM 3 ch 1 */
+ | (2<<GPIO_MODER_MODER7_Pos) /* PA7 - MOSI */
+ | (2<<GPIO_MODER_MODER9_Pos) /* PA9 - SCL */
+ | (2<<GPIO_MODER_MODER10_Pos);/* PA10 - SDA */
+
+ GPIOA->AFR[0] =
+ (1<<GPIO_AFRL_AFSEL1_Pos) /* PA1 */
+ | (1<<GPIO_AFRL_AFSEL2_Pos) /* PA2 */
+ | (1<<GPIO_AFRL_AFSEL3_Pos) /* PA3 */
+ | (1<<GPIO_AFRL_AFSEL6_Pos); /* PA6 */
+ GPIOA->AFR[1] =
+ (4<<GPIO_AFRH_AFSEL9_Pos) /* PA9 */
+ | (4<<GPIO_AFRH_AFSEL10_Pos);/* PA10 */
+
+ GPIOA->ODR = 0; /* Set PA4 ODR to 0 */
+
+ GPIOB->MODER |=
+ (2<<GPIO_MODER_MODER1_Pos); /* PB1 - CTRL_B to TIM 3 ch 4 */
+
+ GPIOB->AFR[0] = (1<<GPIO_AFRL_AFSEL1_Pos); /* PB1 */
+
+ /* FIXME USART config */
+ /* FIXME ADC config */
+ /* FIXME I2C config */
+
+ /* SPI config. SPI1 is used to control the shift register controlling the eight status LEDs. */
+ SPI1->CR2 = (7<<SPI_CR2_DS_Pos);
+
+ /* Baud rate PCLK/128 -> 375.0kHz */
+ SPI1->CR1 =
+ SPI_CR1_SSM
+ | SPI_CR1_SSI
+ | (6<<SPI_CR1_BR_Pos)
+ | SPI_CR1_MSTR
+ | SPI_CR1_CPHA;
+ SPI1->CR1 |= SPI_CR1_SPE;
+
+ /* FIXME debug code */
+ for (;;) {
+ set_status_leds((sys_time & (1<<6)) ? STATUS_LED_OPERATION : 0);
+
+ /* Toggle strobe */
+ GPIOA->BSRR = 1<<4;
+ for (int j = 0; j<100; j++)
+ asm volatile ("nop");
+ GPIOA->BRR = 1<<4;
+
+ for (int j = 0; j<100000; j++)
+ asm volatile ("nop");
+ }
+#if 0
+ /* TIM3 running off 48MHz APB1 clk, T=20.833ns */
+ TIM3->CR1 = 0; /* Disable ARR preload (double-buffering) */
+ TIM3->PSC = 48-1; /* Prescaler 48 -> f=1MHz/T=1us */
+ TIM3->DIER = TIM_DIER_UIE; /* Enable update (overflow) interrupt */
+ TIM3->CCMR1 = 6<<TIM_CCMR1_OC1M_Pos | TIM_CCMR1_OC1PE; /* Configure output compare unit 1 to PWM mode 1, enable CCR1
preload */
- TIM1->CCER = TIM_CCER_CC1NE | TIM_CCER_CC1E; /* Confiugre CH1 to complementary outputs */
- TIM1->BDTR = TIM_BDTR_MOE | (0xc0 | (63-32))<<TIM_BDTR_DTG_Pos; /* Enable MOE on next update event, i.e. on initial timer load.
+ TIM3->CCER = TIM_CCER_CC1NE | TIM_CCER_CC1E; /* Confiugre CH1 to complementary outputs */
+ TIM3->BDTR = TIM_BDTR_MOE | (0xc0 | (63-32))<<TIM_BDTR_DTG_Pos; /* Enable MOE on next update event, i.e. on initial timer load.
Set dead-time to 100us. */
- TIM1->CR1 |= TIM_CR1_CEN;
- TIM1->ARR = 400-1; /* Set f=2.5kHz/T=0.4ms */
+ TIM3->CR1 |= TIM_CR1_CEN;
+ TIM3->ARR = 800-1; /* Set f=2.5kHz/T=0.4ms */
xfr_8b10b_encode_reset(&txstate.st);
txstate.current_symbol = txstate.next_symbol = xfr_8b10b_encode(&txstate.st, K28_1) | 1<<10;
@@ -79,17 +152,6 @@ int main(void) {
NVIC_EnableIRQ(TIM1_UP_IRQn);
NVIC_SetPriority(TIM1_UP_IRQn, 3<<4);
-
-unsigned char x, a, b, c;
-unsigned char random() {
- x++; //x is incremented every round and is not affected by any other variable
- a = (a ^ c ^ x); //note the mix of addition and XOR
- b = (b + a); //And the use of very few instructions
- c = ((c + (b >> 1) ^ a)); // the AES S-Box Operation ensures an even distributon of entropy
- return (c);
-}
-
-
uint8_t txbuf[3] = {0x01, 0x05, 0x01};
int txpos = -1;
/* FIXME test code */
@@ -119,6 +181,7 @@ unsigned char random() {
}
}
}
+#endif
}
int flipbits(int in) {