basic led act blinking

This commit is contained in:
Polprzewodnikowy 2022-09-11 20:00:31 +02:00
parent 660549798f
commit da99bc5619
10 changed files with 152 additions and 12 deletions

View File

@ -16,6 +16,7 @@ SRC_FILES = \
hw.c \ hw.c \
isv.c \ isv.c \
lcmxo2.c \ lcmxo2.c \
led.c \
rtc.c \ rtc.c \
sd.c \ sd.c \
task.c \ task.c \

View File

@ -2,17 +2,20 @@
#include "cic.h" #include "cic.h"
#include "gvr.h" #include "gvr.h"
#include "hw.h" #include "hw.h"
#include "led.h"
#include "rtc.h" #include "rtc.h"
#include "task.h" #include "task.h"
#define CIC_STACK_SIZE (256) #define CIC_STACK_SIZE (256)
#define RTC_STACK_SIZE (256) #define RTC_STACK_SIZE (256)
#define LED_STACK_SIZE (256)
#define GVR_STACK_SIZE (2048) #define GVR_STACK_SIZE (2048)
uint8_t cic_stack[CIC_STACK_SIZE] __attribute__((aligned(8))); uint8_t cic_stack[CIC_STACK_SIZE] __attribute__((aligned(8)));
uint8_t rtc_stack[RTC_STACK_SIZE] __attribute__((aligned(8))); uint8_t rtc_stack[RTC_STACK_SIZE] __attribute__((aligned(8)));
uint8_t led_stack[LED_STACK_SIZE] __attribute__((aligned(8)));
uint8_t gvr_stack[GVR_STACK_SIZE] __attribute__((aligned(8))); uint8_t gvr_stack[GVR_STACK_SIZE] __attribute__((aligned(8)));
@ -22,6 +25,7 @@ void app (void) {
task_create(TASK_ID_CIC, cic_task, cic_stack, CIC_STACK_SIZE); task_create(TASK_ID_CIC, cic_task, cic_stack, CIC_STACK_SIZE);
task_create(TASK_ID_RTC, rtc_task, rtc_stack, RTC_STACK_SIZE); task_create(TASK_ID_RTC, rtc_task, rtc_stack, RTC_STACK_SIZE);
task_create(TASK_ID_LED, led_task, led_stack, LED_STACK_SIZE);
task_create(TASK_ID_GVR, gvr_task, gvr_stack, GVR_STACK_SIZE); task_create(TASK_ID_GVR, gvr_task, gvr_stack, GVR_STACK_SIZE);
task_scheduler_start(); task_scheduler_start();

View File

@ -3,6 +3,7 @@
#include <stdbool.h> #include <stdbool.h>
#include "cic.h" #include "cic.h"
#include "hw.h" #include "hw.h"
#include "led.h"
#include "rtc.h" #include "rtc.h"
#include "task.h" #include "task.h"
@ -39,6 +40,7 @@ static const uint8_t cic_ram_init[2][32] = {{
static void cic_irq_reset_falling (void) { static void cic_irq_reset_falling (void) {
cic_enabled = false; cic_enabled = false;
hw_gpio_set(GPIO_ID_N64_CIC_DQ); hw_gpio_set(GPIO_ID_N64_CIC_DQ);
led_clear_error(LED_ERROR_CIC);
} }
static void cic_irq_reset_rising (void) { static void cic_irq_reset_rising (void) {
@ -122,7 +124,7 @@ static void cic_write_id_failed (void) {
uint8_t current_region = rtc_get_region(); uint8_t current_region = rtc_get_region();
uint8_t next_region = (current_region == REGION_NTSC) ? REGION_PAL : REGION_NTSC; uint8_t next_region = (current_region == REGION_NTSC) ? REGION_PAL : REGION_NTSC;
rtc_set_region(next_region); rtc_set_region(next_region);
// TODO: blink some error code led_blink_error(LED_ERROR_CIC);
} }
static void cic_write_seed (void) { static void cic_write_seed (void) {

View File

@ -51,8 +51,8 @@ static volatile uint8_t *i2c_data_txptr;
static volatile uint8_t *i2c_data_rxptr; static volatile uint8_t *i2c_data_rxptr;
static volatile uint32_t i2c_next_cr2; static volatile uint32_t i2c_next_cr2;
static void (*volatile i2c_callback)(void); static void (*volatile i2c_callback)(void);
static const TIM_TypeDef *tims[] = { TIM14, TIM16, TIM17, TIM3 }; static const TIM_TypeDef *tims[] = { TIM14, TIM16, TIM17, TIM3, TIM1 };
static void (*volatile tim_callbacks[4])(void); static void (*volatile tim_callbacks[5])(void);
static void hw_gpio_init (gpio_id_t id, gpio_mode_t mode, gpio_ot_t ot, gpio_ospeed_t ospeed, gpio_pupd_t pupd, gpio_af_t af, int value) { static void hw_gpio_init (gpio_id_t id, gpio_mode_t mode, gpio_ot_t ot, gpio_ospeed_t ospeed, gpio_pupd_t pupd, gpio_af_t af, int value) {
@ -202,7 +202,7 @@ void hw_tim_setup (tim_id_t id, uint16_t delay, void (*callback)(void)) {
TIM_TypeDef *tim = ((TIM_TypeDef *) (tims[id])); TIM_TypeDef *tim = ((TIM_TypeDef *) (tims[id]));
tim->CR1 = (TIM_CR1_OPM | TIM_CR1_URS); tim->CR1 = (TIM_CR1_OPM | TIM_CR1_URS);
tim->PSC = (64000 - 1); tim->PSC = (64000 - 1);
tim->ARR = (delay - 1); tim->ARR = delay;
tim->DIER = TIM_DIER_UIE; tim->DIER = TIM_DIER_UIE;
tim->EGR = TIM_EGR_UG; tim->EGR = TIM_EGR_UG;
tim->SR = 0; tim->SR = 0;
@ -224,12 +224,15 @@ void hw_tim_disable_irq (tim_id_t id) {
case TIM_ID_RTC: case TIM_ID_RTC:
NVIC_DisableIRQ(TIM16_IRQn); NVIC_DisableIRQ(TIM16_IRQn);
break; break;
case TIM_ID_GVR: case TIM_ID_SD:
NVIC_DisableIRQ(TIM17_IRQn); NVIC_DisableIRQ(TIM17_IRQn);
break; break;
case TIM_ID_DD: case TIM_ID_DD:
NVIC_DisableIRQ(TIM3_IRQn); NVIC_DisableIRQ(TIM3_IRQn);
break; break;
case TIM_ID_LED:
NVIC_DisableIRQ(TIM1_BRK_UP_TRG_COM_IRQn);
break;
default: default:
break; break;
} }
@ -243,12 +246,15 @@ void hw_tim_enable_irq (tim_id_t id) {
case TIM_ID_RTC: case TIM_ID_RTC:
NVIC_EnableIRQ(TIM16_IRQn); NVIC_EnableIRQ(TIM16_IRQn);
break; break;
case TIM_ID_GVR: case TIM_ID_SD:
NVIC_EnableIRQ(TIM17_IRQn); NVIC_EnableIRQ(TIM17_IRQn);
break; break;
case TIM_ID_DD: case TIM_ID_DD:
NVIC_EnableIRQ(TIM3_IRQn); NVIC_EnableIRQ(TIM3_IRQn);
break; break;
case TIM_ID_LED:
NVIC_EnableIRQ(TIM1_BRK_UP_TRG_COM_IRQn);
break;
default: default:
break; break;
} }
@ -430,13 +436,16 @@ static void hw_init_tim (void) {
RCC_APBENR2_TIM17EN | RCC_APBENR2_TIM17EN |
RCC_APBENR2_TIM16EN | RCC_APBENR2_TIM16EN |
RCC_APBENR2_TIM14EN | RCC_APBENR2_TIM14EN |
RCC_APBENR2_USART1EN RCC_APBENR2_USART1EN |
RCC_APBENR2_TIM1EN
); );
DBG->APBFZ1 |= DBG_APB_FZ1_DBG_TIM3_STOP;
DBG->APBFZ2 |= ( DBG->APBFZ2 |= (
DBG_APB_FZ2_DBG_TIM17_STOP | DBG_APB_FZ2_DBG_TIM17_STOP |
DBG_APB_FZ2_DBG_TIM16_STOP | DBG_APB_FZ2_DBG_TIM16_STOP |
DBG_APB_FZ2_DBG_TIM14_STOP DBG_APB_FZ2_DBG_TIM14_STOP |
DBG_APB_FZ2_DBG_TIM1_STOP
); );
} }
@ -465,6 +474,8 @@ void hw_init (void) {
NVIC_SetPriority(TIM14_IRQn, 0); NVIC_SetPriority(TIM14_IRQn, 0);
NVIC_SetPriority(TIM16_IRQn, 1); NVIC_SetPriority(TIM16_IRQn, 1);
NVIC_SetPriority(TIM17_IRQn, 2); NVIC_SetPriority(TIM17_IRQn, 2);
NVIC_SetPriority(TIM3_IRQn, 2);
NVIC_SetPriority(TIM1_BRK_UP_TRG_COM_IRQn, 1);
NVIC_EnableIRQ(EXTI0_1_IRQn); NVIC_EnableIRQ(EXTI0_1_IRQn);
NVIC_EnableIRQ(EXTI2_3_IRQn); NVIC_EnableIRQ(EXTI2_3_IRQn);
@ -474,6 +485,7 @@ void hw_init (void) {
NVIC_EnableIRQ(TIM16_IRQn); NVIC_EnableIRQ(TIM16_IRQn);
NVIC_EnableIRQ(TIM17_IRQn); NVIC_EnableIRQ(TIM17_IRQn);
NVIC_EnableIRQ(TIM3_IRQn); NVIC_EnableIRQ(TIM3_IRQn);
NVIC_EnableIRQ(TIM1_BRK_UP_TRG_COM_IRQn);
} }
void hw_loader_init (void) { void hw_loader_init (void) {
@ -586,3 +598,11 @@ void TIM3_IRQHandler (void) {
tim_callbacks[3] = 0; tim_callbacks[3] = 0;
} }
} }
void TIM1_BRK_UP_TRG_COM_IRQHandler (void) {
TIM1->SR &= ~(TIM_SR_UIF);
if (tim_callbacks[4]) {
tim_callbacks[4]();
tim_callbacks[4] = 0;
}
}

View File

@ -32,8 +32,9 @@ typedef enum {
typedef enum { typedef enum {
TIM_ID_CIC = 0, TIM_ID_CIC = 0,
TIM_ID_RTC = 1, TIM_ID_RTC = 1,
TIM_ID_GVR = 2, TIM_ID_SD = 2,
TIM_ID_DD = 3, TIM_ID_DD = 3,
TIM_ID_LED = 4,
} tim_id_t; } tim_id_t;
typedef enum { typedef enum {

89
sw/controller/src/led.c Normal file
View File

@ -0,0 +1,89 @@
#include <stdbool.h>
#include "hw.h"
#include "led.h"
#include "task.h"
#define LED_TICKRATE_MS (10)
#define LED_CYCLE_TICKS_PERIOD (10)
#define LED_CYCLE_TICKS_ON (3)
static uint32_t timer = 0;
static uint32_t current_act_counter = 0;
static volatile uint32_t next_act_counter = 0;
static volatile bool cic_error = false;
static volatile bool rtc_error = false;
static void led_task_resume (void) {
task_set_ready(TASK_ID_LED);
}
static bool led_has_errors (void) {
return (cic_error | rtc_error);
}
static void led_process_act (void) {
if (timer > 0) {
timer -= 1;
uint32_t cycle = ((LED_CYCLE_TICKS_PERIOD - 1) - (timer % LED_CYCLE_TICKS_PERIOD));
if (cycle < LED_CYCLE_TICKS_ON) {
hw_gpio_set(GPIO_ID_LED);
} else {
hw_gpio_reset(GPIO_ID_LED);
}
} else {
if (current_act_counter != next_act_counter) {
current_act_counter = next_act_counter;
timer = LED_CYCLE_TICKS_PERIOD;
} else {
hw_gpio_reset(GPIO_ID_LED);
}
}
}
static void led_process_errors (void) {
// TODO: implement error blink codes
}
void led_blink_act (void) {
next_act_counter += 1;
}
void led_blink_error (led_error_t error) {
switch (error) {
case LED_ERROR_CIC:
cic_error = true;
break;
case LED_ERROR_RTC:
rtc_error = true;
break;
}
}
void led_clear_error (led_error_t error) {
switch (error) {
case LED_ERROR_CIC:
cic_error = false;
break;
case LED_ERROR_RTC:
rtc_error = false;
break;
}
}
void led_task (void) {
while (1) {
hw_tim_setup(TIM_ID_LED, LED_TICKRATE_MS, led_task_resume);
if (led_has_errors()) {
led_process_errors();
} else {
led_process_act();
}
task_yield();
}
}

17
sw/controller/src/led.h Normal file
View File

@ -0,0 +1,17 @@
#ifndef LED_H__
#define LED_H__
typedef enum {
LED_ERROR_CIC,
LED_ERROR_RTC,
} led_error_t;
void led_blink_act (void);
void led_blink_error (led_error_t error);
void led_clear_error (led_error_t error);
void led_task (void);
#endif

View File

@ -1,5 +1,6 @@
#include "fpga.h" #include "fpga.h"
#include "hw.h" #include "hw.h"
#include "led.h"
#include "rtc.h" #include "rtc.h"
#include "task.h" #include "task.h"
@ -55,7 +56,7 @@ static void rtc_task_resume (void) {
static void rtc_on_error (void) { static void rtc_on_error (void) {
rtc_time_valid = false; rtc_time_valid = false;
// TODO: blink some error code led_blink_error(LED_ERROR_RTC);
task_yield(); task_yield();
} }

View File

@ -2,6 +2,7 @@
#include <stdint.h> #include <stdint.h>
#include "fpga.h" #include "fpga.h"
#include "hw.h" #include "hw.h"
#include "led.h"
#include "sd.h" #include "sd.h"
@ -71,7 +72,7 @@ static void sd_trigger_timeout (void) {
static void sd_prepare_timeout (uint16_t value) { static void sd_prepare_timeout (uint16_t value) {
p.timeout = false; p.timeout = false;
hw_tim_setup(TIM_ID_GVR, value, sd_trigger_timeout); hw_tim_setup(TIM_ID_SD, value, sd_trigger_timeout);
} }
static bool sd_did_timeout (void) { static bool sd_did_timeout (void) {
@ -79,7 +80,7 @@ static bool sd_did_timeout (void) {
} }
static void sd_clear_timeout (void) { static void sd_clear_timeout (void) {
hw_tim_stop(TIM_ID_GVR); hw_tim_stop(TIM_ID_SD);
p.timeout = false; p.timeout = false;
} }
@ -210,6 +211,7 @@ bool sd_read_sectors (uint32_t address, uint32_t sector, uint32_t count) {
while (count > 0) { while (count > 0) {
uint32_t blocks = ((count > DAT_BLOCK_MAX_COUNT) ? DAT_BLOCK_MAX_COUNT : count); uint32_t blocks = ((count > DAT_BLOCK_MAX_COUNT) ? DAT_BLOCK_MAX_COUNT : count);
led_blink_act();
sd_dat_prepare(address, blocks, DAT_READ); sd_dat_prepare(address, blocks, DAT_READ);
if (sd_cmd(23, blocks, RSP_R1, NULL)) { if (sd_cmd(23, blocks, RSP_R1, NULL)) {
sd_dat_abort(); sd_dat_abort();
@ -245,6 +247,8 @@ bool sd_card_init (void) {
p.card_initialized = true; p.card_initialized = true;
p.rca = 0; p.rca = 0;
led_blink_act();
sd_set_clock(CLOCK_400KHZ); sd_set_clock(CLOCK_400KHZ);
sd_cmd(0, 0, RSP_NONE, NULL); sd_cmd(0, 0, RSP_NONE, NULL);

View File

@ -8,6 +8,7 @@
typedef enum { typedef enum {
TASK_ID_CIC, TASK_ID_CIC,
TASK_ID_RTC, TASK_ID_RTC,
TASK_ID_LED,
TASK_ID_GVR, TASK_ID_GVR,
__TASK_ID_MAX __TASK_ID_MAX
} task_id_t; } task_id_t;