add initial dmb fw. improve makefile infrastructure.

This commit is contained in:
Benjamin Krill 2013-12-05 13:17:55 +01:00
parent 0f5947ee39
commit 5b02acc863
12 changed files with 482 additions and 10 deletions

View File

@ -1,11 +1,33 @@
DIRS = lib fw
FW_DIRS = $(wildcard fw_*)
COMMON_DIRS = lib
PROJECT_DEFAULT = atlys
PROJECT_NAME ?= $(PROJECT_DEFAULT)
PROJECT_DIR = fw_$(PROJECT_NAME)
DIRS = $(COMMON_DIRS) $(PROJECT_DIR)
all:
@for dir in $(DIRS); do \
$(MAKE) -C $$dir || exit 1; \
done
##### PRINT ###################################
PW=\033[1m\033[0m
GR=\E[40;32m
WH=\E[40;37m
B=\033[1m
pr_info = "$(B) $(GR)[$(1)]\t $(WH)$(2)$(PW)"
clean:
@for dir in $(DIRS); do \
$(MAKE) -C $$dir clean || exit 1; \
done
##### BUILD RULES #############################
.PHONY: help build clean build_all distclean
help:
@echo -e "$$ make PROJECT_NAME=<top-file> <rule>"
@echo -e "\tprojects (*=default) .. : $(shell echo $(FW_DIRS) | sed 's/fw_//g' | sed 's/$(PROJECT_DEFAULT)/\*$(PROJECT_DEFAULT)/')"
@echo -e "\trule .................. : help build clean build_all distclean"
build: $(DIRS)
@$(foreach dir,$^, echo -e $(call pr_info,MK,Building $(dir)); $(MAKE) -C $(dir) || exit 1;)
clean: $(DIRS)
@$(foreach dir,$^, echo -e $(call pr_info,MK,Cleaning $(dir)); $(MAKE) -C $(dir) clean || exit 1;)
build_all: $(COMMON_DIRS) $(FW_DIRS)
@$(foreach dir,$^, echo -e $(call pr_info,MK,Building $(dir)); $(MAKE) -C $(dir) || exit 1;)
distclean: $(COMMON_DIRS) $(FW_DIRS)
@$(foreach dir,$^, echo -e $(call pr_info,MK,Cleaning $(dir)); $(MAKE) -C $(dir) clean || exit 1;)

9
firmware/fw_dmb/.gitignore vendored Normal file
View File

@ -0,0 +1,9 @@
*.asm
*.lst
*.rel
*.rst
*.sym
*.map
*.mem
*.bix
*.iic

5
firmware/fw_dmb/Makefile Normal file
View File

@ -0,0 +1,5 @@
SOURCES = fw.c device.c
A51_SOURCES = dscr.a51
BASENAME = firmware
include ../lib/fx2.mk

127
firmware/fw_dmb/device.c Normal file
View File

@ -0,0 +1,127 @@
#include <fx2macros.h>
#include <delay.h>
#ifdef DEBUG_FIRMWARE
#include <stdio.h>
#else
#define printf(...)
#endif
//************************** Configuration Handlers *****************************
// change to support as many interfaces as you need
//volatile xdata BYTE interface=0;
//volatile xdata BYTE alt=0; // alt interface
// set *alt_ifc to the current alt interface for ifc
BOOL
handle_get_interface(BYTE ifc, BYTE * alt_ifc)
{
// *alt_ifc=alt;
return TRUE;
}
// return TRUE if you set the interface requested
// NOTE this function should reconfigure and reset the endpoints
// according to the interface descriptors you provided.
BOOL
handle_set_interface(BYTE ifc, BYTE alt_ifc)
{
printf("Set Interface.\n");
//interface=ifc;
//alt=alt_ifc;
return TRUE;
}
// handle getting and setting the configuration
// 1 is the default. If you support more than one config
// keep track of the config number and return the correct number
// config numbers are set int the dscr file.
//volatile BYTE config=1;
BYTE
handle_get_configuration()
{
return 1;
}
// NOTE changing config requires the device to reset all the endpoints
BOOL
handle_set_configuration(BYTE cfg)
{
printf("Set Configuration.\n");
//config=cfg;
return TRUE;
}
//******************* VENDOR COMMAND HANDLERS **************************
BOOL
handle_vendorcommand(BYTE cmd)
{
switch (cmd) {
// case VC_EPSTAT:
// break;
default:
printf ( "Need to implement vendor command: %02x\n", cmd );
}
/* not handled by handlers */
return FALSE;
}
//******************** INIT ***********************
void
main_init()
{
SYNCDELAY4; REVCTL = 0x03;
/* set register default values */
SYNCDELAY4; PINFLAGSAB = 0x00;
SYNCDELAY4; PINFLAGSCD = 0x00;
SYNCDELAY4; FIFOPINPOLAR = 0x00;
/* SLAVE FIFO (set bmIFCLKPOL to ensure better setup times) */
SYNCDELAY4; IFCONFIG = bmIFCLKSRC | bm3048MHZ | bmIFCLKOE | (bmIFCFG1 | bmIFCFG0);
/* only valid endpoints are 2/6 */
/* EP2 is DIR=OUT, TYPE=BULK, SIZE=512, BUF=2x (HOST->DEVICE) */
SYNCDELAY4; EP2CFG = 0xa2;
/* slave fifo configuration 8bit, autoout */
//SYNCDELAY4; EP2FIFOCFG &= ~bmWORDWIDE;
SYNCDELAY4; EP2FIFOCFG = bmAUTOOUT;
SYNCDELAY4; EP2AUTOINLENH = 0x00;
SYNCDELAY4; EP2AUTOINLENL = 0x00;
/* EP6 is DIR=IN, TYPE=BULK, SIZE=512, BUF=2x (DEVICE->HOST) */
SYNCDELAY4; EP6CFG = 0xe2;
/* slave fifo configuration 8bit, autoin, zero length */
//SYNCDELAY4; EP6FIFOCFG &= ~bmWORDWIDE;
SYNCDELAY4; EP6FIFOCFG = bmAUTOIN | bmZEROLENIN;
/* AUTOIN packet length (512byte) */
SYNCDELAY4; EP6AUTOINLENH = 0x02;
SYNCDELAY4; EP6AUTOINLENL = 0x00;
/* unused fifos */
SYNCDELAY4; EP4FIFOCFG = 0;
SYNCDELAY4; EP8FIFOCFG = 0;
/* deactive other endpoints */
SYNCDELAY4; EP1INCFG &= ~bmVALID;
SYNCDELAY4; EP1OUTCFG &= ~bmVALID;
SYNCDELAY4; EP4CFG &= ~bmVALID;
SYNCDELAY4; EP8CFG &= ~bmVALID;
/* Reset the FIFO */
SYNCDELAY4; FIFORESET = 0x80;
SYNCDELAY4; FIFORESET = 0x82;
SYNCDELAY4; FIFORESET = 0x84;
SYNCDELAY4; FIFORESET = 0x86;
SYNCDELAY4; FIFORESET = 0x00;
SYNCDELAY4;
printf("Initialization Done.\n");
}
void
main_loop()
{
// do some work
}

189
firmware/fw_dmb/dscr.a51 Normal file
View File

@ -0,0 +1,189 @@
.module DEV_DSCR
; descriptor types
; same as setupdat.h
DSCR_DEVICE_TYPE=1
DSCR_CONFIG_TYPE=2
DSCR_STRING_TYPE=3
DSCR_INTERFACE_TYPE=4
DSCR_ENDPOINT_TYPE=5
DSCR_DEVQUAL_TYPE=6
; for the repeating interfaces
DSCR_INTERFACE_LEN=9
DSCR_ENDPOINT_LEN=7
; endpoint types
ENDPOINT_TYPE_CONTROL=0
ENDPOINT_TYPE_ISO=1
ENDPOINT_TYPE_BULK=2
ENDPOINT_TYPE_INT=3
.globl _dev_dscr, _dev_qual_dscr, _highspd_dscr, _fullspd_dscr, _dev_strings, _dev_strings_end
; These need to be in code memory. If
; they aren't you'll have to manully copy them somewhere
; in code memory otherwise SUDPTRH:L don't work right
.area DSCR_AREA (CODE)
_dev_dscr:
.db dev_dscr_end-_dev_dscr ; len
.db DSCR_DEVICE_TYPE ; type
.dw 0x0002 ; usb 2.0
.db 0xff ; class (vendor specific)
.db 0xff ; subclass (vendor specific)
.db 0xff ; protocol (vendor specific)
.db 64 ; packet size (ep0)
.dw 0xB404 ; vendor id
.dw 0x4223 ; product id
.dw 0x0100 ; version id
.db 1 ; manufacturure str idx
.db 2 ; product str idx
.db 0 ; serial str idx
.db 1 ; n configurations
dev_dscr_end:
_dev_qual_dscr:
.db dev_qualdscr_end-_dev_qual_dscr
.db DSCR_DEVQUAL_TYPE
.dw 0x0002 ; usb 2.0
.db 0xff
.db 0xff
.db 0xff
.db 64 ; max packet
.db 1 ; n configs
.db 0 ; extra reserved byte
dev_qualdscr_end:
_highspd_dscr:
.db highspd_dscr_end-_highspd_dscr ; dscr len ;; Descriptor length
.db DSCR_CONFIG_TYPE
; can't use .dw because byte order is different
.db (highspd_dscr_realend-_highspd_dscr) % 256 ; total length of config lsb
.db (highspd_dscr_realend-_highspd_dscr) / 256 ; total length of config msb
.db 1 ; n interfaces
.db 1 ; config number
.db 0 ; config string
.db 0x80 ; attrs = bus powered, no wakeup
.db 0x32 ; max power = 100ma
highspd_dscr_end:
; all the interfaces next
; NOTE the default TRM actually has more alt interfaces
; but you can add them back in if you need them.
; here, we just use the default alt setting 1 from the trm
.db DSCR_INTERFACE_LEN
.db DSCR_INTERFACE_TYPE
.db 0 ; index
.db 0 ; alt setting idx
.db 2 ; n endpoints
.db 0xff ; class
.db 0xff
.db 0xff
.db 0 ; string index
; endpoint 2 out
.db DSCR_ENDPOINT_LEN
.db DSCR_ENDPOINT_TYPE
.db 0x02 ; ep2 dir=OUT and address
.db ENDPOINT_TYPE_BULK ; type
.db 0x00 ; max packet LSB
.db 0x02 ; max packet size=512 bytes
.db 0x00 ; polling interval
; endpoint 6 in
.db DSCR_ENDPOINT_LEN
.db DSCR_ENDPOINT_TYPE
.db 0x86 ; ep6 dir=in and address
.db ENDPOINT_TYPE_BULK ; type
.db 0x00 ; max packet LSB
.db 0x02 ; max packet size=512 bytes
.db 0x00 ; polling interval
highspd_dscr_realend:
.even
_fullspd_dscr:
.db fullspd_dscr_end-_fullspd_dscr ; dscr len
.db DSCR_CONFIG_TYPE
; can't use .dw because byte order is different
.db (fullspd_dscr_realend-_fullspd_dscr) % 256 ; total length of config lsb
.db (fullspd_dscr_realend-_fullspd_dscr) / 256 ; total length of config msb
.db 1 ; n interfaces
.db 1 ; config number
.db 0 ; config string
.db 0x80 ; attrs = bus powered, no wakeup
.db 0x32 ; max power = 100ma
fullspd_dscr_end:
; all the interfaces next
; NOTE the default TRM actually has more alt interfaces
; but you can add them back in if you need them.
; here, we just use the default alt setting 1 from the trm
.db DSCR_INTERFACE_LEN
.db DSCR_INTERFACE_TYPE
.db 0 ; index
.db 0 ; alt setting idx
.db 2 ; n endpoints
.db 0xff ; class
.db 0xff
.db 0xff
.db 1 ; string index
; endpoint 2 out
.db DSCR_ENDPOINT_LEN
.db DSCR_ENDPOINT_TYPE
.db 0x02 ; ep2 dir=OUT and address
.db ENDPOINT_TYPE_BULK ; type
.db 0x40 ; max packet LSB
.db 0x00 ; max packet size=64 bytes
.db 0x00 ; polling interval
; endpoint 6 in
.db DSCR_ENDPOINT_LEN
.db DSCR_ENDPOINT_TYPE
.db 0x86 ; ep6 dir=in and address
.db ENDPOINT_TYPE_BULK ; type
.db 0x40 ; max packet LSB
.db 0x00 ; max packet size=64 bytes
.db 0x00 ; polling interval
fullspd_dscr_realend:
.even
_dev_strings:
; sample string
_string0:
.db string0end-_string0 ; len
.db DSCR_STRING_TYPE
.db 0x09, 0x04 ; 0x0409 is the language code for English. Possible to add more codes after this.
string0end:
; add more strings here
_string1:
.db _string1end-_string1 ;; len
.db DSCR_STRING_TYPE
.db 'D',00
.db 'M',00
.db 'B',00
.db '',00
.db 'M',00
.db 'O',00
.db 'D',00
.db 'U',00
.db 'L',00
.db 'E',00
_string1end:
_string2:
.db _string2end-_string2 ;; len
.db DSCR_STRING_TYPE
.db 'V',00
.db 'E',00
.db 'R',00
.db 'S',00
.db 'I',00
.db 'O',00
.db 'N',00
.db '',00
.db 'X',00
_string2end:
_dev_strings_end:
.dw 0x0000 ; in case you wanted to look at memory between _dev_strings and _dev_strings_end

119
firmware/fw_dmb/fw.c Normal file
View File

@ -0,0 +1,119 @@
#include <fx2macros.h>
#include <fx2ints.h>
#include <autovector.h>
#include <delay.h>
#include <setupdat.h>
#ifdef DEBUG_FIRMWARE
#include <serial.h>
#include <stdio.h>
#else
#define printf(...)
#endif
volatile __bit dosud = FALSE;
volatile __bit dosuspend = FALSE;
// custom functions
extern void main_loop();
extern void main_init();
void
main()
{
#ifdef DEBUG_FIRMWARE
SETCPUFREQ(CLK_48M);
// main_init can still set this to whatever you want.
sio0_init(57600); // needed for printf if debug defined
#endif
main_init();
// set up interrupts.
USE_USB_INTS();
ENABLE_SUDAV();
ENABLE_USBRESET();
ENABLE_HISPEED();
ENABLE_SUSPEND();
ENABLE_RESUME();
/* global interrupt enable */
EA = 1;
// iic files (c2 load) don't need to renumerate/delay
// trm 3.6
#ifndef NORENUM
RENUMERATE();
#else
USBCS &= ~bmDISCON;
#endif
while (TRUE) {
main_loop();
if (dosud) {
dosud = FALSE;
handle_setupdata();
}
if (dosuspend) {
dosuspend = FALSE;
do {
printf("I'm going to Suspend.\n");
WAKEUPCS |= bmWU | bmWU2; // make sure ext wakeups are cleared
SUSPEND = 1;
PCON |= 1;
__asm
nop
nop
nop
nop
nop
nop
nop
__endasm;
} while (!remote_wakeup_allowed && REMOTE_WAKEUP());
printf("I'm going to wake up.\n");
// resume
// trm 6.4
if (REMOTE_WAKEUP()) {
delay(5);
USBCS |= bmSIGRESUME;
delay(15);
USBCS &= ~bmSIGRESUME;
}
}
}
}
void
resume_isr() __interrupt RESUME_ISR {
CLEAR_RESUME();
}
void
sudav_isr() __interrupt SUDAV_ISR {
dosud = TRUE;
CLEAR_SUDAV();
}
void
usbreset_isr() __interrupt USBRESET_ISR {
handle_hispeed(FALSE);
CLEAR_USBRESET();
}
void
hispeed_isr() __interrupt HISPEED_ISR {
handle_hispeed(TRUE);
CLEAR_HISPEED();
}
void
suspend_isr() __interrupt SUSPEND_ISR {
dosuspend = TRUE;
CLEAR_SUSPEND();
}

View File

@ -87,8 +87,9 @@ load: $(BUILDDIR)/$(BASENAME).bix
#fxload -vvv -t fx2 -D /dev/bus/usb/002/003 -I $(BUILDDIR)/$(BASENAME).bix
#fxload -vvv -t fx2 -D /dev/bus/usb/002/003 -I build/firmware.ihx
#*.{asm,ihx,lnk,lst,map,mem,rel,rst,sym,adb,cdb,bix}
clean:
rm -f $(BUILDDIR)/*.{asm,ihx,lnk,lst,map,mem,rel,rst,sym,adb,cdb,bix}
rm -rf $(BUILDDIR)/
clean-all: clean
$(MAKE) -C $(FX2LIBDIR)/lib clean