📄 exec.c
字号:
//====================================================================
//--- COPYRIGHT
//====================================================================
// Copyright 2006 Microchip Technology Inc.
//
// Microchip Technology Inc. ("Microchip") licenses this software to
// you solely for use with Microchip products. The software is owned
// by Microchip and is protected under applicable copyright laws. All
// rights reserved.
//
// SOFTWARE IS PROVIDED IN AN "AS IS." MICROCHIP EXPRESSLY DISCLAIMS ANY
// WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED, INCLUDING BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
// PARTICULAR PURPOSE, OR NON-INFRINGEMENT. IN NO EVENT SHALL MICROCHIP
// BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT OR CONSEQUENTIAL
// DAMAGES, LOST PROFITS OR LOST DATA, HARM TO YOUR EQUIPMENT, COST OF
// PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS
// BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF),
// ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER SIMILAR COSTS.
//
//====================================================================
//--- TITLE
//====================================================================
// Filename: exec.c
// Microcontroller: PIC18F2550
// Compiled using: C18 V3.00
//
// Author: Mark Enochson
// Company: Microchip Technology Inc.
//
//====================================================================
//--- DESCRIPTION
//====================================================================
//
//--- EXEC
//
// "executive" control of device processes
// provides supervision of USB & COMM controller(s)
// primary operations:
// - receive/process incoming USB data blocks
// --- read/write circular buffers
// --- execute "immediate" commands
// --- automatically "flush" comm controller buffer(s)
// sending data back to HOST via USB
// - build outgoing USB data blocks
// --- device status block
// --- data from comm controller
//
// init:
// read CONTROL_BLOCK from EE
// if EE checksum bad,
// load CONTROL_BLOCK hard-coded "default"
//
//==========================================================
//--- exec_init()
// initialize exec module
//
//--- exec_svc()
// exec service - USB I/O
//
//--- exec_dflush_time_set()
// set cbuf2 flush timer (from control block)
//
//--- exec_cmnd_proc()
// process "immediate" command
//
//--- exec_cb_load()
// load CONTROL_BLOCK from EE or DEFAULTs
//
//--- exec_cb_load_dflt()
// load CONTROL_BLOCK from DEFAULTs
//
//--- exec_cb_ee_read()
// read CONTROL_BLOCK from EE
//
//--- exec_cb_ee_write()
// write CONTROL_BLOCK to EE
//
//--- exec_packet_proc()
// process USB packet
//
//--- exec_data_get()
// get data byte from USB input buffer
//
//--- exec_data_put()
// put data byte into USB output buffer
//
//--- exec_status_packet()
// build status packet in USB output buffer
//
//--- exec_packet_prep()
// prep varbs for building USB output buffer/packet
//
//--- exec_packet_finish()
// complete then transmit USB output buffer/packet
//
//--- exec_packet_cbuf2()
// load USB output packet/buffer with cbuf2 data
//
//====================================================================
//--- HISTORY
//====================================================================
//
// 0002 - 03-01-08 - ME
// -- added 'immediate command' EXEC_CMND_COMM_CLEAR
// -- added EXEC tags to clear/reset CBUF1,2,3
//
// 12-05-07 - ME
// -- added call to vsrc_init() to exec_init()
//
// 0001 - 08-01-06 - ME
// - initial release
//
//====================================================================
#include "project.h"
#include "exec.h"
#include "comm_gen.h"
#include "cbuf.h"
#include "led2.h"
#include "timer0.h"
#include "ee_util.h"
#include "usb.h"
#include "vsrc.h"
//------------------------------------------------
//--- DEFINITIONS / DECLARATIONS
//------------------------------------------------
#pragma udata
TD_BYTE_B exec_flags;
TD_BYTE *exec_data_p;
TD_BYTE exec_data_count, exec_count;
TD_BYTE exec_tag, exec_data;
TD_BYTE_B exec_control_B[24];
TD_BYTE_B exec_status_B[20];
TD_BYTE exec_status_save_1;
TD_BYTE exec_status_save_2;
TD_BYTE exec_status_save_3;
TD_BYTE exec_debug_1;
TD_BYTE exec_debug_2;
TD_BYTE exec_debug_3;
TD_BYTE exec_status_id;
#pragma romdata exec_constants
#ifndef __DEBUG_EXEC_CBLOCK
//--- DEFAULT CONFIGURATION
const rom TD_BYTE exec_cb_dflt[EXEC_CB_LENGTH] = {\
0xC0, 0x00, 0x00, 0x01, 0xFF, 0x00, 0x00, 0x00, \
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
//--- DEBUG CONFIGURATION
#else
const rom TD_BYTE exec_cb_dflt[EXEC_CB_LENGTH] = { \
0xC0, 0x00, 0x00, 0x01, 0xFF, 0x00, 0x00, 0x00, \
0x04, 0x21, 0xFF, 0x00, 0x80, 0x50, 0x00, 0x00, \
0x02, 0xFF, 0x03, 0x00, 0x22, 0x11, 0x08, 0x02 };
#endif
//==========================================================
#pragma code
//==========================================================
//--- exec_init()
// initialize exec module
//==========================================================
void exec_init(void)
{
exec_flags._b = 0; // clear op flags
cbuf1_init(); // clear buffers
cbuf2_init();
cbuf3_init();
comm_init(); // init comm controller
vsrc_init();
//-----------------------------------
//--- clear status block
//-----------------------------------
for(exec_count = EXEC_SB_REG_ALL_FIRST; exec_count <= EXEC_SB_REG_ALL_LAST; exec_count++)
exec_status_B[exec_count]._byte = 0;
//-----------------------------------
//--- load control block
//-----------------------------------
//debug
//exec_cb_load();
exec_cb_load_dflt();
EXEC_CB_NEW_FLAG = 1;
//-----------------------------------
//--- enable pullup on switch
//-----------------------------------
INTCON2bits.NOT_RBPU = 1;
SW_PIN_DIR = 1;
}
//==========================================================
//--- exec_svc()
// exec service - USB I/O
//
// check/process incoming USB data
// check cbuf2 flush criteria
// send cbuf2 data via USB (if flush criteria met)
// send status packet via USB (if requested)
//==========================================================
void exec_svc(void)
{
//debug
// if(USB_XMTBUF_READY_FLAG)
// if(USB_RCVBUF_READY_FLAG)
// debug_event_set();
// else
// debug_event_rst();
//-----------------------------------
//--- SWITCH STATE
//-----------------------------------
EXEC_SB_SWITCH_FLAG = SW_PIN;
//-----------------------------------
//--- EXEC SWITCH TEST
// use LEDs to reflect switch position
//-----------------------------------
if(EXEC_CB_SWITCH_TEST_FLAG)
{
if(SW_PIN)
{
if(not EXEC_SWTEST_FLAG)
{
led_1_config(EXEC_LED_CONFIG_SWTEST_OFF);
led_2_config(EXEC_LED_CONFIG_SWTEST_ON);
EXEC_SWTEST_FLAG = 1;
}
}
else
{
if(EXEC_SWTEST_FLAG)
{
led_1_config(EXEC_LED_CONFIG_SWTEST_ON);
led_2_config(EXEC_LED_CONFIG_SWTEST_OFF);
EXEC_SWTEST_FLAG = 0;
}
}
EXEC_SB_SWITCH_TEST_FLAG = 1;
}
else
{
if(EXEC_SB_SWITCH_TEST_FLAG)
{
led_1_config(EXEC_LED_CONFIG_SWTEST_OFF);
led_2_config(EXEC_LED_CONFIG_SWTEST_OFF);
EXEC_SB_SWITCH_TEST_FLAG = 0;
}
}
//-----------------------------------
//--- USB buffer full/ready ?
// process incoming USB data
//-----------------------------------
if(USB_RCVBUF_READY_FLAG)
{
exec_data_count = USB_RCVBUF_COUNT_REG;
exec_data_p = USB_RCVBUF_POINTER;
exec_packet_proc();
USB_RCVBUF_RELEASE_FUNC();
}
//-----------------------------------
//--- CBUF2 flush: data threshold ?
//-----------------------------------
if(EXEC_CB_DFLUSH_THRESHOLD_FLAG)
{
if(cbuf2.used > exec_control_B[3]._byte)
EXEC_DFLUSH_FLAG = 1;
}
//-----------------------------------
//--- CBUF2 flush: time ?
//-----------------------------------
if(EXEC_CB_DFLUSH_TIME_FLAG)
{
if(not timer0_A4)
{
exec_dflush_time_set();
if(cbuf2.used)
EXEC_DFLUSH_FLAG = 1;
}
}
//debug
// if(EXEC_RQ_STATUS_PACKET_FLAG && EXEC_DFLUSH_FLAG)
// debug_event_set();
// else
// debug_event_rst();
//-----------------------------------
//--- send: status packet
// don't send until new CB
// has been recognized/processed
//-----------------------------------
if(not EXEC_CB_NEW_FLAG)
{
if((EXEC_RQ_STATUS_PACKET_FLAG) || (EXEC_RQ_STATUS_PACKET_ID_FLAG))
{
if(USB_XMTBUF_READY_FLAG)
{
exec_packet_prep();
if(EXEC_RQ_STATUS_PACKET_FLAG)
{
EXEC_RQ_STATUS_PACKET_FLAG = 0;
exec_packet_status(EXEC_STATUS_PACKET_ID);
}
else
{
EXEC_RQ_STATUS_PACKET_ID_FLAG = 0;
exec_packet_status(exec_status_id);
}
exec_packet_finish();
}
}
}
//-----------------------------------
//--- send: CBUF2 data
//-----------------------------------
if(EXEC_DFLUSH_FLAG)
{
if(USB_XMTBUF_READY_FLAG)
{
//debug
// exec_dflush_time_set();
EXEC_DFLUSH_FLAG = 0;
if(cbuf2.used)
{
exec_packet_prep();
exec_packet_cbuf2();
exec_packet_finish();
}
}
}
//debug
// if(USB_XMTBUF_READY_FLAG)
// if(USB_RCVBUF_READY_FLAG)
// debug_event_set();
// else
// debug_event_rst();
}
//==========================================================
//--- exec_dflush_time_set()
// set cbuf2 flush timer (from control block)
// catch value==0, substitute max time i.e. 255
//==========================================================
void exec_dflush_time_set(void)
{
timer0_A4 = EXEC_CB_DFLUSH_TIME_REG;
if(timer0_A4 == 0)
timer0_A4 = 255;
}
//==========================================================
//--- exec_cmnd_proc()
// process "immediate" command
//==========================================================
void exec_cmnd_proc(TD_BYTE cmnd)
{
switch(cmnd)
{
//==========================================
case EXEC_CMND_INIT:
exec_init();
break;
//==========================================
case EXEC_CMND_COMM_INIT_MODE:
comm_init_mode(exec_control_B[8]._byte);
break;
//==========================================
case EXEC_CMND_RQ_STATUS_PACKET:
EXEC_RQ_STATUS_PACKET_FLAG = 1;
break;
//==========================================
case EXEC_CMND_CB_EE_WRITE:
exec_cb_ee_write();
break;
//==========================================
case EXEC_CMND_CB_EE_READ:
exec_cb_load();
break;
//==========================================
case EXEC_CMND_CBUF2_FLUSH:
EXEC_DFLUSH_FLAG = 1;
break;
//==========================================
case EXEC_CMND_COMM_INIT:
comm_init();
break;
//==========================================
case EXEC_CMND_COMM_CLEAR:
comm_clear();
break;
}
}
//==========================================================
//--- exec_cb_load()
// load CONTROL_BLOCK from EE or DEFAULTs
//==========================================================
void exec_cb_load(void)
{
if(exec_cb_ee_read())
{
exec_cb_load_dflt();
EXEC_SB_CB_DFLT_FLAG = 1;
}
else
EXEC_SB_CB_DFLT_FLAG = 0;
}
//==========================================================
//--- exec_cb_load_dflt()
// load CONTROL_BLOCK from DEFAULTs
//==========================================================
void exec_cb_load_dflt(void)
{
exec_count = 0;
while(exec_count < EXEC_CB_LENGTH)
{
exec_control_B[exec_count]._byte = exec_cb_dflt[exec_count];
exec_count++;
}
}
//==========================================================
//--- exec_cb_ee_write()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -