BIN = bin
ODIR = obj
-_OBJ = ivt.o systick.o sysinfo.o term.o main.o clock.o
+_OBJ = ivt.o systick.o sysinfo.o term.o main.o clock.o rtc.o
OBJ = $(patsubst %, $(ODIR)/%,$(_OBJ))
DDIR = obj/drivers
* Some buses might not support the maximum speed and
* should be prescaled (i.e. low speed APB)
*
- * 2. Routines to setup a real time clock (RTC). A external
- * low speed oscillator (LSE) is used.
- *
* $USAGE
* Check external crystals on board and maximum speed
* for buses. In this example, a 8 Mhz external crystal
while(!rchkbit(RCC_CFGR, 3)); /* Wait for the clock switch to complete */
}
-static void setup_rtc() {
-
-// TODO: long time to get stable?
-// /* Enable PWREN and BKPEN */
-// rsetbit(RCC_APB1ENR, 28);
-// rsetbit(RCC_APB1ENR, 27);
-//
-// /* Enable access to backup registers and RTC */
-// rsetbit(PWR_CR, 8);
-//
-// rsetbit(RCC_BDCR, 0); /* LSE enable */
-// while(!rchkbit(RCC_BDCR, 1)); /* wait for LSE to come up */
-//
-// rsetbitsfrom(RCC_BDCR, 8, 0x1); /* use LSE as RTC source */
-// rsetbit(RCC_BDCR, 15); /* enable RTC */
-//
-
-}
-
void clock_init() {
#ifdef ENABLE_HSE
setup_hse();
#endif
-#ifdef ENABLE_RTC
-setup_rtc();
-#endif
-
}
#include <drivers/uart.h>
-#define RXNE ((*USART1_SR >> 5) & 0x1)
#define UARTBUF 256
#define ECHO 1
void * uart_handler() {
- //uart_puts("echo: ");
- while (RXNE) {
+ while (rchkbit(USART1_SR, 5)) {
char echochar = *USART1_DR;
-// uart_putc(echochar);
linefeed.buf[linefeed.wpos++] = echochar;
if (linefeed.wpos == UARTBUF)
linefeed.wpos = 0;
- //regw_u32(USART1_DR, echochar, 0, O_WRITE);
}
- //uart_putc('\n');
}
linefeed.wpos = 0;
//memset(&linefeed, 0, (sizeof(struct linefeed) ));
- regw_u32(RCC_APB2ENR, 0x4005, 0, SETBIT);// enable clock to UART1, AFIO and GPIOA
+ //regw_u32(RCC_APB2ENR, 0x4005, 0, SETBIT);// enable clock to UART1, AFIO and GPIOA
+ rsetbitsfrom(RCC_APB2ENR, 0, 0x4005);
/* (after enable GPIOA), on PA9&PA10 and set mode
* to alternative output */
- regw_u32(GPIOA_CRH, 0x444444D4, 0, OWRITE);
- regw_u8(AFIO_EVCR, 0x89, 0, OWRITE);// set event control register, output on PA, Pin 9 TODO: check
+ //regw_u32(GPIOA_CRH, 0x444444D4, 0, OWRITE);
+ rwrite(GPIOA_CRH, 0x444444D4);
+ //regw_u8(AFIO_EVCR, 0x89, 0, OWRITE);// set event control register, output on PA, Pin 9 TODO: check
+ rsetbitsfrom(AFIO_EVCR, 0, 0x89);
//disable temporarily to set values
- regw_u8(USART1_CR1, 0x0, 13, SETBIT);
+ //regw_u8(USART1_CR1, 0x0, 13, SETBIT);
+ rclrbit(USART1_CR1, 13);
set_baudrate();
- regw_u32(USART1_CR2, 0x0000, 0, OWRITE); //set stop bit, default is 1 stop bit 0x00
+ //regw_u32(USART1_CR2, 0x0000, 0, OWRITE); //set stop bit, default is 1 stop bit 0x00
+ rwrite(USART1_CR2, 0x0000);
/* parity = 8 bit, UART1 enabled,
* TX and RX enabled, interrupts enabled */
- //regw_u32(USART1_CR1, 0x000030AC, 0, O_WRITE);
- regw_u32(USART1_CR1, 0x0000302C, 0, OWRITE);
+ //regw_u32(USART1_CR1, 0x0000302C, 0, OWRITE);
+ rwrite(USART1_CR1, 0x0000302C);
ivt_set_gate(53, uart_handler, 0);
- *NVIC_ISER1 = (1 << 5); // Enable UART interrupt at NVIC
-}
-
-static void wait() {
- for (int i = 0; i < 400; i++);
+ rsetbit(NVIC_ISER1, 5);
}
void uart_putc(unsigned char ch) {
if (ch == '\n') {
- while (*USART1_SR & 0x0C) { } // transmit data register empty and complete
+ while(!rchkbit(USART1_SR, 6));
regw_u8(USART1_DR, 0x0D, 0, OWRITE); // return line
}
-
- while (*USART1_SR & 0x0C) {}
+ while(!rchkbit(USART1_SR, 6));
regw_u8(USART1_DR, ch, 0, OWRITE);
-
- wait();
}
char uart_getc(void) {
#define STK_RELOAD MEM_ADDR(0xE000E014)
#define STK_CALIB MEM_ADDR(0xE000E01C)
-/* CLOCK REGISTER */
+/* RESET AND CLOCK REGISTER */
#define RCC_CR MEM_ADDR(0x40021000)
#define RCC_CFGR MEM_ADDR(0x40021004)
#define RCC_BDCR MEM_ADDR(0x40021020)
#define GPIOA_CRH MEM_ADDR(0x40010804) // for USART1
#define GPIOB_CRL MEM_ADDR(0x40010C00) // low register (!) for I2C1
-#define GPIOC_CRL MEM_ADDR(0x40011000) // for led
-#define GPIOC_ODR MEM_ADDR(0x4001100C) //
+#define GPIOC_CRL MEM_ADDR(0x40011000) // led
+#define GPIOC_ODR MEM_ADDR(0x4001100C)
+
+//#define GPIOD_CRL MEM_ADDR(0x40011400)
+//#define GPIOD_ODR MEM_ADDR(0x4001140C)
#define AFIO_EVCR MEM_ADDR(0x40010000)
#define USART1_CR1 MEM_ADDR(0x4001380C)
#define USART1_CR2 MEM_ADDR(0x40013810)
#define USART1_CR3 MEM_ADDR(0x40013814)
+
+/* REAL TIME CLOCK REGISTERS */
+#define RTC_CRH MEM_ADDR(0x40002800) // interrupts
+#define RTC_CRL MEM_ADDR(0x40002804)
+#define RTC_PRLL MEM_ADDR(0x4000280C)
+#define RTC_CNTH MEM_ADDR(0x40002818)
+#define RTC_CNTL MEM_ADDR(0x4000281C)
+
+/* BACKUP (CALIBR) REGISTERS */
+#define BKP_RTCCR MEM_ADDR(0x40006C2C) // RTC Calibration
* rates etc.
*/
#define ENABLE_HSE
-#define ENABLE_RTC
//efine CRYSTAL_MHZ 8
//efine CLKSPEED_MHZ 72
extern void clock_init();
-extern int clock_test();
+// extern int clock_test();
// extern void clock_reset();
+/* RTC.C */
+#define ENABLE_RTC
+extern void rtc_init();
+
/* IVT.C */
extern void ivt_init();
extern void ivt_set_gate(unsigned char, void *(), short);
#include <drivers/led.h>
#include <drivers/tm1637.h>
+//void sleep() {
+//
+// __asm__ __volatile__("wfe");
+//
+//}
+
void main()
{
clock_init();
// cputs("ROBSYS LOADING...\n");
systick_init();
led_init();
+ rtc_init();
// SPEED_TEST
/* cputs("START TEST (8MHz) \n");
a + 2;
}
cputs("END TEST\n"); */
-
sysinfo();
+
// tm1637_init();
// tm1637_start();
--- /dev/null
+/* (CC-BY-NC-SA) ROBIN KRENS - ROBIN @ ROBINKRENS.NL
+ *
+ * $LOG$
+ * 2019/7/30 - ROBIN KRENS
+ * Initial version
+ *
+ * $DESCRIPTION$
+ *
+ * */
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include <sys/robsys.h>
+#include <sys/mmap.h>
+
+#include <lib/regfunc.h>
+#include <lib/stdio.h>
+
+
+static void periodic_intr() {
+
+ while(!rchkbit(RTC_CRL, 5)); // Check last write is terminated
+ rsetbit(RTC_CRL, 4);
+
+ rsetbit(RTC_CRH, 0); // enable periodic (second) interrupt
+
+ while(!rchkbit(RTC_CRL, 5));
+
+ rwrite(RTC_PRLL, 0x7FFF); // 1 second
+ rclrbit(RTC_CRL, 4);
+ while(!rchkbit(RTC_CRL, 5)); // Check last write is terminated
+}
+
+static void calibrate_rtc() {
+
+
+// rsetbit(BKP_RTCCR, 7); // enable CC0,
+// while(!rchkbit(RTC_CRL, 5)); // Check last write is terminated
+// rsetbit(RTC_CRL, 4);
+
+ // Set up and check tamper pin
+
+// rclrbit(RTC_CRL, 4);
+// while(!rchkbit(RTC_CRL, 5)); // Check last write is terminated
+}
+
+void * rtc_handler() {
+
+ //cputs("TICKING IN REAL TIME\n");
+ rclrbit(RTC_CRL, 0);
+}
+
+static void setup_rtc() {
+
+// TODO: long time to get stable?
+ /* Enable PWREN and BKPEN */
+ rsetbit(RCC_APB1ENR, 28);
+ rsetbit(RCC_APB1ENR, 27);
+
+ /* Enable access to backup registers and RTC */
+ rsetbit(PWR_CR, 8);
+
+ rsetbit(RCC_BDCR, 0); /* LSE enable */
+ while(!rchkbit(RCC_BDCR, 1)); /* wait for LSE to come up */
+
+ rsetbitsfrom(RCC_BDCR, 8, 0x1); /* use LSE as RTC source */
+ rsetbit(RCC_BDCR, 15); /* enable RTC */
+
+ ivt_set_gate(19, rtc_handler, 0); /* setup interrupt handler */
+
+// calibrate_rtc(); TODO: TAMPER PIN?
+
+ periodic_intr();// setup periodic interrupt
+
+}
+
+void rtc_init() {
+
+#ifdef ENABLE_RTC
+ setup_rtc();
+#endif
+
+}
#define BUFSIZE 200
#define MAXARGS 5
#define WHITESPACE "\t\r\n "
-#define BUILTINCMDS 3
+#define BUILTINCMDS 4
int help(int, char**);
/*
* Built in commands
* info -- shows basic info of system
- * reset -- software reset
+ * uptime -- uptime; read from the RTC register
+ * reset -- software reset TODO
* show [ADDRESS-ADDRESS] -- shows SRAM range
* switchmode -- switch to unprivileged mode
* */
struct cmd builtincmds[4];
-int help(int argc, char ** argsv) {
+int info(int argc, char ** argsv) {
sysinfo();
return 0;
}
+int uptime(int arg, char ** argsv) {
+ cputs("CURRENT UPTIME: ");
+ cputs(regtohex(*RTC_CNTL));
+ cputchar('\n');
+}
+
int led(int argc, char ** argsv) {
void terminal() {
- builtincmds[0].name = "help";
- builtincmds[0].function = help;
+ builtincmds[0].name = "info";
+ builtincmds[0].function = info;
builtincmds[1].name = "led";
builtincmds[1].function = led;
builtincmds[2].name = "show";
builtincmds[2].function = show;
+ builtincmds[3].name = "uptime";
+ builtincmds[3].function = uptime;
+
+
char *buf;
cputs("WELCOME TO ROBSYS!\n");