/*
 * can_interface.c
 *
 *  Created on: Aug 6, 2011
 *      Author: Kay K. Duve
 */
#include "can_interface.h"
__IO uint32_t ret = 0; /* for return of the interrupt handling */

/**
 * @brief  Configures the NVIC and Vector Table base address.
 * @param  None
 * @retval None
 */

#define CANx                       CAN1
#define GPIO_CAN                   GPIO_CAN1
#define GPIO_Remapping_CAN         GPIO_Remapping_CAN1
#define GPIO_CAN                   GPIO_CAN1
#define GPIO_Pin_CAN_RX            GPIO_Pin_CAN1_RX
#define GPIO_Pin_CAN_TX            GPIO_Pin_CAN1_TX

CanType ci_controll = Can_Scilent;

void ci_set_mode(CanType mode) {
	ci_controll = mode;
}

CAN_Data_t ci_data[CAN_TABLE_SIZE];

void CAN1_RX0_IRQHandler() {

	uint32_t id;
	CAN_Data_t* pdata;

	STM32vldiscovery_LEDToggle(LED4);
	/* Check the parameters */
	assert_param(IS_CAN_ALL_PERIPH(CAN1));
	assert_param(IS_CAN_FIFO(CAN_FIFO0));
	/* Get the Id */
	id = (uint32_t) 0x000007FF & (CANx->sFIFOMailBox[CAN_FIFO0].RIR >> 21);

	if (id < CAN_TABLE_SIZE) {
		pdata = &ci_data[id];
		pdata->data.d32[0] = CAN1->sFIFOMailBox[CAN_FIFO0].RDLR;
		pdata->data.d32[1] = CAN1->sFIFOMailBox[CAN_FIFO0].RDHR;
		pdata->dlc = 0x0F & CANx->sFIFOMailBox[CAN_FIFO0].RDTR;
		pdata->timestemp = TIM2->CNT;

	}

	CAN1->RF0R |= CAN_RF0R_RFOM0;
}

void NVIC_Configuration(void) {
	NVIC_InitTypeDef NVIC_InitStructure;

	//NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
	NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX0_IRQn;

	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
}

void ci_init(void) {
	uint16_t i;
	CAN_InitTypeDef CAN_InitStructure;
	GPIO_InitTypeDef GPIO_InitStructure;
	CAN_FilterInitTypeDef CAN_FilterInitStructure;
	//uint32_t i = 0;
	NVIC_Configuration();
	/* GPIO clock enable */
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIO_CAN1, ENABLE);

	/* Configure CAN pin: RX */
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_CAN_RX;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_Init(GPIO_CAN, &GPIO_InitStructure);

	/* Configure CAN pin: TX */
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_CAN_TX;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIO_CAN, &GPIO_InitStructure);

	GPIO_PinRemapConfig(GPIO_Remapping_CAN, ENABLE);

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);

	/* CAN register init */
	CAN_DeInit(CAN1);

	CAN_StructInit(&CAN_InitStructure);

	/* CAN cell init */
	CAN_InitStructure.CAN_TTCM = DISABLE;
	CAN_InitStructure.CAN_ABOM = DISABLE;
	CAN_InitStructure.CAN_AWUM = DISABLE;
	CAN_InitStructure.CAN_NART = DISABLE;
	CAN_InitStructure.CAN_RFLM = DISABLE;
	CAN_InitStructure.CAN_TXFP = DISABLE;
	CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;
	CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;

	/* Baudrate = 125 Kbps */
	CAN_InitStructure.CAN_BS1 = CAN_BS1_2tq;
	CAN_InitStructure.CAN_BS2 = CAN_BS2_3tq;
	CAN_InitStructure.CAN_Prescaler = 48;
	CAN_Init(CAN1, &CAN_InitStructure);

	/* CAN filter init */
	CAN_FilterInitStructure.CAN_FilterNumber = 1;

	CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
	CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
	CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000 << 5;
	CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;
	CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000 << 5;
	CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;
	CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_FIFO0;
	CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
	CAN_FilterInit(&CAN_FilterInitStructure);

	/* CAN FIFO0 message pending interrupt enable */
	CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);

	for(i = 0; i<CAN_TABLE_SIZE; i++){
		ci_data[i].data.d64=0;
		ci_data[i].timestemp=0;
		ci_data[i].dlc=0xFFFF;
	}




}
