mirror of
https://github.com/candle-usb/candleLight_fw.git
synced 2025-01-14 05:42:53 +08:00
main: move per channel CAN handling code out of main loop into separate functions
No functional change intended.
This commit is contained in:
parent
844e6c31f4
commit
78bafcf07b
@ -66,6 +66,7 @@ set(
|
||||
src/usbd_conf.c
|
||||
|
||||
include/can.h src/can.c
|
||||
include/can_common.h src/can_common.c
|
||||
include/device.h
|
||||
include/dfu.h src/dfu.c
|
||||
include/gpio.h src/gpio.c
|
||||
|
36
include/can_common.h
Normal file
36
include/can_common.h
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 Hubert Denkmair
|
||||
|
||||
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.
|
||||
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "can.h"
|
||||
#include "usbd_gs_can.h"
|
||||
|
||||
void CAN_SendFrame(USBD_GS_CAN_HandleTypeDef *hcan, can_data_t *channel);
|
||||
void CAN_ReceiveFrame(USBD_GS_CAN_HandleTypeDef *hcan, can_data_t *channel);
|
||||
void CAN_HandleError(USBD_GS_CAN_HandleTypeDef *hcan, can_data_t *channel);
|
129
src/can_common.c
Normal file
129
src/can_common.c
Normal file
@ -0,0 +1,129 @@
|
||||
/*
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 Hubert Denkmair
|
||||
|
||||
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_common.h"
|
||||
#include "led.h"
|
||||
#include "timer.h"
|
||||
#include "usbd_gs_can.h"
|
||||
|
||||
void CAN_SendFrame(USBD_GS_CAN_HandleTypeDef *hcan, can_data_t *channel)
|
||||
{
|
||||
struct gs_host_frame_object *frame_object;
|
||||
|
||||
bool was_irq_enabled = disable_irq();
|
||||
frame_object = list_first_entry_or_null(&channel->list_from_host,
|
||||
struct gs_host_frame_object,
|
||||
list);
|
||||
if (frame_object) { // send CAN message from host
|
||||
struct gs_host_frame *frame = &frame_object->frame;
|
||||
|
||||
list_del(&frame_object->list);
|
||||
restore_irq(was_irq_enabled);
|
||||
|
||||
if (can_send(channel, frame)) {
|
||||
// Echo sent frame back to host
|
||||
frame->flags = 0x0;
|
||||
frame->reserved = 0x0;
|
||||
frame->timestamp_us = timer_get();
|
||||
|
||||
list_add_tail_locked(&frame_object->list, &hcan->list_to_host);
|
||||
|
||||
led_indicate_trx(&channel->leds, led_tx);
|
||||
} else {
|
||||
list_add_locked(&frame_object->list, &channel->list_from_host);
|
||||
}
|
||||
} else {
|
||||
restore_irq(was_irq_enabled);
|
||||
}
|
||||
}
|
||||
|
||||
void CAN_ReceiveFrame(USBD_GS_CAN_HandleTypeDef *hcan, can_data_t *channel)
|
||||
{
|
||||
struct gs_host_frame_object *frame_object;
|
||||
|
||||
if (can_is_rx_pending(channel)) {
|
||||
bool was_irq_enabled = disable_irq();
|
||||
frame_object = list_first_entry_or_null(&hcan->list_frame_pool,
|
||||
struct gs_host_frame_object,
|
||||
list);
|
||||
if (frame_object) {
|
||||
struct gs_host_frame *frame = &frame_object->frame;
|
||||
|
||||
list_del(&frame_object->list);
|
||||
restore_irq(was_irq_enabled);
|
||||
|
||||
if (can_receive(channel, frame)) {
|
||||
|
||||
frame->timestamp_us = timer_get();
|
||||
frame->echo_id = 0xFFFFFFFF; // not a echo frame
|
||||
frame->channel = 0;
|
||||
frame->flags = 0;
|
||||
frame->reserved = 0;
|
||||
|
||||
list_add_tail_locked(&frame_object->list, &hcan->list_to_host);
|
||||
|
||||
led_indicate_trx(&channel->leds, led_rx);
|
||||
} else {
|
||||
list_add_tail_locked(&frame_object->list, &hcan->list_frame_pool);
|
||||
}
|
||||
} else {
|
||||
restore_irq(was_irq_enabled);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If there are frames to receive, don't report any error frames. The
|
||||
// best we can localize the errors to is "after the last successfully
|
||||
// received frame", so wait until we get there. LEC will hold some error
|
||||
// to report even if multiple pass by.
|
||||
void CAN_HandleError(USBD_GS_CAN_HandleTypeDef *hcan, can_data_t *channel)
|
||||
{
|
||||
struct gs_host_frame_object *frame_object;
|
||||
|
||||
if (!can_is_rx_pending(channel)) {
|
||||
uint32_t can_err = can_get_error_status(channel);
|
||||
|
||||
bool was_irq_enabled = disable_irq();
|
||||
frame_object = list_first_entry_or_null(&hcan->list_frame_pool,
|
||||
struct gs_host_frame_object,
|
||||
list);
|
||||
if (frame_object) {
|
||||
struct gs_host_frame *frame = &frame_object->frame;
|
||||
|
||||
list_del(&frame_object->list);
|
||||
restore_irq(was_irq_enabled);
|
||||
|
||||
frame->timestamp_us = timer_get();
|
||||
if (can_parse_error_status(channel, frame, can_err)) {
|
||||
list_add_tail_locked(&frame_object->list, &hcan->list_to_host);
|
||||
} else {
|
||||
list_add_tail_locked(&frame_object->list, &hcan->list_frame_pool);
|
||||
}
|
||||
} else {
|
||||
restore_irq(was_irq_enabled);
|
||||
}
|
||||
}
|
||||
}
|
87
src/main.c
87
src/main.c
@ -29,6 +29,7 @@ THE SOFTWARE.
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "can.h"
|
||||
#include "can_common.h"
|
||||
#include "config.h"
|
||||
#include "device.h"
|
||||
#include "dfu.h"
|
||||
@ -98,99 +99,21 @@ int main(void)
|
||||
|
||||
while (1) {
|
||||
can_data_t *channel = &hGS_CAN.channels[0];
|
||||
struct gs_host_frame_object *frame_object;
|
||||
|
||||
bool was_irq_enabled = disable_irq();
|
||||
frame_object = list_first_entry_or_null(&channel->list_from_host,
|
||||
struct gs_host_frame_object,
|
||||
list);
|
||||
if (frame_object) { // send CAN message from host
|
||||
struct gs_host_frame *frame = &frame_object->frame;
|
||||
|
||||
list_del(&frame_object->list);
|
||||
restore_irq(was_irq_enabled);
|
||||
|
||||
if (can_send(channel, frame)) {
|
||||
// Echo sent frame back to host
|
||||
frame->flags = 0x0;
|
||||
frame->reserved = 0x0;
|
||||
frame->timestamp_us = timer_get();
|
||||
|
||||
list_add_tail_locked(&frame_object->list, &hGS_CAN.list_to_host);
|
||||
|
||||
led_indicate_trx(&channel->leds, led_tx);
|
||||
} else {
|
||||
list_add_locked(&frame_object->list, &channel->list_from_host);
|
||||
}
|
||||
} else {
|
||||
restore_irq(was_irq_enabled);
|
||||
}
|
||||
CAN_SendFrame(&hGS_CAN, channel);
|
||||
|
||||
USBD_GS_CAN_ReceiveFromHost(&hUSB);
|
||||
|
||||
USBD_GS_CAN_SendToHost(&hUSB);
|
||||
|
||||
if (can_is_rx_pending(channel)) {
|
||||
bool was_irq_enabled = disable_irq();
|
||||
frame_object = list_first_entry_or_null(&hGS_CAN.list_frame_pool,
|
||||
struct gs_host_frame_object,
|
||||
list);
|
||||
if (frame_object) {
|
||||
struct gs_host_frame *frame = &frame_object->frame;
|
||||
|
||||
list_del(&frame_object->list);
|
||||
restore_irq(was_irq_enabled);
|
||||
|
||||
if (can_receive(channel, frame)) {
|
||||
|
||||
frame->timestamp_us = timer_get();
|
||||
frame->echo_id = 0xFFFFFFFF; // not a echo frame
|
||||
frame->channel = 0;
|
||||
frame->flags = 0;
|
||||
frame->reserved = 0;
|
||||
|
||||
list_add_tail_locked(&frame_object->list, &hGS_CAN.list_to_host);
|
||||
|
||||
led_indicate_trx(&channel->leds, led_rx);
|
||||
} else {
|
||||
list_add_tail_locked(&frame_object->list, &hGS_CAN.list_frame_pool);
|
||||
}
|
||||
} else {
|
||||
restore_irq(was_irq_enabled);
|
||||
}
|
||||
// If there are frames to receive, don't report any error frames. The
|
||||
// best we can localize the errors to is "after the last successfully
|
||||
// received frame", so wait until we get there. LEC will hold some error
|
||||
// to report even if multiple pass by.
|
||||
} else {
|
||||
uint32_t can_err = can_get_error_status(channel);
|
||||
|
||||
bool was_irq_enabled = disable_irq();
|
||||
frame_object = list_first_entry_or_null(&hGS_CAN.list_frame_pool,
|
||||
struct gs_host_frame_object,
|
||||
list);
|
||||
if (frame_object) {
|
||||
struct gs_host_frame *frame = &frame_object->frame;
|
||||
|
||||
list_del(&frame_object->list);
|
||||
restore_irq(was_irq_enabled);
|
||||
|
||||
frame->timestamp_us = timer_get();
|
||||
if (can_parse_error_status(channel, frame, can_err)) {
|
||||
list_add_tail_locked(&frame_object->list, &hGS_CAN.list_to_host);
|
||||
} else {
|
||||
list_add_tail_locked(&frame_object->list, &hGS_CAN.list_frame_pool);
|
||||
}
|
||||
} else {
|
||||
restore_irq(was_irq_enabled);
|
||||
}
|
||||
}
|
||||
CAN_ReceiveFrame(&hGS_CAN, channel);
|
||||
CAN_HandleError(&hGS_CAN, channel);
|
||||
|
||||
led_update(&channel->leds);
|
||||
|
||||
if (USBD_GS_CAN_DfuDetachRequested(&hUSB)) {
|
||||
dfu_run_bootloader();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user