Browse Source

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
tags/zoom-1.0
jim 17 years ago
commit
20428f67be
10 changed files with 369 additions and 0 deletions
  1. +13
    -0
      testdac/pic/Makefile
  2. +33
    -0
      testdac/pic/Makefile.pic
  3. +45
    -0
      testdac/pic/config.h
  4. +33
    -0
      testdac/pic/dac.c
  5. +9
    -0
      testdac/pic/dac.h
  6. +13
    -0
      testdac/pic/isr.c
  7. +6
    -0
      testdac/pic/isr.h
  8. +18
    -0
      testdac/pic/main.c
  9. +156
    -0
      testdac/pic/serial.c
  10. +43
    -0
      testdac/pic/serial.h

+ 13
- 0
testdac/pic/Makefile 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
- 0
testdac/pic/Makefile.pic 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
- 0
testdac/pic/config.h 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
- 0
testdac/pic/dac.c 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
- 0
testdac/pic/dac.h 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
- 0
testdac/pic/isr.c 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
- 0
testdac/pic/isr.h View File

@@ -0,0 +1,6 @@
#ifndef ISR_H
#define ISR_H

void interrupt isr(void);

#endif

+ 18
- 0
testdac/pic/main.c 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
- 0
testdac/pic/serial.c 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
- 0
testdac/pic/serial.h 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

Loading…
Cancel
Save