From: John Tsiombikas Date: Sun, 27 Jan 2019 00:41:49 +0000 (+0200) Subject: testing minimal program X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=commitdiff_plain;h=993155fee2327f1f3cda285c9548bbb09688a3f3;p=rpikern testing minimal program --- diff --git a/src/asm.h b/src/asm.h index 61d29ac..f544000 100644 --- a/src/asm.h +++ b/src/asm.h @@ -5,9 +5,11 @@ #define disable_intr() asm volatile ("cpsid i") #define mem_barrier() asm volatile ("dmb" ::: "memory") +/* #define delay(x) asm volatile ( \ "0: subs %0, %0, #1\n\t" \ "bne 0b\n\t" \ :: "r"(x) : "cc") +*/ #endif /* ASM_H_ */ diff --git a/src/config.h b/src/config.h new file mode 100644 index 0000000..0e997c7 --- /dev/null +++ b/src/config.h @@ -0,0 +1,14 @@ +#ifndef CONFIG_H_ +#define CONFIG_H_ + +#ifndef RPI_MODEL +#define RPI_MODEL 2 +#endif + +#if RPI_MODEL == 1 +#define IO_BASE 0x20000000 +#else +#define IO_BASE 0x3f000000 +#endif + +#endif /* CONFIG_H_ */ diff --git a/src/gpio.h b/src/gpio.h index 19ca6c3..3a2e253 100644 --- a/src/gpio.h +++ b/src/gpio.h @@ -1,9 +1,10 @@ #ifndef GPIO_H_ #define GPIO_H_ +#include "config.h" #include "asm.h" -#define GPIO_BASE 0x3f200000 +#define GPIO_BASE (IO_BASE | 0x200000) #define GPIO_REG(x) (*(volatile uint32_t*)(GPIO_BASE | (x))) /* function select */ @@ -83,6 +84,8 @@ static inline void gpio_fsel(int x, int f) } } +void delay(uint32_t x); /* in startup.s */ + static inline void gpio_pullups(uint32_t mask0, uint32_t mask1, int state) { REG_GPPUD = state; diff --git a/src/main.c b/src/main.c index 03a69ea..97fcda7 100644 --- a/src/main.c +++ b/src/main.c @@ -1,141 +1,34 @@ +#include "config.h" + #include #include #include "asm.h" #include "serial.h" -#define WIDTH 640 -#define HEIGHT 480 -#define BPP 16 - -#ifdef RPI1 -#define IOBASEADDR 0x20000000 -#else -#define IOBASEADDR 0x3f000000 -#endif - -#define phys2bus(addr) ((addr) | 0x40000000) -#define bus2phys(addr) ((addr) & 0x3fffffff) - -#define IOREG_ADDR(x) (IOBASEADDR | (x)) -#define REG_MB_READ *((volatile uint32_t*)IOREG_ADDR(0xb880)) -#define REG_MB_STAT *((volatile uint32_t*)IOREG_ADDR(0xb898)) -#define REG_MB_WRITE *((volatile uint32_t*)IOREG_ADDR(0xb8a0)) - -#define MB_STAT_FULL 0x80000000 -#define MB_STAT_EMPTY 0x40000000 - -#define MB_CHAN_FRAMEBUF 1 -#define MB_CHAN_PROP 8 - -#define PROP_CODE_REQ 0 -#define PROP_RESP_OK 0x80000000 - - -#define PROP_TAG_END 0 - -#define PROP_TAG_SET 0x08000 -#define PROP_TAG_TEST 0x04000 -#define PROP_TAG_GET 0 - -#define PROP_TAG_ALLOCBUF 0x40001 -#define PROP_TAG_BLANKSCR 0x40002 -#define PROP_TAG_PHYSRES 0x40003 -#define PROP_TAG_VIRTRES 0x40004 -#define PROP_TAG_DEPTH 0x40005 -#define PROP_TAG_PIXEL_ORDER 0x40006 -#define PROP_TAG_ALPHA_MODE 0x40007 -#define PROP_TAG_PITCH 0x40008 -#define PROP_TAG_VOFFS 0x40009 -#define PROP_TAG_OVERSCAN 0x4000a -#define PROP_TAG_PALETTE 0x4000b -#define PROP_TAG_CUR_INFO 0x00010 -#define PROP_TAG_CUR_STATE 0x00011 - - -void panic(void); -static int send_prop(uint32_t *buf); -int prop_blankscr(int onoff); -int prop_setres(int xsz, int ysz); -int prop_getres(int *xsz, int *ysz); -int prop_setvres(int xsz, int ysz); -int prop_getvres(int *xsz, int *ysz); -int prop_setdepth(int bpp); -int prop_getdepth(void); -int prop_getpitch(void); -void *prop_allocbuf(int *size); - -uint32_t mb_read(int chan); -void mb_write(int chan, uint32_t val); - void dbgled(int x); void exit(int x); -uint32_t propbuf[64] __attribute__((aligned(16))); -uint32_t premade[] __attribute__((aligned(16))) = { - 80, /* size */ - 0, /* request */ - 0x00048003, 8, 0, WIDTH, HEIGHT, /* set phys */ - 0x00048004, 8, 0, WIDTH, HEIGHT, /* set virt */ - 0x00048005, 4, 0, BPP, /* set depth */ - 0, /* end */ - 0, 0, 0 /* padding */ -}; - - int main(void) { - int i, j, bpp, fbsize, pitch, xsz, ysz; -#if BPP == 16 - uint16_t *fb, *fbptr; -#elif BPP == 24 - unsigned char *fb, *fbptr; -#elif BPP == 32 - uint32_t *fb, *fbptr; -#endif - disable_intr(); + dbgled(2); + init_serial(115200); ser_printstr("starting rpkern\n"); - /*if(send_prop(premade) == -1) panic();*/ - - /*if(prop_setres(WIDTH, HEIGHT) == -1) panic();*/ - if(prop_setvres(WIDTH, HEIGHT) == -1) panic(); - if(prop_setdepth(BPP) == -1) panic(); - if(!(fb = prop_allocbuf(&fbsize))) panic(); - - prop_getvres(&xsz, &ysz); - bpp = prop_getdepth(); - pitch = prop_getpitch(); - - if(xsz != WIDTH || ysz != HEIGHT) panic(); - if(bpp != BPP) panic(); - - fbptr = fb; - for(i=0; i> 1) & 0xff; - int g = xor & 0xff; - int b = (xor << 1) & 0xff; - -#if BPP == 16 - *fbptr++ = ((r << 8) & 0xf800) | ((g << 3) & 0x7e0) | ((b >> 3) & 0x1f); -#elif BPP == 24 - *fbptr++ = r; - *fbptr++ = g; - *fbptr++ = b; -#elif BPP == 32 - *fbptr++ = ((r << 16) & 0xff0000) | ((g << 8) & 0xff00) | (b & 0xff); -#endif + for(;;) { + int c = ser_getchar(); + if(c == -1) { + ser_printstr("error!\n"); + } else { + ser_printstr("got: "); + ser_putchar(c); + ser_putchar('\r'); + ser_putchar('\n'); } - - //fbptr += pitch / 2 - 640; } - fb[0] = 0xf800; - return 0; } @@ -144,208 +37,3 @@ void panic(void) dbgled(1); exit(0); } - -static int send_prop(uint32_t *buf) -{ - mem_barrier(); - mb_write(MB_CHAN_PROP, (uint32_t)buf >> 4); - mb_read(MB_CHAN_PROP); - mem_barrier(); - return propbuf[1] == PROP_RESP_OK ? 0 : -1; -} - -int prop_blankscr(int onoff) -{ - uint32_t *pb = propbuf; - - *pb++ = 32; - *pb++ = 0; - *pb++ = PROP_TAG_BLANKSCR; - *pb++ = 4; /* data size */ - *pb++ = PROP_CODE_REQ; - *pb++ = onoff ? 1 : 0; - *pb++ = PROP_TAG_END; - *pb++ = 0; /* padding */ - - return send_prop(propbuf); -} - -int prop_setres(int xsz, int ysz) -{ - uint32_t *pb = propbuf; - - *pb++ = 32; - *pb++ = 0; - *pb++ = PROP_TAG_PHYSRES | PROP_TAG_SET; - *pb++ = 8; /* data size */ - *pb++ = PROP_CODE_REQ; - *pb++ = xsz; - *pb++ = ysz; - *pb++ = PROP_TAG_END; - - return send_prop(propbuf); -} - -int prop_getres(int *xsz, int *ysz) -{ - uint32_t *pb = propbuf; - uint32_t *data; - - *pb++ = 32; - *pb++ = 0; - *pb++ = PROP_TAG_PHYSRES; - *pb++ = 8; - *pb++ = PROP_CODE_REQ; - data = pb; - *pb++ = 0; - *pb++ = 0; - *pb++ = PROP_TAG_END; - - if(send_prop(propbuf) == -1) { - return -1; - } - *xsz = data[0]; - *ysz = data[1]; - return 0; -} - -int prop_setvres(int xsz, int ysz) -{ - uint32_t *pb = propbuf; - - *pb++ = 32; - *pb++ = 0; - *pb++ = PROP_TAG_VIRTRES | PROP_TAG_SET; - *pb++ = 8; /* data size */ - *pb++ = PROP_CODE_REQ; - *pb++ = xsz; - *pb++ = ysz; - *pb++ = PROP_TAG_END; - - return send_prop(propbuf); -} - -int prop_getvres(int *xsz, int *ysz) -{ - uint32_t *pb = propbuf; - uint32_t *data; - - *pb++ = 32; - *pb++ = 0; - *pb++ = PROP_TAG_VIRTRES; - *pb++ = 8; - *pb++ = PROP_CODE_REQ; - data = pb; - *pb++ = 0; - *pb++ = 0; - *pb++ = PROP_TAG_END; - - if(send_prop(propbuf) == -1) { - return -1; - } - *xsz = data[0]; - *ysz = data[1]; - return 0; -} - -int prop_setdepth(int bpp) -{ - uint32_t *pb = propbuf; - - *pb++ = 32; - *pb++ = 0; - *pb++ = PROP_TAG_DEPTH | PROP_TAG_SET; - *pb++ = 4; - *pb++ = PROP_CODE_REQ; - *pb++ = bpp; - *pb++ = PROP_TAG_END; - *pb++ = 0; /* padding */ - - return send_prop(propbuf); -} - -int prop_getdepth(void) -{ - uint32_t *pb = propbuf; - uint32_t *data; - - *pb++ = 32; - *pb++ = 0; - *pb++ = PROP_TAG_DEPTH; - *pb++ = 4; /* data size */ - *pb++ = PROP_CODE_REQ; - data = pb; - *pb++ = 0; - *pb++ = PROP_TAG_END; - *pb++ = 0; /* padding */ - - if(send_prop(propbuf) == -1) { - return 0; - } - return *data; -} - -int prop_getpitch(void) -{ - uint32_t *pb = propbuf; - uint32_t *data; - - *pb++ = 32; - *pb++ = 0; - *pb++ = PROP_TAG_PITCH; - *pb++ = 4; /* data size */ - *pb++ = PROP_CODE_REQ; - data = pb; - *pb++ = 0; - *pb++ = PROP_TAG_END; - *pb++ = 0; /* padding */ - - if(send_prop(propbuf) == -1) { - return 0; - } - return *data; -} - -void *prop_allocbuf(int *size) -{ - uint32_t *pb = propbuf; - uint32_t *data; - - *pb++ = 32; - *pb++ = 0; - *pb++ = PROP_TAG_ALLOCBUF; - *pb++ = 8; /* data size */ - *pb++ = PROP_CODE_REQ; - data = pb; - *pb++ = 16; /* alignment */ - *pb++ = 0; - *pb++ = PROP_TAG_END; - - if(send_prop(propbuf) == -1) { - return 0; - } - *size = data[1]; - return (void*)bus2phys(data[0]); -} - -uint32_t mb_read(int chan) -{ - uint32_t val; - do { - mem_barrier(); - while(REG_MB_STAT & MB_STAT_EMPTY); - mem_barrier(); - val = REG_MB_READ; - } while((val & 0xf) != chan); - return val >> 4; -} - -void mb_write(int chan, uint32_t val) -{ - mem_barrier(); - while(REG_MB_STAT & MB_STAT_FULL) { - mem_barrier(); - } - REG_MB_WRITE = (val << 4) | chan; - mem_barrier(); -} diff --git a/src/serial.c b/src/serial.c index ddd5923..465afc7 100644 --- a/src/serial.c +++ b/src/serial.c @@ -14,13 +14,16 @@ void init_serial(int baud) /* disable pullups for GPIO 14 & 15 */ gpio_pullups(0xc000, 0, PUD_DISABLE); + /* select alt0 function for GPIO 14 & 15 */ + gpio_fsel(14, FSEL_ALT0); + gpio_fsel(15, FSEL_ALT0); - REG_ICR = 0; /* clear pending interrupts */ + REG_ICR = 0x7ff; /* clear pending interrupts */ /* calculate baud rate divisor */ bdiv_fp6 = (UART_CLK << 6) / (16 * baud); - REG_IBRD = (bdiv_fp6 >> 6) & 0xffff; /* 16 bits integer part */ - REG_FBRD = bdiv_fp6 & 0x3f; /* 6 bits fractional precision */ + REG_IBRD = 1;//(bdiv_fp6 >> 6) & 0xffff; /* 16 bits integer part */ + REG_FBRD = 40;//bdiv_fp6 & 0x3f; /* 6 bits fractional precision */ /* line control: fifo enable, 8n1 */ REG_LCRH = LCRH_FIFOEN | LCRH_8BITS; diff --git a/src/startup.s b/src/startup.s index cba8c87..308d4fa 100644 --- a/src/startup.s +++ b/src/startup.s @@ -43,5 +43,10 @@ dbgled: streq r2, [r3, #0x28] @ GPCLR0 bx lr + .global delay +delay: + subs r0, r0, #1 + bne delay + bx lr @ vi:set filetype=armasm: diff --git a/src/timer.h b/src/timer.h new file mode 100644 index 0000000..065fdcf --- /dev/null +++ b/src/timer.h @@ -0,0 +1,30 @@ +#ifndef TIMER_H_ +#define TIMER_H_ + +#include "config.h" + +#define TM_BASE (IO_BASE | 0xb000) + +#define TM_REG(x) (*(volatile uint32_t*)(TIMER_BASE | (x))) +#define TM_LOAD TM_REG(0x400) +#define TM_VALUE TM_REG(0x404) +#define TM_CTL TM_REG(0x408) +#define TM_ICLR TM_REG(0x40c) +#define TM_IRAW TM_REG(0x410) +#define TM_IMSK TM_REG(0x414) +#define TM_RELOAD TM_REG(0x418) +#define TM_PREDIV TM_REG(0x41c) +#define TM_COUNT TM_REG(0x420) + +#define TMCTL_23BIT 0x000002 +#define TMCTL_DIV16 0x000004 +#define TMCTL_DIV256 0x000008 +#define TMCTL_DIV1 0x00000c +#define TMCTL_IEN 0x000020 +#define TMCTL_EN 0x000080 +#define TMCTL_DBGHALT 0x000100 +#define TMCTL_CNTEN 0x000200 + +#define TMCTL_PRESCALER(x) (((uint32_t)(x) & 0xff) << 16) + +#endif /* TIMER_H_ */ diff --git a/src/uart.h b/src/uart.h index ade162e..e330ae4 100644 --- a/src/uart.h +++ b/src/uart.h @@ -1,7 +1,9 @@ #ifndef UART_PL011_H_ #define UART_PL011_H_ -#define UART0_BASE 0x3f201000 +#include "config.h" + +#define UART0_BASE (IO_BASE | 0x201000) #define UART0_REG(x) *(volatile uint32_t*)(UART0_BASE | (x)) #define REG_DR UART0_REG(0x00) /* data register */