OBJ = $(patsubst %, $(ODIR)/%,$(_OBJ))
DDIR = obj/drivers
-_DRIVERS = uart.o
+_DRIVERS = uart.o tm1637.o led.o
DRIVERS = $(patsubst %, $(DDIR)/%,$(_DRIVERS))
LDIR = obj/lib
--- /dev/null
+/* (CC-BY-NC-SA) ROBIN KRENS - ROBIN @ ROBINKRENS.NL
+ *
+ * $LOG$
+ * 2019/7/25 - ROBIN KRENS
+ * Initial version
+ *
+ * $DESCRIPTION$
+ * Hardly a driver, but a driver nonetheless. Enables clock on
+ * a GPIOx range and sets the GPIOx pin in push-pull output mode.
+ * Basic on - off function (writing a 1 or zero 0)
+ *
+ * $USAGE$
+ * In the code below we enable GPIOC and use PC0 as output. But
+ * basically any GPIO range or pin could be used. Note that the
+ * output register is only word accessible.
+ *
+ * */
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include <sys/mmap.h>
+#include <sys/robsys.h>
+
+#include <lib/regfunc.h>
+#include <lib/string.h>
+
+#include <drivers/led.h>
+
+
+void led_init() {
+
+ regw_u8(RCC_APB2ENR, 0x1, 4, SETBIT); // enable GPIOC
+ regw_u32(GPIOC_CRL, 0x44444442, 0, OWRITE); // set PC0 pin to output mode
+ *GPIOC_ODR = 0xFFFF; // only writable in word mode
+
+}
+
+void led_on() {
+ *GPIOC_ODR = 0x0001;
+}
+
+void led_off() {
+ *GPIOC_ODR = 0x0000;
+}
+
--- /dev/null
+/* (CC-BY-NC-SA) ROBIN KRENS - ROBIN @ ROBINKRENS.NL
+ *
+ * $LOG$
+ * 2019/7/25 - ROBIN KRENS
+ * Initial version
+ *
+ * $DESCRIPTION$
+ * Basic driver for the TM1637. The TM1637 is 7 segment
+ * ledclock peripheral. Communication is over I2C.
+ *
+ * */
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include <sys/mmap.h>
+#include <sys/robsys.h>
+
+#include <lib/regfunc.h>
+#include <lib/string.h>
+
+#include <drivers/tm1637.h>
+
+
+void tm1637_init() {
+
+ /* Program the peripheral input clock in I2C_CR2 Register in order to generate correct timings
+ Configure the clock control registers
+ Configure the rise time register
+ Program the I2C_CR1 register to enable the peripheral
+ Set the START bit in the I2C_CR1 register to generate a Start condition
+
+ ENABLE GPIOB6 and B7*/
+
+ //regw_u8(RCC_APB1ENR, 0x1, 21, SETBIT);
+ //regw_u32(RCC_APB2ENR, 0x1, 3, SETBIT);
+ // //regw_u8(AFIO_EVCR, 0x89, 0, SETBIT);// set event control register, output on ?
+
+ // regw_u32(GPIOB_CRL, 0xEE444444, 0, OWRITE);
+
+
+}
+
/* (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
+ regw_u8(AFIO_EVCR, 0x89, 0, OWRITE);// set event control register, output on PA, Pin 9 TODO: check
//disable temporarily to set values
regw_u8(USART1_CR1, 0x0, 13, SETBIT);
--- /dev/null
+extern void led_init();
+extern void led_on();
+extern void led_off();
+
--- /dev/null
+#ifndef __TM1637_H
+#define __TM1637_H
+
+extern void tm1637_init();
+
+#endif
#define SETBIT 0x02
#define CLRBIT 0x03
+/* 64kB SRAM located at SRAM_OFFSET */
+#define SRAM_SIZE 0x00010000
+#define SRAM_OFFSET 0x20000000
+
/* Safety macro's to get the address or value */
#define MEM_VALUE(addr) *((volatile uint32_t(*) (addr))
#define MEM_ADDR(addr) ((volatile uint32_t *) (addr))
/* SYSTEM CONTROL REGISTER */
#define SYSCTRL_RCC MEM_ADDR(0x40021000)
+#define RCC_APB1ENR MEM_ADDR(0x4002101C) // register to enable I2C
#define RCC_APB2ENR MEM_ADDR(0x40021018) // register to enable USART1
#define SYSCTRL_RIS MEM_ADDR(0x400FE050)
#define SYSCTRL_RCGC2 MEM_ADDR(0x400FE108)
#define GPIOPA_AFSEL MEM_ADDR(0x40004420)
-#define GPIOA_CRH MEM_ADDR(0x40010804)
+#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 AFIO_EVCR MEM_ADDR(0x40010000)
/*
* Vector table, each entry contains an interrupt
- * service routine:
- *
+ * service routine:
* interrupt vector 1-15: processor exceptions
* interrupt vector 16-92: irq0 - irq ..
- *
* Vector table needs to be aligned in memory.
* */
-
uint32_t __attribute__((aligned(0x100))) ivt[92];
-/* 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)*/
-
+/* Each message corresponds to each and every exception. */
char * exception_message(uint8_t intnr) {
- char * messages[] = {
- "--",
- "RESET",
- "NMI",
- "HARD FAULT",
- "MEMMANAGE FAULT",
- "BUS FAULT",
- "USAGE FAULT",
- "RESERVED",
- "SVC",
- "DEBUG MONITOR",
- "RESERVED",
- "RESERVED",
- "RESERVED",
- "RESERVED",
- "PENDSV",
- "SYSTICK",
- "IRQ1",
- "IRQ2",
- "IRQ3",
- "IRQ4",
- // add more if needed
- };
-
- if (intnr < 20) // TODO: strlen
- return messages[intnr];
+char * messages[] = {
+ "--",
+ "RESET",
+ "NMI",
+ "HARD FAULT",
+ "MEMMANAGE FAULT",
+ "BUS FAULT",
+ "USAGE FAULT",
+ "RESERVED",
+ "SVC",
+ "DEBUG MONITOR",
+ "RESERVED",
+ "RESERVED",
+ "RESERVED",
+ "RESERVED",
+ "PENDSV",
+ "SYSTICK",
+ "IRQ1",
+ "IRQ2",
+ "IRQ3",
+ "IRQ4",
+ // add more if needed
+};
+if (intnr < 20) // TODO: strlen
+ return messages[intnr];
return NULL;
}
ivt[num] = (uint32_t) isr;
*NVIC_ISER0 = (1 << ((uint32_t)(num) & 0x1F));
- /* Priorities */
+ /* TODO: Priorities */
}
-/* Dummy interrupt: comment out the comment to use a naked f
+/* Dummy interrupt: comment out the comment to use a naked
* function */
// __attribute__ ((interrupt))
/* Initialize interrupt vector */
void ivt_init() {
- /* clear entire IVT, in SRAM location for SRAM + .data (in .bss section) */
+ /* clear entire IVT location in memory */
memset(&ivt, 0, (sizeof(uint32_t) * 92));
- // stack top is loaded from the first entry table on boot/reset
- // don't need to relocate or init this here
+ /* The reset, NMI and hardfault handlers are originally
+ * defined in the assembly start up and can be
+ * reused or overwritten.
+ * */
extern void * reset, * nmi, * hardfault;
+ // set dummy handlers
for (int i = 1; i <= 64 ; i++) {
ivt_set_gate(i, dummy_isr, 0);
}
* Initial version
*
* $DESCRIPTION$
+ * Main intialize basic components of the boards
+ * and jumps to a terminal
*
* */
#include <sys/mmap.h>
#include <drivers/uart.h>
+#include <drivers/led.h>
+#include <drivers/tm1637.h>
void main()
{
ivt_init();
+
uart_init();
-
systick_init();
+
+ led_init();
sysinfo();
- extern void stub();
+ //extern void stub();
//stub();
//__asm__ __volatile__ ("ldc p1, cr1, r0");
- terminal();
+ while(1) {
+ int r;
+ for (int i = 0; i < 50000; i++) {
+ r = 0;
+ }
+ led_on();
+ for (int i = 0; i < 50000; i++) {
+ r = 0;
+ }
+ led_off();
+ }
+ // terminal();
for(;;) {
- .equ STACK_TOP, 0x20010000 /* placed at 32kB, TODO: could place at top of SRAM? */
+/* (CC-BY-NC-SA) ROBIN KRENS - ROBIN @ ROBINKRENS.NL
+ *
+ * $LOG$
+ * 2019/7/20 - ROBIN KRENS
+ * Initial version
+ *
+ * $DESCRIPTION$
+ *
+ * */
+ .equ STACK_TOP, 0x20010000 /* placed at 64kB, top of SRAM */
.text
.global _start
.global reset, nmi, hardfault
+/* (CC-BY-NC-SA) ROBIN KRENS - ROBIN @ ROBINKRENS.NL
+ *
+ * $LOG$
+ * 2019/7/20 - ROBIN KRENS
+ * Initial version
+ *
+ * */
+
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <lib/stdio.h>
#include <lib/regfunc.h>
-#define MEM_SIZE 0x00010000
-#define MEM_OFFSET 0x20000000
uint32_t get_msp(void);
extern char _endofbss;
uint32_t current_stack = get_msp();
- uint32_t stack_usage = (MEM_OFFSET + MEM_SIZE) - current_stack;
- uint32_t data_bss = &_endofbss - MEM_OFFSET;
- uint32_t mem_free = MEM_SIZE - stack_usage - data_bss;
+ uint32_t stack_usage = (SRAM_OFFSET + SRAM_SIZE) - current_stack;
+ uint32_t data_bss = &_endofbss - SRAM_OFFSET;
+ uint32_t mem_free = SRAM_SIZE - stack_usage - data_bss;
cputs("# TOTAL MEMORY: ");
- cputs(regtohex(MEM_SIZE));
+ cputs(regtohex(SRAM_SIZE));
cputchar('\n');
cputs("# FREE MEMORY: ");
cputs(regtohex(mem_free));