KM3NeT CLB  2.0
KM3NeT CLB v2 Embedded Software
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
stmach.c
1 /*
2  * KM3NeT CLB v2 Firmware
3  * ----------------------
4  *
5  * Copyright 2012-2014 KM3NeT Collaboration
6  *
7  * All Rights Reserved.
8  *
9  *
10  * File : stmach.c
11  * Created : 1 sep. 2014
12  * Author : Vincent van Beveren
13  */
14 
15 #include "drv/wb/stmach.h"
16 #include <stdio.h>
17 #include <assert.h>
18 #include "errorcode.h"
19 #include "kernel/err.h"
20 #include "kernel/tm.h"
21 #include "kernel/scheduler.h"
22 #include "lm32soc/lm32.h"
23 
24 #include "util/log.h"
25 
26 LOG_DEF(StMach);
27 
28 // #define DEBUG_STMACH
29 static uint32_t _muInterval;
30 static volatile uint32_t _muTicksTo;
31 
32 static int _stmachTaskId = -1;
33 static volatile bool _runMU;
34 static volatile bool _overflowEnd;
35 static volatile bool _runOF;
36 static volatile uint32_t _tCount;
37 
38 static void stmachTask()
39 {
40  // check if we need to handle an overflow
41  if (_runOF) {
42  // if so, stub call to higher level to handle overflow
43  uint32_t tdc = STMACH->TDC_FULL_IRQ;
44  uint32_t aes = STMACH->AES_FULL_IRQ;
45  _stmachOverflowBegin(tdc, aes);
46  _runOF = false;
47  _overflowEnd = true;
48  } else if (_overflowEnd) {
49  // wait
50  uint32_t tdc = STMACH->TDC_FULL_IRQ;
51  uint32_t aes = STMACH->AES_FULL_IRQ;
52  _stmachOverflowEnd(tdc, aes);
53  STMACH->TDC_FULL_IRQ = 0xFFFFFFFF;
54  STMACH->AES_FULL_IRQ = 0xFFFFFFFF;
55  //STMACH->TDC_FULL_IRQ_TEST = 0;
56  STMACH->TDC_FULL_MASK = 0x0;
57  STMACH->AES_FULL_MASK = 0x0;
58  _overflowEnd = false;
59  }
60 
61  // check if we need to run the monitor update.
62  if (_runMU) {
63  if (STMACH->CSR & STMACH_CSR_MCH_BUSY) {
64  schdRun(_stmachTaskId);
65  return;
66  }
67  _runMU = false;
69  }
70 }
71 
72 bool stmachInit(uint32_t domId, void * buf, size_t len)
73 {
74  assert((((uint32_t)buf) & 0x3) == 0);
75  assert(len < 1024);
76 
77  STMACH->MMEM_BASE = (uint32_t)buf;
78  STMACH->MMEM_WORDS = ( len + 3 ) >> 2;
79  STMACH->DOM_ID = domId;
80 
81  if (_stmachTaskId == -1)
82  if (!schdRegister(stmachTask, true, &_stmachTaskId)) return false;
83 
84  irqMaskSet(IRQ_OVERFLOW, true);
85 
86  return true;
87 }
88 
89 
90 void stmachMUCfg(uint32_t intervalMs)
91 {
92  irqMaskSet(IRQ_TSLICE, false);
93  _muInterval = intervalMs;
94  _muTicksTo = timeOutInit(intervalMs);
95  irqMaskSet(IRQ_TSLICE, true);
96 }
97 
98 bool stmachConfig(uint32_t packSize, uint32_t duration)
99 {
100  uint32_t value = ( duration * (WISHBONE_FREQ / 100000) + 5 ) / 10;
101 
102  if ((WISHBONE_FREQ % value) != 0)
103  return errSet(ERROR_CTX_INFO(E_INVARGUMENT, "stmach duration"));
104  if (packSize < STMACH_PL_SIZE_MIN || packSize > STMACH_PL_SIZE_MAX)
105  return errSet(ERROR_CTX_INFO(E_INVARGUMENT, "stmach packet size"));
106 
107  STMACH->PL_SIZE = packSize;
108  STMACH->TSLICE_LEN = value;
109  return true;
110 }
111 
112 
113 void stmachFlush(uint32_t flush, uint8_t mode)
114 {
115  //logTrace(">Fls CSR: %08lx\n", STMACH->CSR);
116  // only disabled channels are flushed
117 
118  uint32_t csr = STMACH->CSR;
119 
120  if (mode & STMACH_FLUSH_OP_START) STMACH->CSR = csr | ( STMACH_CSR_FLUSH_MASK & (flush << STMACH_CSR_FLUSH_SHIFT) );
121  if (mode & STMACH_FLUSH_OP_END) STMACH->CSR = csr & ~STMACH_CSR_FLUSH_MASK;
122  //logTrace("<Fls CSR: %08lx\n", STMACH->CSR);
123 }
124 
125 
126 
127 bool stmachEnable(uint32_t enable)
128 {
129  STMACH->CSR = (STMACH->CSR & ~STMACH_CSR_ENA_MASK) |
131 
132  // wait for syncing.
133  uint32_t to = timeOutInit(500); // assume syncing never lasts more than 500ms
134 
135  while (STMACH->CSR & STMACH_CSR_SYNC) {
136  if (timeOut(to)) {
137  return errSet(ERROR_CTX_INFO(E_TIMEOUT, "stmachEnable"));
138  }
139  };
140 
141  return true;
142 }
143 
144 uint32_t stmachEnabled()
145 {
147 }
148 
149 void stmachGetStCommit(uint16_t * tdc, uint16_t * aes)
150 {
151  *tdc = ( STMACH->ST_COMMIT & STMACH_ST_COMMIT_TDC_MASK ) >> STMACH_ST_COMMIT_TDC_SHIFT;
152  *aes = ( STMACH->ST_COMMIT & STMACH_ST_COMMIT_AES_MASK ) >> STMACH_ST_COMMIT_AES_SHIFT;
153 }
154 
155 void stmachFakeFull(uint32_t mask)
156 {
157  //STMACH->TDC_FULL_IRQ_TEST = mask;
158 }
159 
161 {
162  _tCount++;
163  if (_stmachTaskId == -1) return;
164 
165  if (_overflowEnd) {
166  schdRunIRQ(_stmachTaskId);
167  }
168 
169  if (timeOut(_muTicksTo)) {
170  // set new interval
171  _muTicksTo = timeOutUpdate(_muTicksTo, _muInterval);
172  //printf("IRQ enabled before?: %d\n", __isIrqEnable());
173  schdRunIRQ(_stmachTaskId);
174  // printf("IRQ enabled after?: %d\n", __isIrqEnable());
175  _runMU = true;
176  }
177 
178 }
179 
181 {
182  __irqDisable();
183  uint32_t t = _tCount;
184  __irqEnable();
185  return t;
186 }
187 
188 
189 
190 
192 {
193  if (_stmachTaskId == -1) return;
194  // Prevent more IRQs from occuring
195  STMACH->AES_FULL_MASK = 0xFFFFFFFF;
196  STMACH->TDC_FULL_MASK = 0xFFFFFFFF;
197  schdRunIRQ(_stmachTaskId);
198  _runOF = true;
199 }
200 
201 
uint32_t stmachEnabled()
Returns which state-machine channels are enabled.
Definition: stmach.c:144
bool stmachInit(uint32_t domId, void *monbuf, size_t monlen)
Initializes the state-machine with the DOM ID and the monitoring channel CPU data pointer...
Definition: stmach.c:72
bool stmachEnable(uint32_t enable)
Enables one or more STMACH channels.
Definition: stmach.c:127
#define IRQ_TSLICE
New timeslice.
Definition: cfg_soc.h:97
#define STMACH_CSR_FLUSH_MASK
Channel flush mask.
Definition: dev_stmach.h:51
State Machine Driver.
static void __irqEnable()
Enabled IRQ&#39;s on a global level.
Definition: lm32.h:75
void _stmachOverflowEnd(uint32_t tdcFifo, uint32_t aesFifo)
Invoked when an AES or TDC fifo should be enabled again.
Definition: sub_sys.c:130
Low level routines for LM32, including interrupt handling.
bool schdRegister(SchdTaskF task, bool priority, int *taskId)
Register a task with the scheduler.
Definition: scheduler.c:95
void stmachFlush(uint32_t flush, uint8_t op)
Flushes one or more state-machine channels.
Definition: stmach.c:113
void stmachMUCfg(uint32_t intervalMs)
Configure Monitor Update.
Definition: stmach.c:90
static void __irqDisable()
Disables IRQ&#39;s on a global level.
Definition: lm32.h:62
#define STMACH_CSR_MCH_BUSY
Monitoring channel busy.
Definition: dev_stmach.h:53
Simple task scheduler for tasks.
#define STMACH_CSR_ENA_SHIFT
Channel enable shift.
Definition: dev_stmach.h:49
#define STMACH
State Machine base pointer.
Definition: dev_soc.h:61
void _stmachUpdateMonitor()
Stub function invoked when it is time to update the monitor channel.
Definition: sub_sys.c:160
#define IRQ_HANDLER(IRQ)
Defines an IRQ handler.
Definition: lm32.h:47
uint32_t stmachTSliceCount()
Returns the number of timeslice IRQs since system start.
Definition: stmach.c:180
#define STMACH_CSR_SYNC
Indicates the state machine is syncing the enable state.
Definition: dev_stmach.h:50
#define E_INVARGUMENT
Generic error: invalid argument.
Definition: errorcode.h:112
void schdRun(int taskId)
Run a task &#39;now&#39;.
Definition: scheduler.c:233
void irqMaskSet(int irq, bool set)
Set/clear the interrupt mask for the specified IRQ.
Definition: lm32.c:77
static uint32_t timeOutInit(uint32_t msec)
Initializes a timeout with the specified no of msecs.
Definition: tm.h:53
void stmachFakeFull(uint32_t mask)
Debugging stuff, don&#39;t touch!
Definition: stmach.c:155
#define STMACH_CSR_FLUSH_SHIFT
Channel flush shift.
Definition: dev_stmach.h:52
static bool timeOut(uint32_t to)
Checks whether or not the timeout has expired.
Definition: tm.h:77
Manages the global system error.
#define STMACH_ST_COMMIT_AES_SHIFT
AES commit mask.
Definition: dev_stmach.h:60
void schdRunIRQ(int taskId)
Schedule a task from an IRQ.
Definition: scheduler.c:242
bool stmachConfig(uint32_t packSize, uint32_t duration)
Configures the stateMachine.
Definition: stmach.c:98
void _stmachOverflowBegin(uint32_t tdcFifo, uint32_t aesFifo)
Invoked when an AES or TDC fifo overflow occurs.
Definition: sub_sys.c:85
Simple timer functions.
This module is responsible for distributing error codes.
#define E_TIMEOUT
Generic error: Timeout error.
Definition: errorcode.h:100
#define STMACH_ST_COMMIT_TDC_SHIFT
TDC commit mask.
Definition: dev_stmach.h:63
#define LOG_DEF(NAME,...)
Define a logger for a module.
Definition: log.h:129
bool errSet(uint32_t code, const char *error, const char *name)
Sets an error.
#define STMACH_CSR_ENA_MASK
Channel enable mask.
Definition: dev_stmach.h:48
#define IRQ_OVERFLOW
Overflow.
Definition: cfg_soc.h:98
Implements a generic logger facility.
static uint32_t timeOutUpdate(uint32_t to, uint32_t msec)
Updates the original timeout with the new timeout.
Definition: tm.h:67
void stmachGetStCommit(uint16_t *tdc, uint16_t *aes)
Debug feature: Get TDC and AES state machine Fifo commits.
Definition: stmach.c:149