$(CC) $(CFLAGS) -c -I./include -ffreestanding -o sysinfo.o sysinfo.c
$(CC) $(CFLAGS) -c -I./include -ffreestanding -o lib.o lib.c
$(CC) $(CFLAGS) -c -I./include -ffreestanding -o mm.o mm.c
- $(LD) -nostartfiles -T link.ld -o start.out start.o main.o uart.o ivt.o systick.o sysinfo.o lib.o mm.o
+ $(CC) $(CFLAGS) -c -I./include -ffreestanding -o regf.o regf.c
+ $(LD) -nostartfiles -T link.ld -o start.out start.o main.o uart.o ivt.o systick.o sysinfo.o lib.o mm.o regf.o
$(MKIMG) -Obinary -R .data start.out kernel.bin
run:
*
* */
-
#define BSS_BASE ((volatile uint32_t *)(0x20000800)) //TODO: .data flexible siz
#define TOTAL_MEM_SIZE 64000;
/* SYSTEM INFO AND DEBUG */
-#define MCU_ID ((volatile uint32_t*)( 0xE0042000))
+#define MCU_ID ((volatile uint32_t*)( 0xE000ED00))
#define FLASH_MEM ((volatile uint32_t*)( 0x1FFFF000))
/* SYSTEM CONTROL BLOCK REGISTER */
/* NESTED VECTOR INTERRUPT CONTROL REGISTER */
#define NVIC_ISER0 ((volatile uint32_t*)( 0xE000E100)) // interrupt set enable register
+#define NVIC_ISER1 ((volatile uint32_t*)( 0xE000E104)) // interrupt set enable register
/* SYSTICK REGISTER */
#define STK_CTRL ((volatile uint32_t *)(0xE000E010))
/* SYSTEM CONTROL REGISTER */
#define SYSCTRL_RCC ((volatile unsigned long *)(0x40021000))
-#define RCC_APB2ENR ((volatile unsigned long *)(0x40021018)) // register to enable USART1
+#define RCC_APB2ENR ((volatile uint32_t *)(0x40021018)) // register to enable USART1
#define SYSCTRL_RIS ((volatile unsigned long *)(0x400FE050))
#define SYSCTRL_RCGC1 ((volatile unsigned long *)(0x400FE104))
#define GPIOPA_AFSEL ((volatile unsigned long *)(0x40004420))
#define GPIOA_CRH ((volatile unsigned long *)(0x40010804))
-#define AFIO_EVCR ((volatile unsigned long *)(0x40010000))
+
+#define AFIO_EVCR ((volatile uint32_t *)(0x40010000))
+//#define AFIO_EXTICR1 ((volatile uint32_t *)(AFIO_EVCR + 0x08))
+
+/* EXTERNAL INTERRUPTS */
+#define EXTI_IMR ((volatile uint32_t *)(0x40010400))
+#define EXTI_RTSR ((volatile uint32_t *) (EXTI_IMR + 0x08))
+//#define EXTI_FTSR ((volatile uint32_t *) (EXTI_IMR + 0x04))
/* UART1 REGISTERS */
#define USART1_BASE ((volatile uint32_t) (0x40013800))
extern void free(void *);
extern void test_memory(uint32_t *);
+/* REGF.C */
+extern void regw_u8(volatile uint32_t *, uint8_t, short, short);
+extern void regw_u32(volatile uint32_t *, uint32_t, short, short);
+
#endif
#include <mmap.h>
/*
+ * These values are pushed on the stack just before
+ * entering the ISR. Normally, this would require
+ * assembly or inline assembly code. I use a so-called
+ * 'naked function' __attribute__ ((interrupt)) which
+ * gives me a little bit more control over the caller
+ *
+ * The following register are pushed to the stack
+ * in reverse order
+ *
+ * */
+struct interrupt_frame {
+
+ uint32_t r0; // N-32
+ uint32_t r1;
+ uint32_t r2;
+ uint32_t r3;
+ uint32_t r12;
+ uint32_t lr;
+ uint32_t pc;
+ uint32_t psr; // N-4
+};
+
+/*
* Vector table, each entry contains an interrupt
- * service routine: *
+ * service routine:
*
* interrupt vector 1-15: processor exceptions
- * interrupt vector 16-32: irq0 - irq ..
+ * interrupt vector 16-64: irq0 - irq ..
* */
-uint32_t ivt[32];
+uint32_t ivt[64];
+/* each message corresponds to each and every exception.
+ * We get the correct message by accessing
+ * exception_message[interrupt_number]
+ * exception_message[0] is not used (=MSP)*/
+unsigned char *exception_messages[] =
+{
+ "--",
+ "RESET",
+ "NMI",
+ "HARD FAULT",
+ "MEMMANAGE FAULT",
+ "BUS FAULT",
+ "USAGE FAULT",
+ "RESERVED",
+ "SVC",
+ "DEBUG MONITOR",
+ "RESERVED",
+ "PENDSV",
+ "SYSTICK",
+ "IRQ1",
+ "IRQ2",
+ "IRQ3",
+ "IRQ4",
+ // add more if needed
+};
void ivt_set_gate(unsigned char num, void * isr(), short pri) {
/* Dummy interrupt */
-void * dummy_isr() {
+__attribute__ ((interrupt))
+void * dummy_isr(struct interrupt_frame * frame) {
+
+
+ uint32_t * p = (volatile uint32_t *) 0x21000000;
+ addrtohex(frame->r0);
+ addrtohex(frame->r1);
+ addrtohex(frame->r2);
+ addrtohex(frame->r3);
+ addrtohex(frame->r12);
+ addrtohex(frame->lr);
+ addrtohex(frame->pc);
+ addrtohex(frame->psr);
+
+ //__asm__ __volatile__ ("MRS r0, IPSR");
+ //addrtohex(frame->r0);
uart_puts("EXCEPTION X: SYSTEM HALTED\n");
+
for(;;);
}
// don't need to relocate or init this here
extern void * reset, * nmi, * hardfault;
- ivt_set_gate(1, dummy_isr, 0);
- ivt_set_gate(2, dummy_isr, 0);
- ivt_set_gate(3, dummy_isr, 0);
- ivt_set_gate(4, dummy_isr, 0);
- ivt_set_gate(5, dummy_isr, 0);
- ivt_set_gate(6, dummy_isr, 0);
+ for (int i = 1; i < 7; i++) {
+ ivt_set_gate(i, dummy_isr, 0);
+ }
/* the vector table starts at 0x0. Since the address 0x0 point to
* bootcode, it is on ROM or FLASH. The vector table can be
* relocated to other memory locations. We can do this by setting
* a register in the NVIC called the vector table offset register */
- *SCB_VTOR = (volatile uint32_t) &ivt;
+ //*SCB_VTOR = (volatile uint32_t) &ivt;
+ regw_u32(SCB_VTOR, (uint32_t) &ivt, 0, 0x01);
}
/* Temporary libc functions, which can later be
* replaced by a *real* library */
-char hexbuf[8] = {'0', '0','0', '0','0', '0','0', '0'};
+char hexbuf[8];
void addrtohex(uint32_t addr) {
char tmpbuf[6] = {'A', 'B', 'C', 'D', 'E', 'F'};
uart_putc('\n');
}
+
+
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
-#include <stm32.h> // <-- your own header file located located in ./include
+#include <stm32.h> // <-- my own header file located located in ./include
#include <mmap.h>
ivt_init();
// clock_init();
uart_init();
- systick_init();
+// systick_init();
uart_puts("LOADING SYSTEM 0.1 ...\n");
sysinfo();
mm_init();
- int * p2 = mm_alloc(200);
- *p2 = 0x12345678;
+ //int * p2 = mm_alloc(512);
+ //memset(p2, 'a', 512);
- test_memory(p2);
+ //addrtohex(p2);
+ //addrtohex(*p2);
- addrtohex(p2);
- addrtohex(*p2);
+ //uint32_t * p = (volatile unsigned) 0x21000000;
+ //regw_u32(p, 0x0CCCCCCCC, 4, 0x01);
+ //regw_u8(p, 0xFF, 0, 0x02);
+
+ //addrtohex(*p);
//addrtohex((volatile uint32_t) 0x12345678 );
//addrtohex((volatile uint32_t) SCB_VTOR );
--- /dev/null
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stm32.h>
+
+#define O_WRITE 0x01
+#define SET 0x02
+#define CLEAR 0x03
+
+/* write value (uint8_t) to register */
+void regw_u8(volatile uint32_t * reg, uint8_t val, short shift, short flag) {
+
+ switch(flag) {
+ case O_WRITE:
+ (*(volatile uint32_t *) (reg)) = (val << shift);
+ break;
+ case SET:
+ (*(volatile uint32_t *) (reg)) =
+ ((*(volatile uint32_t *) (reg)) | (val << shift));
+ break;
+ case CLEAR:
+ (*(volatile uint32_t *) (reg)) = (val << shift);
+ break;
+ }
+}
+
+/* write value (uint32_t) to register */
+void regw_u32(volatile uint32_t * reg, uint32_t val, short shift, short flag) {
+
+ switch(flag) {
+ case O_WRITE:
+ (*(volatile uint32_t *) (reg)) = (val << shift);
+ break;
+ case SET:
+ (*(volatile uint32_t *) (reg)) =
+ ((*(volatile uint32_t *) (reg)) | (val << shift));
+ case CLEAR:
+ //
+ break;
+ }
+}
+
+
tmp = (tmp >> 16);
uart_puts("# REVISION: ");
+// addrtohex(tmp);
switch (tmp) {
case 0x1000:
uart_puts("REVISION A\n");
#include <stm32.h>
#include <mmap.h>
+struct interrupt_frame {
-void * systick_handler() {
+ uint32_t r0; // N-32
+ uint32_t r1;
+ uint32_t r2;
+ uint32_t r3;
+ uint32_t r12;
+ uint32_t lr;
+ uint32_t pc;
+ uint32_t psr; // N-4
+};
+
+
+/* void * systick_handler() {
// *RANDOM_ADDR = (volatile uint32_t) 0x10101010 ;
// uart_puts("TEST");
+} */
+
+__attribute__ ((interrupt))
+void * systick_handler(struct interrupt_frame * frame) {
+
+ uart_puts("TICKING\n");
+// addrtohex((uint32_t) 0x12345678);
+ // for(;;);
}
+
void systick_init() {
/* Enable the counter and enable the interrupt
#include <stm32.h>
#include <mmap.h>
+#define RXNE ((*USART1_SR >> 5) & 0x1)
+
+#define O_WRITE 0x01
+#define SET 0x02
+#define CLEAR 0x03
+
+void * uart_handler() {
+
+ uart_puts("\n echo: ");
+ while (RXNE) {
+ char echochar = *USART1_DR;
+ // regw_u8(USART1_DR, echochar, 0, O_WRITE);
+ uart_putc(echochar);
+ }
+//for(;;);
+
+}
void uart_init() {
+ // global interrupt setup
+// regw_u32(EXTI_IMR, 0x000FFFFF, 0, O_WRITE);
+// regw_u32(EXTI_RTSR, 0x000FFFFF, 0, O_WRITE);
+
+
+ regw_u32(RCC_APB2ENR, 0x4005, 0, SET);// enable clock to UART1, AFIO and GPIOA
- *RCC_APB2ENR = 0x4005; // enable clock to UART1, AFIO and GPIOA
- *GPIOA_CRH = 0x444444D4; // (after enable GPIOA), on PA9&PA10 and set mode to alternative output
- *AFIO_EVCR = 0x89; // (after enable) set event control register, output on PA, Pin 9
+ /* (after enable GPIOA), on PA9&PA10 and set mode
+ * to alternative output */
+ regw_u32(GPIOA_CRH, 0x444444D4, 0, O_WRITE);
+ regw_u8(AFIO_EVCR, 0x89, 0, O_WRITE);// set event control register, output on PA, Pin 9
- *USART1_CR1 = (0 << 13); // disable temporarily to set values
+ //disable temporarily to set values
+ regw_u8(USART1_CR1, 0x0, 13, SET);
/* baud rate 115200, 8MHz / (16 * USARTDIV)
* USARTDIV = 4.34
* MANTISSA: 0d4.34 0d4 -> 0x4
* USART_BRR = 0x45*/
- /* baud rate 2400
- *
- * 16 * 0.33 -> 0x5
- * 208 -> 0x34 */
-
- *USART1_BRR = (volatile uint32_t) 0x00000045;
+ regw_u32(USART1_BRR, 0x00000045, 0, O_WRITE);
+ regw_u32(USART1_CR2, 0x0000, 0, O_WRITE); //set stop bit, default is 1 stop bit 0x00
- *USART1_CR2 = (volatile uint32_t) 0x0000; // set stop bit, default is 1 stop bit 0x00
- // enable DMA
- // *USART1_CR3 = 0x0C0;
/* parity = 8 bit, UART1 enabled,
* TX and RX enabled, interrupts enabled */
- *USART1_CR1 = (volatile uint32_t) 0x000030AC;
-
-/*
- * Configure UART0:
- 1. Disable the UART by clearing the UARTEN bit in the UARTCTL register.
- 2. Write the integer portion of the BRD to the UARTIBRD register.
- 3. Write the fractional portion of the BRD to the UARTFBRD register.
- 4. Write the desired serial parameters to the UARTLCRH register
- 5. Enable the UART by setting the UARTEN bit in the UARTCTL register.
-*/
+ //regw_u32(USART1_CR1, 0x000030AC, 0, O_WRITE);
+ regw_u32(USART1_CR1, 0x0000302C, 0, O_WRITE);
+
+ ivt_set_gate(53, uart_handler, 0);
+
+ *NVIC_ISER1 = (1 << 5); // Enable UART interrupt at NVIC
}
void wait() {
if (ch == '\n') {
while (*USART1_SR & 0x0C) { } // transmit data register empty and complete
- *USART1_DR = 0x0D; // return line
+ regw_u8(USART1_DR, 0x0D, 0, O_WRITE); // return line
}
-
while (*USART1_SR & 0x0C) {}
- *USART1_DR = ch;
+ regw_u8(USART1_DR, ch, 0, O_WRITE);
-
-
wait();
}
-extern void uart_puts(unsigned char *str)
-{
-
+extern void uart_puts(unsigned char *str) {
int i;
-
- for (i = 0; i < strlen(str); i++)
- {
+ for (i = 0; i < strlen(str); i++) {
uart_putc(str[i]);
}
}
-char * uart_read() {
+char uart_read() {
- return NULL;
+ /* while (buffer not empty)
+ * read()
+ * uart_putc(ch) // echo
+ * if ch = enter
+ * process inquiry.
+ */
+
}