ESP32: CAN module (#1958)
* can extension * can extension: bit timing and filter * can -> CAN * post CAN data callback * CAN docs * CAN: fixed receive, filter, extended frame * reorder fn in can.md, remove driver_can/Kconfig * fixed a leak when can.stop()
This commit is contained in:
parent
1915714bc2
commit
ff30f479e1
|
@ -0,0 +1,241 @@
|
||||||
|
/**
|
||||||
|
* @section License
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2017, Thomas Barth, barth-dev.de
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||||
|
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||||
|
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "CAN.h"
|
||||||
|
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "freertos/queue.h"
|
||||||
|
|
||||||
|
#include "esp_intr.h"
|
||||||
|
#include "soc/dport_reg.h"
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#include "driver/gpio.h"
|
||||||
|
|
||||||
|
#include "can_regdef.h"
|
||||||
|
#include "CAN_config.h"
|
||||||
|
|
||||||
|
|
||||||
|
static void CAN_read_frame();
|
||||||
|
static void CAN_isr(void *arg_p);
|
||||||
|
|
||||||
|
|
||||||
|
static void CAN_isr(void *arg_p){
|
||||||
|
|
||||||
|
uint8_t interrupt;
|
||||||
|
|
||||||
|
// Read interrupt status and clears flags
|
||||||
|
interrupt = MODULE_CAN->IR.U;
|
||||||
|
|
||||||
|
// Handle TX complete interrupt
|
||||||
|
if ((interrupt & __CAN_IRQ_TX) != 0) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle RX frame available interrupt
|
||||||
|
if ((interrupt & __CAN_IRQ_RX) != 0) {
|
||||||
|
if (CAN_cfg.rx_queue == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
CAN_read_frame();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle error interrupts.
|
||||||
|
if ((interrupt & (__CAN_IRQ_ERR //0x4
|
||||||
|
| __CAN_IRQ_DATA_OVERRUN //0x8
|
||||||
|
| __CAN_IRQ_WAKEUP //0x10
|
||||||
|
| __CAN_IRQ_ERR_PASSIVE //0x20
|
||||||
|
| __CAN_IRQ_ARB_LOST //0x40
|
||||||
|
| __CAN_IRQ_BUS_ERR //0x80
|
||||||
|
)) != 0) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void CAN_read_frame(){
|
||||||
|
|
||||||
|
//byte iterator
|
||||||
|
uint8_t __byte_i;
|
||||||
|
|
||||||
|
//frame read buffer
|
||||||
|
CAN_frame_t __frame;
|
||||||
|
|
||||||
|
// for extended format frames, FF is 1.
|
||||||
|
if(MODULE_CAN->MBX_CTRL.FCTRL.FIR.B.FF==1){
|
||||||
|
//Get Message ID
|
||||||
|
__frame.MsgID = (((uint32_t)MODULE_CAN->MBX_CTRL.FCTRL.TX_RX.EXT.ID[0] << 21)
|
||||||
|
| (MODULE_CAN->MBX_CTRL.FCTRL.TX_RX.EXT.ID[1] << 13)
|
||||||
|
| (MODULE_CAN->MBX_CTRL.FCTRL.TX_RX.EXT.ID[2] << 5)
|
||||||
|
| (MODULE_CAN->MBX_CTRL.FCTRL.TX_RX.EXT.ID[3] >> 3));
|
||||||
|
|
||||||
|
//get DLC
|
||||||
|
__frame.DLC = MODULE_CAN->MBX_CTRL.FCTRL.FIR.B.DLC;
|
||||||
|
__frame.Extended = 1;
|
||||||
|
//deep copy data bytes
|
||||||
|
for(__byte_i=0;__byte_i<__frame.DLC;__byte_i++)
|
||||||
|
__frame.data.u8[__byte_i]=MODULE_CAN->MBX_CTRL.FCTRL.TX_RX.EXT.data[__byte_i];
|
||||||
|
} else {
|
||||||
|
//Get Message ID
|
||||||
|
__frame.MsgID = (((uint32_t)MODULE_CAN->MBX_CTRL.FCTRL.TX_RX.STD.ID[0] << 3) | (MODULE_CAN->MBX_CTRL.FCTRL.TX_RX.STD.ID[1]>>5));
|
||||||
|
|
||||||
|
//get DLC
|
||||||
|
__frame.DLC = MODULE_CAN->MBX_CTRL.FCTRL.FIR.B.DLC;
|
||||||
|
__frame.Extended = 0;
|
||||||
|
//deep copy data bytes
|
||||||
|
for(__byte_i=0;__byte_i<__frame.DLC;__byte_i++)
|
||||||
|
__frame.data.u8[__byte_i]=MODULE_CAN->MBX_CTRL.FCTRL.TX_RX.STD.data[__byte_i];
|
||||||
|
}
|
||||||
|
// Let the hardware know the frame has been read.
|
||||||
|
MODULE_CAN->CMR.B.RRB=1;
|
||||||
|
|
||||||
|
//send frame to input queue
|
||||||
|
xQueueSendFromISR(CAN_cfg.rx_queue,&__frame,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int CAN_write_frame(const CAN_frame_t* p_frame){
|
||||||
|
|
||||||
|
//byte iterator
|
||||||
|
uint8_t __byte_i;
|
||||||
|
|
||||||
|
if(p_frame->Extended) {
|
||||||
|
MODULE_CAN->MBX_CTRL.FCTRL.FIR.U=p_frame->DLC | 0x80;
|
||||||
|
|
||||||
|
//Write message ID
|
||||||
|
MODULE_CAN->MBX_CTRL.FCTRL.TX_RX.EXT.ID[0] = ((p_frame->MsgID & 0x1fe00000) >> 21);
|
||||||
|
MODULE_CAN->MBX_CTRL.FCTRL.TX_RX.EXT.ID[1] = ((p_frame->MsgID & 0x001fe000) >> 13);
|
||||||
|
MODULE_CAN->MBX_CTRL.FCTRL.TX_RX.EXT.ID[2] = ((p_frame->MsgID & 0x00001fe0) >> 5);
|
||||||
|
MODULE_CAN->MBX_CTRL.FCTRL.TX_RX.EXT.ID[3] = ((p_frame->MsgID & 0x0000001f) << 3);
|
||||||
|
|
||||||
|
// Copy the frame data to the hardware
|
||||||
|
for(__byte_i=0;__byte_i<p_frame->DLC;__byte_i++)
|
||||||
|
MODULE_CAN->MBX_CTRL.FCTRL.TX_RX.EXT.data[__byte_i]=p_frame->data.u8[__byte_i];
|
||||||
|
} else {
|
||||||
|
//set frame format to standard and no RTR (needs to be done in a single write)
|
||||||
|
MODULE_CAN->MBX_CTRL.FCTRL.FIR.U=p_frame->DLC;
|
||||||
|
|
||||||
|
//Write message ID
|
||||||
|
MODULE_CAN->MBX_CTRL.FCTRL.TX_RX.STD.ID[0] = ((p_frame->MsgID) >> 3);
|
||||||
|
MODULE_CAN->MBX_CTRL.FCTRL.TX_RX.STD.ID[1] = ((p_frame->MsgID) << 5);
|
||||||
|
|
||||||
|
// Copy the frame data to the hardware
|
||||||
|
for(__byte_i=0;__byte_i<p_frame->DLC;__byte_i++)
|
||||||
|
MODULE_CAN->MBX_CTRL.FCTRL.TX_RX.STD.data[__byte_i]=p_frame->data.u8[__byte_i];
|
||||||
|
}
|
||||||
|
// Transmit frame
|
||||||
|
MODULE_CAN->CMR.B.TR=1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int CAN_init(){
|
||||||
|
|
||||||
|
//enable module
|
||||||
|
SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_CAN_CLK_EN);
|
||||||
|
CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_CAN_RST);
|
||||||
|
|
||||||
|
//configure TX pin
|
||||||
|
gpio_set_direction(CAN_cfg.tx_pin_id,GPIO_MODE_OUTPUT);
|
||||||
|
gpio_matrix_out(CAN_cfg.tx_pin_id,CAN_TX_IDX,0,0);
|
||||||
|
gpio_pad_select_gpio(CAN_cfg.tx_pin_id);
|
||||||
|
|
||||||
|
//configure RX pin
|
||||||
|
gpio_set_direction(CAN_cfg.rx_pin_id,GPIO_MODE_INPUT);
|
||||||
|
gpio_matrix_in(CAN_cfg.rx_pin_id,CAN_RX_IDX,0);
|
||||||
|
gpio_pad_select_gpio(CAN_cfg.rx_pin_id);
|
||||||
|
|
||||||
|
//set to PELICAN mode
|
||||||
|
MODULE_CAN->CDR.B.CAN_M=0x1;
|
||||||
|
|
||||||
|
//synchronization jump width is the same for all baud rates
|
||||||
|
MODULE_CAN->BTR0.B.SJW =0x1;
|
||||||
|
|
||||||
|
//select time quantum and set TSEG1
|
||||||
|
switch(CAN_cfg.speed){
|
||||||
|
case CAN_SPEED_1000KBPS:
|
||||||
|
case CAN_SPEED_800KBPS:
|
||||||
|
MODULE_CAN->BTR1.B.TSEG1 = 8 - 1;
|
||||||
|
MODULE_CAN->BTR1.B.TSEG2 = 1 - 1;
|
||||||
|
MODULE_CAN->BTR0.B.BRP = APB_CLK_FREQ / CAN_cfg.speed / 2000 / (1 + 8 + 1) - 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
MODULE_CAN->BTR1.B.TSEG1 = 13 - 1;
|
||||||
|
MODULE_CAN->BTR1.B.TSEG2 = 2 - 1;
|
||||||
|
MODULE_CAN->BTR0.B.BRP = APB_CLK_FREQ / CAN_cfg.speed/ 2000 / (1 + 13 + 2) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set sampling
|
||||||
|
* 1 -> triple; the bus is sampled three times; recommended for low/medium speed buses (class A and B) where filtering spikes on the bus line is beneficial
|
||||||
|
* 0 -> single; the bus is sampled once; recommended for high speed buses (SAE class C)*/
|
||||||
|
MODULE_CAN->BTR1.B.SAM =0x1;
|
||||||
|
|
||||||
|
//enable all interrupts
|
||||||
|
MODULE_CAN->IER.U = 0xff;
|
||||||
|
|
||||||
|
MODULE_CAN->MOD.B.AFM = CAN_cfg.dual_filter? 0 : 1;
|
||||||
|
|
||||||
|
//no acceptance filtering, as we want to fetch all messages
|
||||||
|
MODULE_CAN->MBX_CTRL.ACC.CODE[0] = CAN_cfg.code >> 24;
|
||||||
|
MODULE_CAN->MBX_CTRL.ACC.CODE[1] = (CAN_cfg.code >> 16) & 0x00ff;
|
||||||
|
MODULE_CAN->MBX_CTRL.ACC.CODE[2] = (CAN_cfg.code >> 8) & 0x00ff;
|
||||||
|
MODULE_CAN->MBX_CTRL.ACC.CODE[3] = CAN_cfg.code & 0x00ff;
|
||||||
|
MODULE_CAN->MBX_CTRL.ACC.MASK[0] = CAN_cfg.mask >> 24;
|
||||||
|
MODULE_CAN->MBX_CTRL.ACC.MASK[1] = (CAN_cfg.mask >> 16) & 0x00ff;
|
||||||
|
MODULE_CAN->MBX_CTRL.ACC.MASK[2] = (CAN_cfg.mask >> 8) & 0x00ff;
|
||||||
|
MODULE_CAN->MBX_CTRL.ACC.MASK[3] = CAN_cfg.mask & 0x00ff;
|
||||||
|
|
||||||
|
//set to normal mode
|
||||||
|
MODULE_CAN->OCR.B.OCMODE=__CAN_OC_NOM;
|
||||||
|
|
||||||
|
//clear error counters
|
||||||
|
MODULE_CAN->TXERR.U = 0;
|
||||||
|
MODULE_CAN->RXERR.U = 0;
|
||||||
|
(void)MODULE_CAN->ECC;
|
||||||
|
|
||||||
|
//clear interrupt flags
|
||||||
|
(void)MODULE_CAN->IR.U;
|
||||||
|
|
||||||
|
//install CAN ISR
|
||||||
|
esp_intr_alloc(ETS_CAN_INTR_SOURCE,0,CAN_isr,NULL,NULL);
|
||||||
|
|
||||||
|
//Showtime. Release Reset Mode.
|
||||||
|
MODULE_CAN->MOD.B.RM = 0;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CAN_stop(){
|
||||||
|
|
||||||
|
MODULE_CAN->MOD.B.RM = 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
#
|
||||||
|
# Main component makefile.
|
||||||
|
#
|
||||||
|
# This Makefile can be left empty. By default, it will take the sources in the
|
||||||
|
# src/ directory, compile them and link them into lib(subdirectory_name).a
|
||||||
|
# in the build directory. This behaviour is entirely configurable,
|
||||||
|
# please read the ESP-IDF documents if you need to do this.
|
||||||
|
#
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
/**
|
||||||
|
* @section License
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2017, Thomas Barth, barth-dev.de
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||||
|
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||||
|
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __DRIVERS_CAN_H__
|
||||||
|
#define __DRIVERS_CAN_H__
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "CAN_config.h"
|
||||||
|
|
||||||
|
/** \brief CAN Frame structure */
|
||||||
|
typedef struct {
|
||||||
|
uint8_t Extended;
|
||||||
|
uint32_t MsgID; /**< \brief Message ID */
|
||||||
|
uint32_t DLC; /**< \brief Length */
|
||||||
|
union {
|
||||||
|
uint8_t u8[8]; /**< \brief Payload byte access*/
|
||||||
|
uint32_t u32[2]; /**< \brief Payload u32 access*/
|
||||||
|
} data;
|
||||||
|
}CAN_frame_t;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Initialize the CAN Module
|
||||||
|
*
|
||||||
|
* \return 0 CAN Module had been initialized
|
||||||
|
*/
|
||||||
|
int CAN_init(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Send a can frame
|
||||||
|
*
|
||||||
|
* \param p_frame Pointer to the frame to be send, see #CAN_frame_t
|
||||||
|
* \return 0 Frame has been written to the module
|
||||||
|
*/
|
||||||
|
int CAN_write_frame(const CAN_frame_t* p_frame);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Stops the CAN Module
|
||||||
|
*
|
||||||
|
* \return 0 CAN Module was stopped
|
||||||
|
*/
|
||||||
|
int CAN_stop(void);
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,62 @@
|
||||||
|
/**
|
||||||
|
* @section License
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2017, Thomas Barth, barth-dev.de
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||||
|
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||||
|
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __DRIVERS_CAN_CFG_H__
|
||||||
|
#define __DRIVERS_CAN_CFG_H__
|
||||||
|
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "freertos/queue.h"
|
||||||
|
#include "driver/gpio.h"
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief CAN Node Bus speed */
|
||||||
|
typedef enum {
|
||||||
|
CAN_SPEED_100KBPS=100, /**< \brief CAN Node runs at 100kBit/s. */
|
||||||
|
CAN_SPEED_125KBPS=125, /**< \brief CAN Node runs at 125kBit/s. */
|
||||||
|
CAN_SPEED_250KBPS=250, /**< \brief CAN Node runs at 250kBit/s. */
|
||||||
|
CAN_SPEED_500KBPS=500, /**< \brief CAN Node runs at 500kBit/s. */
|
||||||
|
CAN_SPEED_800KBPS=800, /**< \brief CAN Node runs at 800kBit/s. */
|
||||||
|
CAN_SPEED_1000KBPS=1000 /**< \brief CAN Node runs at 1000kBit/s. */
|
||||||
|
}CAN_speed_t;
|
||||||
|
|
||||||
|
/** \brief CAN configuration structure */
|
||||||
|
typedef struct {
|
||||||
|
CAN_speed_t speed; /**< \brief CAN speed. */
|
||||||
|
gpio_num_t tx_pin_id; /**< \brief TX pin. */
|
||||||
|
gpio_num_t rx_pin_id; /**< \brief RX pin. */
|
||||||
|
QueueHandle_t rx_queue; /**< \brief Handler to FreeRTOS RX queue. */
|
||||||
|
uint32_t code;
|
||||||
|
uint32_t mask;
|
||||||
|
bool dual_filter;
|
||||||
|
}CAN_device_t;
|
||||||
|
|
||||||
|
/** \brief CAN configuration reference */
|
||||||
|
extern CAN_device_t CAN_cfg;
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* __DRIVERS_CAN_CFG_H__ */
|
|
@ -0,0 +1,237 @@
|
||||||
|
/**
|
||||||
|
* @section License
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2017, Thomas Barth, barth-dev.de
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||||
|
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||||
|
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __DRIVERS_CAN_REGDEF_H_
|
||||||
|
#define __DRIVERS_CAN_REGDEF_H_
|
||||||
|
|
||||||
|
/** \brief Start address of CAN registers */
|
||||||
|
#define MODULE_CAN ((volatile CAN_Module_t *)0x3ff6b000)
|
||||||
|
|
||||||
|
/** \brief Interrupt status register */
|
||||||
|
typedef enum {
|
||||||
|
__CAN_IRQ_RX= BIT(0), /**< \brief RX Interrupt */
|
||||||
|
__CAN_IRQ_TX= BIT(1), /**< \brief TX Interrupt */
|
||||||
|
__CAN_IRQ_ERR= BIT(2), /**< \brief Error Interrupt */
|
||||||
|
__CAN_IRQ_DATA_OVERRUN= BIT(3), /**< \brief Date Overrun Interrupt */
|
||||||
|
__CAN_IRQ_WAKEUP= BIT(4), /**< \brief Wakeup Interrupt */
|
||||||
|
__CAN_IRQ_ERR_PASSIVE= BIT(5), /**< \brief Passive Error Interrupt */
|
||||||
|
__CAN_IRQ_ARB_LOST= BIT(6), /**< \brief Arbitration lost interrupt */
|
||||||
|
__CAN_IRQ_BUS_ERR= BIT(7), /**< \brief Bus error Interrupt */
|
||||||
|
}__CAN_IRQ_t;
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief OCMODE options. */
|
||||||
|
typedef enum {
|
||||||
|
__CAN_OC_BOM= 0b00, /**< \brief bi-phase output mode */
|
||||||
|
__CAN_OC_TOM= 0b01, /**< \brief test output mode */
|
||||||
|
__CAN_OC_NOM= 0b10, /**< \brief normal output mode */
|
||||||
|
__CAN_OC_COM= 0b11, /**< \brief clock output mode */
|
||||||
|
}__CAN_OCMODE_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CAN controller (SJA1000).
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
union{uint32_t U; /**< \brief Unsigned access */
|
||||||
|
struct {
|
||||||
|
unsigned int RM:1; /**< \brief MOD.0 Reset Mode */
|
||||||
|
unsigned int LOM:1; /**< \brief MOD.1 Listen Only Mode */
|
||||||
|
unsigned int STM:1; /**< \brief MOD.2 Self Test Mode */
|
||||||
|
unsigned int AFM:1; /**< \brief MOD.3 Acceptance Filter Mode */
|
||||||
|
unsigned int SM:1; /**< \brief MOD.4 Sleep Mode */
|
||||||
|
unsigned int reserved_27:27; /**< \brief \internal Reserved */
|
||||||
|
} B;
|
||||||
|
} MOD;
|
||||||
|
union{uint32_t U; /**< \brief Unsigned access */
|
||||||
|
struct {
|
||||||
|
unsigned int TR:1; /**< \brief CMR.0 Transmission Request */
|
||||||
|
unsigned int AT:1; /**< \brief CMR.1 Abort Transmission */
|
||||||
|
unsigned int RRB:1; /**< \brief CMR.2 Release Receive Buffer */
|
||||||
|
unsigned int CDO:1; /**< \brief CMR.3 Clear Data Overrun */
|
||||||
|
unsigned int GTS:1; /**< \brief CMR.4 Go To Sleep */
|
||||||
|
unsigned int reserved_27:27; /**< \brief \internal Reserved */
|
||||||
|
} B;
|
||||||
|
} CMR;
|
||||||
|
union{uint32_t U; /**< \brief Unsigned access */
|
||||||
|
struct {
|
||||||
|
unsigned int RBS:1; /**< \brief SR.0 Receive Buffer Status */
|
||||||
|
unsigned int DOS:1; /**< \brief SR.1 Data Overrun Status */
|
||||||
|
unsigned int TBS:1; /**< \brief SR.2 Transmit Buffer Status */
|
||||||
|
unsigned int TCS:1; /**< \brief SR.3 Transmission Complete Status */
|
||||||
|
unsigned int RS:1; /**< \brief SR.4 Receive Status */
|
||||||
|
unsigned int TS:1; /**< \brief SR.5 Transmit Status */
|
||||||
|
unsigned int ES:1; /**< \brief SR.6 Error Status */
|
||||||
|
unsigned int BS:1; /**< \brief SR.7 Bus Status */
|
||||||
|
unsigned int reserved_24:24; /**< \brief \internal Reserved */
|
||||||
|
} B;
|
||||||
|
} SR;
|
||||||
|
union{uint32_t U; /**< \brief Unsigned access */
|
||||||
|
struct {
|
||||||
|
unsigned int RI:1; /**< \brief IR.0 Receive Interrupt */
|
||||||
|
unsigned int TI:1; /**< \brief IR.1 Transmit Interrupt */
|
||||||
|
unsigned int EI:1; /**< \brief IR.2 Error Interrupt */
|
||||||
|
unsigned int DOI:1; /**< \brief IR.3 Data Overrun Interrupt */
|
||||||
|
unsigned int WUI:1; /**< \brief IR.4 Wake-Up Interrupt */
|
||||||
|
unsigned int EPI:1; /**< \brief IR.5 Error Passive Interrupt */
|
||||||
|
unsigned int ALI:1; /**< \brief IR.6 Arbitration Lost Interrupt */
|
||||||
|
unsigned int BEI:1; /**< \brief IR.7 Bus Error Interrupt */
|
||||||
|
unsigned int reserved_24:24; /**< \brief \internal Reserved */
|
||||||
|
} B;
|
||||||
|
} IR;
|
||||||
|
union{uint32_t U; /**< \brief Unsigned access */
|
||||||
|
struct {
|
||||||
|
unsigned int RIE:1; /**< \brief IER.0 Receive Interrupt Enable */
|
||||||
|
unsigned int TIE:1; /**< \brief IER.1 Transmit Interrupt Enable */
|
||||||
|
unsigned int EIE:1; /**< \brief IER.2 Error Interrupt Enable */
|
||||||
|
unsigned int DOIE:1; /**< \brief IER.3 Data Overrun Interrupt Enable */
|
||||||
|
unsigned int WUIE:1; /**< \brief IER.4 Wake-Up Interrupt Enable */
|
||||||
|
unsigned int EPIE:1; /**< \brief IER.5 Error Passive Interrupt Enable */
|
||||||
|
unsigned int ALIE:1; /**< \brief IER.6 Arbitration Lost Interrupt Enable */
|
||||||
|
unsigned int BEIE:1; /**< \brief IER.7 Bus Error Interrupt Enable */
|
||||||
|
unsigned int reserved_24:24; /**< \brief \internal Reserved */
|
||||||
|
} B;
|
||||||
|
} IER;
|
||||||
|
uint32_t RESERVED0;
|
||||||
|
union{uint32_t U; /**< \brief Unsigned access */
|
||||||
|
struct {
|
||||||
|
unsigned int BRP:6; /**< \brief BTR0[5:0] Baud Rate Prescaler */
|
||||||
|
unsigned int SJW:2; /**< \brief BTR0[7:6] Synchronization Jump Width*/
|
||||||
|
unsigned int reserved_24:24; /**< \brief \internal Reserved */
|
||||||
|
} B;
|
||||||
|
} BTR0;
|
||||||
|
union{uint32_t U; /**< \brief Unsigned access */
|
||||||
|
struct {
|
||||||
|
unsigned int TSEG1:4; /**< \brief BTR1[3:0] Timing Segment 1 */
|
||||||
|
unsigned int TSEG2:3; /**< \brief BTR1[6:4] Timing Segment 2*/
|
||||||
|
unsigned int SAM:1; /**< \brief BTR1.7 Sampling*/
|
||||||
|
unsigned int reserved_24:24; /**< \brief \internal Reserved */
|
||||||
|
} B;
|
||||||
|
} BTR1;
|
||||||
|
union{uint32_t U; /**< \brief Unsigned access */
|
||||||
|
struct {
|
||||||
|
unsigned int OCMODE:2; /**< \brief OCR[1:0] Output Control Mode, see # */
|
||||||
|
unsigned int OCPOL0:1; /**< \brief OCR.2 Output Control Polarity 0 */
|
||||||
|
unsigned int OCTN0:1; /**< \brief OCR.3 Output Control Transistor N0 */
|
||||||
|
unsigned int OCTP0:1; /**< \brief OCR.4 Output Control Transistor P0 */
|
||||||
|
unsigned int OCPOL1:1; /**< \brief OCR.5 Output Control Polarity 1 */
|
||||||
|
unsigned int OCTN1:1; /**< \brief OCR.6 Output Control Transistor N1 */
|
||||||
|
unsigned int OCTP1:1; /**< \brief OCR.7 Output Control Transistor P1 */
|
||||||
|
unsigned int reserved_24:24; /**< \brief \internal Reserved */
|
||||||
|
} B;
|
||||||
|
} OCR;
|
||||||
|
uint32_t RESERVED1[2];
|
||||||
|
union{uint32_t U; /**< \brief Unsigned access */
|
||||||
|
struct {
|
||||||
|
unsigned int ALC:8; /**< \brief ALC[7:0] Arbitration Lost Capture */
|
||||||
|
unsigned int reserved_24:24; /**< \brief \internal Reserved */
|
||||||
|
} B;
|
||||||
|
} ALC;
|
||||||
|
union{uint32_t U; /**< \brief Unsigned access */
|
||||||
|
struct {
|
||||||
|
unsigned int ECC:8; /**< \brief ECC[7:0] Error Code Capture */
|
||||||
|
unsigned int reserved_24:24; /**< \brief \internal Reserved */
|
||||||
|
} B;
|
||||||
|
} ECC;
|
||||||
|
union{uint32_t U; /**< \brief Unsigned access */
|
||||||
|
struct {
|
||||||
|
unsigned int EWLR:8; /**< \brief EWLR[7:0] Error Warning Limit */
|
||||||
|
unsigned int reserved_24:24; /**< \brief \internal Reserved */
|
||||||
|
} B;
|
||||||
|
} EWLR;
|
||||||
|
union{uint32_t U; /**< \brief Unsigned access */
|
||||||
|
struct {
|
||||||
|
unsigned int RXERR:8; /**< \brief RXERR[7:0] Receive Error Counter */
|
||||||
|
unsigned int reserved_24:24; /**< \brief \internal Reserved */
|
||||||
|
} B;
|
||||||
|
} RXERR;
|
||||||
|
union{uint32_t U; /**< \brief Unsigned access */
|
||||||
|
struct {
|
||||||
|
unsigned int TXERR:8; /**< \brief TXERR[7:0] Transmit Error Counter */
|
||||||
|
unsigned int reserved_24:24; /**< \brief \internal Reserved */
|
||||||
|
} B;
|
||||||
|
} TXERR;
|
||||||
|
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
uint32_t CODE[4]; /**< \brief Acceptance Message ID */
|
||||||
|
uint32_t MASK[4]; /**< \brief Acceptance Mask */
|
||||||
|
uint32_t RESERVED2[5];
|
||||||
|
} ACC; /**< \brief Acceptance filtering */
|
||||||
|
|
||||||
|
struct {
|
||||||
|
union{uint32_t U; /**< \brief Unsigned access */
|
||||||
|
struct {
|
||||||
|
unsigned int DLC:4; /**< \brief [3:0] DLC, Data length container */
|
||||||
|
unsigned int unknown_2:2; /**< \brief \internal unknown */
|
||||||
|
unsigned int RTR:1; /**< \brief [6:6] RTR, Remote Transmission Request */
|
||||||
|
unsigned int FF:1; /**< \brief [7:7] Frame Format */
|
||||||
|
unsigned int reserved_24:24; /**< \brief \internal Reserved */
|
||||||
|
} B;
|
||||||
|
} FIR; /**< \brief Frame information record */
|
||||||
|
|
||||||
|
union{
|
||||||
|
struct {
|
||||||
|
uint32_t ID[2]; /**< \brief Standard frame message-ID*/
|
||||||
|
uint32_t data[8]; /**< \brief Standard frame payload */
|
||||||
|
uint32_t reserved[2];
|
||||||
|
} STD; /**< \brief Standard frame format */
|
||||||
|
struct {
|
||||||
|
uint32_t ID[4]; /**< \brief Extended frame message-ID*/
|
||||||
|
uint32_t data[8]; /**< \brief Extended frame payload */
|
||||||
|
} EXT; /**< \brief Extended frame format */
|
||||||
|
}TX_RX; /**< \brief RX/TX interface */
|
||||||
|
}FCTRL; /**< \brief Function control regs */
|
||||||
|
} MBX_CTRL; /**< \brief Mailbox control */
|
||||||
|
|
||||||
|
union{uint32_t U; /**< \brief Unsigned access */
|
||||||
|
struct {
|
||||||
|
unsigned int RMC:8; /**< \brief RMC[7:0] RX Message Counter */
|
||||||
|
unsigned int reserved_24:24; /**< \brief \internal Reserved Enable */
|
||||||
|
} B;
|
||||||
|
} RMC;
|
||||||
|
union{uint32_t U; /**< \brief Unsigned access */
|
||||||
|
struct {
|
||||||
|
unsigned int RBSA:8; /**< \brief RBSA[7:0] RX Buffer Start Address */
|
||||||
|
unsigned int reserved_24:24; /**< \brief \internal Reserved Enable */
|
||||||
|
} B;
|
||||||
|
} RBSA;
|
||||||
|
union{uint32_t U; /**< \brief Unsigned access */
|
||||||
|
struct {
|
||||||
|
unsigned int COD:3; /**< \brief CDR[2:0] CLKOUT frequency selector based of fOSC*/
|
||||||
|
unsigned int COFF:1; /**< \brief CDR.3 CLKOUT off*/
|
||||||
|
unsigned int reserved_1:1; /**< \brief \internal Reserved */
|
||||||
|
unsigned int RXINTEN:1; /**< \brief CDR.5 This bit allows the TX1 output to be used as a dedicated receive interrupt output*/
|
||||||
|
unsigned int CBP:1; /**< \brief CDR.6 allows to bypass the CAN input comparator and is only possible in reset mode.*/
|
||||||
|
unsigned int CAN_M:1; /**< \brief CDR.7 If CDR.7 is at logic 0 the CAN controller operates in BasicCAN mode. If set to logic 1 the CAN controller operates in PeliCAN mode. Write access is only possible in reset mode*/
|
||||||
|
unsigned int reserved_24:24; /**< \brief \internal Reserved */
|
||||||
|
} B;
|
||||||
|
} CDR;
|
||||||
|
uint32_t IRAM[2];
|
||||||
|
}CAN_Module_t;
|
||||||
|
|
||||||
|
#endif /* __DRIVERS_CAN_REGDEF_H_ */
|
|
@ -67,6 +67,12 @@ config LUA_MODULE_BTHCI
|
||||||
help
|
help
|
||||||
Includes the simple BlueTooth HCI module.
|
Includes the simple BlueTooth HCI module.
|
||||||
|
|
||||||
|
config LUA_MODULE_CAN
|
||||||
|
bool "CAN module"
|
||||||
|
default "n"
|
||||||
|
help
|
||||||
|
Includes the can module.
|
||||||
|
|
||||||
config LUA_MODULE_DHT
|
config LUA_MODULE_DHT
|
||||||
bool "DHT11/21/22/AM2301/AM2302 module"
|
bool "DHT11/21/22/AM2301/AM2302 module"
|
||||||
default "n"
|
default "n"
|
||||||
|
|
|
@ -0,0 +1,168 @@
|
||||||
|
// Module for interfacing with adc hardware
|
||||||
|
|
||||||
|
#include "module.h"
|
||||||
|
#include "lauxlib.h"
|
||||||
|
#include "platform.h"
|
||||||
|
|
||||||
|
#include "CAN.h"
|
||||||
|
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "freertos/task.h"
|
||||||
|
#include "freertos/queue.h"
|
||||||
|
#include "esp_task.h"
|
||||||
|
#include "esp_log.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "task/task.h"
|
||||||
|
|
||||||
|
CAN_device_t CAN_cfg = {
|
||||||
|
.speed = CAN_SPEED_1000KBPS, // CAN Node baudrade
|
||||||
|
.tx_pin_id = -1, // CAN TX pin
|
||||||
|
.rx_pin_id = -1, // CAN RX pin
|
||||||
|
.rx_queue = NULL, // FreeRTOS queue for RX frames
|
||||||
|
.code = 0,
|
||||||
|
.mask = 0xffffffff,
|
||||||
|
.dual_filter = false
|
||||||
|
};
|
||||||
|
|
||||||
|
static task_handle_t can_data_task_id;
|
||||||
|
static int can_on_received = LUA_NOREF;
|
||||||
|
|
||||||
|
static xTaskHandle xCanTaskHandle = NULL;
|
||||||
|
|
||||||
|
// LUA
|
||||||
|
static void can_data_task( task_param_t param, task_prio_t prio ) {
|
||||||
|
CAN_frame_t *frame = (CAN_frame_t *)param;
|
||||||
|
|
||||||
|
if(can_on_received == LUA_NOREF) {
|
||||||
|
free( frame );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
lua_State *L = lua_getstate();
|
||||||
|
|
||||||
|
lua_rawgeti(L, LUA_REGISTRYINDEX, can_on_received);
|
||||||
|
lua_pushinteger(L, frame->Extended? 1 : 0);
|
||||||
|
lua_pushinteger(L, frame->MsgID);
|
||||||
|
lua_pushlstring(L, (char *)frame->data.u8, frame->DLC);
|
||||||
|
free( frame );
|
||||||
|
lua_call(L, 3, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// RTOS
|
||||||
|
static void task_CAN( void *pvParameters ){
|
||||||
|
(void)pvParameters;
|
||||||
|
|
||||||
|
//frame buffer
|
||||||
|
CAN_frame_t frame;
|
||||||
|
|
||||||
|
//create CAN RX Queue
|
||||||
|
CAN_cfg.rx_queue = xQueueCreate(10, sizeof(CAN_frame_t));
|
||||||
|
|
||||||
|
//start CAN Module
|
||||||
|
CAN_init();
|
||||||
|
|
||||||
|
for (;;){
|
||||||
|
//receive next CAN frame from queue
|
||||||
|
if( xQueueReceive( CAN_cfg.rx_queue, &frame, 3 * portTICK_PERIOD_MS ) == pdTRUE ){
|
||||||
|
CAN_frame_t *postFrame = (CAN_frame_t *)malloc( sizeof( CAN_frame_t ) );
|
||||||
|
memcpy(postFrame, &frame, sizeof( CAN_frame_t ));
|
||||||
|
task_post_medium( can_data_task_id, (task_param_t)postFrame );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lua: setup( {}, callback )
|
||||||
|
static int can_setup( lua_State *L )
|
||||||
|
{
|
||||||
|
if(xCanTaskHandle != NULL)
|
||||||
|
luaL_error( L, "Stop CAN before setup" );
|
||||||
|
luaL_checkanytable (L, 1);
|
||||||
|
|
||||||
|
luaL_checkanyfunction (L, 2);
|
||||||
|
lua_settop (L, 2);
|
||||||
|
if(can_on_received != LUA_NOREF) luaL_unref(L, LUA_REGISTRYINDEX, can_on_received);
|
||||||
|
can_on_received = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||||
|
|
||||||
|
lua_getfield (L, 1, "speed");
|
||||||
|
CAN_cfg.speed = luaL_checkint(L, -1);
|
||||||
|
lua_getfield (L, 1, "tx");
|
||||||
|
CAN_cfg.tx_pin_id = luaL_checkint(L, -1);
|
||||||
|
lua_getfield (L, 1, "rx");
|
||||||
|
CAN_cfg.rx_pin_id = luaL_checkint(L, -1);
|
||||||
|
lua_getfield (L, 1, "dual_filter");
|
||||||
|
CAN_cfg.dual_filter = lua_toboolean(L, 0);
|
||||||
|
lua_getfield (L, 1, "code");
|
||||||
|
CAN_cfg.code = (uint32_t)luaL_optnumber(L, -1, 0);
|
||||||
|
lua_getfield (L, 1, "mask");
|
||||||
|
CAN_cfg.mask = (uint32_t)luaL_optnumber(L, -1, 0x0ffffffff);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int can_start( lua_State *L )
|
||||||
|
{
|
||||||
|
if(xCanTaskHandle != NULL)
|
||||||
|
luaL_error( L, "CAN started" );
|
||||||
|
xTaskCreate(task_CAN, "CAN", 2048, NULL, ESP_TASK_MAIN_PRIO + 1, &xCanTaskHandle);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int can_stop( lua_State *L )
|
||||||
|
{
|
||||||
|
if(xCanTaskHandle) {
|
||||||
|
vTaskDelete(xCanTaskHandle);
|
||||||
|
xCanTaskHandle = NULL;
|
||||||
|
}
|
||||||
|
CAN_stop();
|
||||||
|
if(CAN_cfg.rx_queue) {
|
||||||
|
vQueueDelete( CAN_cfg.rx_queue );
|
||||||
|
CAN_cfg.rx_queue = NULL;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int can_send( lua_State *L )
|
||||||
|
{
|
||||||
|
uint32_t format = (uint8_t)luaL_checkinteger( L, 1 );
|
||||||
|
uint32_t msg_id = luaL_checkinteger( L, 2 );
|
||||||
|
size_t len;
|
||||||
|
const char *data = luaL_checklstring( L, 3, &len );
|
||||||
|
uint8_t i;
|
||||||
|
CAN_frame_t frame;
|
||||||
|
|
||||||
|
if(xCanTaskHandle == NULL)
|
||||||
|
luaL_error( L, "CAN not started" );
|
||||||
|
|
||||||
|
if(len > 8)
|
||||||
|
luaL_error( L, "CAN can not send more than 8 bytes" );
|
||||||
|
|
||||||
|
frame.Extended = format? 1 : 0;
|
||||||
|
frame.MsgID = msg_id;
|
||||||
|
frame.DLC = len;
|
||||||
|
|
||||||
|
for(i = 0; i < len; i++)
|
||||||
|
frame.data.u8[i] = data[i];
|
||||||
|
|
||||||
|
CAN_write_frame(&frame);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Module function map
|
||||||
|
static const LUA_REG_TYPE can_map[] =
|
||||||
|
{
|
||||||
|
{ LSTRKEY( "setup" ), LFUNCVAL( can_setup ) },
|
||||||
|
{ LSTRKEY( "start" ), LFUNCVAL( can_start ) },
|
||||||
|
{ LSTRKEY( "stop" ), LFUNCVAL( can_stop ) },
|
||||||
|
{ LSTRKEY( "send" ), LFUNCVAL( can_send ) },
|
||||||
|
{ LSTRKEY( "STANDARD_FRAME" ), LNUMVAL( 0 ) },
|
||||||
|
{ LSTRKEY( "EXTENDED_FRAME" ), LNUMVAL( 1 ) },
|
||||||
|
{ LNILKEY, LNILVAL }
|
||||||
|
};
|
||||||
|
|
||||||
|
int luaopen_can( lua_State *L ) {
|
||||||
|
can_data_task_id = task_get_id( can_data_task ); // reset CAN after sw reset
|
||||||
|
CAN_stop();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
NODEMCU_MODULE(CAN, "can", can_map, luaopen_can);
|
|
@ -0,0 +1,77 @@
|
||||||
|
# CAN Module
|
||||||
|
| Since | Origin / Contributor | Maintainer | Source |
|
||||||
|
| :----- | :-------------------- | :---------- | :------ |
|
||||||
|
| 2017-04-27 | [@ThomasBarth](https://github.com/ThomasBarth/ESP32-CAN-Driver/), zelll | | [can.c](../../../components/modules/can.c)|
|
||||||
|
|
||||||
|
The CAN module provides access to the in-built CAN controller.
|
||||||
|
|
||||||
|
|
||||||
|
## can.send()
|
||||||
|
Send a frame.
|
||||||
|
|
||||||
|
#### Syntax
|
||||||
|
`can.send(format, msg_id, data)`
|
||||||
|
|
||||||
|
#### Parameters
|
||||||
|
- `format` Frame format. `can.STANDARD_FRAME` or `can.EXTENDED_FRAME`
|
||||||
|
- `msg_id` CAN Messge ID
|
||||||
|
- `data` CAN data, up to 8 bytes
|
||||||
|
|
||||||
|
#### Returns
|
||||||
|
nil
|
||||||
|
|
||||||
|
|
||||||
|
## can.setup()
|
||||||
|
Configuration CAN controller.
|
||||||
|
|
||||||
|
#### Syntax
|
||||||
|
```lua
|
||||||
|
can.setup({
|
||||||
|
speed = 1000,
|
||||||
|
tx = 5,
|
||||||
|
rx = 4,
|
||||||
|
dual_filter = false,
|
||||||
|
code = 0,
|
||||||
|
mask = 0xffffffff
|
||||||
|
}, function(format, msg_id, data) end)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Parameters
|
||||||
|
- `config`
|
||||||
|
- `speed` kbps. One of following value: `1000`, `800`, `500`, `250`, `100`.
|
||||||
|
- `tx` Pin num for TX.
|
||||||
|
- `rx` Pin num for RX.
|
||||||
|
- `dual_filter` `true` dual filter mode, `false` single filter mode (default)
|
||||||
|
- `code` 4-bytes integer. Use this with mask to filter CAN frame. Default: `0`. See [SJA1000](http://www.nxp.com/documents/data_sheet/SJA1000.pdf)
|
||||||
|
- `mask` 4-bytes integer. Default: `0xffffffff`
|
||||||
|
- `callback` function to be called when CAN data received.
|
||||||
|
- `format` Frame format. `can.STANDARD_FRAME` or `can.EXTENDED_FRAME`
|
||||||
|
- `msg_id` CAN Messge ID
|
||||||
|
- `data` CAN data, up to 8 bytes
|
||||||
|
|
||||||
|
#### Returns
|
||||||
|
nil
|
||||||
|
|
||||||
|
|
||||||
|
## can.start()
|
||||||
|
Start CAN controller.
|
||||||
|
|
||||||
|
#### Syntax
|
||||||
|
`can.start()`
|
||||||
|
|
||||||
|
#### Parameters
|
||||||
|
|
||||||
|
#### Returns
|
||||||
|
nil
|
||||||
|
|
||||||
|
|
||||||
|
## can.stop()
|
||||||
|
Stop CAN controller.
|
||||||
|
|
||||||
|
#### Syntax
|
||||||
|
`can.stop()`
|
||||||
|
|
||||||
|
#### Parameters
|
||||||
|
|
||||||
|
#### Returns
|
||||||
|
nil
|
|
@ -35,6 +35,7 @@ pages:
|
||||||
- 'adc': 'en/modules/adc.md'
|
- 'adc': 'en/modules/adc.md'
|
||||||
- 'bit': 'en/modules/bit.md'
|
- 'bit': 'en/modules/bit.md'
|
||||||
- 'bthci': 'en/modules/bthci.md'
|
- 'bthci': 'en/modules/bthci.md'
|
||||||
|
- 'can': 'en/modules/can.md'
|
||||||
- 'dht': 'en/modules/dht.md'
|
- 'dht': 'en/modules/dht.md'
|
||||||
- 'file': 'en/modules/file.md'
|
- 'file': 'en/modules/file.md'
|
||||||
- 'gpio': 'en/modules/gpio.md'
|
- 'gpio': 'en/modules/gpio.md'
|
||||||
|
|
Loading…
Reference in New Issue