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:
commit
20428f67be
13
testdac/pic/Makefile
Normal file
13
testdac/pic/Makefile
Normal 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
33
testdac/pic/Makefile.pic
Normal 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
45
testdac/pic/config.h
Normal 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
33
testdac/pic/dac.c
Normal 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
9
testdac/pic/dac.h
Normal 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
13
testdac/pic/isr.c
Normal 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
6
testdac/pic/isr.h
Normal file
|
@ -0,0 +1,6 @@
|
|||
#ifndef ISR_H
|
||||
#define ISR_H
|
||||
|
||||
void interrupt isr(void);
|
||||
|
||||
#endif
|
18
testdac/pic/main.c
Normal file
18
testdac/pic/main.c
Normal 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
156
testdac/pic/serial.c
Normal 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
43
testdac/pic/serial.h
Normal 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
|
Loading…
Reference in New Issue
Block a user