Compare commits

..

No commits in common. "6c8119424b92399540ace96dbdb4666e7fe68081" and "eff851b2748aece7fbb219dd49cbc873d6b92d61" have entirely different histories.

9 changed files with 23 additions and 282 deletions

View file

@ -147,7 +147,7 @@ sources = irena mainloop parser message isr crc \
usb controlpipe usbconfig dma stream \
enc28j60 net udp \
expression variables display \
pressure gpio ltc2656 ads8688 timer \
pressure gpio ltc2656 ads8688 \
adc rtc \
plugin \
nomalloc strtol uart uart1 base85

6
gpio.h
View file

@ -15,10 +15,10 @@
* 0.7: (31) SPI SSEL (PWM, EINT) (power board)
* 0.8: (33) TxD1 (AD1.1, PWM)
* 0.9: (34) RxD1 (PWM, EINT)
* 0.10: (35) AD1.2 (CAP1.0) (power board)
* 0.10: (35) AD1.2 (power board)
* 0.11: (37) SSP SSEL DAC (open drain)
* 0.12: (38) AD1.3 (MAT1.0) (power board)
* 0.13: (39) AD1.4 Ipos (MAT1.1)
* 0.12: (38) AD1.3 (MAT) (power board)
* 0.13: (39) AD1.4 Ipos (MAT)
* 0.14: (41) EINT1 ISP
* 0.15: (45) AD1.5 Ineg (EINT)
* 0.16: (46) SSP SSEL/MCLK MAT0.2

View file

@ -157,7 +157,7 @@
#define PCB_PINSEL1_P028_MASK 0x03000000
#define PCB_PINSEL1_P028_GPIO 0x00000000
#define PCB_PINSEL1_P028_AD0_1 0x01000000
#define PCB_PINSEL1_P028_Capture0_2 0x02000000
#define PCB_PINSEL1_P028_Capture_0_2 0x02000000
#define PCB_PINSEL1_P028_Match0_2 0x03000000
#define PCB_PINSEL1_P029_MASK 0x0c000000

15
irena.c
View file

@ -3,12 +3,12 @@
#include <lpc2148/scb.h>
#include <lpc2148/pcb.h>
#include <lpc2148/vic.h>
#include <lpc2148/timer.h>
#include <lpc2148/gpio.h>
#include "isr.h"
#include "spi.h"
#include "uart.h"
#include "timer.h"
#include "ssp.h"
#include "adc.h"
#include "rtc.h"
@ -26,7 +26,6 @@ void irena_init()
init_vic();
SCB_PCONP = SCB_PCONP_PCTIM0
| SCB_PCONP_PCTIM1
| SCB_PCONP_PCUART0
| SCB_PCONP_PCUART1
| SCB_PCONP_PCSPI0
@ -37,7 +36,7 @@ void irena_init()
| SCB_PCONP_PUSB
;
// not powered:
//
// | SCB_PCONP_PCTIM1
// | SCB_PCONP_PCI2C0
// | SCB_PCONP_PCI2C1
@ -117,8 +116,14 @@ void irena_init()
// Doing Enhanced GPIO on both ports
SCB_SCS = SCB_SCS_GPIO0M | SCB_SCS_GPIO1M;
timer0_init();
timer1_init();
// Timer 0 captures the Altera Attn Flag
T0CTCR = TxCTCR_Timer;
T0PR = 0; // Prescale = 60MHz
T0MR2 = 915; // 32751 kHz
T0MCR = TxMCR_MR2R;
T0EMR = TxEMR_EMC2_Toggle;
T0TCR = TxTCR_Counter_Enable;
uart_init();
uart1_init();

13
isr.h
View file

@ -30,16 +30,15 @@ static inline void enable_irq(unsigned int flag)
}
#define IrqVec_Timer0 2
#define IrqVec_UART0 4
#define IrqVec_UART1 5
#define IrqVec_USB 6
#define IrqVec_SPI 7
#define IrqVec_RTC 8
#define IrqVec_AD0 9
#define IrqVec_AD1 10
#define IrqVec_Timer1 11
#define IrqVec_Timer0 12
#define IrqVec_SSP 13
#define IrqVec_SPI 8
#define IrqVec_RTC 10
#define IrqVec_AD0 11
#define IrqVec_AD1 12
#define IrqVec_SSP 14
extern const unsigned int stack_guard_val;
extern unsigned int const *user_stack_guard;

61
ssp.c
View file

@ -12,8 +12,7 @@
static volatile struct ssp_job job;
struct ssp_match ssp_match;
static const struct ssp_batch *ssp_batch;
static int ssp_batch_repeats;
unsigned int ssp_bits;
volatile unsigned int ssp_lastword;
unsigned int ssp_ssel_mask = SSP_SSEL_MASK0 | SSP_SSEL_MASK1;
@ -153,18 +152,6 @@ int ssp_submit(const unsigned short *cmd, int cmd_size, unsigned int ic, unsigne
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)
{
SSPIMSC = 0;
@ -258,49 +245,3 @@ struct ssp_config ssp_conf_bate[] = {
.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
View file

@ -61,8 +61,8 @@ struct ssp_job {
unsigned int cmd_count;
unsigned int read_count;
unsigned int idle_count;
const unsigned short *command;
unsigned int buf_count;
const unsigned short *command;
unsigned short *buf_ptr;
};
@ -76,11 +76,9 @@ extern struct ssp_match {
} ssp_match;
struct ssp_batch {
int count;
struct ssp_job *job;
struct ssp_match *match;
struct ssp_config *ssel;
struct ssp_wait *wait;
};
// search for a pattern before recording frames

168
timer.c
View file

@ -1,168 +0,0 @@
#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
View file

@ -1,34 +0,0 @@
#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