# HG changeset patch # User Paul Boddie # Date 1540157155 -7200 # Node ID 7f5b697dd9e0c6937acac264aaf5d91a079326b3 # Parent f98e73f2ccc0b57747d245d6df8ca2362bbfdc43 Added support for parallel mode. diff -r f98e73f2ccc0 -r 7f5b697dd9e0 init.c --- a/init.c Sun Oct 21 19:16:10 2018 +0200 +++ b/init.c Sun Oct 21 23:25:55 2018 +0200 @@ -112,13 +112,13 @@ void init_dma(void) { - /* Disable DMA interrupts. */ + /* Disable DMA interrupts (DMAxIE). */ - CLR_REG(DMAIEC, 0b1111 << DMAINTBASE); /* DMA3IE...DMA0IE = 0 */ + CLR_REG(DMAIEC, 0b1111 << DMAINTBASE); - /* Clear DMA interrupt flags. */ + /* Clear DMA interrupt flags (DMAxIF). */ - CLR_REG(DMAIFS, 0b1111 << DMAINTBASE); /* DMA3IF...DMA0IF = 0 */ + CLR_REG(DMAIFS, 0b1111 << DMAINTBASE); /* Enable DMA. */ @@ -351,6 +351,96 @@ +/* Parallel mode configuration. */ + +void init_pm(void) +{ + int i; + + /* Disable PM interrupts (PMxIE). */ + + CLR_REG(PMIEC, 0b11 << PMINTBASE); + + /* Clear PM interrupt flags (PMxIF). */ + + CLR_REG(PMIFS, 0b11 << PMINTBASE); + + /* Disable PM for configuration. */ + + for (i = PMMIN; i <= PMMAX; i++) + REG(PM_REG(i, PMxCON)) = 0; +} + +/* Configure the parallel mode. */ + +void pm_init(int port, uint8_t mode) +{ + if ((port < PMMIN) || (port > PMMAX)) + return; + + REG(PM_REG(port, PMxMODE)) = (mode & 0b11) << 8; + REG(PM_REG(port, PMxAEN)) = 0; + REG(PM_REG(port, PMxADDR)) = 0; + SET_REG(PM_REG(port, PMxCON), 1 << 1); /* WRSP: PMENB active high */ +} + +/* Configure output signals. */ + +void pm_set_output(int port, int write_enable, int read_enable) +{ + if ((port < PMMIN) || (port > PMMAX)) + return; + + REG(PM_REG(port, PMxCON)) = (write_enable ? (1 << 9) : 0) | + (read_enable ? (1 << 8) : 0); +} + +/* Configure interrupts caused by parallel mode. */ + +void pm_init_interrupt(int port, uint8_t pri, uint8_t sub) +{ + if ((port < PMMIN) || (port > PMMAX)) + return; + + /* Disable interrupt and clear interrupt flag. */ + + CLR_REG(PMIEC, PM_INT_FLAGS(port, PMxIE)); + CLR_REG(PMIFS, PM_INT_FLAGS(port, PMxIF)); + + /* Set interrupt priorities. */ + + REG(PM_IPC_REG(port)) = (REG(PM_IPC_REG(port)) & + ~(PM_IPC_PRI(port, 7, 3))) | + PM_IPC_PRI(port, pri, sub); + + /* Enable interrupt. */ + + SET_REG(PMIEC, PM_INT_FLAGS(port, PMxIE)); +} + +/* Enable parallel mode. */ + +void pm_on(int port) +{ + if ((port < PMMIN) || (port > PMMAX)) + return; + + SET_REG(PM_REG(port, PMxCON), 1 << 15); +} + +/* Disable parallel mode. */ + +void pm_off(int port) +{ + if ((port < PMMIN) || (port > PMMAX)) + return; + + CLR_REG(PM_REG(port, PMxCON), 1 << 15); +} + + + + /* Timer configuration. */ void timer_init(int timer, uint8_t prescale, uint16_t limit) @@ -548,6 +638,29 @@ return (flags & 0b1) << (OCINTBASE + (unit - OCMIN) * OCINTSTEP); } +/* Return encoded parallel mode interrupt priorities for combining with a register. */ + +uint32_t PM_IPC_PRI(int port, uint8_t pri, uint8_t sub) +{ + (void) port; + return PRI(pri, sub) << PMIPCBASE; +} + +/* Return the parallel mode interrupt priorities register. */ + +uint32_t PM_IPC_REG(int port) +{ + (void) port; + return PMIPC; +} + +/* Return the parallel mode interrupt flags for combining with a register. */ + +int PM_INT_FLAGS(int port, uint8_t flags) +{ + return (flags & 0b11) << (PMINTBASE + (port - PMMIN) * PMINTSTEP); +} + /* Return encoded timer interrupt priorities for combining with a register. */ uint32_t TIMER_IPC_PRI(int timer, uint8_t pri, uint8_t sub) diff -r f98e73f2ccc0 -r 7f5b697dd9e0 init.h --- a/init.h Sun Oct 21 19:16:10 2018 +0200 +++ b/init.h Sun Oct 21 23:25:55 2018 +0200 @@ -111,6 +111,27 @@ +/* Parallel mode configuration. */ + +void init_pm(void); + +void pm_init(int port, uint8_t mode); + +void pm_init_interrupt(int port, uint8_t pri, uint8_t sub); + +void pm_off(int port); + +void pm_on(int port); + +void pm_set_output(int port, int write_enable, int read_enable); + +int PM_INT_FLAGS(int port, uint8_t flags); + +uint32_t PM_IPC_PRI(int port, uint8_t pri, uint8_t sub); +uint32_t PM_IPC_REG(int port); + + + /* Timer configuration. */ void timer_init(int timer, uint8_t prescale, uint16_t limit); diff -r f98e73f2ccc0 -r 7f5b697dd9e0 pic32.h --- a/pic32.h Sun Oct 21 19:16:10 2018 +0200 +++ b/pic32.h Sun Oct 21 23:25:55 2018 +0200 @@ -27,14 +27,6 @@ * PIC32MX1XX/2XX 28/36/44-pin Family Data Sheet */ -#define PMCON 0xBF807000 -#define PMMODE 0xBF807010 -#define PMADDR 0xBF807020 -#define PMDOUT 0xBF807030 -#define PMDIN 0xBF807040 -#define PMAEN 0xBF807050 -#define PMSTAT 0xBF807060 - #define OSCCON 0xBF80F000 #define REFOCON 0xBF80F020 #define REFOTRIM 0xBF80F030 @@ -190,6 +182,39 @@ #define OC5IPC IPC5 #define OCIPCBASE 16 +/* Parallel mode conveniences. */ + +#define PMCON 0xBF807000 + +#define PMxCON 0x00 +#define PMxMODE 0x10 +#define PMxADDR 0x20 +#define PMxDOUT 0x30 +#define PMxDIN 0x40 +#define PMxAEN 0x50 +#define PMxSTAT 0x60 + +#define PMMIN 0 +#define PMMAX 0 +#define PMBASE PMCON +#define PMSTEP 0 + +#define PMIEC IEC1 + +#define PMxIE 1 +#define PMxEIE 2 + +#define PMIFS IFS1 + +#define PMxIF 1 +#define PMxEIF 2 + +#define PMINTBASE 16 +#define PMINTSTEP 0 + +#define PMIPC IPC8 +#define PMIPCBASE 24 + /* Timer conveniences. */ #define T1CON 0xBF800600 @@ -281,6 +306,8 @@ #define OC3 17 #define OC4 22 #define OC5 27 +#define PMP 48 +#define PMPE 49 #define T1 4 #define T2 9 #define T3 14 diff -r f98e73f2ccc0 -r 7f5b697dd9e0 pic32_c.h --- a/pic32_c.h Sun Oct 21 19:16:10 2018 +0200 +++ b/pic32_c.h Sun Oct 21 23:25:55 2018 +0200 @@ -79,6 +79,11 @@ return OCBASE + reg + (unit - OCMIN) * OCSTEP; } +static inline uint32_t PM_REG(int port, uint32_t reg) +{ + return PMBASE + reg + (port - PMMIN) * PMSTEP; +} + static inline uint32_t TIMER_REG(int timer, uint32_t reg) { return TIMERBASE + reg + (timer - TIMERMIN) * TIMERSTEP;