4
D:\Projects\Voltech\Modbus\USBModbus\main.c /*!--------------------------------------------------------------------------- ** @file main.c ** ** @brief Firmware main file for USB Modbus I/O Interface ** **--------------------------------------------------------------------------- ** ** Copyright 2010 Roy Hopkins ([email protected]) ** ** This file is part of the firmware for the Field of Cows USB Modbus I/O ** project (USBModbus) ** ** USBModbus is free software: you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation, either version 3 of the License, or ** (at your option) any later version. ** ** USBModbus is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with USBModbus. If not, see <http://www.gnu.org/licenses/>. ** */ /*--------------------------------------------------------------------------- ** Includes */ #include < p18f4550 . h > #include < portb . h > #include "usb_config.h" #include "USB/usb.h" #include "USB/usb_function_cdc.h" #include "USB/usb_device.h" #include "modbus.h" /*--------------------------------------------------------------------------- ** Defines and Macros */ #pragma config PLLDIV = 5 // (20 MHz crystal) #pragma config CPUDIV = OSC1_PLL2 #pragma config USBDIV = 2 // Clock source from 96MHz PLL/2 #pragma config FOSC = HSPLL_HS #pragma config FCMEN = OFF #pragma config IESO = OFF #pragma config PWRT = OFF #pragma config BOR = ON #pragma config BORV = 3 #pragma config VREGEN = ON // USB Voltage Regulator #pragma config WDT = OFF #pragma config WDTPS = 32768 #pragma config MCLRE = ON #pragma config LPT1OSC = OFF #pragma config PBADEN = OFF #pragma config STVREN = ON #pragma config LVP = OFF #pragma config XINST = OFF // Extended Instruction Set #pragma config CP0 = OFF #pragma config CP1 = OFF #pragma config CPB = OFF #pragma config WRT0 = OFF #pragma config WRT1 = OFF #pragma config WRTB = OFF // Boot Block Write Protection #pragma config WRTC = OFF #pragma config EBTR0 = OFF #pragma config EBTR1 = OFF #pragma config EBTRB = OFF 1

Main Modbus

Embed Size (px)

Citation preview

Page 1: Main Modbus

D:\Projects\Voltech\Modbus\USBModbus\main.c

/*!---------------------------------------------------------------------------

** @file main.c

**

** @brief Firmware main file for USB Modbus I/O Interface

**

**---------------------------------------------------------------------------

**

** Copyright 2010 Roy Hopkins ([email protected])

**

** This file is part of the firmware for the Field of Cows USB Modbus I/O

** project (USBModbus)

**

** USBModbus is free software: you can redistribute it and/or modify

** it under the terms of the GNU General Public License as published by

** the Free Software Foundation, either version 3 of the License, or

** (at your option) any later version.

**

** USBModbus is distributed in the hope that it will be useful,

** but WITHOUT ANY WARRANTY; without even the implied warranty of

** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the

** GNU General Public License for more details.

**

** You should have received a copy of the GNU General Public License

** along with USBModbus. If not, see <http://www.gnu.org/licenses/>.

**

*/

/*---------------------------------------------------------------------------

** Includes

*/

#include <p18f4550.h>

#include <portb.h>

#include "usb_config.h"

#include "USB/usb.h"

#include "USB/usb_function_cdc.h"

#include "USB/usb_device.h"

#include "modbus.h"

/*---------------------------------------------------------------------------

** Defines and Macros

*/

#pragma config PLLDIV = 5 // (20 MHz crystal)

#pragma config CPUDIV = OSC1_PLL2

#pragma config USBDIV = 2 // Clock source from 96MHz PLL/2

#pragma config FOSC = HSPLL_HS

#pragma config FCMEN = OFF

#pragma config IESO = OFF

#pragma config PWRT = OFF

#pragma config BOR = ON

#pragma config BORV = 3

#pragma config VREGEN = ON // USB Voltage Regulator

#pragma config WDT = OFF

#pragma config WDTPS = 32768

#pragma config MCLRE = ON

#pragma config LPT1OSC = OFF

#pragma config PBADEN = OFF

#pragma config STVREN = ON

#pragma config LVP = OFF

#pragma config XINST = OFF // Extended Instruction Set

#pragma config CP0 = OFF

#pragma config CP1 = OFF

#pragma config CPB = OFF

#pragma config WRT0 = OFF

#pragma config WRT1 = OFF

#pragma config WRTB = OFF // Boot Block Write Protection

#pragma config WRTC = OFF

#pragma config EBTR0 = OFF

#pragma config EBTR1 = OFF

#pragma config EBTRB = OFF

1

Page 2: Main Modbus

D:\Projects\Voltech\Modbus\USBModbus\main.c

#define CLOCK_FREQ 48000000

#define GetSystemClock() (CLOCK_FREQ)

/*---------------------------------------------------------------------------

** Typedefs

*/

/*---------------------------------------------------------------------------

** Local function prototypes

*/

void handle_high_isr(void);

void handle_low_isr(void);

/*---------------------------------------------------------------------------

** Data

*/

/*---------------------------------------------------------------------------

** Interrupt vectors and handlers

*/

//

// Define the high priority interrupt vector jump at address 0x08

//

#pragma code HIGH_INTERRUPT_VECTOR = 0x08

void

high_isr(

void

) {

// The code here is in a vector table so we have only got a few

// bytes to play with. Therefore just jump to the isr

_asm goto handle_high_isr _endasm

}

//

// Define the low priority interrupt vector jump at address 0x18

//

#pragma code LOW_INTERRUPT_VECTOR = 0x18

void

low_isr(

void

) {

_asm goto handle_low_isr _endasm

}

#pragma code

//

// The vector jump for the high priority interrupt jumps

// to this function. The #pragma interrupt ensures that

// the correct return is generated from the function

//

#pragma interrupt handle_high_isr

void

handle_high_isr(

void

) {

// Handle any pending USB tasks

USBDeviceTasks();

}

//

// The vector jump for the low priority interrupt jumps

// to this function. The #pragma interruptlow ensures that

// the correct return is generated from the function

//

#pragma interruptlow handle_low_isr

void

handle_low_isr(

void

) {

2

Page 3: Main Modbus

D:\Projects\Voltech\Modbus\USBModbus\main.c

}

//--------------------------------------------------------------------------

/*!

** @brief Main firmware process entry point

**

*/

void main(void) {

unsigned char count = 0;

// Initialise the USB library

USBDeviceInit();

USBDeviceAttach();

// Initialise the Modbus routines

#ifdef MODECONTROL_SW

setMode(MODE_RTU);

#endif

initialiseModbus();

// Enter the main processing loop

while (1) {

if ((USBDeviceState >= CONFIGURED_STATE) &&

(USBSuspendControl != 1)) {

processModbus();

CDCTxService();

}

}

}

//--------------------------------------------------------------------------

/*!

** @brief Handler that is called when the host sets the baud rate for

** the CDC connection

**

** This function gets called when a SetLineCoding command

** is sent on the bus. This function will evaluate the request

** and determine if the application should update the baudrate

** or not.

**

*/

void

set_line_coding_handler(

void

) {

//If the request is not in a valid range

if (cdc_notice.GetLineCoding.dwDTERate.Val > 115200) {

// Stalling the endpoint is the correct thing to do in this

// case but it can cause the host application to crash if it

// doesn't handle this properly. If that is the case then

// the line below can be commented-out

USBStallEndpoint(0, 1);

}

else {

DWORD_VAL baud;

// Update the baudrate info in the CDC driver

CDCSetBaudRate(cdc_notice.GetLineCoding.dwDTERate.Val);

// Update the baudrate of the UART

baud.Val = (GetSystemClock() / 4) / line_coding.dwDTERate.Val - 1;

SPBRG = baud.v[0];

SPBRGH = baud.v[1];

}

}

//--------------------------------------------------------------------------

/*!

** @brief USB event callback

**

** @return TRUE

3

Page 4: Main Modbus

D:\Projects\Voltech\Modbus\USBModbus\main.c

**

** This function is called from the USB stack to

** notify a user application that a USB event

** occured. This callback is in interrupt context

**

** @param[in] event Type of event

** @param[in] pdata Pointer to event data

** @param[in] size Size of event data

*/

BOOL

USER_USB_CALLBACK_EVENT_HANDLER(

USB_EVENT event,

void *pdata,

WORD size

) {

// We just forward these events to the relevant CDC handler

switch (event) {

case EVENT_CONFIGURED:

CDCInitEP();

break;

case EVENT_EP0_REQUEST:

USBCheckCDCRequest();

break;

case EVENT_TRANSFER:

Nop();

break;

default:

break;

}

return TRUE;

}

4