VivicoreSerial library
VivicoreSerial.h
Go to the documentation of this file.
1 /*
2  Copyright (c) 2021 VIVIWARE JAPAN, Inc. All right reserved.
3 
4  This program is free software; you can redistribute it and/or
5  modify it under the terms of the GNU General Public License
6  as published by the Free Software Foundation; either version 2
7  of the License, or (at your option) any later version.
8 
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with this program; if not, write to the Free Software
16  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 
18  NeoHWSerial.h - Hardware serial library
19 
20  This library is free software; you can redistribute it and/or
21  modify it under the terms of the GNU Lesser General Public
22  License as published by the Free Software Foundation; either
23  version 2.1 of the License, or (at your option) any later version.
24 
25  This library is distributed in the hope that it will be useful,
26  but WITHOUT ANY WARRANTY; without even the implied warranty of
27  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
28  Lesser General Public License for more details.
29 
30  You should have received a copy of the GNU Lesser General Public
31  License along with this library; if not, write to the Free Software
32  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
33 
34  Created 2006 Nicholas Zambetti
35  Modified 28 September 2010 by Mark Sproul
36  Modified 14 August 2012 by Alarus
37  Modified 31 October 2015 by SlashDev
38 */
39 
57 #include <viviware.h>
58 
59 #ifndef VIVICORESERIAL_H
60 # define VIVICORESERIAL_H
61 
63 # define BOARD_REV_FP1_EVT (1)
64 # define BOARD_REV_FP1_DVT (2)
65 # define BOARD_REV_FP1_PVT (3)
66 # define BOARD_REV (BOARD_REV_FP1_DVT)
67 
68 # ifndef BOARD_TYPE
69 # define BOARD_TYPE (BOARD_TYPE_BRANCH)
70 # endif
71 
72 # if (BOARD_TYPE == BOARD_TYPE_DEPRECATED_CUSTOM)
73 # define CORE_COMM_UART_PORT (1)
74 # define SKIP_VERIFY_BRANCH_TYPE
75 # elif (BOARD_TYPE == BOARD_TYPE_CUSTOM)
76 # define CORE_COMM_UART_PORT (1)
77 # define SKIP_VERIFY_BRANCH_TYPE
78 //# define SWITCH_POWER_ENABLE_PIN // TODO:
79 # elif (BOARD_TYPE == BOARD_TYPE_USER_BRANCH)
80 # define CORE_COMM_UART_PORT (0)
81 # define SKIP_VERIFY_BRANCH_TYPE
82 # else
83 # define CORE_COMM_UART_PORT (0)
84 # endif
85 
86 # include <Arduino.h>
87 # include "CommunicationProtocol.h"
88 # include "VivicoreSerialDataCode.h"
89 # include "VivicoreSerialVersion.h"
90 # include "VivicoreSerialDebug.h"
91 
92 # define NUM_SERIAL_BYTES (10)
93 # define NUM_BRTYPE_BYTES (4)
94 
95 # define NUM_MAX_TEMP_BUFF (30) // maximum byte of tempBuffer
96 # define NUM_MAX_READ_BUFF (64) // To be removed: maximum byte of RingBuffer<unsigned char>
97 
98 // Define constants and variables for buffering incoming serial data. We're
99 // using a ring buffer (I think), in which head is the index of the location
100 // to which to write the next incoming character and tail is the index of the
101 // location from which to read.
102 # if (RAMEND < 1000)
103 # define SERIAL_BUFFER_SIZE (1UL << 4)
104 # else
105 # define SERIAL_BUFFER_SIZE (1UL << 6)
106 # endif
107 
108 # define RING_PKT_BUFFER_SIZE (10)
109 
110 template <typename T, size_t N> size_t countof(const T (&)[N]) {
111  return N;
112 }
113 
114 template <typename T, size_t SIZE> struct RingBuffer {
115  T buffer[SIZE] = {};
116  volatile unsigned int head;
117  volatile unsigned int tail;
118 
119  RingBuffer(const unsigned int HEAD, const unsigned int TAIL) : head(HEAD), tail(TAIL) {}
120 };
121 
122 enum dataType_t {
123  DATA_TYPE_NONE = 0,
124  DATA_TYPE_RAW,
125  DATA_TYPE_DCDT,
126 };
127 
128 struct pkt_payload_t {
129  uint8_t data[NUM_MAX_UART_PKT_BODY_DATA];
130  uint16_t size;
131  dataType_t type;
132 };
138 struct ScalerData_t {
139  uint8_t dc_n;
140  int32_t data;
141  bool success;
142 };
143 
147 struct RawData_t {
149  size_t data_len;
150  bool success;
151 };
152 
157  uint8_t raw;
158  uint8_t scaler;
159 };
160 
165 public:
167  VivicoreSerial(volatile uint8_t *ubrrh, // USART baudrate register high
168  volatile uint8_t *ubrrl, // USART baudrate register low
169  volatile uint8_t *ucsra, // USART Control and Status Registers
170  volatile uint8_t *ucsrb, // USART Control and Status Registers
171  volatile uint8_t *ucsrc, // USART Control and Status Registers
172  volatile uint8_t *udr, // USART Data Register
173  uint8_t rxen, // Receiver Enable bit on UCSR0B, UCSR1B
174  uint8_t txen, // Transmitter Enable bit on UCSR0B, UCSR1B
175  uint8_t rxcie, // RX Complete Interrupt Enable bit on UCSR0B, UCSR1B
176  uint8_t udrie, // Data Register Empty Interrupt Enable bit on UCSR0A, UCSR1A
177  uint8_t u2x, // Double the USART Transmission Speed bit on UCSR0A, UCSR1A
178  uint8_t txc, // USART Transmit Complete bit on UCSR0A, UCSR1A
179  uint8_t dor, // Data OverRun bit on UCSR0A, UCSR1A
180  uint8_t upe, // USART Parity Error bit on UCSR0A, UCSR1A
181  uint8_t fe); // Frame Error bit on UCSR0A, UCSR1A
182  virtual ~VivicoreSerial(void);
200  bool begin(const uint32_t branch_type, const uint16_t user_version, const dcInfo_t *dc_info, const uint8_t dc_num,
201  const uint16_t min_lib_buildno = 0);
202 
218 
235  ScalerData_t read(void);
236 
246  RawData_t readRaw(void);
247 
264  bool write(const uint8_t dc_n, const int32_t data_scaler);
265 
283  bool writeRaw(const uint8_t *data, const size_t data_len, const dataType_t data_type = DATA_TYPE_DCDT);
284 
292  bool flush(void);
293 
300  void end(void);
301 
306  bool isInFatalError(void);
307 
308  BranchCommand_t parseCommand(const uint8_t c);
309  BranchCommandRes_t processCommand(const BranchCommand_t cmd);
310  bool sendResponse(const BranchCommand_t bcmd, const BranchCommandRes_t res_type);
311 
312  void clearTransmitting(void);
313  void setSyncBreakReceived(void);
314 
315  volatile uint8_t *const _ubrrh; // USART baudrate register high
316  volatile uint8_t *const _ubrrl; // USART baudrate register low
317  volatile uint8_t *const _ucsra; // USART Control and Status Registers
318  volatile uint8_t *const _ucsrb; // USART Control and Status Registers
319  volatile uint8_t *const _ucsrc; // USART Control and Status Registers
320  volatile uint8_t *const _udr; // USART Data Register
321  const uint8_t _rxen; // Receiver Enable bit on UCSR0B, UCSR1B
322  const uint8_t _txen; // Transmitter Enable bit on UCSR0B, UCSR1B
323  const uint8_t _rxcie; // RX Complete Interrupt Enable bit on UCSR0B, UCSR1B
324  const uint8_t _udrie; // Data Register Empty Interrupt Enable bit on UCSR0A, UCSR1A
325  const uint8_t _u2x; // Double the USART Transmission Speed bit on UCSR0A, UCSR1A
326  const uint8_t _txc; // USART Transmit Complete bit on UCSR0A, UCSR1A
327  const uint8_t _dor; // Data OverRun bit on UCSR0A, UCSR1A
328  const uint8_t _upe; // USART Parity Error bit on UCSR0A, UCSR1A
329  const uint8_t _fe; // Frame Error bit on UCSR0A, UCSR1A
330 
331  RingBuffer<pkt_payload_t, RING_PKT_BUFFER_SIZE> *_rx_buffer = nullptr;
332  RingBuffer<unsigned char, SERIAL_BUFFER_SIZE> * _tx_buffer = nullptr;
333 
334  bool _is_passthru_mode = false;
337 private:
338  struct scalerDataW_t {
339  int16_t body[NUM_MAX_DC];
340  bool is_set[NUM_MAX_DC];
341  };
342 
343  struct scalerDataR_t {
344  int16_t body[NUM_MAX_DC];
345  uint8_t dc_nums[NUM_MAX_DC];
346  uint8_t dc_nums_count;
347  };
348 
349  const uint8_t _signature[3];
350  const uint8_t _serial_number[NUM_SERIAL_BYTES];
351 
352  uint8_t _data_by_user[NUM_MAX_UART_PKT] = {};
353  uint8_t _data_response[NUM_MAX_UART_PKT] = {};
354  uint8_t *_cmd_params = nullptr;
355  uint8_t _cmd_params_len = 0;
356  uint8_t _data_len_by_user = 0;
357 
358  scalerDataR_t _scaler_data_by_core = {};
359  scalerDataW_t _scaler_data_by_user = {};
360  scalerDataW_t _scaler_data_for_ini = {};
361  data_pkt _raw_data_by_core = {};
362  data_pkt _raw_data_by_user = {};
363 
364  DataCodeTranslator *_translator = nullptr;
365 
366  const dcInfo_t *_dc_info = nullptr;
367  uint8_t _dc_num = 0;
368  bool _dominate_led = false;
369 
370  volatile bool _is_dcdt_ok = false;
371  volatile bool _send_flag = false; // Written data is available for transmission if true
372  bool _is_read_polling = false;
373  bool _in_transmitting = false; // UART transmission is on-going if true
374  bool _is_sync_break_received = false; // sync break is issued if true
375 
376  uint8_t _my_branch_id = 0;
377  uint32_t _my_branch_type = 0;
378  uint16_t _user_fw_ver = 0;
379  uint16_t _min_lib_buildno = 0;
380  bool _fatal_mode = false;
381  BranchCommandParamFind_t _find_branch_mode = BCMDPARAM_FIND_BLINK_OFF;
382  uint32_t _saved_branch_type = 0;
383 
385  VivicoreSerial &operator=(const VivicoreSerial &);
386 
387  void init(void);
388  bool pullFromRxRingBuff(data_pkt *raw_data);
389  void pushToRxRingBuff(const uint8_t *buffer, const uint8_t length, const dataType_t data_type);
390  size_t pushToTxRingBuff(const uint8_t c);
391  void pushToTxRingBuffAndTransmit(const uint8_t *buffer, const uint8_t datalen);
392 
393  void setTransmitting(void);
394  bool isTransmitting(void);
395  bool isSyncBreakReceived(void);
396 
397  void setBaud(unsigned long baud);
398  void setSyncBreak(void);
399 
400  void controlLedBlink(const bool *timing_table, const uint8_t max_count);
401  void controlLedOnOff(const bool stop_blink);
402  void manageLedState(void);
403 
404  uint8_t getCRC8(const uint8_t *buff, const size_t size);
405 };
406 
407 extern VivicoreSerial Vivicore;
409 #endif // VIVICORESERIAL_H
Communication protocol definitions for VIVIWARE Cell Branch and Custom.
#define NUM_MAX_UART_PKT
Maximum packet size for UART communication protocol.
Definition: CommunicationProtocol.h:168
#define NUM_MAX_UART_PKT_BODY_DATA
Maximum data size on a packet for UART communication protocol.
Definition: CommunicationProtocol.h:150
#define NUM_MAX_DC
Maximum number of DC info in a Branch.
Definition: CommunicationProtocol.h:265
VivicoreSerial Vivicore
Data code translater library to encode/decode DCDT for VIVIWARE Cell Branch and Custom.
Debug print library for VIVIWARE Cell Branch and Custom.
VivicoreSerial library version definition.
This class is to encode and decode DCDT format data which is used between VIVIWARE Cell App,...
Definition: VivicoreSerialDataCode.h:57
This class is for branch to talk with core.
Definition: VivicoreSerial.h:164
bool begin(const uint32_t branch_type, const uint16_t user_version, const dcInfo_t *dc_info, const uint8_t dc_num, const uint16_t min_lib_buildno=0)
Definition: VivicoreSerial.cpp:743
bool writeRaw(const uint8_t *data, const size_t data_len, const dataType_t data_type=DATA_TYPE_DCDT)
Definition: VivicoreSerial.cpp:1059
bool flush(void)
Definition: VivicoreSerial.cpp:997
RawData_t readRaw(void)
Definition: VivicoreSerial.cpp:976
AvailableNum_t available(void)
Definition: VivicoreSerial.cpp:920
void end(void)
Definition: VivicoreSerial.cpp:875
bool write(const uint8_t dc_n, const int32_t data_scaler)
Definition: VivicoreSerial.cpp:1086
ScalerData_t read(void)
Definition: VivicoreSerial.cpp:944
This is data buffer structure to get the number of available data for VivicoreSerial::available.
Definition: VivicoreSerial.h:156
uint8_t raw
Definition: VivicoreSerial.h:157
uint8_t scaler
Definition: VivicoreSerial.h:158
This is data buffer structure to read raw data from core.
Definition: VivicoreSerial.h:147
size_t data_len
Definition: VivicoreSerial.h:149
bool success
Definition: VivicoreSerial.h:150
uint8_t data[NUM_MAX_UART_PKT_BODY_DATA]
Definition: VivicoreSerial.h:148
This is data buffer structure to read scaler data from core.
Definition: VivicoreSerial.h:138
uint8_t dc_n
Definition: VivicoreSerial.h:139
bool success
Definition: VivicoreSerial.h:141
int32_t data
Definition: VivicoreSerial.h:140
DC information structure for each input or output of Branch.
Definition: VivicoreSerialDataCode.h:35