Add zoom nilm stuff, start with code to test dac

git-svn-id: https://bucket.mit.edu/svn/nilm/zoom@4367 ddd99763-3ecb-0310-9145-efcb8ce7c51f
This commit is contained in:
jim 2007-02-21 19:53:24 +00:00
commit 20428f67be
10 changed files with 369 additions and 0 deletions

13
testdac/pic/Makefile Normal file
View File

@ -0,0 +1,13 @@
sources = main.c serial.c isr.c dac.c
dest = main.hex
# Default rule: build dest, plus assembly for all source
all: $(dest) $(sources:.c=.as)
# Destination is built from all object files
$(dest) : $(sources:.c=.obj)
burn: $(dest)
jimpic -b $<
include Makefile.pic

33
testdac/pic/Makefile.pic Normal file
View File

@ -0,0 +1,33 @@
PICCFLAGS ?= -16f627a -DPIC -O -Zg
PICLDFLAGS ?= -16f627a
PICC ?= picl
%.d: %.c
$(SHELL) -ec '$(CC) -MM $(CPPFLAGS) $< \
| sed '\''s/\($*\)\.o[ :]*/\1.obj $@ : /g'\'' > $@; \
[ -s $@ ] || rm -f $@'
include $(sources:.c=.d)
.PHONY: clean burn
clean:
rm -f *.{d*,o,obj,sym,lst,map,cod,cof,dep,hex,as,rlf} *~
%.lst %.hex : %.asm
gpasm $<
%.as : %.c
cd $(dir $<) && $(PICC) $(PICCFLAGS) -S -c $(notdir $<)
%.o : %.asm
gpasm -c $<
%.o : %.pal
gpal -t -c $<
%.obj : %.c
cd $(dir $<) && $(PICC) $(PICCFLAGS) -c $(notdir $<)
%.hex : %.obj
$(PICC) $(PICLDFLAGS) -O$@ -o $^

45
testdac/pic/config.h Normal file
View File

@ -0,0 +1,45 @@
#ifndef CONFIG_H
#define CONFIG_H
#define CONFIGWORD (WDTDIS & PWRTEN & MCLREN & BOREN & LVPEN & HS)
#define FOSC 4000000
/* Max standard baudrate with FOSC=4000000 is 19200 */
/* Max standard baudrate with FOSC=18432000 is 230400 */
/* Max standard baudrate with FOSC=20000000 is 115200 */
#define BAUDRATE 9600L
typedef unsigned char uint8_t;
typedef signed char sint8_t;
typedef unsigned int uint16_t;
typedef signed int sint16_t;
typedef unsigned long uint32_t;
typedef signed long uint32_t;
/* Serial */
#define RX RB1
#define TRISRX TRISB1
#define TX RB2
#define TRISTX TRISB2
/* DAC */
#define D15 RB7
#define D14 RB6
#define D13 RB5
#define D12 RB3
#define D11 RA3
#define D10 RA2
#define D9 RA1
#define D8 RA0
#define LDAC RB0
#define TRIS_D15 TRISB7
#define TRIS_D14 TRISB6
#define TRIS_D13 TRISB5
#define TRIS_D12 TRISB3
#define TRIS_D11 TRISA3
#define TRIS_D10 TRISA2
#define TRIS_D9 TRISA1
#define TRIS_D8 TRISA0
#define TRIS_LDAC TRISB0
#endif

33
testdac/pic/dac.c Normal file
View File

@ -0,0 +1,33 @@
#include <pic.h>
#include "config.h"
#include "dac.h"
/* Initialize dac */
void dac_init(void)
{
TRIS_D15 = 0;
TRIS_D14 = 0;
TRIS_D13 = 0;
TRIS_D12 = 0;
TRIS_D11 = 0;
TRIS_D10 = 0;
TRIS_D9 = 0;
TRIS_D8 = 0;
TRIS_LDAC = 0;
LDAC = 1;
}
/* Write value to dac */
void dac_set(uint8_t val)
{
D15 = 0; if (val & (1 << 7)) D15 = 1;
D14 = 0; if (val & (1 << 6)) D14 = 1;
D13 = 0; if (val & (1 << 5)) D13 = 1;
D12 = 0; if (val & (1 << 4)) D12 = 1;
D11 = 0; if (val & (1 << 3)) D11 = 1;
D10 = 0; if (val & (1 << 2)) D10 = 1;
D9 = 0; if (val & (1 << 1)) D9 = 1;
D8 = 0; if (val & (1 << 0)) D8 = 1;
LDAC = 0;
LDAC = 1;
}

9
testdac/pic/dac.h Normal file
View File

@ -0,0 +1,9 @@
#ifndef DAC_H
#define DAC_H
#include "config.h"
void dac_init(void);
void dac_set(uint8_t val);
#endif

13
testdac/pic/isr.c Normal file
View File

@ -0,0 +1,13 @@
#include <pic.h>
#include "config.h"
#include "isr.h"
#include "serial.h"
#pragma interrupt_level 1
void interrupt isr(void)
{
if(TXIE && TXIF)
serial_interrupt_tx();
if(RCIE && RCIF)
serial_interrupt_rx();
}

6
testdac/pic/isr.h Normal file
View File

@ -0,0 +1,6 @@
#ifndef ISR_H
#define ISR_H
void interrupt isr(void);
#endif

18
testdac/pic/main.c Normal file
View File

@ -0,0 +1,18 @@
#include <pic.h>
#include "config.h"
#include "serial.h"
#include "dac.h"
__CONFIG(CONFIGWORD);
void main(void) {
CMCON = 7;
serial_init();
dac_init();
while(1)
{
dac_set(serial_get());
}
}

156
testdac/pic/serial.c Normal file
View File

@ -0,0 +1,156 @@
#include <pic.h>
#include "config.h"
#include "serial.h"
volatile uint8_t stq[STQ_SIZE], stq_start, stq_len;
volatile uint8_t bank1 srq[SRQ_SIZE], srq_start, srq_len;
/*
* Initialization
*/
void serial_init(void)
{
/* Set up serial transmit queue and serial receive queue */
stq_start = stq_len = 0;
srq_start = srq_len = 0;
/* Initialize serial port with baudrate specified in config.h */
TRISRX = 1;
TRISTX = 1;
BRGH = 1;
#define BRG (((FOSC + (8 * BAUDRATE - 1)) /(16 * BAUDRATE)) - 1)
#if (BRG < 1) || (BRG > 255)
#error Cannot achieve baudrate
#endif
#define ACT_BR (FOSC / (16 * (BRG + 1)))
#if ((ACT_BR * 100 / BAUDRATE) > 105) || ((ACT_BR * 100 / BAUDRATE) < 94)
#error Actual baudrate is too far from requested baudrate. Ratio is
#error FOSC/(16*floor((FOSC+(8*BAUDRATE-1))/(16*BAUDRATE)))/BAUDRATE
#endif
SPBRG = BRG;
SYNC = 0;
SPEN = 1;
CREN = 1;
SREN = 0;
TX9 = 0;
RX9 = 0;
TXEN = 1;
/* Enable serial port interrupts. To avoid being interrupted
all the time, TXIE is kept off until we have data to
transmit. */
TXIE = 0;
RCIE = 1;
PEIE = 1;
}
/*
* Interrupt handling
*/
/* Get a byte from the transmit queue and send it */
void serial_interrupt_tx(void)
{
if(stq_len != 0) {
TXREG = stq[stq_start];
stq_start = (stq_start + 1) & STQ_MASK;
stq_len--;
}
/* If queue is empty, disable interrupt */
if(stq_len == 0)
TXIE = 0;
}
/* Receive a byte and write it to the receive queue. */
void serial_interrupt_rx(void)
{
if(FERR) {
/* Framing error: discard byte */
(void) RCREG;
return;
}
if(OERR) {
/* Overflow error, clear it */
CREN = 0;
CREN = 1;
return;
}
if(!(srq_len & SRQ_SIZE)) {
srq[(srq_start + srq_len) & SRQ_MASK] = RCREG;
srq_len++;
} else {
/* Queue is full; discard data */
(void) RCREG;
}
}
/*
* Userspace interface
*/
/* Send byte to PC. Blocks iff transmit queue is full. */
void serial_put(uint8_t x)
{
while(!serial_can_put())
continue;
GIE = 0;
stq[(stq_start + stq_len) & STQ_MASK] = x;
stq_len++;
TXIE = 1;
GIE = 1;
}
/* Get byte from PC. Blocks iff receive queue is empty. */
uint8_t serial_get(void)
{
uint8_t x;
while(!serial_can_get())
continue;
x = srq[srq_start];
GIE = 0;
srq_start = (srq_start + 1) & SRQ_MASK;
srq_len--;
GIE = 1;
return x;
}
/*
* I/O helpers
*/
void serial_put_string(const uint8_t *s)
{
while(s && *s)
serial_put(*s++);
}
const uint8_t hex[16]={'0','1','2','3','4','5','6','7',
'8','9','a','b','c','d','e','f'};
void serial_put_hex(uint8_t x)
{
serial_put(hex[x >> 4]);
serial_put(hex[x & 15]);
}
void serial_put_hex32(uint32_t x)
{
serial_put_hex((x >> 24) & 0xFF);
serial_put_hex((x >> 16) & 0xFF);
serial_put_hex((x >> 8) & 0xFF);
serial_put_hex((x) & 0xFF);
}
void serial_crlf(void)
{
serial_put('\r');
serial_put('\n');
}

43
testdac/pic/serial.h Normal file
View File

@ -0,0 +1,43 @@
#ifndef SERIAL_H
#define SERIAL_H
/* These serial port routines use both transmit and receive queues.
The actual sending/receiving is handled by the serial_interrupt
functions, which should get called on TXIF or RCIF. */
#include "config.h"
#define STQ_BITS 6 /* transmit queue */
#define SRQ_BITS 6 /* receive queue */
#define STQ_SIZE (1<<(STQ_BITS))
#define SRQ_SIZE (1<<(SRQ_BITS))
#define STQ_MASK (STQ_SIZE-1)
#define SRQ_MASK (SRQ_SIZE-1)
extern volatile uint8_t stq[STQ_SIZE], stq_start, stq_len;
extern volatile bank1 uint8_t srq[SRQ_SIZE], srq_start, srq_len;
/* Initialize serial port, queues, serial interrupt */
void serial_init(void);
/* Call this on (TXIE && TXIF) and (RCIE && RCIF), respectively */
void serial_interrupt_tx(void);
void serial_interrupt_rx(void);
/* Send byte to PC. Blocks iff transmit queue is full. */
void serial_put(uint8_t x);
/* Helper functions */
void serial_put_string(const uint8_t *s);
void serial_crlf(void);
void serial_put_hex(uint8_t x);
void serial_put_hex32(uint32_t x);
/* Get byte from PC. Blocks iff receive queue is empty. */
uint8_t serial_get(void);
/* Returns true if the respective get/put operation would not block */
#define serial_can_get() (srq_len != 0)
#define serial_can_put() (!(stq_len & STQ_SIZE))
#endif