From: Pavel Pisa Date: Thu, 12 Feb 2015 23:47:42 +0000 (+0100) Subject: Prepare build-able skeleton for LX_DAD application. X-Git-Url: http://rtime.felk.cvut.cz/gitweb/fpga/lx-cpu1/lx-dad.git/commitdiff_plain/e703e6b834bc521e85df59352dc7cc6bfa608eb8 Prepare build-able skeleton for LX_DAD application. Signed-off-by: Pavel Pisa --- diff --git a/sw/.gitignore b/sw/.gitignore new file mode 100644 index 0000000..5040514 --- /dev/null +++ b/sw/.gitignore @@ -0,0 +1,5 @@ +_build +_compiled +config.omk-default +sources.txt +tags diff --git a/sw/Makefile.omk b/sw/Makefile.omk index a09fd2e..873b424 100644 --- a/sw/Makefile.omk +++ b/sw/Makefile.omk @@ -1,6 +1,6 @@ # -*- makefile -*- -SUBDIRS = app arch board libs4c pxmc +SUBDIRS = app arch board libs4c -include $(SOURCES_DIR)/Makefile.omk-additional diff --git a/sw/app/lx_dad/Makefile.omk b/sw/app/lx_dad/Makefile.omk index 2cbdbf1..8fefde0 100644 --- a/sw/app/lx_dad/Makefile.omk +++ b/sw/app/lx_dad/Makefile.omk @@ -1,15 +1,158 @@ # -*- makefile -*- -#bin_PROGRAMS = appfoo +default_CONFIG = CONFIG_APP_LX_DAD=x +#default_CONFIG += CONFIG_OC_MWENGINE=x +default_CONFIG += CONFIG_APP_LX_DAD_WITH_ULAN=x +default_CONFIG += CONFIG_APP_LX_DAD_WITH_SUITK=x +default_CONFIG += CONFIG_APP_LX_DAD_WITH_FPGA=x +default_CONFIG += CONFIG_APP_LX_DAD_WITH_SIM_POSIX=x +default_CONFIG += CONFIG_OC_UL_DRV_SYSLESS=x +default_CONFIG += CONFIG_OC_I2C_DRV_SYSLESS=x +default_CONFIG += CONFIG_OC_SPI_DRV_SYSLESS=x +default_CONFIG += CONFIG_APP_LX_DAD_WITH_USB=n +default_CONFIG += CONFIG_KEYVAL=x +default_CONFIG += CONFIG_LIB_U2U_V2=x +default_CONFIG += CONFIG_OC_CMDPROC=x CONFIG_PXMC=x -#lib_LIBRARIES = +ifeq ($(CONFIG_APP_LX_DAD),y) -#include_HEADERS = +#ULAN_ID=LX_DAD -#appfoo_SOURCES += appfoo_main.c appfoo_run.c +ifeq ($(USB_APP_VID),0xdead) +USB_APP_VID = 0x1669 +USB_APP_PID = 0x1027 +endif -#appfoo_EMBEDTARFILES = rootfs +default_CONFIG += CONFIG_ULOI_LT=x +default_CONFIG += CONFIG_ULAN_DY=x +default_CONFIG += MACH=x +default_CONFIG += ULAN_ID=x -#lib_LOADLIBES += bar +LOCAL_CONFIG_H = appl_config.h +#INCLUDES += -I$(USER_INCLUDE_DIR)/ul_lib -I. +INCLUDES += -I. + +bin_PROGRAMS = lx_dad + +lx_dad_SOURCES = appl_main.c ul_idstr.c appl_loop.c appl_actions.c +ifneq ($(CONFIG_APP_ROCON_WITH_SIM_POSIX),y) +ifeq ($(CONFIG_APP_LX_DAD_WITH_FPGA),y) +lx_dad_SOURCES += appl_fpga.c +endif +endif +ifeq ($(CONFIG_APP_LX_DAD_WITH_SUITK),y) +lx_dad_SOURCES += setup_dinfo.c +lx_dad_SOURCES += distore_base.c appl_distore.c appl_eeprom.c +endif +ifeq ($(CONFIG_APP_LX_DAD_WITH_ULAN),y) +lx_dad_SOURCES += ul_idstr.c appl_oi.c appl_oi_sup.c appl_oi_dinfo.c +endif + +ifeq ($(CONFIG_KEYVAL),y) +lx_dad_SOURCES += setup_distore.c +endif + +ifeq ($(CONFIG_APP_LX_DAD_WITH_SUITK),y) +lx_dad_SOURCES += appl_gui_suitk.c appl_gui_fonts.c +lx_dad_SOURCES += appl_scr_common.c appl_scr_main.c +lx_dad_SOURCES += appl_scr_settings.c +lx_dad_SOURCES += appl_scr_progedit.c +lx_dad_SOURCES += appl_scr_progsave.c +lx_dad_SOURCES += appl_scr_service.c +lx_dad_SOURCES += appl_scr_auxcycle.c +lx_dad_SOURCES += appl_scr_invitation.c +lx_dad_SOURCES += appl_scr_setcom.c +lx_dad_SOURCES += appl_gui_style.c mw2sui.c +else +ifeq ($(CONFIG_OC_MWENGINE),y) +lx_dad_SOURCES += appl_gui_mw.c +endif +endif + +ifeq ($(CONFIG_OC_CMDPROC),y) +lx_dad_SOURCES += appl_cmdproc.c cmd_uartcon.c +ifneq ($(CONFIG_APP_LX_DAD_WITH_SIM_POSIX),y) +lx_dad_SOURCES += appl_tests.c +endif +endif + +ifneq ($(CONFIG_APP_LX_DAD_WITH_SIM_POSIX),y) +lx_dad_MOREOBJS = $(USER_LIB_DIR)/system_stub.o +ifeq ($(findstring $(MACH),lpc17xx lpc178x),) +lx_dad_MOREOBJS += $(USER_LIB_DIR)/ivt.o +endif +endif + +lib_LOADLIBES = bspbase +ifeq ($(CONFIG_APP_LX_DAD_WITH_ULAN),y) +lib_LOADLIBES += uloi uloicom +ifeq ($(CONFIG_OC_UL_DRV_SYSLESS),y) +lib_LOADLIBES += ul_drv +endif +endif +ifeq ($(CONFIG_KEYVAL),y) +lib_LOADLIBES += keyval lpciap_kvpb lpciap +endif +ifneq ($(CONFIG_APP_LX_DAD_WITH_SIM_POSIX),y) +lib_LOADLIBES += mach_hal +endif +ifeq ($(CONFIG_APP_LX_DAD_WITH_ULAN),y) +ifeq ($(CONFIG_ULAN_DY),y) +lib_LOADLIBES += uldy +endif +lib_LOADLIBES += ulan +endif +ifeq ($(CONFIG_APP_LX_DAD_WITH_SUITK),y) +lib_LOADLIBES += suitk suiut suitk suifont ulut sha1 +ifeq ($(CONFIG_APP_LX_DAD_WITH_SIM_POSIX),y) +lib_LOADLIBES += suixml suitk suiut sha1 +endif +endif +ifeq ($(CONFIG_OC_MWENGINE),y) +lib_LOADLIBES += mwengine mwfonts mwdrivers mwfonts mwengine mwdrivers +endif +ifeq ($(CONFIG_OC_I2C_DRV_SYSLESS),y) +lib_LOADLIBES += i2c_drv +endif +ifeq ($(CONFIG_OC_SPI_DRV_SYSLESS),y) +lib_LOADLIBES += spi_drv +endif + +ifeq ($(CONFIG_PXMC),y) +ifneq ($(CONFIG_APP_LX_DAD_WITH_SIM_POSIX),y) +lx_dad_SOURCES += appl_pxmc.c +endif +lib_LOADLIBES += pxmc pxmcbsp +endif + +ifeq ($(CONFIG_OC_CMDPROC),y) +lib_LOADLIBES += cmdproc misc +endif + +ifeq ($(CONFIG_APP_LX_DAD_WITH_USB),y) +lx_dad_SOURCES += appl_usb.c +ifeq ($(CONFIG_LIB_U2U_V2),y) +lib_LOADLIBES += u2u_dcnv +endif +lib_LOADLIBES += usbbase usbmore +ifeq ($(CONFIG_USB_LPCUSB),y) +lib_LOADLIBES += lpcusb +endif +endif + +ifeq ($(CONFIG_OC_ULUT),y) +lib_LOADLIBES += ulut +endif + +ifeq ($(CONFIG_APP_LX_DAD_WITH_SIM_POSIX),y) +lx_dad_SOURCES += appl_sim_posix.c +lib_LOADLIBES += rt +endif + +lib_LOADLIBES += m + +link_VARIANTS = app sdram + +endif #CONFIG_APP_LX_DAD diff --git a/sw/app/lx_dad/appl_actions.c b/sw/app/lx_dad/appl_actions.c new file mode 100644 index 0000000..abcefcf --- /dev/null +++ b/sw/app/lx_dad/appl_actions.c @@ -0,0 +1,36 @@ +#include "appl_defs.h" +#include +#include + +UL_LOG_CUST(ulogd_dad) + +void appl_global_action_store_user_heper() +{ + #ifdef APPL_WITH_DISTORE_EEPROM_USER + appl_distore_user_set_check4change(); + appl_distore_user_change_check(); + #endif /*APPL_WITH_DISTORE_EEPROM_USER*/ +} + +int appl_global_action(int action_code) +{ + int res; + + switch(action_code) { + + case APPL_ACT_ERRCLR: + return 0; + + case APPL_ACT_SETUP_SAVE: + appl_global_action_store_user_heper(); + break; + + case APPL_ACT_SERVICE_SAVE: + #ifdef APPL_WITH_DISTORE_KEYVAL_SERVICE + setup_distore_store(); + #endif /*APPL_WITH_DISTORE_KEYVAL_SERVICE*/ + break; + + } + return 0; +} diff --git a/sw/app/lx_dad/appl_cmdproc.c b/sw/app/lx_dad/appl_cmdproc.c new file mode 100644 index 0000000..e2c611d --- /dev/null +++ b/sw/app/lx_dad/appl_cmdproc.c @@ -0,0 +1,38 @@ +#include +#include +#include +#include +#include + +#include "appl_defs.h" + +extern cmd_des_t const *cmd_pxmc_base[]; +extern cmd_des_t const *cmd_appl_tests[]; +extern cmd_des_t const *cmd_pxmc_ptable[]; + +cmd_des_t const **cmd_list; + +cmd_des_t const cmd_des_help={ + 0, 0, + "help","prints help for commands", + cmd_do_help,{(char*)&cmd_list}}; + + +cmd_des_t const *cmd_list_main[]={ + &cmd_des_help, + CMD_DES_INCLUDE_SUBLIST(cmd_appl_tests), + #ifdef CONFIG_PXMC + CMD_DES_INCLUDE_SUBLIST(cmd_pxmc_base), + CMD_DES_INCLUDE_SUBLIST(cmd_pxmc_ptable), + #endif + NULL +}; + +cmd_des_t const **cmd_list = cmd_list_main; + +extern cmd_io_t cmd_io_uartcon; + +int cmdproc_poll(void) +{ + return cmd_processor_run(&cmd_io_uartcon, cmd_list_main); +} diff --git a/sw/app/lx_dad/appl_defs.h b/sw/app/lx_dad/appl_defs.h new file mode 100644 index 0000000..e1b16fd --- /dev/null +++ b/sw/app/lx_dad/appl_defs.h @@ -0,0 +1,209 @@ +#ifndef _TEST_LPC_H +#define _TEST_LPC_H + +#ifdef __cplusplus +/*extern "C" {*/ +#endif + +#include "appl_config.h" + +#include +#include + +#ifdef CONFIG_APP_LX_DAD_WITH_SUITK +#define APPL_WITH_SUITK +#endif /*CONFIG_APP_LX_DAD_WITH_SUITK*/ + +#ifdef CONFIG_APP_LX_DAD_WITH_SIM_POSIX +#define APPL_WITH_SIM_POSIX +#define APPL_WITH_FINALIZATION_CHECK +#endif /*CONFIG_APP_LX_DAD_WITH_SIM_POSIX*/ + +#ifdef CONFIG_APP_LX_DAD_WITH_FPGA +#define APPL_WITH_FPGA +#endif /*CONFIG_APP_LX_DAD_WITH_FPGA*/ + +#ifdef CONFIG_APP_LX_DAD_WITH_USB +#define APPL_WITH_USB +#endif /*CONFIG_APP_LX_DAD_WITH_USB*/ + +#ifdef CONFIG_APP_LX_DAD_WITH_ULAN +#define APPL_WITH_ULAN +#include +#include +#ifdef CONFIG_ULAN_DY + #include + extern ul_dyac_t *ul_dyac; +#endif /*CONFIG_ULAN_DY*/ +/* ulan identification */ +extern const char *ul_idstr; +/* ulan variables */ +extern ul_fd_t ul_fd,ul_fd1; +extern ul_msginfo umsginfo; +extern uloi_coninfo_t *coninfo; +#endif /*CONFIG_APP_LX_DAD_WITH_ULAN*/ + +extern int usb_enable_flag; + +extern int app_exit_request; + +#ifdef CONFIG_OC_I2C_DRV_SYSLESS +#define APPL_EEPROM_ADDR_SIZE 2 + +#define DISTORE_EEPROM_I2C_ADDR 0xA0 + +#define DISTORE_EEPROM_SIGNATURE 0x51 +#define DISTORE_EEPROM_HEADER_SIZE 6 + +#define DISTORE_EEPROM_PAGE 0x0020 +#define DISTORE_EEPROM_SIZE 0x2000 +#define DISTORE_EEPROM_USER_START 0x100 +#define DISTORE_EEPROM_USER_SIZE 0x400 +/* user end 0x100 + 2 * 0x400 = 0x900 */ + +/* +#define APPL_WITH_DISTORE_EEPROM_USER +#define appl_distore_eeprom_user_des lcd_distore_user_des +int appl_distore_init(void); +int appl_distore_user_set_check4change(void); +int appl_distore_user_restore(void); +int appl_distore_user_change_check(void); +*/ + +/* +#define APPL_WITH_TIMEPROG_EEPROM_STORE +#define TIMEPROG_EEPROM_STORE_START 0x0900 +#define TIMEPROG_EEPROM_STORE_SIZE 0x1700 +*/ + +#define appl_timeprog_eeprom_identifier lcd_timeprog +long timeprog_stored_size; +int appl_timeprog_eeprom_restore(void); +#endif /*CONFIG_OC_I2C_DRV_SYSLESS*/ + +#define APPL_TIMEPROG_AREA_SIZE 0x1700 + +#ifdef CONFIG_KEYVAL +/* +#define KVPB_KEYID_SETUP_SERVICE 0x104 +#define KVPB_SETUP_SERVICE_MAX_SIZE 1024 +#define APPL_WITH_DISTORE_KEYVAL_SERVICE +#define setup_distore_service_des lcd_distore_service_des +int setup_distore_restore(void); +int setup_distore_store(void); +*/ +#endif /*CONFIG_KEYVAL*/ + +LT_TIMER_DEC(lt_10msec) + +#ifdef APPL_WITH_ULAN +extern const uloi_objdes_array_t uloi_objdes_main; +#endif /*APPL_WITH_ULAN*/ + +void mloop(void); + +int gui_init(void); + +int gui_poll(void); + +#define APPL_WITH_GUI_POLL_EXTENSION + +int cmdproc_poll(void); + +void save_cfg(void); + +extern int usb_loadder_active; + +int usb_app_init(void); + +int usb_app_poll(void); + +int usb_app_fill_serial_number(uint32_t ul_sn); + +#define APPL_ACT_STOP 1 +#define APPL_ACT_STOP_CER 2 +#define APPL_ACT_MOTSTART 3 +#define APPL_ACT_MOTSTART_CER 4 +#define APPL_ACT_PURGE 5 +#define APPL_ACT_PRGRUN 6 +#define APPL_ACT_PRGEND 7 +#define APPL_ACT_ERRCLR 8 +#define APPL_ACT_PRGEND_PREP 9 +#define APPL_ACT_PRGHOLD 10 +#define APPL_ACT_PRGCONT 11 +#define APPL_ACT_SETUP_SAVE 12 +#define APPL_ACT_SERVICE_SAVE 13 + +int appl_global_action(int action_code); + +/* LPC Quadrature encoder events processing */ +struct lpc_qei_state_t; +void pxmc_lpc_qei_callback_index(struct lpc_qei_state_t *qst, void *context); +void lpc_qei_callback_cmpos0(struct lpc_qei_state_t *qst, void *context); +void lpc_qei_callback_cmpos1(struct lpc_qei_state_t *qst, void *context); + +void lcd_sfi_isr(void); +void lcd_sfi_slow_isr(void); + +#define APPL_RUN_AT_FAST_SFI do { \ + /*lcd_sfi_isr();*/ \ + ; \ + } while(0) + +#define APPL_RUN_AT_SLOW_SFI do { \ + /*lcd_sfi_slow_isr();*/ \ + ; \ + } while(0) + +#define APPL_SLOW_SFI_USEC 10000 + +/* Interrupt of the unused peripheral which is used to activate slow IRQ handling */ +#define SLOW_SFI_INVOKE_IRQn SSP2_IRQn + +#ifndef CONFIG_APP_LX_DAD_WITH_SIM_POSIX +void kbd_lc61spi_SetIndicatorsState(unsigned long mask, unsigned long xor_state); +#define kbd_SetIndicatorsState kbd_lc61spi_SetIndicatorsState +#endif +static inline void appl_update_indicators(void) +{ + /*lcd_update_indicators();*/ +} +extern int lcd_backlight_level; +int lcd_set_constrast_level(int level); + +#define KBD_LED_RUN_b 15 +#define KBD_LED_HOLD_b 14 +#define KBD_LED_PURGE_b 13 +#define KBD_LED_ERROR_b 12 +#define KBD_LED_A_b 6 +#define KBD_LED_B_b 5 +#define KBD_LED_C_b 4 +#define KBD_LED_D_b 3 +#define KBD_LED_MOTOR_b 1 + +#define KBD_LED_BACKLO_b 11 +#define KBD_LED_BACKHI_b 10 +#define KBD_LED_BEEPF_b 9 +#define KBD_LED_BEEPN_b 8 + +#define KBD_LED_RUN_m (1 << KBD_LED_RUN_b) +#define KBD_LED_HOLD_m (1 << KBD_LED_HOLD_b) +#define KBD_LED_PURGE_m (1 << KBD_LED_PURGE_b) +#define KBD_LED_ERROR_m (1 << KBD_LED_ERROR_b) +#define KBD_LED_A_m (1 << KBD_LED_A_b) +#define KBD_LED_B_m (1 << KBD_LED_B_b) +#define KBD_LED_C_m (1 << KBD_LED_C_b) +#define KBD_LED_D_m (1 << KBD_LED_D_b) +#define KBD_LED_MOTOR_m (1 << KBD_LED_MOTOR_b) + +#define KBD_LED_BACKLO_m (1 << KBD_LED_BACKLO_b) +#define KBD_LED_BACKHI_m (1 << KBD_LED_BACKHI_b) +#define KBD_LED_BEEPN_m (1 << KBD_LED_BEEPN_b) +#define KBD_LED_BEEPF_m (1 << KBD_LED_BEEPF_b) + +#ifdef __cplusplus +/*}*/ /* extern "C"*/ +#endif + +#endif /* _TEST_LPC_H */ + diff --git a/sw/app/lx_dad/appl_distore.c b/sw/app/lx_dad/appl_distore.c new file mode 100644 index 0000000..25bd04b --- /dev/null +++ b/sw/app/lx_dad/appl_distore.c @@ -0,0 +1,402 @@ +#include +#include + +#include "appl_defs.h" + +#include "appl_eeprom.h" + +#ifdef CONFIG_OC_I2C_DRV_SYSLESS +#include +extern i2c_drv_t i2c_drv; +#endif + +#include "distore_simple.h" + +#include +extern UL_LOG_CUST(ulogd_distore) + +#ifdef APPL_WITH_TIMEPROG_EEPROM_STORE +#include "timeprog.h" +extern timeprog_t appl_timeprog_eeprom_identifier; +#endif + +#ifdef CONFIG_OC_I2C_DRV_SYSLESS + +void *(* const appl_distore_reserve_ram)(size_t size); + +typedef struct appl_distore_eeprom_context_t { + size_t pos; + size_t limit; + void *buf; + const distore_des_array_t *des; + int changed:1; + int write2nd:1; + volatile unsigned char check4change; + unsigned char gen_cnt; + unsigned short area_start; + unsigned short area_size; + + appl_eeprom_chip_context_t *chip; +} appl_distore_eeprom_context_t; + +ssize_t appl_distore_eeprom_wrfnc(void *context, const void *buf, size_t count) +{ + appl_distore_eeprom_context_t *c = (appl_distore_eeprom_context_t *)context; + if(c->limit - c->pos < count) + return -1; + if(memcmp((char *)c->buf + c->pos, buf, count)) + c->changed = 1; + memcpy((char *)c->buf + c->pos, buf, count); + c->pos += count; + return count; +} + +ssize_t appl_distore_eeprom_rdfnc(void *context, void *buf, size_t count) +{ + appl_distore_eeprom_context_t *c = (appl_distore_eeprom_context_t *)context; + if(c->limit - c->pos < count) + return -1; + memcpy(buf, (char *)c->buf + c->pos, count); + c->pos += count; + return count; +} + +unsigned int appl_distore_eeprom_chksum(void *data, size_t size) +{ + unsigned int chksum = 0x1234; + unsigned char *p = data; + + while(size --) { + chksum = (*p ^ chksum) + (*p << 8) + 1; + p++; + } + return chksum; +} + +int appl_distore_eeprom_load(appl_distore_eeprom_context_t *c) +{ + const distore_des_array_t *des = c->des; + unsigned char u[DISTORE_EEPROM_HEADER_SIZE]; + size_t ma; + unsigned int chksum, load_chksum; + int res; + unsigned char area_bad[2] = {0, 0}; + unsigned char area_gen_cnt[2]; + unsigned int area_limit[2]; + int area_act; + + if(c->buf == NULL) + return -1; + + if(c->chip == NULL) + return -1; + + for(area_act = 0; area_act < 2; area_act++) { + ma = c->area_start + c->area_size * area_act; + if(appl_eeprom_chip_load(c->chip, ma, u, DISTORE_EEPROM_HEADER_SIZE) < 0) { + return -1; + } + if(u[0] != DISTORE_EEPROM_SIGNATURE) { + area_bad[area_act] = 1; + ul_logmsg("appl_distore_eeprom_load area %d has bad signature\n", area_act); + continue; + } + area_gen_cnt[area_act] = u[1]; + area_limit[area_act] = u[4] | ((unsigned int)u[5] << 8); + if(c->area_size < area_limit[area_act]) { + area_bad[area_act] = 1; + ul_logmsg("appl_distore_eeprom_load area %d size 0x%lx < stored size 0x%lx\n", area_act, + (unsigned long)c->area_size, (unsigned long)area_limit[area_act]); + continue; + } + ul_logdeb("appl_distore_eeprom_load area %d gen_cnt is 0x%x stored size 0x%lx\n", + area_act, u[1], (unsigned long)area_limit[area_act]); + } + area_act = 0; + if((ul_cyclic_gt(area_gen_cnt[1],area_gen_cnt[0]) && !area_bad[1]) || area_bad[0]) + area_act = 1; + + for( ; 1; area_bad[area_act] = 1, area_act = area_act ^ 1) { + if(area_bad[area_act]) { + ul_logmsg("appl_distore_eeprom_load no valid area found\n"); + return -1; + } + + c->limit = area_limit[area_act]; + + ma = c->area_start + c->area_size * area_act; + if(appl_eeprom_chip_load(c->chip, ma, c->buf, c->limit) < 0) { + continue; + } + chksum = appl_distore_eeprom_chksum((unsigned char *)c->buf + 4, c->limit - 4); + load_chksum = *((unsigned char *)c->buf + 2); + load_chksum |= *((unsigned char *)c->buf + 3) << 8; + + if((chksum ^ load_chksum) & 0xffff) { + ul_logmsg("appl_distore_eeprom_load area %d has bad checksum (0x%04x != 0x%04x)\n", + area_act, chksum & 0xffff, load_chksum); + continue; + } + + c->write2nd = area_act ^ 1; + c->gen_cnt = area_gen_cnt[area_act]; + ul_logdeb("appl_distore_eeprom_load reading data from %d area\n", area_act); + + c->pos = DISTORE_EEPROM_HEADER_SIZE; + + res = distore_load_data(des, appl_distore_eeprom_rdfnc, c, + DISTORE_LOAD_IGNORE_UNKNOWN | DISTORE_LOAD_IGNORE_WRITE_ERR); + + if(res < 0) { + ul_logmsg("appl_distore_eeprom_load data decode from %d area failed\n", area_act); + continue; + } else { + ul_logmsg("appl_distore_eeprom_load decoded from %d area\n", area_act); + } + break; + } + return res; +} + +int appl_distore_eeprom_init(appl_distore_eeprom_context_t *c) +{ + const distore_des_array_t *des = c->des; + ssize_t sz; + + c->buf = NULL; + c->limit = 0; + c->pos = 0; + sz = distore_count_maxsize(des); + if(sz < 0) + return -1; + if(sz + DISTORE_EEPROM_HEADER_SIZE >= c->area_size) { + ul_logerr("appl_distore max_size %ld > EEPROM target area %ld\n", + (unsigned long)sz, (unsigned long)c->area_size); + return -1; + } + + if(appl_distore_reserve_ram != NULL) + c->buf = appl_distore_reserve_ram(c->area_size); + if(c->buf == NULL) + c->buf = malloc(c->area_size); + + if(c->buf == NULL) { + ul_logerr("appl_distore_eeprom_init RAM allocation failed\n"); + return -1; + } + + memset(c->buf, 0, c->area_size > 16? 16: c->area_size); + + c->limit = c->area_size; + + return 0; +} + +int appl_distore_eeprom_store(appl_distore_eeprom_context_t *c, int forced) +{ + int res; + unsigned int chksum; + unsigned char u[DISTORE_EEPROM_HEADER_SIZE]; + const distore_des_array_t *des = c->des; + + if(c->buf == NULL) + return -1; + + if(c->chip->tx_inpr > 0) + return -2; + + c->check4change = 0; + + c->pos = DISTORE_EEPROM_HEADER_SIZE; + c->limit = c->area_size; + + c->changed = 0; + + res = distore_store_data(des, appl_distore_eeprom_wrfnc, c); + if(res < 0) { + return -1; + } + + if(!c->changed && !forced) + return 0; + + c->limit = c->pos; + + /* The length of the data is part of the area covered by checksum */ + u[4] = c->limit & 0xff; + u[5] = c->limit >> 8; + c->pos = 4; + appl_distore_eeprom_wrfnc(c, u+4, 2); + + chksum = appl_distore_eeprom_chksum((unsigned char *)c->buf + 4, c->limit - 4); + + u[0] = DISTORE_EEPROM_SIGNATURE; + u[1] = (c->gen_cnt + 1) & 0xff; + u[2] = chksum & 0xff; + u[3] = (chksum >> 8) & 0xff; + + c->pos = 0; + appl_distore_eeprom_wrfnc(c, u, DISTORE_EEPROM_HEADER_SIZE); + + c->pos = 0; + + return 1; +} + +#endif /*CONFIG_OC_I2C_DRV_SYSLESS*/ + +#ifdef APPL_WITH_DISTORE_EEPROM_USER +extern const distore_des_array_t appl_distore_eeprom_user_des; + +appl_eeprom_chip_context_t appl_eeprom_chip_context = { + .page_size = DISTORE_EEPROM_PAGE, + .i2c_drv = &i2c_drv, + .i2c_addr = DISTORE_EEPROM_I2C_ADDR, +}; + +appl_distore_eeprom_context_t appl_distore_eeprom_user_context = { + .des = &appl_distore_eeprom_user_des, + .area_start = DISTORE_EEPROM_USER_START, + .area_size = DISTORE_EEPROM_USER_SIZE, + .chip = &appl_eeprom_chip_context, +}; + +int appl_distore_eeprom_user_finish_callback(struct appl_eeprom_chip_context_t *chip, + void *context, int result) +{ + appl_distore_eeprom_context_t *c = (appl_distore_eeprom_context_t *)context; + + ul_loginf("finished distore save with result %d\n", result); + + if(result >= 0) { + c->write2nd = (c->write2nd ^ 1) & 1; + c->gen_cnt += 1; + } + + return 0; +} + +#ifdef APPL_WITH_TIMEPROG_EEPROM_STORE +int appl_timeprog_eeprom_store_finish_callback(struct appl_eeprom_chip_context_t *chip, + void *context, int result) +{ + timeprog_t *timeprog = (timeprog_t *)context; + + ul_loginf("finished timeprog save with result %d\n", result); + + timeprog->save_rq_state = (result >= 0)? 0: -1; + + return 0; +} +#endif /*APPL_WITH_TIMEPROG_EEPROM_STORE*/ + +int appl_distore_user_change_check(void) +{ + int res; + unsigned int ma; + appl_distore_eeprom_context_t *c = &appl_distore_eeprom_user_context; + appl_eeprom_chip_context_t *chip = c->chip; + int transfer_pend_fl = 0; + + if(chip->tx_inpr > 0) + return 2; + + #ifdef APPL_WITH_TIMEPROG_EEPROM_STORE + if(chip->opstate == APPL_EEPROM_ST_IDLE) { + timeprog_t *timeprog = &appl_timeprog_eeprom_identifier; + if(timeprog->save_rq_state) { + long size_to_store = timeprog_size_to_store(timeprog); + res = -1; + if((size_to_store>0)&&(size_to_store<=TIMEPROG_EEPROM_STORE_SIZE)) { + res = appl_eeprom_chip_write_transfer_setup(chip, timeprog->region_start, + TIMEPROG_EEPROM_STORE_START, size_to_store, + appl_timeprog_eeprom_store_finish_callback, timeprog); + } + if(res<0) { + timeprog->save_rq_state = -1; + } else { + c->check4change = 1; + transfer_pend_fl = 1; + timeprog_stored_size = size_to_store; + } + } + } + #endif /*APPL_WITH_TIMEPROG_EEPROM_STORE*/ + if(c->check4change && !transfer_pend_fl) { + res = appl_distore_eeprom_store(c, 0); + if(res < 0) + return -1; + if(res > 0) { + ma = c->area_start; + if(c->write2nd) + ma += c->area_size; + appl_eeprom_chip_write_transfer_setup(chip, c->buf, ma, c->limit, + appl_distore_eeprom_user_finish_callback, c); + } + } + if(chip->opstate == APPL_EEPROM_ST_IDLE) + return 0; + + return appl_eeprom_chip_process(chip); +} + +int appl_distore_user_set_check4change(void) +{ + appl_distore_eeprom_context_t *c = &appl_distore_eeprom_user_context; + + c->check4change = 1; + + return 0; +} + +int appl_distore_user_restore(void) +{ + appl_distore_eeprom_context_t *c = &appl_distore_eeprom_user_context; + + return appl_distore_eeprom_load(c); +} + +#ifdef APPL_WITH_TIMEPROG_EEPROM_STORE +int appl_timeprog_eeprom_restore(void) +{ + appl_distore_eeprom_context_t *c = &appl_distore_eeprom_user_context; + appl_eeprom_chip_context_t *chip = c->chip; + timeprog_t *timeprog = &appl_timeprog_eeprom_identifier; + long sz = timeprog_stored_size; + + if((timeprog->region_limit==NULL)||(timeprog->region_start==NULL)) + return -1; + if((sz <= 0) || (sz > (char*)timeprog->region_limit-(char*)timeprog->region_start)) + return -1; + if(sz>TIMEPROG_EEPROM_STORE_SIZE) + return -1; + + timeprog->preprocess_state=TIMEPROG_PPST_MODIFIED; + __memory_barrier(); + + if(appl_eeprom_chip_load(chip, TIMEPROG_EEPROM_STORE_START, timeprog->region_start, sz) < 0) { + size_t region_size = timeprog->region_limit-timeprog->region_start; + memset(timeprog->region_start, 0, region_size); + timeprog->gen_cnt++; + return -1; + } + timeprog->gen_cnt++; + + if(!timeprog_actual_is_empty(timeprog)) + timeprog_end_and_prepare(timeprog); + + return 0; +} +#endif /*APPL_WITH_TIMEPROG_EEPROM_STORE*/ + + +int appl_distore_init(void) +{ + appl_distore_eeprom_context_t *c = &appl_distore_eeprom_user_context; + if(appl_eeprom_chip_init(c->chip) < 0) { + return -1; + } + return appl_distore_eeprom_init(c); +} + +#endif /* APPL_WITH_DISTORE_EEPROM_USER */ diff --git a/sw/app/lx_dad/appl_eeprom.c b/sw/app/lx_dad/appl_eeprom.c new file mode 100644 index 0000000..23c4eb4 --- /dev/null +++ b/sw/app/lx_dad/appl_eeprom.c @@ -0,0 +1,218 @@ +#include + +#include "appl_defs.h" + +#include "appl_eeprom.h" + +#ifdef WATCHDOG_ENABLED +#include +#endif /* WATCHDOG_ENABLED */ + +#include +extern UL_LOG_CUST(ulogd_distore) + +#ifdef CONFIG_OC_I2C_DRV_SYSLESS + +void *(* const appl_distore_reserve_ram)(size_t size); + +int appl_eeprom_chip_init(appl_eeprom_chip_context_t *chip) +{ + size_t pgbufflen = chip->page_size+APPL_EEPROM_ADDR_SIZE; + if(appl_distore_reserve_ram != NULL) + chip->rxtx_buf = appl_distore_reserve_ram(pgbufflen); + if(chip->rxtx_buf == NULL) + chip->rxtx_buf = malloc(pgbufflen); + if(chip->rxtx_buf == NULL) { + ul_logerr("appl_eeprom_chip_init RAM allocation failed\n"); + return -1; + } + return 0; +} + +#define APPL_EEPROM_CHUNK_SIZE 512 + +int appl_eeprom_chip_load(appl_eeprom_chip_context_t *chip, unsigned int start_addr, + void *data, unsigned int len) +{ + unsigned char u[APPL_EEPROM_ADDR_SIZE]; + int wrc, rdc; + int res; + + while(len) { + int chunk = APPL_EEPROM_CHUNK_SIZE; + if(len < chunk) + chunk = len; + + #ifdef WATCHDOG_ENABLED + watchdog_feed(); + #endif /* WATCHDOG_ENABLED */ + + + if(APPL_EEPROM_ADDR_SIZE >= 2) { + u[0] = start_addr >> 8; + u[1] = start_addr & 0xff; + } else { + u[0] = start_addr & 0xff; + } + res = i2c_drv_master_transfer(chip->i2c_drv, chip->i2c_addr, + APPL_EEPROM_ADDR_SIZE, chunk, u, data, &wrc, &rdc); + if((res < 0) || (wrc != APPL_EEPROM_ADDR_SIZE) || (rdc != chunk)) { + ul_logerr("appl_eeprom_chip_load address 0x%x failed\n", start_addr); + return -1; + } + len -= chunk; + start_addr += chunk; + data = (char *)data + chunk; + } + return 0; +} + +int appl_eeprom_chip_transfer_callback(struct i2c_drv *drv, int code, struct i2c_msg_head *msg); + +int appl_eeprom_chip_transfer(appl_eeprom_chip_context_t *chip, + unsigned int start_addr, const void *data, unsigned int len) +{ + unsigned char *p; + + chip->tx_inpr = 1; + +// msg.flags = I2C_MSG_CB_PROC | I2C_MSG_NOPROC | I2C_MSG_MS_TX; + chip->i2c_msg.flags = I2C_MSG_CB_END | I2C_MSG_NOPROC | I2C_MSG_MS_TX; + chip->i2c_msg.addr = chip->i2c_addr; + chip->i2c_msg.tx_rq = len + APPL_EEPROM_ADDR_SIZE; + chip->i2c_msg.rx_rq = 0; + chip->i2c_msg.tx_buf = chip->rxtx_buf; + chip->i2c_msg.rx_buf = 0; + chip->i2c_msg.on_queue = NULL; + chip->i2c_msg.callback = appl_eeprom_chip_transfer_callback; + chip->i2c_msg.private = (unsigned long)chip; + + p = chip->rxtx_buf; + + if(APPL_EEPROM_ADDR_SIZE>=2) + *(p++) = start_addr >> 8; + + *(p++) = start_addr & 0xff; + if(data != NULL) + memcpy(p, data, len); + + if(i2c_drv_master_msg_ins(chip->i2c_drv, &chip->i2c_msg)<0) + return -1; + return 0; +} + +int appl_eeprom_chip_transfer_callback(struct i2c_drv *drv, int code, struct i2c_msg_head *msg) +{ + appl_eeprom_chip_context_t *chip = (appl_eeprom_chip_context_t *)msg->private; + + if (msg->flags&I2C_MSG_FAIL) { + chip->tx_inpr = -1; + return 0; + } + if (msg->tx_len!=msg->tx_rq) { + chip->tx_inpr = -1; + return 0; + } + + chip->tx_inpr = 0; + return 0; +} + +int appl_eeprom_chip_process(appl_eeprom_chip_context_t *chip) +{ + size_t ma, len; + void *data; + int res; + + if(chip->tx_inpr > 0) + return 2; + + switch(chip->opstate) { + case APPL_EEPROM_ST_IDLE: + return 0; + case APPL_EEPROM_ST_START: + chip->opstate = APPL_EEPROM_ST_WRDATA; + chip->tx_inpr = 0; + chip->retry_cnt = 0; + chip->pos = 0; + case APPL_EEPROM_ST_WRDATA: + if(chip->tx_inpr < 0) { + if(chip->retry_cnt++ > 2000) { + chip->opstate = APPL_EEPROM_ST_IDLE; + ul_logerr("appl_eeprom_chip write failed at addr 0x%lx\n", + (unsigned long)(chip->data_start+chip->pos)); + if(chip->finish_callback) + chip->finish_callback(chip, chip->callback_context, -1); + return -1; + } + } else { + chip->pos += chip->page_size; + chip->retry_cnt = 0; + } + + if(chip->pos >= chip->data_len) { + chip->opstate = APPL_EEPROM_ST_WRHEADER; + chip->pos = 0; + } + + retry_transfer: + + len = chip->page_size; + if(len > chip->data_len - chip->pos) + len = chip->data_len - chip->pos; + ma = chip->data_start + chip->pos; + data = (char*)chip->data_buf + chip->pos; + + ul_logdeb("appl_eeprom_chip write chunk at %p to 0x%lx len %ld\n", data, (long)ma, (long)len); + + res = appl_eeprom_chip_transfer(chip, ma, data, len); + if(res < 0) { + chip->opstate = APPL_EEPROM_ST_IDLE; + ul_logerr("appl_eeprom_chip write transfer request failed %d\n", res); + if(chip->finish_callback) + chip->finish_callback(chip, chip->callback_context, -2); + return -1; + } + break; + + case APPL_EEPROM_ST_WRHEADER: + + if(chip->tx_inpr < 0) { + if(chip->retry_cnt++ > 2000) { + chip->opstate = APPL_EEPROM_ST_IDLE; + ul_logerr("appl_eeprom_chip write failed at addr 0x%lx\n", + (unsigned long)(chip->data_start+chip->pos)); + if(chip->finish_callback) + chip->finish_callback(chip, chip->callback_context, -1); + return -1; + } + goto retry_transfer; + } + + chip->opstate = APPL_EEPROM_ST_IDLE; + if(chip->finish_callback) + chip->finish_callback(chip, chip->callback_context, 0); + break; + } + return 1; +} + +int appl_eeprom_chip_write_transfer_setup(appl_eeprom_chip_context_t *chip, + void *buf, size_t start_addr, size_t len, + int (*finish_cb)(struct appl_eeprom_chip_context_t *chip, void *context, int result), + void *ctx) +{ + if(chip->tx_inpr > 0) + return -1; + + chip->opstate = APPL_EEPROM_ST_START; + chip->data_buf = buf; + chip->data_start = start_addr; + chip->data_len = len; + chip->finish_callback = finish_cb; + chip->callback_context = ctx; + + return 0; +} + +#endif /*CONFIG_OC_I2C_DRV_SYSLESS*/ diff --git a/sw/app/lx_dad/appl_eeprom.h b/sw/app/lx_dad/appl_eeprom.h new file mode 100644 index 0000000..e5a4725 --- /dev/null +++ b/sw/app/lx_dad/appl_eeprom.h @@ -0,0 +1,52 @@ +#ifndef _APPL_EEPROM_H +#define _APPL_EEPROM_H + +#include + +#include "appl_defs.h" + +#ifdef CONFIG_OC_I2C_DRV_SYSLESS +#include + +typedef struct appl_eeprom_chip_context_t { + unsigned char opstate; + i2c_drv_t *i2c_drv; + unsigned char i2c_addr; + i2c_msg_head_t i2c_msg; + unsigned char *rxtx_buf; + unsigned short page_size; + volatile signed char tx_inpr; + volatile unsigned char retry_cnt; + void *data_buf; + size_t data_start; + size_t data_len; + size_t pos; + int (*finish_callback)(struct appl_eeprom_chip_context_t *chip, void *context, int result); + void *callback_context; +} appl_eeprom_chip_context_t; + +enum appl_eeprom_st { + APPL_EEPROM_ST_IDLE = 0, + APPL_EEPROM_ST_START = 1, + APPL_EEPROM_ST_WRDATA = 2, + APPL_EEPROM_ST_WRHEADER = 3, +}; + +int appl_eeprom_chip_init(appl_eeprom_chip_context_t *chip); + +int appl_eeprom_chip_load(appl_eeprom_chip_context_t *chip, unsigned int start_addr, + void *data, unsigned int len); + +int appl_eeprom_chip_transfer(appl_eeprom_chip_context_t *chip, + unsigned int start_addr, const void *data, unsigned int len); + +int appl_eeprom_chip_process(appl_eeprom_chip_context_t *chip); + +int appl_eeprom_chip_write_transfer_setup(appl_eeprom_chip_context_t *chip, + void *buf, size_t start_addr, size_t len, + int (*finish_cb)(struct appl_eeprom_chip_context_t *chip, void *context, int result), + void *ctx); + +#endif /*CONFIG_OC_I2C_DRV_SYSLESS*/ + +#endif /*_APPL_EEPROM_H*/ diff --git a/sw/app/lx_dad/appl_fpga.c b/sw/app/lx_dad/appl_fpga.c new file mode 100644 index 0000000..8c9647c --- /dev/null +++ b/sw/app/lx_dad/appl_fpga.c @@ -0,0 +1,365 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "appl_defs.h" +#include "appl_version.h" +#include "appl_fpga.h" + +#define SWAB32(x) ((x >> 24) | ((x & 0x00FF0000) >> 8) | ((x & 0x0000FF00) << 8) | (x << 24)) + +/* Variables for configuration */ +volatile uint16_t *fpga_configure_line = (volatile uint16_t *)0x80007FF0; +int fpga_configured = 0; +int fpga_reconfiguration_locked = 1; + +/* BUS measurement - registers to measure the delay necessary for reading and writing */ +volatile uint32_t *fpga_bus_meas_read1 = (volatile uint32_t *)0x80007FF0; +volatile uint32_t *fpga_bus_meas_write1 = (volatile uint32_t *)0x80007FF4; + +volatile uint32_t *fpga_bus_meas_read2 = (volatile uint32_t *)0x80007FF8; +volatile uint32_t *fpga_bus_meas_write2 = (volatile uint32_t *)0x80007FFC; + +/* BUS measurement - values (shifting all bits) */ +#define MEAS_VAL1 0xAAAAAAAA +#define MEAS_VAL2 0x55555555 + +void fpga_init() +{ + /* Initialze EMC for FPGA */ + + /* Settings: + * 32 bus width + * CS polarity: LOW (ATTENTION: Must match FPGA setup) + * Byte line state: Reads are only 32 bits + * Extended wait: off + * Buffer: disabled + * Write protection: disabled + */ + LPC_EMC->StaticConfig0 = 0x00000002; + + /* Delays - not measured at this point + * We're running on 72 MHz, FPGA bus is running on 50 MHz async. + * Read: 32 cycles + * Write: 33 cycles + * Turnaround: 2 cycles (cca. 28 ns) + */ + LPC_EMC->StaticWaitRd0 = 0x1F; + LPC_EMC->StaticWaitWr0 = 0x1F; + LPC_EMC->StaticWaitTurn0 = 0x01; + + /* Shift addresses by 2 (32-bit bus) */ + LPC_SC->SCS &= 0xFFFFFFFE; + + printf("EMC for FPGA initialized!\n"); +} + +/* + * Bus measurement - functions can be called via USB interface + * Proper usage: + * 1) Measurement read + * 2) Measurement write + * 3) Set turnaround + * bus is not pipelined, therefore + * just necessary delay for I/O to enter + * high impedance state (synchronous clocking => only 1 cycle necessary) + */ + +/* Cannot be on stack due to memory barrier for gcc */ +static uint32_t a, b; + +int fpga_measure_bus_read() +{ + int i; + + /* Set the delays are set to highest (default) value */ + LPC_EMC->StaticWaitRd0 = 0x1F; + + while (LPC_EMC->StaticWaitRd0 >= 0) + { + for (i = 0; i < 1024; i++) + { + /* Reset the values */ + __memory_barrier(); + a = 0xFFFFFFFF; + b = 0xFFFFFFFF; + __memory_barrier(); + /* Read the values several times - so there are two flips at least + * NOTE: SDRAM reads / writes may occur in between! + */ + a = *fpga_bus_meas_read1; + b = *fpga_bus_meas_read2; + a = *fpga_bus_meas_read1; + b = *fpga_bus_meas_read2; + a = *fpga_bus_meas_read1; + b = *fpga_bus_meas_read2; + a = *fpga_bus_meas_read1; + b = *fpga_bus_meas_read2; + __memory_barrier(); + + /* Verify */ + if (a != MEAS_VAL1 || b != MEAS_VAL2) + { + if (LPC_EMC->StaticWaitRd0 == 0x1F) + { + printf("ERROR: FPGA bus is not working properly!\n"); + return 1; + } + else + { + LPC_EMC->StaticWaitRd0++; + printf("FPGA bus: StaticWaitRd0 set to 0x%02X\n", (unsigned int) LPC_EMC->StaticWaitRd0); + return 0; + } + } + } + + /* We're good, lower it */ + if (LPC_EMC->StaticWaitRd0 == 0) + { + printf("FPGA bus: StaticWaitRd0 set to 0x%02X\n", (unsigned int) LPC_EMC->StaticWaitRd0); + break; + } + else + LPC_EMC->StaticWaitRd0--; + } + + return 0; +} + +int fpga_measure_bus_write() +{ + int i; + + /* Set the delays are set to highest (default) value */ + LPC_EMC->StaticWaitWr0 = 0x1F; + + while (LPC_EMC->StaticWaitWr0 >= 0) + { + for (i = 0; i < 1024; i++) + { + /* Make sure there is nothing other going on */ + __memory_barrier(); + *fpga_bus_meas_write1 = 0x00000000; + *fpga_bus_meas_write2 = 0x00000000; + __memory_barrier(); + a = 0xFFFFFFFF; + b = 0xFFFFFFFF; + __memory_barrier(); + /* Write the values several times - so there are two flips at least + * NOTE: SDRAM reads / writes may occur in between! + */ + *fpga_bus_meas_write1 = MEAS_VAL1; + *fpga_bus_meas_write2 = MEAS_VAL2; + *fpga_bus_meas_write1 = MEAS_VAL1; + *fpga_bus_meas_write2 = MEAS_VAL2; + *fpga_bus_meas_write1 = MEAS_VAL1; + *fpga_bus_meas_write2 = MEAS_VAL2; + *fpga_bus_meas_write1 = MEAS_VAL1; + *fpga_bus_meas_write2 = MEAS_VAL2; + /* + * Strongly ordered memory + * GCC is blocked by volatilness + */ + __memory_barrier(); + a = *fpga_bus_meas_write1; + b = *fpga_bus_meas_write2; + __memory_barrier(); + + /* Verify */ + if (a != MEAS_VAL1 || b != MEAS_VAL2) + { + if (LPC_EMC->StaticWaitWr0 == 0x1F) + { + printf("ERROR: FPGA bus is not working properly!\n"); + printf("a = 0x%08X, b = 0x%08X\n", (unsigned int) a, (unsigned int) b); + return 1; + } + else + { + LPC_EMC->StaticWaitWr0++; + printf("FPGA bus: StaticWaitWr0 set to 0x%02X\n", (unsigned int) LPC_EMC->StaticWaitWr0); + return 0; + } + } + } + + /* We're good, lower it */ + if (LPC_EMC->StaticWaitWr0 == 0) + { + printf("FPGA bus: StaticWaitWr0 set to 0x%02X\n", (unsigned int) LPC_EMC->StaticWaitWr0); + break; + } + else + LPC_EMC->StaticWaitWr0--; + } + + return 0; +} + +void fpga_set_reconfiguration_lock(int lock) +{ + fpga_reconfiguration_locked = lock; +} + +int fpga_get_reconfiguration_lock() +{ + return fpga_reconfiguration_locked; +} + +int fpga_configure() +{ + int i, j; + uint16_t *data; + char *magic; + uint32_t size; + + if (fpga_configured && fpga_reconfiguration_locked) + return FPGA_CONF_ERR_RECONF_LOCKED; + + if (fpga_reconfiguaration_initiated != NULL) + fpga_reconfiguaration_initiated(); + + /* Make sure INIT_B is set as input */ + hal_gpio_direction_input(XC_INIT_PIN); + + /* PROGRAM_B to low */ + hal_gpio_set_value(XC_PROGRAM_PIN, 0); + + /* SUSPEND to low (permamently) */ + hal_gpio_set_value(XC_SUSPEND_PIN, 0); + + /* Wait some cycles (minimum: 500 ns) */ + for (i = 0; i < 4096; i++) + {} + + /* PROGRAM_B to high */ + hal_gpio_set_value(XC_PROGRAM_PIN, 1); + + /* Wait for INIT_B to be high */ + j = 0; + + while (!hal_gpio_get_value(XC_INIT_PIN)) + { + if (j >= 4096) + { + hal_gpio_set_value(XC_SUSPEND_PIN, 1); + return FPGA_CONF_ERR_RESET_FAIL; + } + + j++; + } + + /* Use highest EMC delays */ + LPC_EMC->StaticWaitRd0 = 0x1F; + LPC_EMC->StaticWaitWr0 = 0x1F; + + /* Assert RWDR to WRITE */ + hal_gpio_set_value(XC_RDWR_PIN, 0); + + /* Send bin file (NOTE: Bits must be reversed!) via EMC) + * + * Embedded steps: + * 1) sync + * 2) device ID check + * 3) send configuration data + * 4) crc check + * + * INIT_B is LOW in case of a failure + * DONE is HIGH in case of a success + * + * When DONE is HIGH, deassert RWDR and do GPIO reconfiguration: + * + * GPIOs need to be reconfigured: + * + * INIT_B - used as reset, triggered LOW right after startup, + * change from input to output (OUTPUT DRAIN) + */ + + /* Get size */ + magic = (char *)FPGA_CONFIGURATION_FILE_ADDRESS; + + if (magic[0] != 'F' || magic[1] != 'P' || magic[2] != 'G' || magic[3] != 'A') + { + hal_gpio_set_value(XC_SUSPEND_PIN, 1); + return 1; + } + + size = (*(uint32_t *)(FPGA_CONFIGURATION_FILE_ADDRESS + 4)) >> 1; + data = (uint16_t *)(FPGA_CONFIGURATION_FILE_ADDRESS + 4 + sizeof(uint32_t)); + + /* Periodically check for failure */ + i = 0; + j = 0; + + while (i < size) + { + *fpga_configure_line = *data; + + if (j >= 128) + { + /* Check state */ + if (!hal_gpio_get_value(XC_INIT_PIN)) + { + hal_gpio_set_value(XC_SUSPEND_PIN, 1); + return FPGA_CONF_ERR_WRITE_ERR; + } + + j = 0; + } + + j++; + i++; + data++; + } + + /* We're done, deassert RDWR */ + hal_gpio_set_value(XC_RDWR_PIN, 1); + + while (!hal_gpio_get_value(XC_DONE_PIN)) + { + if (!hal_gpio_get_value(XC_INIT_PIN)) + { + hal_gpio_set_value(XC_SUSPEND_PIN, 1); + return FPGA_CONF_ERR_CRC_ERR; + } + } + + /* Issue startup clocks with data all 1s (at least 8 recommended) */ + for (i = 0; i < 16; i++) + *fpga_configure_line = 0xFFFF; + + /* In our design, INIT_B is used as reset, convert it to output, and trigger it */ + hal_gpio_direction_output(XC_INIT_PIN, 0); + + /* Hold it for some time */ + for (i = 0; i < 128; i++) + {} + + /* Use EMC delays obtained through measurement */ + LPC_EMC->StaticWaitWr0 = 0x02; + LPC_EMC->StaticWaitWen0 = 0x01; + LPC_EMC->StaticWaitRd0 = 0x08; + LPC_EMC->StaticWaitPage0 = 0x07; + LPC_EMC->StaticWaitOen0 = 0x01; + LPC_EMC->StaticWaitTurn0 = 0x01; + + /* Lift the reset */ + hal_gpio_direction_output(XC_INIT_PIN, 1); + + /* Give it some time */ + for (i = 0; i < 1024; i++) + {} + + fpga_configured = 1; + printf("FPGA configured!\n"); + + if (fpga_reconfiguaration_finished != NULL) + fpga_reconfiguaration_finished(); + + return FPGA_CONF_SUCESS; +} diff --git a/sw/app/lx_dad/appl_fpga.h b/sw/app/lx_dad/appl_fpga.h new file mode 100644 index 0000000..1d92e1d --- /dev/null +++ b/sw/app/lx_dad/appl_fpga.h @@ -0,0 +1,28 @@ +#ifndef _APPL_FPGA_H +#define _APPL_FPGA_H + +#include "appl_defs.h" + +/* Register defines */ + +/* Configuration defines */ + +#define FPGA_CONFIGURATION_FILE_ADDRESS 0xA1C00000 + +#define FPGA_CONF_SUCESS 0 +#define FPGA_CONF_ERR_RECONF_LOCKED 1 +#define FPGA_CONF_ERR_RESET_FAIL 2 +#define FPGA_CONF_ERR_WRITE_ERR 3 +#define FPGA_CONF_ERR_CRC_ERR 4 + +int (*fpga_reconfiguaration_initiated)(void); +int (*fpga_reconfiguaration_finished)(void); + +void fpga_init(); +int fpga_configure(); +int fpga_measure_bus_read(); +int fpga_measure_bus_write(); +void fpga_set_reconfiguration_lock(int lock); +int fpga_get_reconfiguration_lock(); + +#endif /*_APPL_FPGA_H*/ diff --git a/sw/app/lx_dad/appl_loop.c b/sw/app/lx_dad/appl_loop.c new file mode 100644 index 0000000..95f5cad --- /dev/null +++ b/sw/app/lx_dad/appl_loop.c @@ -0,0 +1,134 @@ +#include +#include +#include + +#include + +#include "appl_defs.h" + +int app_exit_request; + +int timer_led_usbact_off; +int timer_led_usbconfigured; +int timer_str; + +void timer_10ms(void) +{ + #ifndef APPL_WITH_SIM_POSIX + if (timer_led_usbact_off!=0) timer_led_usbact_off--; + else SET_OUT_PIN(LED_PORT,LED2_BIT); + #ifdef APPL_WITH_ULAN + if (!timer_str) { + timer_str=10; + ul_stroke(ul_fd); + } else timer_str--; + #endif /*APPL_WITH_ULAN*/ + if (timer_led_usbconfigured!=0) timer_led_usbconfigured--; + else { + timer_led_usbconfigured=20; + if (1 /*!ul_dcnv_is_open(&ep1_dcnv_state)*/) { + if(GET_IN_PIN(LED_PORT,LED1_BIT)) + CLR_OUT_PIN(LED_PORT,LED1_BIT); + else + SET_OUT_PIN(LED_PORT,LED1_BIT); + } + } + #endif /*APPL_WITH_SIM_POSIX*/ +} + + +void mloop() +{ + lt_mstime_t ltime; + + lt_mstime_t led1_time; + lt_mstime_t led2_time; + + lt_mstime_update(); + ltime=actual_msec; + led1_time=actual_msec; + led2_time=actual_msec; + + while(!app_exit_request){ + + /* 10ms timer */ + if (lt_10msec_expired(10)) { + timer_10ms(); + + #ifdef CONFIG_OC_MWENGINE + appl_update_indicators(); + #endif /*CONFIG_OC_MWENGINE*/ + + #ifdef WATCHDOG_ENABLED + watchdog_feed(); + #endif /* WATCHDOG_ENABLED */ + } + + #ifdef APPL_WITH_ULAN + if (ul_inepoll(ul_fd)>0) { + int free_fl = 0; + do { + /* processing of ulan messages */ + if (ul_acceptmsg(ul_fd, &umsginfo)<0) + break; /* No mesage reported - break */ + free_fl = 1; + if (umsginfo.flg&(UL_BFL_PROC|UL_BFL_FAIL)) + break; /* Reported message informs about fault or carried out processing */ + + if(umsginfo.cmd==uloi_con_ulan_cmd(coninfo)){ + if (uloi_process_msg(ULOI_ARG_coninfo (uloi_objdes_array_t*)&uloi_objdes_main, &umsginfo)>=0) + free_fl = 0; + break; + } + #ifdef CONFIG_ULAN_DY + if (umsginfo.cmd==UL_CMD_NCS) { + if(uldy_process_msg(ULDY_ARG_ul_dyac &umsginfo)>=0) + free_fl = 0; + break; + } + #endif /*CONFIG_ULAN_DY*/ + + } while(0); + + if (free_fl) + ul_freemsg(ul_fd); + } + #ifdef CONFIG_ULAN_DY + /* test request for address */ + if (uldy_rqa(ULDY_ARG1_ul_dyac)) + uldy_addr_rq(ULDY_ARG1_ul_dyac); + #endif /*CONFIG_ULAN_DY*/ + #endif /*APPL_WITH_ULAN*/ + + lt_mstime_update(); + if((lt_msdiff_t)(actual_msec-ltime) > 5000){ + ltime+=5000; + + } + + #ifdef APPL_RUN_AT_MAIN_LOOP + APPL_RUN_AT_MAIN_LOOP; + #endif /*APPL_RUN_AT_MAIN_LOOP*/ + + #ifdef CONFIG_OC_MWENGINE + gui_poll(); + #endif /*CONFIG_OC_MWENGINE*/ + + #ifdef APPL_WITH_USB + if(usb_enable_flag) { + if(usb_app_poll()>0) { + timer_led_usbact_off=5; + CLR_OUT_PIN(LED_PORT,LED2_BIT); + } + } + #endif /*APPL_WITH_USB*/ + + #ifdef CONFIG_OC_CMDPROC + cmdproc_poll(); + #endif /*CONFIG_OC_CMDPROC*/ + + #ifdef APPL_WITH_DISTORE_EEPROM_USER + appl_distore_user_change_check(); + #endif /*APPL_WITH_DISTORE_EEPROM_USER*/ + } +} diff --git a/sw/app/lx_dad/appl_main.c b/sw/app/lx_dad/appl_main.c new file mode 100644 index 0000000..27bf41c --- /dev/null +++ b/sw/app/lx_dad/appl_main.c @@ -0,0 +1,471 @@ +#include +#include +#include +#include + +#include "appl_defs.h" +#include "appl_version.h" +#include "appl_fpga.h" + +#ifdef CONFIG_KEYVAL +#include +#include +#include +#include +#include + +#endif /*CONFIG_KEYVAL*/ + +#ifdef CONFIG_OC_I2C_DRV_SYSLESS +#include +extern i2c_drv_t i2c_drv; +#endif + +#ifdef CONFIG_OC_SPI_DRV_SYSLESS +#include +#endif + +#include +#include + +#if defined(APPL_WITH_SUITK) && defined(OMK_FOR_TARGET) +#define UL_LOG_TO_STDOUT +extern FILE *ul_log_default_file; +#endif + +/***********************************/ +// global variables +#ifdef CONFIG_KEYVAL +kvpb_block_t kvpb_block_global; +kvpb_block_t *kvpb_block=&kvpb_block_global; +#endif /*CONFIG_KEYVAL*/ + +#ifdef APPL_WITH_ULAN +uloi_con_ulan_t uloi_con_ulan_global; +uloi_coninfo_t *coninfo=&uloi_con_ulan_global.con; + +#ifdef CONFIG_ULAN_DY +UL_DYAC_VAR_LOC ul_dyac_t ul_dyac_global; +ul_dyac_t *ul_dyac=&ul_dyac_global; +char ul_dyac_gst_reply[4+2]; +#endif /*CONFIG_ULAN_DY*/ + +/* ulan variables */ +ul_fd_t ul_fd,ul_fd1; +ul_msginfo umsginfo; +uint8_t uaddr=3; + +#ifdef APPL_WITH_UL_FD4TIMEPROG +ul_fd_t ul_fd4timeprog; +#endif +#endif /*APPL_WITH_ULAN*/ + +uint32_t usn; /* uLAN/USB device serial number */ + +int usb_enable_flag=1; + +LT_TIMER_IMP(lt_10msec) + +/***********************************/ +/* alternative memory reservation for framebuffer and uLan*/ +#ifndef APPL_WITH_SIM_POSIX +void *(* const gr_driver_reserve_ram)(size_t size) = + lpc_reserve_usb_ram; + +void *(* const ul_drv_reserve_ram)(size_t size) = + lpc_reserve_usb_ram; + +void *(* const timeprog_reserve_ram)(size_t size) = + lpc_reserve_usb_ram; + +void *(* const appl_distore_reserve_ram)(size_t size) = + lpc_reserve_usb_ram; +#endif /*APPL_WITH_SIM_POSIX*/ + +/***********************************/ +int sys_err() +{ + printf("System error at %p\n", __builtin_return_address(0)); + while(1); +} + +/***********************************/ +char ul_save_sn(uint32_t usn) +{ + #ifdef CONFIG_KEYVAL + kvpb_set_key(kvpb_block,KVPB_KEYID_ULAN_SN,4,&usn); + #endif /*CONFIG_KEYVAL*/ + return 0; +} + +/***********************************/ +char ul_save_adr(uint8_t uaddr) +{ + #ifdef CONFIG_KEYVAL + kvpb_set_key(kvpb_block,KVPB_KEYID_ULAN_ADDR,1,&uaddr); + #endif /*CONFIG_KEYVAL*/ + return 0; +} + +void save_cfg() +{ + // kvpb_set_key(kvpb_block,KVPB_KEYID_APPL_PARAM,sizeof(appl_param_t),&appl_param); +} + +/***********************************/ +#ifdef CONFIG_OC_SPI_DRV_SYSLESS +// received data bits 28..31 KBD variant (1) +// bits 1..25 keys +// bit 0 sticky 1 +// send data bits 12..15 LED indicators +// bits 0.. 7 LED indicators +// bit 10 backlight full +// bit 11 backlight medium +// bit 8 beep on (0) +// bit 9 tone freq select +// LEDs RUN 0, HOLD 1, PURGE 2, ERROR 3, A 5, B 6, C 7 +// D 12, MOTOR 14 +// Keys '1'-'9' 1-9, '.' 10, '0' 11, ENTER 12, STOP 13, START 14, +// down 15, right 16, up 17, lesft 18, ESC 19, P/M 20, +// D 21, C 22, B 23, A 24, MENU 25 +int check_spi_kbd_presence() +{ + int res; + uint8_t tx_buff[4] = {0x00, 0x00, 0x09, 0x55}; + uint8_t rx_buff[4]; + spi_drv_t *spi_drv = spi_find_drv(NULL, 0); + + if(spi_drv == NULL) + return -1; + + res = spi_transfer_with_mode(spi_drv, 4, 4, tx_buff, rx_buff, SPI_MODE_3); + if(res < 0) + return -1; + + printf("kbd_presence %02x %02x %02x %02x\n", + rx_buff[0], rx_buff[1], rx_buff[2], rx_buff[3]); + + return 0; +} +#endif /*CONFIG_OC_SPI_DRV_SYSLESS*/ + +/***********************************/ + +#ifndef APPL_WITH_SIM_POSIX +#include +int appl_adc_init() +{ + hal_pin_conf(ADC0_PIN); + hal_pin_conf(ADC1_PIN); + hal_pin_conf(ADC2_PIN); + hal_pin_conf(ADC3_PIN); + hal_pin_conf(ADC7_PIN); + + LPC_SC->PCONP |= (1 << 12); /*PCADC*/ + + LPC_ADC->CR = (1 << 21); /*PDN*/ + + LPC_ADC->CR |= 0x8F; /*SEL selsect channels 0 to 3 and 7*/ + LPC_ADC->CR |= (9 << 8); /*CLKDIV*/ + LPC_ADC->CR |= (1 << 16); /*BURST start burst mode*/ + + return 0; +} +#endif /*APPL_WITH_SIM_POSIX*/ + +/***********************************/ + +#if !defined(APPL_WITH_SIM_POSIX) && \ + defined(APPL_RUN_AT_FAST_SFI) +extern void (*timer0_isr_appl_call)(void); + +#ifdef APPL_RUN_AT_SLOW_SFI +long appl_run_fast_sfi_usec=1000000/SYS_TIMER_HZ; +long appl_run_slow_sfi_usec=APPL_SLOW_SFI_USEC; +long appl_run_fast2slow_sfi_accum; +#endif /*APPL_RUN_AT_SLOW_SFI*/ + +void appl_run_at_fast_sfi(void) +{ + APPL_RUN_AT_FAST_SFI; + #if defined(SLOW_SFI_INVOKE_IRQn) && defined(APPL_RUN_AT_SLOW_SFI) + { + appl_run_fast2slow_sfi_accum+=appl_run_fast_sfi_usec; + if(appl_run_fast2slow_sfi_accum>=appl_run_slow_sfi_usec) { + appl_run_fast2slow_sfi_accum-=appl_run_slow_sfi_usec; + NVIC->STIR=SLOW_SFI_INVOKE_IRQn; + } + } + #endif /*SLOW_SFI_INVOKE_IRQn*/ +} + +int appl_run_at_fast_sfi_setup(void) +{ + timer0_isr_appl_call=appl_run_at_fast_sfi; + return 0; +} + +#else /*APPL_WITH_SIM_POSIX APPL_RUN_AT_FAST_SFI */ +int appl_run_at_fast_sfi_setup(void) +{ + return 0; +} +#endif /*APPL_WITH_SIM_POSIX APPL_RUN_AT_FAST_SFI */ + +/***********************************/ + +#if !defined(APPL_WITH_SIM_POSIX) && \ + defined(APPL_RUN_AT_SLOW_SFI) + +IRQ_HANDLER_FNC(appl_run_at_slow_sfi_isr) +{ + APPL_RUN_AT_SLOW_SFI; +} + +int appl_run_at_slow_sfi_setup(void) +{ + if(request_irq(SLOW_SFI_INVOKE_IRQn, appl_run_at_slow_sfi_isr, + 0, "slow_sfi", NULL) < 0) + return -1; + return 0; +} +#else /* APPL_WITH_SIM_POSIX APPL_RUN_AT_SLOW_SFI */ + +int appl_run_at_slow_sfi_setup(void) +{ + return 0; +} + +#endif /* APPL_WITH_SIM_POSIX APPL_RUN_AT_SLOW_SFI */ + +/***********************************/ + +/* +UL_LOG_CUST(ulogd_main) +*/ + +#define UL_LOGL_DEF UL_LOGL_MSG + +#include "log_domains.inc" + +static void register_logdomains(void) +{ + ul_logreg_domains_static(ul_log_domains_array, sizeof(ul_log_domains_array)/sizeof(ul_log_domains_array[0])); +} + + +/***********************************/ +int main() +{ + int i; + + #ifndef APPL_WITH_SIM_POSIX + /* Setup default interrupt priority into middle of the range */ + for(i=0;iIP);i++) + NVIC->IP[i]=0x80; + + #ifdef SLOW_SFI_INVOKE_IRQn + /* The lowes priority to IRQ invoking slow activities */ + NVIC->IP[SLOW_SFI_INVOKE_IRQn]=0xc0; + #endif + + /* Higher priority for SPI to gradient valves */ + NVIC->IP[SSP1_IRQn]=0x40; + + /* Start of the cam period */ + NVIC->IP[MCPWM_IRQn]=0x20; + + /* The most critical - position compare events */ + NVIC->IP[QEI_IRQn]=0x00; + #endif /*APPL_WITH_SIM_POSIX*/ + + /* + unsigned long bb_val; + bbconf_get_param(BBCONF_PTTAG_BBVER, &bb_val); + */ + #ifdef UL_LOG_TO_STDOUT + ul_log_default_file = stdout; + #endif + register_logdomains(); + + printf(APP_VER_ID " initializing\n"); + + #ifdef SDRAM_BASE + if (((void*)main >= (void*)SDRAM_BASE) && + ((void*)main <= (void*)(SDRAM_BASE + SDRAM_SIZE))) + printf("running from SDRAM\n"); + #endif /*SDRAM_BASE*/ + + #ifdef CONFIG_KEYVAL + /***********************************/ + // kvpb init + kvpb_block->base=(uint8_t*)KEYVAL_START; + kvpb_block->size=KEYVAL_PAGE_LEN; + kvpb_block->flags=KVPB_DESC_DOUBLE|KVPB_DESC_CHUNKWO; + kvpb_block->chunk_size=KVPB_CHUNK_SIZE; + kvpb_block->erase=lpcisp_kvpb_erase; + kvpb_block->copy=lpcisp_kvpb_copy; + kvpb_block->flush=lpcisp_kvpb_flush; + if (kvpb_check(kvpb_block,1)<0) sys_err(); + if (kvpb_check(kvpb_block,1)<0) sys_err(); + printf("Keyval ready\n"); + + /***********************************/ + // set configuration for device + #ifdef APPL_WITH_ULAN + kvpb_get_key(kvpb_block,KVPB_KEYID_ULAN_ADDR,1,&uaddr); + kvpb_get_key(kvpb_block,KVPB_KEYID_ULAN_SN,4,&usn); + #endif /*APPL_WITH_ULAN*/ + +// kvpb_get_key(kvpb_block,KVPB_KEYID_APPL_PARAM,sizeof(appl_param_t),&appl_param); + + printf("Keyval variables read\n"); + #endif /*CONFIG_KEYVAL*/ + + /***********************************/ + // timers + lt_10msec_init(); + + #ifdef APPL_WITH_ULAN + /***********************************/ + // ulan init + // uld_printk_flush(); + ul_fd=ul_open(NULL,NULL); + if (ul_fd==UL_FD_INVALID) sys_err(); + ul_fd1=ul_open(NULL,NULL); + if (ul_fd1==UL_FD_INVALID) sys_err(); + ul_setidstr(ul_fd,ul_idstr); + #ifdef APPL_WITH_UL_FD4TIMEPROG + ul_fd4timeprog=ul_open(NULL,NULL); + if (ul_fd4timeprog==UL_FD_INVALID) sys_err(); + #endif /*APPL_WITH_UL_FD4TIMEPROG*/ + + printf("uLAN open\n"); + + ul_setmyadr(ul_fd,uaddr); + printf("Setting address %d\n",uaddr); + + //umsginfo.sadr=0; + //umsginfo.dadr=0; + //umsginfo.cmd=0; + //ul_addfilt(ul_fd,&umsginfo); + + #ifndef APPL_WITH_SIM_POSIX + ul_stroke(ul_fd); + #endif /*APPL_WITH_SIM_POSIX*/ + + umsginfo.dadr=2; + umsginfo.cmd=5; + umsginfo.flg=UL_BFL_SND; + //ul_newmsg(ul_fd,&umsginfo); + //ul_freemsg(ul_fd); + + /***********************************/ + #ifdef CONFIG_ULAN_DY + // uLan dyac init + uldy_init(ul_dyac, ul_fd, ul_save_sn,ul_save_adr,(char*)ul_idstr,usn); + + memset(&umsginfo, 0, sizeof(umsginfo)); + umsginfo.cmd=UL_CMD_NCS; + ul_addfilt(ul_fd, &umsginfo); + + ul_opdata_add_iac(ul_fd,UL_CMD_GST,UL_IAC_OP_SND,ul_iac_call_gst,ul_dyac_gst_reply,sizeof(ul_dyac_gst_reply),0,ul_dyac); + + printf("uLAN dynamic adressing initialized\n"); + #endif /*CONFIG_ULAN_DY*/ + + /***********************************/ + // uLan object interface init + uloi_con_ulan_set_cmd_fd(coninfo, UL_CMD_OISV, ul_fd, ul_fd1); + + memset(&umsginfo, 0, sizeof(umsginfo)); + umsginfo.cmd=UL_CMD_OISV; + ul_addfilt(uloi_con_ulan_rdfd(coninfo), &umsginfo); + #endif /*APPL_WITH_ULAN*/ + /***********************************/ + // DINFO and other persistent data + #ifdef APPL_WITH_DISTORE_EEPROM_USER + appl_distore_init(); + #endif /* APPL_WITH_DISTORE_EEPROM_USER */ + + /***********************************/ + // Micro Windows GUI + + #ifdef CONFIG_OC_MWENGINE + #ifdef CONFIG_OC_SPI_DRV_SYSLESS + check_spi_kbd_presence(); + #endif /*CONFIG_OC_SPI_DRV_SYSLESS*/ + i=gui_init(); + printf("gui_init ret %d\n", i); + #endif /*CONFIG_OC_MWENGINE*/ + + /***********************************/ + // USB initialization + + #ifdef APPL_WITH_USB + usb_app_fill_serial_number(usn); + if(usb_enable_flag) { + usb_app_init(); + printf("usb_app_init\n"); + } + #endif /*APPL_WITH_USB*/ + + /***********************************/ + // LCP engine initialization + + #ifndef APPL_WITH_SIM_POSIX + appl_adc_init(); + #ifdef APPL_WITH_AUX_IO + aux_io_init(); + #endif /*APPL_WITH_AUX_IO*/ + #endif /*APPL_WITH_SIM_POSIX*/ + + #ifdef APPL_WITH_FPGA + /* Init FPGA */ + fpga_init(); + #endif /*APPL_WITH_FPGA*/ + + #ifdef CONFIG_PXMC + i=pxmc_initialize(); + printf("pxmc_initialize ret %d\n", i); + #endif /*CONFIG_PXMC*/ + + #ifdef APPL_WITH_DISTORE_KEYVAL_SERVICE + setup_distore_restore(); + #endif /*APPL_WITH_DISTORE_KEYVAL_SERVICE*/ + + #ifdef APPL_WITH_DISTORE_EEPROM_USER + appl_distore_user_restore(); + #endif /* APPL_WITH_DISTORE_EEPROM_USER */ + + #ifdef APPL_WITH_TIMEPROG_EEPROM_STORE + appl_timeprog_eeprom_restore(); + #endif /*APPL_WITH_TIMEPROG_EEPROM_STORE*/ + + appl_run_at_slow_sfi_setup(); + appl_run_at_fast_sfi_setup(); + + #ifdef APPL_WITH_AUX_IO + aux_out_set_init_val(); + #endif /*APPL_WITH_AUX_IO*/ + + #ifdef APPL_RUN_AT_INIT + APPL_RUN_AT_INIT; + #endif /*APPL_RUN_AT_INIT*/ + + /***********************************/ + // Main application loop + mloop(); + + /***********************************/ + // Greace finalization of application to check memory leakage + #ifdef APPL_WITH_FINALIZATION_CHECK + + #ifdef CONFIG_OC_MWENGINE + gui_done(); + #endif /*CONFIG_OC_MWENGINE*/ + + #endif /*APPL_WITH_FINALIZATION_CHECK*/ + return 0; +} + diff --git a/sw/app/lx_dad/appl_sim_posix.c b/sw/app/lx_dad/appl_sim_posix.c new file mode 100644 index 0000000..fd6a082 --- /dev/null +++ b/sw/app/lx_dad/appl_sim_posix.c @@ -0,0 +1,36 @@ +#include +#include + +int uart0Getch(void) +{ + return -1; +} + +int uart0PutchNW(int ch) +{ + putchar(ch); + return (unsigned char)ch; +} + +cmd_des_t const *cmd_appl_tests[]={ + NULL +}; + +int appl_distore_init(void) +{ + return 0; +} +int appl_distore_user_set_check4change(void) +{ + return 0; +} + +int appl_distore_user_restore(void) +{ + return 0; +} + +int appl_distore_user_change_check(void) +{ + return 0; +} diff --git a/sw/app/lx_dad/appl_tests.c b/sw/app/lx_dad/appl_tests.c new file mode 100644 index 0000000..253dc60 --- /dev/null +++ b/sw/app/lx_dad/appl_tests.c @@ -0,0 +1,329 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "appl_defs.h" + +int cmd_do_test_memusage(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[]) +{ + void *maxaddr; + char str[40]; + + maxaddr = sbrk(0); + + snprintf(str,sizeof(str),"memusage maxaddr 0x%08lx\n",(unsigned long)maxaddr); + cmd_io_write(cmd_io,str,strlen(str)); + + return 0; +} + +int cmd_do_test_adc(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[]) +{ + printf("ADC: %ld %ld %ld %ld %ld\n",(LPC_ADC->DR[0] & 0xFFF0)>>4, + (LPC_ADC->DR[1] & 0xFFF0)>>4, + (LPC_ADC->DR[2] & 0xFFF0)>>4, + (LPC_ADC->DR[3] & 0xFFF0)>>4, + (LPC_ADC->DR[7] & 0xFFF0)>>4); + return 0; +} + +#ifdef APPL_WITH_DISTORE_EEPROM_USER +int cmd_do_test_distore(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[]) +{ + appl_distore_user_set_check4change(); + return 0; +} + +int cmd_do_test_diload(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[]) +{ + appl_distore_user_restore(); + return 0; +} +#endif /*APPL_WITH_DISTORE_EEPROM_USER*/ + +int cmd_do_test_loglevel_cb(ul_log_domain_t *domain, void *context) +{ + char s[30]; + cmd_io_t *cmd_io = (cmd_io_t *)context; + + s[sizeof(s)-1]=0; + snprintf(s,sizeof(s)-1,"%s (%d)\n\r",domain->name, domain->level); + cmd_io_puts(cmd_io, s); + return 0; +} + +int cmd_do_test_loglevel(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[]) +{ + int res=0; + char *line; + line = param[1]; + + if(!line||(si_skspace(&line),!*line)) { + ul_logreg_for_each_domain(cmd_do_test_loglevel_cb, cmd_io); + } else { + res=ul_log_domain_arg2levels(line); + } + + return res>=0?0:CMDERR_BADPAR; +} + +int cmd_do_spimst_blocking(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[]) +{ + int res; + int opchar; + char *p=param[3]; + int spi_chan = (int)(intptr_t)des->info[0]; + uint8_t *tx_buff = NULL; + uint8_t *rx_buff = NULL; + long addr = 0; + int len = 0; + spi_drv_t *spi_drv; + + if((opchar=cmd_opchar_check(cmd_io,des,param))<0) return opchar; + if(opchar!=':') + return -CMDERR_OPCHAR; + + if(spi_chan==-1) + spi_chan=*param[1]-'0'; + + spi_drv = spi_find_drv(NULL, spi_chan); + if(spi_drv==NULL) + return -CMDERR_BADSUF; + + p=param[3]; + + si_skspace(&p); + if(isdigit((int)*p)){ + if(si_long(&p,&addr,16)<0) return -CMDERR_BADPAR; + } + if(si_fndsep(&p,"({")<0) return -CMDERR_BADSEP; + + if((res=si_add_to_arr(&p, (void**)&tx_buff, &len, 16, 1, "})"))<0) + return -CMDERR_BADPAR; + + rx_buff=malloc(len); + + res=-1; + if(rx_buff!=NULL) + res = spi_transfer_with_mode(spi_drv, addr, len, tx_buff, rx_buff, SPI_MODE_3); + + if(res < 0) { + printf("SPI! %02lX ERROR\n",addr); + } else { + int i; + printf("SPI! %02lX ",addr); + printf("TX("); + for(i=0;iRNR = i; + ra = MPU->RBAR & MPU_RBAR_ADDR_Msk; + rsz = (1 << (__mfld2val(MPU_RASR_SIZE_Msk, MPU->RASR) + 1)) - 1; + printf("R%d %08lX..%08lX %08lX %08lX\n", i, ra, ra + rsz, MPU->RBAR, MPU->RASR); + } + + /*printf("IAP version %08X\n", lpcisp_read_partid());*/ + + return 0; +} + +int cmd_do_goaddr(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[]) +{ + char *p; + long addr; + + p = param[1]; + + si_skspace(&p); + if(si_ulong(&p,&addr,16)<0) return -CMDERR_BADPAR; + + printf("Jump to address %08lX\n\n", addr); + + ((void(*)(void))addr)(); + + return 0; +} + +cmd_des_t const cmd_des_test_memusage={0, 0, + "memusage","report memory usage",cmd_do_test_memusage, + {0, + 0}}; + +cmd_des_t const cmd_des_test_adc={0, 0, + "testadc","adc test",cmd_do_test_adc, + {0, + 0}}; + +#ifdef APPL_WITH_DISTORE_EEPROM_USER +cmd_des_t const cmd_des_test_distore={0, 0, + "testdistore","test DINFO store",cmd_do_test_distore, + {0, + 0}}; + +cmd_des_t const cmd_des_test_diload={0, 0, + "testdiload","test DINFO load",cmd_do_test_diload, + {0, + 0}}; +#endif /*APPL_WITH_DISTORE_EEPROM_USER*/ + +cmd_des_t const cmd_des_test_loglevel={0, 0, + "loglevel","select logging level", + cmd_do_test_loglevel,{}}; + +cmd_des_t const cmd_des_spimst={0, CDESM_OPCHR|CDESM_WR, + "SPIMST","SPI master communication request", + cmd_do_spimst_blocking,{(void*)0}}; + +cmd_des_t const cmd_des_spimstx={0, CDESM_OPCHR|CDESM_WR, + "SPIMST#","SPI# master communication request", + cmd_do_spimst_blocking,{(void*)-1}}; + +cmd_des_t const cmd_des_testsdram={0, 0, + "testsdram","test SDRAM", + cmd_do_testsdram,{(void*)0}}; + +cmd_des_t const cmd_des_testmpu={0, 0, + "testmpu","test MPU", + cmd_do_testmpu,{(void*)0}}; + +cmd_des_t const cmd_des_goaddr={0, 0, + "goaddr","run from address", + cmd_do_goaddr,{(void*)0}}; + +cmd_des_t const *const cmd_appl_tests[]={ + &cmd_des_test_memusage, + &cmd_des_test_adc, + #ifdef APPL_WITH_DISTORE_EEPROM_USER + &cmd_des_test_distore, + &cmd_des_test_diload, + #endif /*APPL_WITH_DISTORE_EEPROM_USER*/ + &cmd_des_test_loglevel, + &cmd_des_spimst, + &cmd_des_spimstx, + &cmd_des_testsdram, + &cmd_des_testmpu, + &cmd_des_goaddr, + NULL +}; diff --git a/sw/app/lx_dad/appl_usb.c b/sw/app/lx_dad/appl_usb.c new file mode 100644 index 0000000..7b2bf9a --- /dev/null +++ b/sw/app/lx_dad/appl_usb.c @@ -0,0 +1,471 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "appl_defs.h" +#include "usb/usb_defs.h" + +#ifdef APPL_WITH_FPGA +#include "appl_fpga.h" +#endif /*APPL_WITH_FPGA*/ + +#ifdef CONFIG_KEYVAL +#include +#include +#include +#include +#endif /*CONFIG_KEYVAL*/ + +#include +#if __BYTE_ORDER == __BIG_ENDIAN +#include +#define SWAP(x) ((((x) & 0xFF) << 8) | (((x) >> 8) & 0xFF)) +#else /*__LITTLE_ENDIAN*/ +#define SWAP(x) (x) +#endif + +#define USB_VENDOR_TARGET_32BIT 0x04 + +#define USB_CMD_FPGA_CONFIGURE 0xF000 +#define USB_CMD_FPGA_MEASURE_READ 0xF001 +#define USB_CMD_FPGA_MEASURE_WRITE 0xF002 + +#define USB_CMD_FPGA_RESET 0xFFFF + +usb_device_t usb_device; +usb_ep_t eps[NUM_ENDPOINTS]; + +#define MASK_EP1RX 0x01 +#define MASK_EP1TX 0x02 + +unsigned char ep1_rx_buff[USB_MAX_PACKET] __attribute__ ((aligned (8))); +unsigned char ep1_tx_buff[USB_MAX_PACKET] __attribute__ ((aligned (8))); +unsigned char ep0_buffer[USB_MAX_PACKET0] __attribute__ ((aligned (8))); +int usb_active = 0; +int ep1_rx_index = 0, ep1_rx_ready = 1; +int ep1_tx_index = 0, ep1_tx_chars = 0; + +#ifdef CONFIG_OC_CMDPROC + +cmd_io_t cmd_io_usbcon_dev; + +#define ED_LINE_CHARS 512 + +char ed_line_chars_usbcon_in[ED_LINE_CHARS + 1]; +char ed_line_chars_usbcon_out[ED_LINE_CHARS + 1]; + +ed_line_buf_t ed_line_buf_usbcon_in = +{ +flg: + FL_ELB_ECHO, + inbuf: 0, +alloc: + sizeof(ed_line_chars_usbcon_in), + maxlen: 0, + lastch: 0, +buf: + ed_line_chars_usbcon_in +}; + +ed_line_buf_t ed_line_buf_usbcon_out = +{ +flg: + FL_ELB_NOCRLF, + inbuf: 0, +alloc: + sizeof(ed_line_chars_usbcon_out), + maxlen: 0, + lastch: 0, +buf: + ed_line_chars_usbcon_out +}; + +cmd_io_t cmd_io_usbcon = +{ +putc: + cmd_io_line_putc, +getc: + NULL, +write: + cmd_io_write_bychar, +read: + NULL, +priv: + { + ed_line: + { + in: + &ed_line_buf_usbcon_in, + out: + &ed_line_buf_usbcon_out, + io_stack: + &cmd_io_usbcon_dev + } + } +}; + +#endif + +static int usb_flash_pkt_wr(struct usb_ep_t *ep, int len, int code) +{ + unsigned char *ptr = ep->ptr - len; + +#ifdef CONFIG_KEYVAL + lpcisp_kvpb_copy(NULL, (void *)ep->user_data, ptr, len); +#endif /*CONFIG_KEYVAL*/ + + ep->user_data += len; + ep->ptr = ep0_buffer; + return USB_COMPLETE_OK; +} + +static int usb_32bit_pkt_wr(struct usb_ep_t *ep, int len, int code) +{ + uint32_t *srcptr = (uint32_t *)(ep->ptr - len); + volatile uint32_t *dstptr = (uint32_t *)ep->user_data; + int pos; + + for (pos = 0; len - pos >= 4; pos += 4, dstptr++, srcptr++) + *dstptr = *srcptr; + + ep->user_data += len; + ep->ptr = ep0_buffer; + return USB_COMPLETE_OK; +} + +int usb_32bit_pkt_rd(struct usb_ep_t *ep, int len, int code) +{ + volatile uint32_t *srcptr; + uint32_t *dstptr; + int pos; + + ep->ptr = ep0_buffer; + dstptr = (uint32_t *)ep->ptr; + srcptr = (uint32_t *)ep->user_data; + + for (pos = 0; len - pos >= 4; pos += 4, dstptr++, srcptr++) + *dstptr = *srcptr; + + ep->user_data += len; + return USB_COMPLETE_OK; +} + +static int usb_flash_erase(unsigned addr, unsigned len) +{ +#ifdef CONFIG_KEYVAL + lpcisp_erase((void *)addr, len); +#endif /*CONFIG_KEYVAL*/ + return 0; +} + +static void usb_goto(unsigned address) +{ +#ifdef CONFIG_KEYVAL + lpc_watchdog_init(1, 10); + lpc_watchdog_feed(); + + while (1) + {} + +#endif /*CONFIG_KEYVAL*/ +} + +/* Not re-entrant */ +uint16_t vendor_call_ret = 0xFFFF; + +uint16_t appl_usb_vendor_call(uint16_t command, uint16_t argument) +{ + int i; + + switch (command) + { + #ifdef APPL_WITH_FPGA + case USB_CMD_FPGA_CONFIGURE: + return fpga_configure(); + + case USB_CMD_FPGA_MEASURE_READ: + return fpga_measure_bus_read(); + + case USB_CMD_FPGA_MEASURE_WRITE: + return fpga_measure_bus_write(); + + case USB_CMD_FPGA_RESET: + hal_gpio_direction_output(XC_INIT_PIN, 0); + + for (i = 0; i < 128; i++) + {} + + hal_gpio_direction_output(XC_INIT_PIN, 1); + #endif /*APPL_WITH_FPGA*/ + return 0; + } + + return 0xFFFF; +} + +int appl_usb_vendor(usb_device_t *udev) +{ + unsigned long addr; + unsigned len; + USB_DEVICE_REQUEST *dreq; + + usb_active = 1; + dreq = &udev->request; + +#ifdef CONFIG_KEYVAL + + if (dreq->bRequest != (USB_VENDOR_GET_SET_MEMORY | + USB_DATA_DIR_FROM_HOST | USB_VENDOR_TARGET_FLASH)) + lpcisp_kvpb_flush(NULL); + +#endif /*CONFIG_KEYVAL*/ + + switch (dreq->bRequest & USB_VENDOR_MASK) + { + case USB_VENDOR_GET_CAPABILITIES: + ep0_buffer[0] = 0xAA; // test + usb_send_control_data(udev, ep0_buffer, 1); + return 1; + + case USB_VENDOR_RESET_DEVICE: + usb_send_control_data(udev, NULL, 0); +#ifdef CONFIG_KEYVAL + lpc_watchdog_init(1, 10); + lpc_watchdog_feed(); + + while (1) + {} + +#endif /*CONFIG_KEYVAL*/ + return 1; + + case USB_VENDOR_GOTO: + usb_send_control_data(udev, NULL, 0); + usb_goto(dreq->wValue); + return 1; + + case USB_VENDOR_ERASE_MEMORY: + usb_send_control_data(udev, NULL, 0); + usb_flash_erase(dreq->wValue, dreq->wIndex); + return 1; + + case USB_VENDOR_ERASE_1KB_MEMORY: /* erase memory for 1 KB */ + usb_send_control_data(udev, NULL, 0); + usb_flash_erase((uint32_t)dreq->wValue << 10, dreq->wIndex << 10); + return 1; + + case USB_VENDOR_CALL: + vendor_call_ret = SWAP(appl_usb_vendor_call(dreq->wIndex, dreq->wValue)); + usb_send_control_data(udev, (unsigned char *) &vendor_call_ret, sizeof(uint16_t)); + return 1; + + case USB_VENDOR_GET_SET_MEMORY: + addr = (dreq->wValue & 0xffff) | (((unsigned long)dreq->wIndex & 0xffff) << 16); + len = dreq->wLength; + + if ((dreq->bmRequestType & USB_DATA_DIR_MASK) == USB_DATA_DIR_FROM_HOST) + { + switch (dreq->bRequest & USB_VENDOR_TARGET_MASK) + { + case USB_VENDOR_TARGET_RAM: + udev->ep0.ptr = (void *)addr; + break; + + case USB_VENDOR_TARGET_FLASH: + udev->ep0.next_pkt_fnc = usb_flash_pkt_wr; + udev->ep0.user_data = addr; + udev->ep0.ptr = ep0_buffer; + break; + + case USB_VENDOR_TARGET_32BIT: + udev->ep0.next_pkt_fnc = usb_32bit_pkt_wr; + udev->ep0.user_data = addr; + udev->ep0.ptr = ep0_buffer; + break; + + default: + return -1; + } + + if (len) + usb_set_control_endfnc(udev, usb_ack_setup); + else + usb_send_control_data(udev, NULL, 0); + + return 1; + } + else + { + switch (dreq->bRequest & USB_VENDOR_TARGET_MASK) + { + case USB_VENDOR_TARGET_RAM: + usb_send_control_data(udev, (void *)addr, len); + break; + + case USB_VENDOR_TARGET_32BIT: + udev->ep0.next_pkt_fnc = usb_32bit_pkt_rd; + udev->ep0.user_data=addr; + usb_send_control_data( udev, ep0_buffer, len); + break; + + default: + return -1; + } + + return 1; + } + + break; + } + + return 0; +} + +int usb_app_fill_serial_number(uint32_t ul_sn) +{ + char *p = usb_devdes_serial_number; + int len_max = sizeof(usb_devdes_serial_number); + char c; + + while ((len_max -= 2) >= 2) + { + p += 2; + c = ((ul_sn >> (32 - 4)) & 0xf) + '0'; + ul_sn <<= 4; + + if (c > '9') + c += 'A' - '9' - 1; + + *p = c; + } + + return 0; +} + +int usb_app_init(void) +{ + memset(&usb_device, 0, sizeof(usb_device)); + + eps[0].max_packet_size = USB_MAX_PACKET; + eps[1].max_packet_size = USB_MAX_PACKET; + eps[0].epnum = 0x81; + eps[1].epnum = 0x01; + eps[0].event_mask = 0x08; + eps[1].event_mask = 0x04; + eps[0].udev = &usb_device; + eps[1].udev = &usb_device; + + usb_device.id = 1; + usb_device.devdes_table = &usb_devdes_table; + usb_device.init = usb_lpc_init; + usb_debug_set_level(DEBUG_LEVEL_NONE); + usb_device.cntep = NUM_ENDPOINTS; + usb_device.ep = eps; + usb_device.vendor_fnc = appl_usb_vendor; + + usb_init(&usb_device); + usb_connect(&usb_device); + + return 0; +} + +int usb_check_ep1() +{ + if (usb_device.ep_events & MASK_EP1RX) + { + usb_device.ep_events &= ~MASK_EP1RX; + //TODO: Use some field in the structure, probably flags + ep1_rx_ready = 1; + } + + /* Respond if there is something to send and RX is ready */ + if (ep1_rx_ready && ep1_rx_index != 0) + { + usb_udev_write_endpoint(&eps[0], ep1_rx_buff, ep1_rx_index); + ep1_rx_index = 0; + ep1_rx_ready = 0; + hal_gpio_set_value(LED2_PIN, 0); + return 1; + } + + return 0; +} + +int usb_app_poll(void) +{ + int active = usb_active; + usb_active = 0; + + usb_check_events(&usb_device); + usb_control_response(&usb_device); + + /* Check TX endpoint */ + if (usb_device.ep_events & MASK_EP1TX) + { + ep1_tx_chars = usb_udev_read_endpoint(&eps[1], ep1_tx_buff, USB_MAX_PACKET); + ep1_tx_index = 0; + usb_device.ep_events &= ~MASK_EP1TX; + hal_gpio_set_value(LED2_PIN, 0); + usb_active = 1; + } + + /* Check RX endpoint */ + usb_active |= usb_check_ep1(); + + return active; +} + +int usb_app_stop(void) +{ + usb_disconnect(&usb_device); + return 0; +} + +#ifdef CONFIG_OC_CMDPROC + +int cmd_io_getc_usbcon(struct cmd_io *cmd_io) +{ + if (ep1_tx_index >= ep1_tx_chars) + return -1; + + return ep1_tx_buff[ep1_tx_index++]; +} + +int cmd_io_putc_usbcon(struct cmd_io *cmd_io, int ch) +{ + if (ep1_rx_index >= USB_MAX_PACKET) + { + /* Check EP1 status and return -1 if unavailable */ + usb_check_events(&usb_device); + usb_check_ep1(); + + /* Check again if it wasn't emptied */ + if (ep1_rx_index >= USB_MAX_PACKET) + return -1; + } + + ep1_rx_buff[ep1_rx_index++] = (unsigned char)ch; + return ch; +} + +cmd_io_t cmd_io_usbcon_dev = +{ + .putc = cmd_io_putc_usbcon, + .getc = cmd_io_getc_usbcon, + .write = cmd_io_write_bychar, + .read = cmd_io_read_bychar, + .priv.uart = { -1 } +}; + +#endif diff --git a/sw/app/lx_dad/appl_version.h b/sw/app/lx_dad/appl_version.h new file mode 100644 index 0000000..b36b647 --- /dev/null +++ b/sw/app/lx_dad/appl_version.h @@ -0,0 +1,17 @@ +#ifndef _APPL_VERSION_H +#define _APPL_VERSION_H + +#include "appl_defs.h" +#include "system_def.h" + +#ifndef ULAN_ID +#define ULAN_ID LX_DAD +#endif /*ULAN_ID*/ + +#define APP_VER_ID "LX_DAD" +#define APP_VER_MAJOR 0 +#define APP_VER_MINOR 1 +#define APP_VER_PATCH 0 +#define APP_VER_CODE VER_CODE(APP_VER_MAJOR,APP_VER_MINOR,APP_VER_PATCH) + +#endif /*_APPL_VERSION_H*/ diff --git a/sw/app/lx_dad/cmd_uartcon.c b/sw/app/lx_dad/cmd_uartcon.c new file mode 100644 index 0000000..4f38a06 --- /dev/null +++ b/sw/app/lx_dad/cmd_uartcon.c @@ -0,0 +1,109 @@ +/******************************************************************* + Components for embedded applications builded for + laboratory and medical instruments firmware + + cmd_uartcon.c - interconnection of text command processor + with RS-232 line + + Copyright (C) 2001 by Pavel Pisa pisa@cmp.felk.cvut.cz + (C) 2002 by PiKRON Ltd. http://www.pikron.com + + *******************************************************************/ + +#include +#include +#include +#include +#include + +#define ED_LINE_CHARS 512 + +cmd_io_t cmd_io_uartcon_dev; + +char ed_line_chars_uartcon_in[ED_LINE_CHARS + 1]; +char ed_line_chars_uartcon_out[ED_LINE_CHARS + 1]; + +ed_line_buf_t ed_line_buf_uartcon_in = +{ +flg: + FL_ELB_ECHO, + inbuf: 0, +alloc: + sizeof(ed_line_chars_uartcon_in), + maxlen: 0, + lastch: 0, +buf: + ed_line_chars_uartcon_in +}; + +ed_line_buf_t ed_line_buf_uartcon_out = +{ +flg: + FL_ELB_NOCRLF, + inbuf: 0, +alloc: + sizeof(ed_line_chars_uartcon_out), + maxlen: 0, + lastch: 0, +buf: + ed_line_chars_uartcon_out +}; + +cmd_io_t cmd_io_uartcon = +{ +putc: + cmd_io_line_putc, +getc: + NULL, +write: + cmd_io_write_bychar, +read: + NULL, +priv: + { + ed_line: + { + in: + &ed_line_buf_uartcon_in, + out: + &ed_line_buf_uartcon_out, + io_stack: + &cmd_io_uartcon_dev + } + } +}; + +int cmd_io_putc_uartcon(struct cmd_io *cmd_io, int ch) +{ + int uartch = cmd_io->priv.uart.uartch; + + ch = uart0PutchNW(ch); + + if (ch == -1) + return -1; + else + return ch; +} + +int cmd_io_getc_uartcon(struct cmd_io *cmd_io) +{ + int ch; + int uartch = cmd_io->priv.uart.uartch; + + ch = uart0Getch(); + + if (ch == -1) + return -1; + else + return ch; +} + +cmd_io_t cmd_io_uartcon_dev = +{ + .putc = cmd_io_putc_uartcon, + .getc = cmd_io_getc_uartcon, + .write = cmd_io_write_bychar, + .read = cmd_io_read_bychar, + .priv.uart = { -1} +}; + diff --git a/sw/app/lx_dad/distore_base.c b/sw/app/lx_dad/distore_base.c new file mode 100644 index 0000000..caf1070 --- /dev/null +++ b/sw/app/lx_dad/distore_base.c @@ -0,0 +1,438 @@ +#include +#include +#include +#include + +#define DISTORE_LONG_BIT (sizeof(long)*CHAR_BIT) + +#include "distore_simple.h" + +#include +UL_LOG_CUST(ulogd_distore) + +static int +distore_des_array_bsearch_indx (const distore_des_array_t * array, + const distore_id_t key) +{ + unsigned a, b, c; + int r; + if (!array->array.items || !array->array.count){ + return -1; + } + a = 0; + b = array->array.count; + while (1){ + c = (a + b) / 2; + r = array->array.items[c].id - key; + if (!r) + break; + if (r <= 0) + a = c + 1; + else + b = c; + if (a == b) { + return -a-1; + } + } + return c; +} + +const distore_des_item_t * +distore_des_array_at (const distore_des_array_t * array, unsigned indx) +{ + if (indx >= array->array.count) + return NULL; + return &array->array.items[indx]; +} + +const distore_des_item_t * +distore_des_array_find (const distore_des_array_t * array, distore_id_t const * key) +{ + int indx; + indx=distore_des_array_bsearch_indx (array, *key); + if (indx<0) + return NULL; + return &array->array.items[indx]; +} + +static ssize_t distore_encform_maxsize(unsigned int encform) +{ + unsigned int enccode; + + if(!((encform ^ DISTORE_ENC_TEXT_CODE) & ~DISTORE_ENC_TEXT_LEN)) + return (encform & DISTORE_ENC_TEXT_LEN) + 1; + + enccode = (encform & ~DISTORE_ENC_NUM_LEN); + + if((enccode == DISTORE_ENC_UNSIGNED_CODE) || + (enccode == DISTORE_ENC_SIGNED_CODE) || + (enccode == DISTORE_ENC_FLOAT_CODE)) + return encform & DISTORE_ENC_NUM_LEN; + + return -1; +} + +int distore_write_unsigned(distore_wrfnc_t *wrfnc, void *context, + unsigned long val, int len) +{ + unsigned char buf[DISTORE_ENC_NUM_LEN+1]; + if((len > 4) || (len > DISTORE_LONG_BIT / 8)) { + int i; + for(i = 0; i < len; i++) { + buf[i] = val & 0xff; + val >>= 8; + } + } else { + buf[0] = val; + buf[1] = val >> 8; + buf[2] = val >> 16; + buf[3] = val >> 24; + } + return (*wrfnc)(context, buf, len) >= 0? 0: -1; +} + +int distore_read_unsigned(distore_rdfnc_t *rdfnc, void *context, + unsigned long *pval, int len) +{ + unsigned long val; + unsigned char buf[DISTORE_ENC_NUM_LEN+1]; + + if ((*rdfnc)(context, buf, len)<0) + return -1; + + if(len * 8 != DISTORE_LONG_BIT) { + int i; + val = 0; + for(i = len; i --; ) { + val <<= 8; + val |= buf[i] & 0xff; + } + } else { + val = buf[0]; + val |= (unsigned)buf[1] << 8; + val |= (unsigned long)buf[2] << 16; + val |= (unsigned long)buf[3] << 24; + } + *pval = val; + return 0; +} + +int distore_write_signed(distore_wrfnc_t *wrfnc, void *context, + long val, int len) +{ + unsigned char buf[DISTORE_ENC_NUM_LEN+1]; + if((len > 4) || (len > DISTORE_LONG_BIT / 8)) { + int i; + for(i = 0; i < len; i++) { + buf[i] = val & 0xff; + val >>= 8; + } + } else { + buf[0] = val; + buf[1] = val >> 8; + buf[2] = val >> 16; + buf[3] = val >> 24; + } + return (*wrfnc)(context, buf, len) >= 0? 0: -1; +} + +int distore_read_signed(distore_rdfnc_t *rdfnc, void *context, + signed long *pval, int len) +{ + signed long val; + unsigned char buf[DISTORE_ENC_NUM_LEN+1]; + + if ((*rdfnc)(context, buf, len)<0) + return -1; + + if(len * 8 != DISTORE_LONG_BIT) { + int i; + val = 0; + if(len && (len * 8 < DISTORE_LONG_BIT) && (buf[len-1] & 0x80)) + val = -1; + for(i = len; i--; ) { + val <<= 8; + val |= buf[i] & 0xff; + } + } else { + val = buf[0]; + val |= (unsigned int)buf[1] << 8; + val |= (unsigned long)buf[2] << 16; + val |= (unsigned long)buf[3] << 24; + } + *pval = val; + return 0; +} + +int distore_write_float(distore_wrfnc_t *wrfnc, void *context, + float val, int len) +{ + unsigned char buf[sizeof(float)]; + if(len != sizeof(float)) + return -1; + /* More sophisticated solution could be used there in the future */ + memcpy(buf, &val, sizeof(float)); + return (*wrfnc)(context, buf, len) >= 0? 0: -1; +} + +int distore_read_float(distore_rdfnc_t *rdfnc, void *context, + float *pval, int len) +{ + float val; + unsigned char buf[DISTORE_ENC_NUM_LEN+1]; + if(len != sizeof(float)) + return -1; + if ((*rdfnc)(context, buf, len)<0) + return -1; + /* More sophisticated solution could be used there in the future */ + memcpy(&val, buf, sizeof(float)); + *pval = val; + return 0; +} + +int distore_write_dinfo(distore_wrfnc_t *wrfnc, void *context, + sui_dinfo_t *dinfo, long idx, unsigned int encform) +{ + unsigned int enccode; + int res = -1; + int len; + + if(!((encform ^ DISTORE_ENC_TEXT_CODE) & ~DISTORE_ENC_TEXT_LEN)) { + utf8 *val; + if(sui_rd_utf8(dinfo, idx, &val) != SUI_RET_OK) + return -1; + len = sui_utf8_bytesize(val); + if(len > (encform & DISTORE_ENC_TEXT_LEN)) + encform = DISTORE_ENC_TEXT_LEN; + if(distore_write_unsigned(wrfnc, context, len, 1) < 0) + goto error_utf8; + if((*wrfnc)(context, sui_utf8_get_text(val), len) < 0) + goto error_utf8; + res = 0; + error_utf8: + sui_utf8_dec_refcnt(val); + return res; + } + + enccode = encform >> DISTORE_ENC_NUM_LEN_BITS; + len = encform & DISTORE_ENC_NUM_LEN; + + switch(enccode) { + case DISTORE_ENC_UNSIGNED_CODE >> DISTORE_ENC_NUM_LEN_BITS: { + unsigned long val; + if(sui_rd_ulong(dinfo, idx, &val) != SUI_RET_OK) + return -1; + if(distore_write_unsigned(wrfnc, context, val, len) < 0) + return -1; + return 0; + } + case DISTORE_ENC_SIGNED_CODE >> DISTORE_ENC_NUM_LEN_BITS: { + long val; + if(sui_rd_long(dinfo, idx, &val) != SUI_RET_OK) + return -1; + if(distore_write_signed(wrfnc, context, val, len) < 0) + return -1; + return 0; + } + case DISTORE_ENC_FLOAT_CODE >> DISTORE_ENC_NUM_LEN_BITS: { + float val; + if (dinfo->rdval == NULL) + return -1; + if (dinfo->rdval(dinfo, idx, &val) != SUI_RET_OK) + return -1; + if(distore_write_float(wrfnc, context, val, len) < 0) + return -1; + return 0; + } + default: + return -1; + } +} + +int distore_read_dinfo(distore_rdfnc_t *rdfnc, void *context, + sui_dinfo_t *dinfo, long idx, unsigned int encform) +{ + unsigned int enccode; + int res = -2; + int len; + unsigned long u; + + if(!((encform ^ DISTORE_ENC_TEXT_CODE) & ~DISTORE_ENC_TEXT_LEN)) { + utf8 *val; + if(distore_read_unsigned(rdfnc, context, &u, 1) < 0) + return -2; + val = sui_utf8_dynamic(NULL, -1, u); + if(val == NULL) + return -2; + if((*rdfnc)(context, sui_utf8_get_text(val), u) < 0) + goto error_utf8; + res = -1; + if(dinfo) + if(sui_wr_utf8(dinfo, idx, &val) != SUI_RET_OK) + goto error_utf8; + res = 0; + error_utf8: + sui_utf8_dec_refcnt(val); + return res; + } + + enccode = encform >> DISTORE_ENC_NUM_LEN_BITS; + len = encform & DISTORE_ENC_NUM_LEN; + + switch(enccode) { + case DISTORE_ENC_UNSIGNED_CODE >> DISTORE_ENC_NUM_LEN_BITS: { + unsigned long val; + if(distore_read_unsigned(rdfnc, context, &val, len) < 0) + return -2; + if(dinfo) + if(sui_wr_ulong(dinfo, idx, &val) != SUI_RET_OK) + return -1; + return 0; + } + case DISTORE_ENC_SIGNED_CODE >> DISTORE_ENC_NUM_LEN_BITS: { + long val; + if(distore_read_signed(rdfnc, context, &val, len) < 0) + return -2; + if(dinfo) + if(sui_wr_long(dinfo, idx, &val) != SUI_RET_OK) + return -1; + return 0; + } + case DISTORE_ENC_FLOAT_CODE >> DISTORE_ENC_NUM_LEN_BITS: { + float val; + if(distore_read_float(rdfnc, context, &val, len) < 0) + return -2; + if (dinfo->wrval == NULL) + return -1; + if (dinfo->wrval(dinfo, idx, &val) != SUI_RET_OK) + return -1; + return 0; + } + default: + return -2; + } +} + +ssize_t distore_count_maxsize(const distore_des_array_t *des) +{ + ssize_t count=0; + ssize_t ims; + int idx; + const distore_des_item_t *item; + int idxlimit; + + for(idx=0; idxarray.count; idx++) { + item = distore_des_array_at(des, idx); + if(item == NULL) + return -1; + idxlimit = item->idxlimit; + if(!idxlimit) { + idxlimit=item->dinfo->idxsize; + } + ims=distore_encform_maxsize(item->encform); + if(ims<0) + return -1; + count+=1+1+2; + count+=ims*idxlimit; + } + count+=1; + return count; +} + +int distore_store_data(const distore_des_array_t *des, + distore_wrfnc_t *wrfnc, void *context) +{ + int idx; + int i; + const distore_des_item_t *item; + int idxlimit; + + for(idx=0; idxarray.count; idx++) { + item = distore_des_array_at(des, idx); + if(item == NULL) + return -1; + if(item->flags & DISTORE_FLG_LOAD_ONLY) + continue; + idxlimit = item->idxlimit; + if(!idxlimit || (idxlimit > item->dinfo->idxsize)) { + idxlimit=item->dinfo->idxsize; + } + if(distore_write_unsigned(wrfnc, context, item->encform, 1) < 0) + goto error; + if(distore_write_unsigned(wrfnc, context, idxlimit, 1) < 0) + goto error; + if(distore_write_unsigned(wrfnc, context, item->id, 2) < 0) + goto error; + + for(i=0; idinfo, i, item->encform) < 0) + goto error; + } + } + + if(distore_write_unsigned(wrfnc, context, 0, 1) < 0) + goto error; + + return 0; + + error: + return -1; +} + +int distore_load_data(const distore_des_array_t *des, + distore_rdfnc_t *rdfnc, void *context, int mode) +{ + unsigned long u; + unsigned int encform; + unsigned int idxlimit; + distore_id_t id; + const distore_des_item_t *item; + sui_dinfo_t *dinfo; + int i; + + do { + dinfo = NULL; + if(distore_read_unsigned(rdfnc, context, &u, 1) < 0) + goto error; + encform = u; + if(encform == DISTORE_ENC_END) + break; + if(distore_read_unsigned(rdfnc, context, &u, 1) < 0) + goto error; + idxlimit = u; + if(distore_read_unsigned(rdfnc, context, &u, 2) < 0) + goto error; + id=u; + item = distore_des_array_find(des, &id); + do { + if(item == NULL) { + if(mode & DISTORE_LOAD_IGNORE_UNKNOWN) + break; + goto error; + } + if(encform != item->encform) { + if(!((encform ^ DISTORE_ENC_TEXT_CODE) & ~DISTORE_ENC_TEXT_LEN)) { + if((encform ^ item->encform) & ~DISTORE_ENC_TEXT_LEN) + break; + } else if((encform == DISTORE_ENC_UNSIGNED_CODE) || + (encform == DISTORE_ENC_SIGNED_CODE) || + (encform == DISTORE_ENC_FLOAT_CODE)) { + if((encform ^ item->encform) & ~DISTORE_ENC_NUM_LEN) + break; + } else break; + } + dinfo = item->dinfo; + } while(0); + for(i=0; i +#include + +#include "appl_defs.h" + +#ifdef CONFIG_OC_I2C_DRV_SYSLESS +#include +extern i2c_drv_t i2c_drv; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +enum distore_encformat { + DISTORE_ENC_END = 0x00, + DISTORE_ENC_FLOAT_CODE = 0x10, + DISTORE_ENC_SIGNED_CODE = 0x20, + DISTORE_ENC_UNSIGNED_CODE = 0x30, + DISTORE_ENC_NUM_LEN = 0x0f, + DISTORE_ENC_NUM_LEN_BITS = 4, + DISTORE_ENC_TEXT_CODE = 0x80, + DISTORE_ENC_TEXT_LEN = 0x7f, +}; + +#define DISTORE_FLG_LOAD_ONLY 1 + +typedef unsigned short distore_id_t; + +typedef struct distore_des_item_t { + sui_dinfo_t *dinfo; + unsigned char encform; + unsigned char idxlimit; + distore_id_t id; + unsigned short flags; +} distore_des_item_t; + +typedef struct distore_des_array_t { + struct { + const distore_des_item_t *items; + unsigned count; + } array; +} distore_des_array_t; + +const distore_des_item_t * +distore_des_array_at (const distore_des_array_t * array, unsigned indx); + +const distore_des_item_t * +distore_des_array_find (const distore_des_array_t * array, + distore_id_t const * key); + +typedef ssize_t distore_wrfnc_t(void *context, const void *buf, size_t count); +typedef ssize_t distore_rdfnc_t(void *context, void *buf, size_t count); + +ssize_t distore_count_maxsize(const distore_des_array_t *des); + +int distore_store_data(const distore_des_array_t *des, + distore_wrfnc_t *wrfnc, void *context); + +#define DISTORE_LOAD_IGNORE_UNKNOWN 1 +#define DISTORE_LOAD_IGNORE_WRITE_ERR 2 + +int distore_load_data(const distore_des_array_t *des, + distore_rdfnc_t *rdfnc, void *context, int mode); + +#ifdef __cplusplus +} /* extern "C"*/ +#endif + +#endif /* _DISTORE_SIMPLE_H*/ diff --git a/sw/app/lx_dad/log_domains.inc b/sw/app/lx_dad/log_domains.inc new file mode 100644 index 0000000..29ab5e4 --- /dev/null +++ b/sw/app/lx_dad/log_domains.inc @@ -0,0 +1,10 @@ +/* + * This is generated file, do not edit it directly. + * Take it from standard output of "ul_log_domains" + * script called in the top level project directory + */ +ul_log_domain_t ulogd_dad = {UL_LOGL_DEF, "dad"}; + +ul_log_domain_t *const ul_log_domains_array[] = { + &ulogd_dad, +}; diff --git a/sw/app/lx_dad/setup_distore.c b/sw/app/lx_dad/setup_distore.c new file mode 100644 index 0000000..cda7539 --- /dev/null +++ b/sw/app/lx_dad/setup_distore.c @@ -0,0 +1,139 @@ +#include + +#include "appl_defs.h" + +#ifdef APPL_WITH_DISTORE_KEYVAL_SERVICE + +#include +#include "distore_simple.h" + +#include +extern UL_LOG_CUST(ulogd_distore) + +extern kvpb_block_t *kvpb_block; + +typedef struct setup_distore_context_t { + size_t pos; + size_t limit; + void *buf; +} setup_distore_context_t; + +extern const distore_des_array_t setup_distore_service_des; + +ssize_t setup_distore_wrfnc(void *context, const void *buf, size_t count) +{ + setup_distore_context_t *c = (setup_distore_context_t *)context; + if(c->limit - c->pos < count) + return -1; + memcpy((char *)c->buf + c->pos, buf, count); + c->pos += count; + return count; +} + +ssize_t setup_distore_rdfnc(void *context, void *buf, size_t count) +{ + setup_distore_context_t *c = (setup_distore_context_t *)context; + if(c->limit - c->pos < count) + return -1; + memcpy(buf, (char *)c->buf + c->pos, count); + c->pos += count; + return count; +} + +int setup_distore_store(void) +{ + setup_distore_context_t ctx; + setup_distore_context_t *c = &ctx; + const distore_des_array_t *des = &setup_distore_service_des; + ssize_t sz; + int res = -1; + + if(kvpb_block == NULL) + return -1; + + c->buf = NULL; + c->limit = 0; + c->pos = 0; + sz = distore_count_maxsize(des); + if(sz < 0) { + ul_logerr("setup_distore_store can not compute maxsize\n"); + return -1; + } + c->buf = malloc(sz); + if(c->buf == NULL) { + ul_logerr("setup_distore_store malloc failed\n"); + return -1; + } + c->limit = sz; + + if(distore_store_data(des, setup_distore_wrfnc, c) < 0) { + ul_logerr("setup_distore_store DINFO encoding failed\n"); + goto error; + } + + if(kvpb_set_key(kvpb_block, KVPB_KEYID_SETUP_SERVICE, c->pos, c->buf)<0) { + ul_logerr("setup_distore_store kvpb_set_key failed\n"); + goto error; + } + + ul_logmsg("setup_distore_store proceed OK\n"); + res = 0; +error: + if(c->buf != NULL) + free(c->buf); + return res; +} + +int setup_distore_restore(void) +{ + setup_distore_context_t ctx; + setup_distore_context_t *c = &ctx; + const distore_des_array_t *des = &setup_distore_service_des; + ssize_t sz; + int res = -1; + + if(kvpb_block == NULL) + return -1; + + c->buf = NULL; + c->limit = 0; + c->pos = 0; + + sz = kvpb_get_key(kvpb_block, KVPB_KEYID_SETUP_SERVICE, 0, NULL); + + if(sz < 0) { + ul_logmsg("setup_distore_restore SETUP_SERVICE key not found\n"); + return -1; + } + + if(sz > KVPB_SETUP_SERVICE_MAX_SIZE) { + ul_logmsg("setup_distore_restore SETUP_SERVICE key size exceed\n"); + return -1; + } + + c->buf = malloc(sz); + if(c->buf == NULL) { + ul_logerr("setup_distore_restore malloc failed\n"); + return -1; + } + c->limit = sz; + + if(kvpb_get_key(kvpb_block, KVPB_KEYID_SETUP_SERVICE, sz, c->buf) != sz) { + ul_logerr("setup_distore_restore kvpb_get_key error\n"); + goto error; + } + + res = distore_load_data(des, setup_distore_rdfnc, c, + DISTORE_LOAD_IGNORE_UNKNOWN | DISTORE_LOAD_IGNORE_WRITE_ERR); + + if(res < 0) + ul_logerr("setup_distore_restore DINFO decode failed (%d)\n", res); + else + ul_logmsg("setup_distore_restore proceed OK\n"); +error: + if(c->buf != NULL) + free(c->buf); + return res; +} + +#endif /* APPL_WITH_DISTORE_KEYVAL_SERVICE */ diff --git a/sw/app/lx_dad/ul_idstr.c b/sw/app/lx_dad/ul_idstr.c new file mode 100644 index 0000000..547a5df --- /dev/null +++ b/sw/app/lx_dad/ul_idstr.c @@ -0,0 +1,43 @@ +#include "appl_config.h" +#include "appl_version.h" + +#ifndef __STRINGIFY +#define __STRINGIFY(x) #x /* stringify without expanding x */ +#endif /*__STRINGIFY*/ +#ifndef STRINGIFY +#define STRINGIFY(x) __STRINGIFY(x) /* expand x, then stringify */ +#endif /*STRINGIFY*/ + +#ifdef CONFIG_ULAN_DY + #define UL_DYC " .dy" +#else + #define UL_DYC +#endif + +#ifdef CONFIG_ULOI_LT + #define UL_OIC " .oi" +#else + #define UL_OIC +#endif + +#ifdef APP_VER_MAJOR +#ifndef APP_VER_MINOR +#define APP_VER_MINOR 0 +#endif +#define APP_UL_VER_STR " v" STRINGIFY(APP_VER_MAJOR) "." STRINGIFY(APP_VER_MINOR) +#else /*APP_VER_MAJOR*/ +#define APP_UL_VER_STR +#endif /*APP_VER_MAJOR*/ + + +#define NAME ".mt " \ + STRINGIFY(ULAN_ID) \ + APP_UL_VER_STR \ + " .uP " \ + STRINGIFY(MACH) \ + UL_DYC \ + UL_OIC \ + " .co " \ + __DATE__ " " __TIME__ + +const char *ul_idstr = NAME; diff --git a/sw/app/lx_dad/usb/usb_defs.h b/sw/app/lx_dad/usb/usb_defs.h new file mode 100644 index 0000000..c960fd0 --- /dev/null +++ b/sw/app/lx_dad/usb/usb_defs.h @@ -0,0 +1,230 @@ + +#ifndef USB_DEFS_MODULE +#define USB_DEFS_MODULE + +#include +#include +#include +#include + +#include +#if __BYTE_ORDER == __BIG_ENDIAN +#include +#define SWAP(x) ((((x) & 0xFF) << 8) | (((x) >> 8) & 0xFF)) +#else /*__LITTLE_ENDIAN*/ +#define SWAP(x) (x) +#endif + +#ifndef CODE +#define CODE +#endif + +/*****************************************************/ +/*** Static data structures for device descriptors ***/ +/*****************************************************/ +#define USB_VENDOR_ID 0x1669 /* PIKRON company bought vendor ID */ +#define USB_PRODUCT_ID 0x1027 /* Number reserved for LX_DAD on LX_CPU1 */ +#define USB_RELEASE_VER 0x0100 + +/*** Class codes for device description ***/ +#define USB_CLASS_CODE 0xFF +#define USB_SUBCLASS_CODE 0x00 +#define USB_PROTOCOL_CODE 0x00 + +#define NUM_ENDPOINTS 2 + +/*** Device descriptor ***/ +CODE const USB_DEVICE_DESCRIPTOR DeviceDescription = +{ + sizeof(USB_DEVICE_DESCRIPTOR), + USB_DESCRIPTOR_TYPE_DEVICE, + SWAP(0x0100), + USB_CLASS_CODE, + USB_SUBCLASS_CODE, + USB_PROTOCOL_CODE, + USB_MAX_PACKET0, + SWAP(USB_VENDOR_ID), + SWAP(USB_PRODUCT_ID), + SWAP(USB_RELEASE_VER), + 1, /* manufacturer string ID */ + 2, /* product string ID */ + 3, /* serial number string ID */ + 1 +}; + +/*** All In Configuration 0 ***/ +CODE const struct +{ + USB_CONFIGURATION_DESCRIPTOR configuration; + USB_INTERFACE_DESCRIPTOR interface; + USB_ENDPOINT_DESCRIPTOR endpoint_tx; + USB_ENDPOINT_DESCRIPTOR endpoint_rx; +} ConfigDescription = +{ + /*** Configuration descriptor ***/ + { + sizeof(USB_CONFIGURATION_DESCRIPTOR), + USB_DESCRIPTOR_TYPE_CONFIGURATION, + sizeof(ConfigDescription), + 1, /* cnt of interfaces */ + 1, /* this configuration ID */ + 4, /* config.name string ID */ + 0x80, /* cfg, in spec is, taha bit 7 must be set to one -> 0xe0 , orig 0x60*/ + 250 /* device power current from host 500mA / 2 */ + }, + /*** Interface Descriptor ***/ + { + sizeof(USB_INTERFACE_DESCRIPTOR), + USB_DESCRIPTOR_TYPE_INTERFACE, + 0, /* index of this interface for SetInterface request */ + 0, /* ID alternate interface */ + NUM_ENDPOINTS, + USB_CLASS_CODE, + USB_SUBCLASS_CODE, + USB_PROTOCOL_CODE, + 5 + }, + /*** Endpoint 1 - Rx,Bulk ***/ + { + sizeof(USB_ENDPOINT_DESCRIPTOR), + USB_DESCRIPTOR_TYPE_ENDPOINT, + 0x81, + USB_ENDPOINT_TYPE_BULK, + SWAP(USB_MAX_PACKET), + 0 + }, + /*** Endpoint 1 - Tx,Bulk ***/ + { + sizeof(USB_ENDPOINT_DESCRIPTOR), + USB_DESCRIPTOR_TYPE_ENDPOINT, + 0x01, + USB_ENDPOINT_TYPE_BULK, + SWAP(USB_MAX_PACKET), + 0 + } +}; +/*** Strings - in unicode ***/ +CODE const char Str0Desc[] = /* supported languages of strings */ +{ + 4, 0x03, /* 2+2*N , N is count of supported languages */ + 0x09, 0x04 /* english 0x0409 */ +}; + +CODE const char Str1Desc[] = /* 1 = manufacturer */ +{ + 24, 0x03, + 'P', 0, + 'i', 0, + 'K', 0, + 'R', 0, + 'O', 0, + 'N', 0, + ' ', 0, + 'L', 0, + 't', 0, + 'd', 0, + '.', 0, +}; + +CODE const char Str2Desc[] = /* 2 = product */ +{ + 14, 0x03, + 'L', 0, + 'X', 0, + '_', 0, + 'D', 0, + 'A', 0, + 'D', 0, +}; + +#define usb_devdes_serial_number Str3Desc +/* Serial number is stored in data area to be set at device start-up */ +char Str3Desc[(1 + 8) * 2] = /* 3 = serial number */ +{ + 18, 0x03, + 'X', 0, + 'X', 0, + 'X', 0, + 'X', 0, + 'X', 0, + 'X', 0, + 'X', 0, + 'X', 0, +}; + +CODE const char Str4Desc[] = /* 4 = configuration */ +{ + 34, 0x03, + 'C', 0, + 'o', 0, + 'n', 0, + 'f', 0, + 'i', 0, + 'g', 0, + 'u', 0, + 'r', 0, + 'a', 0, + 't', 0, + 'i', 0, + 'o', 0, + 'n', 0, + ' ', 0, + '#', 0, + '1', 0 +}; +CODE const char Str5Desc[] = /* 5 = interface */ +{ + 26, 0x03, + 'I', 0, + 'n', 0, + 't', 0, + 'e', 0, + 'r', 0, + 'f', 0, + 'a', 0, + 'c', 0, + 'e', 0, + ' ', 0, + '#', 0, + '0', 0 +}; + +/* all strings in pointers array */ +CODE const PUSB_STRING_DESCRIPTOR StringDescriptors[] = +{ + (PUSB_STRING_DESCRIPTOR) Str0Desc, + (PUSB_STRING_DESCRIPTOR) Str1Desc, + (PUSB_STRING_DESCRIPTOR) Str2Desc, + (PUSB_STRING_DESCRIPTOR) Str3Desc, + (PUSB_STRING_DESCRIPTOR) Str4Desc, + (PUSB_STRING_DESCRIPTOR) Str5Desc +}; + +#define CNT_STRINGS (sizeof(StringDescriptors)/sizeof(StringDescriptors[0])) + +CODE const USB_DEVICE_CONFIGURATION_ENTRY usb_devdes_configurations[] = +{ + { + .pConfigDescription = &ConfigDescription.configuration, + .iConfigTotalLength = sizeof(ConfigDescription) + } +}; + +CODE const USB_INTERFACE_DESCRIPTOR *usb_devdes_interfaces[] = +{ + &ConfigDescription.interface +}; + +CODE const USB_DEVICE_DESCRIPTORS_TABLE usb_devdes_table = +{ + .pDeviceDescription = &DeviceDescription, + .pConfigurations = usb_devdes_configurations, + .pInterfaceDescriptors = usb_devdes_interfaces, + .pStrings = StringDescriptors, + .iNumStrings = CNT_STRINGS, + .bNumEndpoints = NUM_ENDPOINTS, + .bNumConfigurations = 1, + .bNumInterfaces = 1 +}; + +#endif /* USB_DEFS_MODULE */ diff --git a/sw/config.omk b/sw/config.omk index e004ca6..146b90c 100644 --- a/sw/config.omk +++ b/sw/config.omk @@ -2,26 +2,32 @@ LN_HEADERS=y LD_SCRIPT=lpc1788 +CONFIG_STDIO_COM_PORT=0 + CONFIG_OC_ULUT=y CONFIG_OC_ULUT_INCDIR=y +CONFIG_KEYVAL=y + CONFIG_OC_UL_DRV_SYSLESS=n CONFIG_ULBOOT=n -CONFIG_APP_LCD61=y +CONFIG_APP_LX_DAD=y +CONFIG_APP_LX_DAD_WITH_USB=y +CONFIG_APP_LX_DAD_WITH_FPGA=y -CONFIG_OC_MWENGINE=y +CONFIG_OC_MWENGINE=n CONFIG_OC_MWSCRDRV=dogxl -#CONFIG_OC_MWMOUSEDRV=x +CONFIG_OC_MWMOUSEDRV=x CONFIG_OC_MWKBDDRV=lc61spi CONFIG_OC_MWSCREEN_WIDTH=160 CONFIG_OC_MWSCREEN_HEIGHT=104 -CONFIG_APP_LCD61_WITH_SUITK=y -CFLAGS += -DMICROWINDOWS_090 -CFLAGS += -DSUI_CANBE_CONST=const -CFLAGS += -DSUI_CANBE_CONST_VMT=const +CONFIG_APP_LX_DAD_WITH_SUITK=n +#CFLAGS += -DMICROWINDOWS_090 +#CFLAGS += -DSUI_CANBE_CONST=const +#CFLAGS += -DSUI_CANBE_CONST_VMT=const CONFIG_OC_I2C_DRV_SYSLESS=y CONFIG_OC_I2C_CHIP_C552=y @@ -32,11 +38,6 @@ CONFIG_OC_SPI_CHIP_LPCSSP=y CONFIG_USB_BASE=y CONFIG_USB_LPCUSB=y CONFIG_USB_MORE=y -CONFIG_APP_LCD61_WITH_USB=y -CONFIG_LIB_U2U_V2=y - -CONFIG_OC_CMDPROC_TEST=y +CONFIG_LIB_U2U_V2=x -CONFIG_PXMC=y -CONFIG_PXMC_WITH_PTABLE=y -CONFIG_PXMC_BSP=lpc17xx-common +CONFIG_OC_CMDPROC_TEST=n