/*
* Main.c
*
* Created on: 15.01.2014
* Author: oe
* emtas GmbH
*/
/* header of standard C - libraries
---------------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
/* header of project specific types
---------------------------------------------------------------------------*/
#include <gen_define.h>
#include <co_canopen.h>
#include <co_401.h>
#include <usr_401.h>
#include <stm32f4_discovery.h>
#include <stm32f4xx_gpio.h>
#include <stm32f4xx_rcc.h>
#include <stm32f4xx_usart.h>
/* list of external used functions, if not in headers
--------------------------------------------------------------------------*/
void SystemInit(void);
void SystemCoreClockUpdate(void);
int codrvHardwareInit(void);
/* list of local defined functions
---------------------------------------------------------------------------*/
static RET_T nmtInd(BOOL_T execute, CO_NMT_STATE_T newState);
static void hbState(UNSIGNED8 nodeId, CO_ERRCTRL_T state,
CO_NMT_STATE_T nmtState);
static RET_T sdoServerReadInd(BOOL_T execute, UNSIGNED8 sdoNr, UNSIGNED16 index,
UNSIGNED8 subIndex);
static RET_T sdoServerCheckWriteInd(BOOL_T execute, UNSIGNED8 node,
UNSIGNED16 index, UNSIGNED8 subIndex, const UNSIGNED8 *pData);
static RET_T sdoServerWriteInd(BOOL_T execute, UNSIGNED8 sdoNr,
UNSIGNED16 index, UNSIGNED8 subIndex);
static void pdoInd(UNSIGNED16);
static void pdoRecEvent(UNSIGNED16);
static void canInd(CO_CAN_STATE_T);
static void commInd(CO_COMM_STATE_EVENT_T);
static void ledGreenInd(BOOL_T);
static void ledRedInd(BOOL_T);
static void evaTimeOver(void *pData);
void InitUSART2(int speed);
/* global variables
---------------------------------------------------------------------------*/
/* local defined variables
---------------------------------------------------------------------------*/
static CO_TIMER_T evaTimer; /**< local timer used as one-shot timer */
static int speed = 125; /**< CAN speed used in Kbit/s */
int main(void)
{
/* Generic Board initialization */
SystemInit();
SystemCoreClockUpdate();
/* initialize on-board LEDs */
STM_EVAL_LEDInit(LED3); /* orange */
STM_EVAL_LEDInit(LED4); /* green, used by CANopen */
STM_EVAL_LEDInit(LED5); /* red */
STM_EVAL_LEDInit(LED6); /* blue */
/* initialize USART2/USB for printf() debug messages */
InitUSART2(115200); /* use a high speed, because TX polling */
printf("\n\n************** START ***************\n\n");
printf("Slave CiA 401 example, compiled %s\n", __DATE__);
/* init customer CAN hardware */
codrvHardwareInit();
/* additional hardware initialization */
p401HardwareInit();
printf("CAN init with %d Kbit/s\n", speed);
if (codrvCanInit(speed) != RET_OK) {
exit(1);
}
if (coCanOpenStackInit(NULL) != RET_OK) {
printf("error init library\n");
exit(1);
}
if (codrvTimerSetup(CO_TIMER_INTERVAL) != RET_OK) {
exit(2);
}
/* register event functions */
if (coEventRegister_NMT(nmtInd) != RET_OK) {
exit(3);
}
if (coEventRegister_ERRCTRL(hbState) != RET_OK) {
exit(4);
}
if (coEventRegister_SDO_SERVER_READ(sdoServerReadInd) != RET_OK) {
exit(5);
}
if (coEventRegister_SDO_SERVER_CHECK_WRITE(sdoServerCheckWriteInd) != RET_OK) {
exit(6);
}
if (coEventRegister_SDO_SERVER_WRITE(sdoServerWriteInd) != RET_OK) {
exit(7);
}
if (coEventRegister_PDO(pdoInd) != RET_OK) {
exit(8);
}
if (coEventRegister_PDO_REC_EVENT(pdoRecEvent) != RET_OK) {
exit(9);
}
if (coEventRegister_LED_GREEN(ledGreenInd) != RET_OK) {
exit(10);
}
if (coEventRegister_LED_RED(ledRedInd) != RET_OK) {
exit(11);
}
if (coEventRegister_CAN_STATE(canInd) != RET_OK) {
exit(12);
}
if (coEventRegister_COMM_EVENT(commInd) != RET_OK) {
exit(13);
}
/* --- 401 specific ------------------------------------------------*/
/* profile 401 HW acess registration */
if (co401Init() != RET_OK) {
// printf("error init 401 profile handler\n");
exit(14);
}
if (coEventRegister_401(
byte_in_piInd, /* digital in HW API function */
byte_out_printfInd, /* digital out HW API function */
analog_in_piInd, /* the analog in HW API function */
analog_out_printfInd /* analog out HW API function */
) != RET_OK) {
printf("Registration of 401 HW access functions failed\n");
exit(15);
}
/* -----------------------------------------------------------------*/
/* set up a timer to signal that the evaluation period is over soon.
* The battery example is build using an CANopen stack library
* which only works for a specified period of time. If this duration
* is over, CANopen simply stops working */
if(coTimerStart(&evaTimer, 60*60*1000000ul, evaTimeOver, NULL, CO_TIMER_ATTR_ROUNDUP) != RET_OK) {
exit(16);
}
printf("Enable CAN and go into application loop\n\r\n");
codrvCanEnable();
while (1) {
coCommTask();
co401Task();
}
}
/* Evaluation period is over, switch blue LED on */
static void evaTimeOver(void *pData)
{
(void)pData; /* not used */
printf("\nBe prepared, application will stop working soon\n");
STM_EVAL_LEDOn(LED6);
}
/*********************************************************************
The following are definitions of communication indication functions.
The application can use these functions to process communication events
application specific. This example, implementing the CiA 401 profile,
is only using the indications to display it using simple printf()
messages.
**********************************************************************/
/*********************************************************************/
RET_T nmtInd(
BOOL_T execute,
CO_NMT_STATE_T newState
)
{
printf("USR: nmtInd: New Nmt state %d - execute %d\n", newState, execute);
return(RET_OK);
}
/*********************************************************************/
void pdoInd(
UNSIGNED16 pdoNr
)
{
printf("USR: pdoInd: pdo %d received\n", pdoNr);
}
/*********************************************************************/
void pdoRecEvent(
UNSIGNED16 pdoNr
)
{
printf("USR: pdoRecEvent: pdo %d time out\n", pdoNr);
}
/*********************************************************************/
void hbState(
UNSIGNED8 nodeId,
CO_ERRCTRL_T state,
CO_NMT_STATE_T nmtState
)
{
printf("USR: hbInd: HB Event %d node %d nmtState: %d\n", state, nodeId, nmtState);
return;
}
/*********************************************************************/
static RET_T sdoServerReadInd(
BOOL_T execute,
UNSIGNED8 sdoNr,
UNSIGNED16 index,
UNSIGNED8 subIndex
)
{
// printf("USR: sdo server read ind: exec: %d, sdoNr %d, index %x:%d\n",
// execute, sdoNr, index, subIndex);
return(RET_OK);
}
/*********************************************************************/
static RET_T sdoServerCheckWriteInd(
BOOL_T execute,
UNSIGNED8 sdoNr,
UNSIGNED16 index,
UNSIGNED8 subIndex,
const UNSIGNED8 *pData
)
{
// printf("USR: sdo server check write ind: exec: %d, sdoNr %d, index %x:%d\n",
// execute, sdoNr, index, subIndex);
return(RET_OK);
}
/*********************************************************************/
static RET_T sdoServerWriteInd(
BOOL_T execute,
UNSIGNED8 sdoNr,
UNSIGNED16 index,
UNSIGNED8 subIndex
)
{
// printf("USR: sdo server write ind: exec: %d, sdoNr %d, index %x:%d\n",
// execute, sdoNr, index, subIndex);
return(RET_OK);
}
/*********************************************************************/
static void canInd(
CO_CAN_STATE_T canState
)
{
switch (canState) {
case CO_CAN_STATE_BUS_OFF:
printf("USR: CAN: Bus Off\n\n");
break;
case CO_CAN_STATE_BUS_ON:
printf("USR: CAN: Bus On\n\n");
break;
case CO_CAN_STATE_PASSIVE:
printf("USR: CAN: Passiv\n\n");
break;
case CO_CAN_STATE_UNCHANGED:
printf("USR: CAN: unchanged\n");
break;
default:
break;
}
}
/*********************************************************************/
static void commInd(
CO_COMM_STATE_EVENT_T commEvent
)
{
switch (commEvent) {
case CO_COMM_STATE_EVENT_BUS_OFF:
// printf("COMM-Event Bus Off\n");
break;
case CO_COMM_STATE_EVENT_BUS_OFF_RECOVERY:
// printf("COMM-Event Bus Off\n");
break;
case CO_COMM_STATE_EVENT_BUS_ON:
// printf("COMM-Event Bus On\n");
break;
case CO_COMM_STATE_EVENT_PASSIVE:
// printf("COMM-Event Bus Passive\n");
break;
case CO_COMM_STATE_EVENT_ACTIVE:
// printf("COMM-Event Bus Active\n");
break;
case CO_COMM_STATE_EVENT_CAN_OVERRUN:
// printf("COMM-Event CAN Overrun\n");
break;
case CO_COMM_STATE_EVENT_REC_QUEUE_FULL:
// printf("COMM-Event Rec Queue Full\n");
break;
case CO_COMM_STATE_EVENT_REC_QUEUE_OVERFLOW:
// printf("COMM-Event Rec Queue Overflow\n");
break;
case CO_COMM_STATE_EVENT_TR_QUEUE_FULL:
// printf("COMM-Event Tr Queue Full\n");
break;
case CO_COMM_STATE_EVENT_TR_QUEUE_OVERFLOW:
// printf("COMM-Event Tr Queue Empty\n");
break;
case CO_COMM_STATE_EVENT_TR_QUEUE_EMPTY:
// printf("COMM-Event Tr Queue Empty\n");
break;
default:
break;
}
}
/*********************************************************************/
/* LED indication functions, control on-board LEDs */
static void ledGreenInd(
BOOL_T on
)
{
#if 1
if(on) {
STM_EVAL_LEDOn(LED4);
} else {
STM_EVAL_LEDOff(LED4);
}
#endif
}
/*********************************************************************/
static void ledRedInd(
BOOL_T on
)
{
#if 1
if (on) {
STM_EVAL_LEDOn(LED4);
} else {
STM_EVAL_LEDOff(LED4);
}
#endif
}
void InitUSART2(int speed)
{
USART_InitTypeDef USART_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
speed = speed;
/* Enable clocks */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
/* Configure UART2_Tx pin PA2 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init (GPIOA, &GPIO_InitStructure);
/* Connect USART2 pins to AF2 */
GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2);
/* Configure UART2_Rx pin PA3 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_Init (GPIOA, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2);
USART_StructInit(&USART_InitStructure);
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No ;
USART_InitStructure.USART_BaudRate = speed;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = (USART_Mode_Tx | USART_Mode_Rx);
USART_Init(USART2, &USART_InitStructure);
/* enable USART2 */
USART_Cmd(USART2, ENABLE);
}
/* exit() is implemented to switch on the error LED
* and stay in a while() loop
* proto type is in stdlib.h
*/
void exit(int exitcode)
{
printf("Run time error %d", exitcode);
STM_EVAL_LEDOn(LED4);
while(1);
}
/* vim: set ts=4 sw=4 spelllang=en : */
|
|