Compare commits
5 commits
eff851b274
...
6c8119424b
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6c8119424b | ||
|
|
44a7192afb | ||
|
|
3e62d01ad8 | ||
|
|
4d08354a50 | ||
|
|
91fa47d67c |
9 changed files with 282 additions and 23 deletions
2
Makefile
2
Makefile
|
|
@ -147,7 +147,7 @@ sources = irena mainloop parser message isr crc \
|
||||||
usb controlpipe usbconfig dma stream \
|
usb controlpipe usbconfig dma stream \
|
||||||
enc28j60 net udp \
|
enc28j60 net udp \
|
||||||
expression variables display \
|
expression variables display \
|
||||||
pressure gpio ltc2656 ads8688 \
|
pressure gpio ltc2656 ads8688 timer \
|
||||||
adc rtc \
|
adc rtc \
|
||||||
plugin \
|
plugin \
|
||||||
nomalloc strtol uart uart1 base85
|
nomalloc strtol uart uart1 base85
|
||||||
|
|
|
||||||
6
gpio.h
6
gpio.h
|
|
@ -15,10 +15,10 @@
|
||||||
* 0.7: (31) SPI SSEL (PWM, EINT) (power board)
|
* 0.7: (31) SPI SSEL (PWM, EINT) (power board)
|
||||||
* 0.8: (33) TxD1 (AD1.1, PWM)
|
* 0.8: (33) TxD1 (AD1.1, PWM)
|
||||||
* 0.9: (34) RxD1 (PWM, EINT)
|
* 0.9: (34) RxD1 (PWM, EINT)
|
||||||
* 0.10: (35) AD1.2 (power board)
|
* 0.10: (35) AD1.2 (CAP1.0) (power board)
|
||||||
* 0.11: (37) SSP SSEL DAC (open drain)
|
* 0.11: (37) SSP SSEL DAC (open drain)
|
||||||
* 0.12: (38) AD1.3 (MAT) (power board)
|
* 0.12: (38) AD1.3 (MAT1.0) (power board)
|
||||||
* 0.13: (39) AD1.4 Ipos (MAT)
|
* 0.13: (39) AD1.4 Ipos (MAT1.1)
|
||||||
* 0.14: (41) EINT1 ISP
|
* 0.14: (41) EINT1 ISP
|
||||||
* 0.15: (45) AD1.5 Ineg (EINT)
|
* 0.15: (45) AD1.5 Ineg (EINT)
|
||||||
* 0.16: (46) SSP SSEL/MCLK MAT0.2
|
* 0.16: (46) SSP SSEL/MCLK MAT0.2
|
||||||
|
|
|
||||||
|
|
@ -157,7 +157,7 @@
|
||||||
#define PCB_PINSEL1_P028_MASK 0x03000000
|
#define PCB_PINSEL1_P028_MASK 0x03000000
|
||||||
#define PCB_PINSEL1_P028_GPIO 0x00000000
|
#define PCB_PINSEL1_P028_GPIO 0x00000000
|
||||||
#define PCB_PINSEL1_P028_AD0_1 0x01000000
|
#define PCB_PINSEL1_P028_AD0_1 0x01000000
|
||||||
#define PCB_PINSEL1_P028_Capture_0_2 0x02000000
|
#define PCB_PINSEL1_P028_Capture0_2 0x02000000
|
||||||
#define PCB_PINSEL1_P028_Match0_2 0x03000000
|
#define PCB_PINSEL1_P028_Match0_2 0x03000000
|
||||||
|
|
||||||
#define PCB_PINSEL1_P029_MASK 0x0c000000
|
#define PCB_PINSEL1_P029_MASK 0x0c000000
|
||||||
|
|
|
||||||
15
irena.c
15
irena.c
|
|
@ -3,12 +3,12 @@
|
||||||
#include <lpc2148/scb.h>
|
#include <lpc2148/scb.h>
|
||||||
#include <lpc2148/pcb.h>
|
#include <lpc2148/pcb.h>
|
||||||
#include <lpc2148/vic.h>
|
#include <lpc2148/vic.h>
|
||||||
#include <lpc2148/timer.h>
|
|
||||||
#include <lpc2148/gpio.h>
|
#include <lpc2148/gpio.h>
|
||||||
|
|
||||||
#include "isr.h"
|
#include "isr.h"
|
||||||
#include "spi.h"
|
#include "spi.h"
|
||||||
#include "uart.h"
|
#include "uart.h"
|
||||||
|
#include "timer.h"
|
||||||
#include "ssp.h"
|
#include "ssp.h"
|
||||||
#include "adc.h"
|
#include "adc.h"
|
||||||
#include "rtc.h"
|
#include "rtc.h"
|
||||||
|
|
@ -26,6 +26,7 @@ void irena_init()
|
||||||
init_vic();
|
init_vic();
|
||||||
|
|
||||||
SCB_PCONP = SCB_PCONP_PCTIM0
|
SCB_PCONP = SCB_PCONP_PCTIM0
|
||||||
|
| SCB_PCONP_PCTIM1
|
||||||
| SCB_PCONP_PCUART0
|
| SCB_PCONP_PCUART0
|
||||||
| SCB_PCONP_PCUART1
|
| SCB_PCONP_PCUART1
|
||||||
| SCB_PCONP_PCSPI0
|
| SCB_PCONP_PCSPI0
|
||||||
|
|
@ -36,7 +37,7 @@ void irena_init()
|
||||||
| SCB_PCONP_PUSB
|
| SCB_PCONP_PUSB
|
||||||
;
|
;
|
||||||
// not powered:
|
// not powered:
|
||||||
// | SCB_PCONP_PCTIM1
|
//
|
||||||
// | SCB_PCONP_PCI2C0
|
// | SCB_PCONP_PCI2C0
|
||||||
// | SCB_PCONP_PCI2C1
|
// | SCB_PCONP_PCI2C1
|
||||||
|
|
||||||
|
|
@ -116,14 +117,8 @@ void irena_init()
|
||||||
// Doing Enhanced GPIO on both ports
|
// Doing Enhanced GPIO on both ports
|
||||||
SCB_SCS = SCB_SCS_GPIO0M | SCB_SCS_GPIO1M;
|
SCB_SCS = SCB_SCS_GPIO0M | SCB_SCS_GPIO1M;
|
||||||
|
|
||||||
// Timer 0 captures the Altera Attn Flag
|
timer0_init();
|
||||||
|
timer1_init();
|
||||||
T0CTCR = TxCTCR_Timer;
|
|
||||||
T0PR = 0; // Prescale = 60MHz
|
|
||||||
T0MR2 = 915; // 32751 kHz
|
|
||||||
T0MCR = TxMCR_MR2R;
|
|
||||||
T0EMR = TxEMR_EMC2_Toggle;
|
|
||||||
T0TCR = TxTCR_Counter_Enable;
|
|
||||||
|
|
||||||
uart_init();
|
uart_init();
|
||||||
uart1_init();
|
uart1_init();
|
||||||
|
|
|
||||||
13
isr.h
13
isr.h
|
|
@ -30,15 +30,16 @@ static inline void enable_irq(unsigned int flag)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define IrqVec_Timer0 2
|
|
||||||
#define IrqVec_UART0 4
|
#define IrqVec_UART0 4
|
||||||
#define IrqVec_UART1 5
|
#define IrqVec_UART1 5
|
||||||
#define IrqVec_USB 6
|
#define IrqVec_USB 6
|
||||||
#define IrqVec_SPI 8
|
#define IrqVec_SPI 7
|
||||||
#define IrqVec_RTC 10
|
#define IrqVec_RTC 8
|
||||||
#define IrqVec_AD0 11
|
#define IrqVec_AD0 9
|
||||||
#define IrqVec_AD1 12
|
#define IrqVec_AD1 10
|
||||||
#define IrqVec_SSP 14
|
#define IrqVec_Timer1 11
|
||||||
|
#define IrqVec_Timer0 12
|
||||||
|
#define IrqVec_SSP 13
|
||||||
|
|
||||||
extern const unsigned int stack_guard_val;
|
extern const unsigned int stack_guard_val;
|
||||||
extern unsigned int const *user_stack_guard;
|
extern unsigned int const *user_stack_guard;
|
||||||
|
|
|
||||||
61
ssp.c
61
ssp.c
|
|
@ -12,7 +12,8 @@
|
||||||
|
|
||||||
static volatile struct ssp_job job;
|
static volatile struct ssp_job job;
|
||||||
struct ssp_match ssp_match;
|
struct ssp_match ssp_match;
|
||||||
|
static const struct ssp_batch *ssp_batch;
|
||||||
|
static int ssp_batch_repeats;
|
||||||
unsigned int ssp_bits;
|
unsigned int ssp_bits;
|
||||||
volatile unsigned int ssp_lastword;
|
volatile unsigned int ssp_lastword;
|
||||||
unsigned int ssp_ssel_mask = SSP_SSEL_MASK0 | SSP_SSEL_MASK1;
|
unsigned int ssp_ssel_mask = SSP_SSEL_MASK0 | SSP_SSEL_MASK1;
|
||||||
|
|
@ -152,6 +153,18 @@ int ssp_submit(const unsigned short *cmd, int cmd_size, unsigned int ic, unsigne
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ssp_submit_job(const struct ssp_job *jj)
|
||||||
|
{
|
||||||
|
unsigned int iflg = disable_irq(INT_DISABLE);
|
||||||
|
size_t n = sizeof(job);
|
||||||
|
if (!jj->buf_ptr)
|
||||||
|
n -= 8;
|
||||||
|
memcpy((void*)&job, jj, n);
|
||||||
|
enable_irq(iflg);
|
||||||
|
ssp_poll();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void ssp_reset(void)
|
void ssp_reset(void)
|
||||||
{
|
{
|
||||||
SSPIMSC = 0;
|
SSPIMSC = 0;
|
||||||
|
|
@ -245,3 +258,49 @@ struct ssp_config ssp_conf_bate[] = {
|
||||||
.ssel = SSP_EXT | SSP_MCLK,
|
.ssel = SSP_EXT | SSP_MCLK,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
int ssp_wait_miso(const struct ssp_wait *wait)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ssp_run_batch(void)
|
||||||
|
{
|
||||||
|
const struct ssp_batch *batch = ssp_batch;
|
||||||
|
if (!batch || !batch->job)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (batch->wait) {
|
||||||
|
int c = ssp_wait_miso(batch->wait);
|
||||||
|
if (c)
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ssp_batch_repeats++ >= batch->count) {
|
||||||
|
ssp_batch_repeats = 0;
|
||||||
|
ssp_batch++;
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct ssp_config *ssel = batch->ssel;
|
||||||
|
if (ssel)
|
||||||
|
if (ssel->mode)
|
||||||
|
ssp_init(ssel);
|
||||||
|
else if (ssel->ssel)
|
||||||
|
ssp_config.ssel = ssel->ssel;
|
||||||
|
const struct ssp_match *match = batch->match;
|
||||||
|
if (match)
|
||||||
|
ssp_match = *match;
|
||||||
|
if (ssel)
|
||||||
|
ssp_assert_ssel();
|
||||||
|
return ssp_submit_job(batch->job);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ssp_submit_batch(const struct ssp_batch *batch, int timeout)
|
||||||
|
{
|
||||||
|
unsigned int c = ssp_wait(timeout);
|
||||||
|
if (c)
|
||||||
|
return c;
|
||||||
|
ssp_batch_repeats = 0;
|
||||||
|
ssp_batch = batch;
|
||||||
|
return ssp_run_batch();
|
||||||
|
}
|
||||||
|
|
|
||||||
4
ssp.h
4
ssp.h
|
|
@ -61,8 +61,8 @@ struct ssp_job {
|
||||||
unsigned int cmd_count;
|
unsigned int cmd_count;
|
||||||
unsigned int read_count;
|
unsigned int read_count;
|
||||||
unsigned int idle_count;
|
unsigned int idle_count;
|
||||||
unsigned int buf_count;
|
|
||||||
const unsigned short *command;
|
const unsigned short *command;
|
||||||
|
unsigned int buf_count;
|
||||||
unsigned short *buf_ptr;
|
unsigned short *buf_ptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -76,9 +76,11 @@ extern struct ssp_match {
|
||||||
} ssp_match;
|
} ssp_match;
|
||||||
|
|
||||||
struct ssp_batch {
|
struct ssp_batch {
|
||||||
|
int count;
|
||||||
struct ssp_job *job;
|
struct ssp_job *job;
|
||||||
struct ssp_match *match;
|
struct ssp_match *match;
|
||||||
struct ssp_config *ssel;
|
struct ssp_config *ssel;
|
||||||
|
struct ssp_wait *wait;
|
||||||
};
|
};
|
||||||
|
|
||||||
// search for a pattern before recording frames
|
// search for a pattern before recording frames
|
||||||
|
|
|
||||||
168
timer.c
Normal file
168
timer.c
Normal file
|
|
@ -0,0 +1,168 @@
|
||||||
|
|
||||||
|
#include "timer.h"
|
||||||
|
#include "isr.h"
|
||||||
|
#include <lpc2148/vic.h>
|
||||||
|
#include <lpc2148/pcb.h>
|
||||||
|
|
||||||
|
volatile struct timer_tick timer0_tick, timer1_tick;
|
||||||
|
|
||||||
|
static inline
|
||||||
|
void tick_timer(volatile struct timer_tick *tick, unsigned int ir)
|
||||||
|
{
|
||||||
|
tick->ir = ir;
|
||||||
|
unsigned short n = tick->n;
|
||||||
|
if (n != 0xffff)
|
||||||
|
tick->n = n+1;
|
||||||
|
if (tick->callback)
|
||||||
|
tick->callback(ir, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__ ((interrupt ("IRQ")))
|
||||||
|
static void timer0_isr(void)
|
||||||
|
{
|
||||||
|
unsigned int ir = T0IR;
|
||||||
|
T0IR = ir;
|
||||||
|
tick_timer(&timer0_tick, ir|0x100);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__ ((interrupt ("IRQ")))
|
||||||
|
static void timer1_isr(void)
|
||||||
|
{
|
||||||
|
unsigned int ir = T1IR;
|
||||||
|
T1IR = ir;
|
||||||
|
tick_timer(&timer1_tick, ir|0x200);
|
||||||
|
}
|
||||||
|
|
||||||
|
void timer0_init()
|
||||||
|
{
|
||||||
|
T0CTCR = TxCTCR_Timer;
|
||||||
|
T0PR = 0; // Prescale = 60MHz
|
||||||
|
T0MR2 = 915; // 32751 kHz for MS5534C pressure sensor
|
||||||
|
T0MCR = TxMCR_MR2R;
|
||||||
|
T0EMR = TxEMR_EMC2_Toggle;
|
||||||
|
T0TCR = TxTCR_Counter_Enable;
|
||||||
|
|
||||||
|
VICVectAddrs[IrqVec_Timer0] = timer0_isr;
|
||||||
|
VICVectCntl[IrqVec_Timer0] = VICVectCntl_TIMER0;
|
||||||
|
VICIntEnable = VIC_TIMER0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void timer1_init()
|
||||||
|
{
|
||||||
|
T1CTCR = TxCTCR_Timer;
|
||||||
|
T1PR = 0; // Prescale = 60MHz
|
||||||
|
T1MR0 = 60000; // 1ms
|
||||||
|
T1MCR = TxMCR_MR0S | TxMCR_MR0I;
|
||||||
|
T1TCR = TxTCR_Counter_Reset;
|
||||||
|
|
||||||
|
VICVectAddrs[IrqVec_Timer1] = timer1_isr;
|
||||||
|
VICVectCntl[IrqVec_Timer1] = VICVectCntl_TIMER1;
|
||||||
|
VICIntEnable = VIC_TIMER1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct timer_wait *waiting;
|
||||||
|
|
||||||
|
static unsigned int psel0m, psel1m, psel0v, psel1v;
|
||||||
|
|
||||||
|
static void timer_wait_abort(void) {
|
||||||
|
if (!waiting)
|
||||||
|
return;
|
||||||
|
timer0_tick.callback = 0;
|
||||||
|
timer1_tick.callback = 0;
|
||||||
|
T0MCR = TxMCR_MR2R;
|
||||||
|
T0CCR = 0;
|
||||||
|
T1CCR = 0;
|
||||||
|
T1TCR = TxTCR_Counter_Reset;
|
||||||
|
PCB_PINSEL0 = PCB_PINSEL0 & ~psel0m | psel0v;
|
||||||
|
PCB_PINSEL1 = PCB_PINSEL1 & ~psel1m | psel1v;
|
||||||
|
psel0m = psel1m = psel0v = psel1v = 0;
|
||||||
|
waiting = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void wait_callback(unsigned int ir, unsigned int n)
|
||||||
|
{
|
||||||
|
const struct timer_wait *w = waiting;
|
||||||
|
if (!w)
|
||||||
|
return;
|
||||||
|
if (timer_wait_pin_status(w))
|
||||||
|
goto hit;
|
||||||
|
if (w->mclk && n >= w->mclk)
|
||||||
|
goto hit;
|
||||||
|
if (w->pclk && ir & 1)
|
||||||
|
goto hit;
|
||||||
|
return;
|
||||||
|
hit:
|
||||||
|
timer_wait_abort();
|
||||||
|
if (w->callback)
|
||||||
|
w->callback();
|
||||||
|
}
|
||||||
|
|
||||||
|
int timer_wait_init(const struct timer_wait *wait)
|
||||||
|
{
|
||||||
|
timer_wait_abort();
|
||||||
|
if (!wait)
|
||||||
|
return 0;
|
||||||
|
timer0_tick = (struct timer_tick){.callback=0};
|
||||||
|
timer1_tick = (struct timer_tick){.callback=0};
|
||||||
|
unsigned int iflg = disable_irq(INT_DISABLE);
|
||||||
|
if (wait->pclk) {
|
||||||
|
T1MR0 = wait->pclk;
|
||||||
|
T1TCR = TxTCR_Counter_Enable;
|
||||||
|
}
|
||||||
|
else if (wait->ccr1) {
|
||||||
|
T1MR0 = 6000000; // 100ms
|
||||||
|
T1TCR = TxTCR_Counter_Enable;
|
||||||
|
}
|
||||||
|
if (wait->mclk) {
|
||||||
|
T0MCR = TxMCR_MR2R | TxMCR_MR2I;
|
||||||
|
}
|
||||||
|
if (wait->ccr1 & TxCCR_CAP0I) {
|
||||||
|
psel0m = PCB_PINSEL0_P010_MASK;
|
||||||
|
psel0v = PCB_PINSEL0 & psel1m;
|
||||||
|
PCB_PINSEL0 = PCB_PINSEL0 & ~psel0m | PCB_PINSEL0_P010_Capture1_0;
|
||||||
|
T1CCR = wait->ccr1 & (TxCCR_CAP0RE|TxCCR_CAP0FE|TxCCR_CAP0I);
|
||||||
|
}
|
||||||
|
else if (wait->ccr1 & TxCCR_CAP3I) {
|
||||||
|
psel1m = PCB_PINSEL1_P018_MASK;
|
||||||
|
psel1v = PCB_PINSEL1 & psel1m;
|
||||||
|
PCB_PINSEL1 = PCB_PINSEL1 & ~psel1m | PCB_PINSEL1_P018_Capture1_3;
|
||||||
|
T1CCR = wait->ccr1 & (TxCCR_CAP3RE|TxCCR_CAP3FE|TxCCR_CAP3I);
|
||||||
|
}
|
||||||
|
else if (wait->ccr0 & TxCCR_CAP0I) {
|
||||||
|
psel1m = PCB_PINSEL1_P030_MASK;
|
||||||
|
psel1v = PCB_PINSEL1 & psel1m;
|
||||||
|
PCB_PINSEL1 = PCB_PINSEL1 & ~psel1m | PCB_PINSEL1_P030_Capture0_0;
|
||||||
|
T0CCR = wait->ccr0 & (TxCCR_CAP0RE|TxCCR_CAP0FE|TxCCR_CAP0I);
|
||||||
|
}
|
||||||
|
else if (wait->ccr0 & TxCCR_CAP2I) {
|
||||||
|
psel1m = PCB_PINSEL1_P028_MASK;
|
||||||
|
psel1v = PCB_PINSEL1 & psel1m;
|
||||||
|
PCB_PINSEL1 = PCB_PINSEL1 & ~psel1m | PCB_PINSEL1_P028_Capture0_2;
|
||||||
|
T0CCR = wait->ccr0 & (TxCCR_CAP2RE|TxCCR_CAP2FE|TxCCR_CAP2I);
|
||||||
|
}
|
||||||
|
else if (wait->ccr0 & TxCCR_CAP3I) {
|
||||||
|
psel1m = PCB_PINSEL1_P029_MASK;
|
||||||
|
psel1v = PCB_PINSEL1 & psel1m;
|
||||||
|
PCB_PINSEL1 = PCB_PINSEL1 & ~psel1m | PCB_PINSEL1_P029_Capture0_3;
|
||||||
|
T0CCR = wait->ccr0 & (TxCCR_CAP3RE|TxCCR_CAP3FE|TxCCR_CAP3I);
|
||||||
|
}
|
||||||
|
|
||||||
|
waiting = wait;
|
||||||
|
if (wait->ccr0 || wait->mclk)
|
||||||
|
timer0_tick.callback = &wait_callback;
|
||||||
|
if (wait->ccr1 || wait->pclk)
|
||||||
|
timer1_tick.callback = &wait_callback;
|
||||||
|
wait_callback(0,0);
|
||||||
|
enable_irq(iflg);
|
||||||
|
return !!waiting;
|
||||||
|
}
|
||||||
|
|
||||||
|
int timer_wait_status(const struct timer_wait *wait)
|
||||||
|
{
|
||||||
|
return waiting && (!wait || wait==waiting);
|
||||||
|
}
|
||||||
|
|
||||||
|
int timer_wait_mclk_status(const struct timer_wait *w)
|
||||||
|
{
|
||||||
|
return timer0_tick.n;
|
||||||
|
}
|
||||||
34
timer.h
Normal file
34
timer.h
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
#ifndef _timer_h_
|
||||||
|
#define _timer_h_
|
||||||
|
#include <lpc2148/gpio.h>
|
||||||
|
#include <lpc2148/timer.h>
|
||||||
|
|
||||||
|
void timer0_init();
|
||||||
|
void timer1_init();
|
||||||
|
|
||||||
|
extern volatile struct timer_tick {
|
||||||
|
unsigned int ir;
|
||||||
|
unsigned int n;
|
||||||
|
void (*callback)(unsigned, unsigned);
|
||||||
|
} timer0_tick, timer1_tick;
|
||||||
|
|
||||||
|
struct timer_wait {
|
||||||
|
unsigned int pclk;
|
||||||
|
unsigned int mclk;
|
||||||
|
unsigned short ccr0;
|
||||||
|
unsigned short ccr1;
|
||||||
|
unsigned int pinmask;
|
||||||
|
unsigned int pinvalue;
|
||||||
|
void (*callback)(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
int timer_wait_init(const struct timer_wait *wait);
|
||||||
|
int timer_wait_status(const struct timer_wait *wait);
|
||||||
|
|
||||||
|
static inline
|
||||||
|
int timer_wait_pin_status(const struct timer_wait *w)
|
||||||
|
{
|
||||||
|
return w->pinmask && (GPIO_FIO0PIN & w->pinmask) == w->pinvalue;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
Loading…
Add table
Add a link
Reference in a new issue