-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.c
151 lines (135 loc) · 5.3 KB
/
main.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#include <stdint.h>
#include <pru_cfg.h>
#include <pru_intc.h>
#include <pru_rpmsg.h>
#include <pru_ecap.h>
#include <string.h>
#include "resource_table.h"
volatile register unsigned __R31;
#define VIRTIO_CONFIG_S_DRIVER_OK 4
unsigned char payload[RPMSG_BUF_SIZE];
/**
* main.c
*/
int main(void)
{
struct pru_rpmsg_transport transport;
unsigned short src, dst, len;
volatile unsigned char *status;
/* Allow OCP master port access by the PRU so the PRU can read external memories */
CT_CFG.SYSCFG_bit.STANDBY_INIT = 0;
/* Clear the status of the PRU-ICSS system event that the ARM will use to 'kick' us */
CT_INTC.SICR_bit.STS_CLR_IDX = FROM_ARM_HOST;
/* Make sure the Linux drivers are ready for RPMsg communication */
/* this is another place where a hang could occur */
status = &resourceTable.rpmsg_vdev.status;
while (!(*status & VIRTIO_CONFIG_S_DRIVER_OK))
;
/* Initialize the RPMsg transport structure */
/* this function is defined in rpmsg_pru.c. It's sole purpose is to call pru_virtqueue_init twice (once for
vring0 and once for vring1). pru_virtqueue_init is defined in pru_virtqueue.c. It's sole purpose is to
call vring_init. Not sure yet where that's defined, but it appears to be part of the pru_rpmsg iface.*/
/* should probably test for RPMSG_SUCCESS. If not, then the interface is not working and code should halt */
pru_rpmsg_init(&transport, &resourceTable.rpmsg_vring0,
&resourceTable.rpmsg_vring1, TO_ARM_HOST, FROM_ARM_HOST);
/* Create the RPMsg channel between the PRU and ARM user space using the transport structure. */
// In a real-time environment, rather than waiting forever, this can probably be run loop-after-loop
// until success is achieved. At that point, set a flag and then enable the send/receive functionality
while (pru_rpmsg_channel(RPMSG_NS_CREATE, &transport, CHAN_NAME, CHAN_DESC,
CHAN_PORT) != PRU_RPMSG_SUCCESS)
;
// Disabilito ed azzero interrupts
CT_ECAP.ECEINT = 0x00;
CT_ECAP.ECCTL2 &= EC_STOP_MSK; // Stop ecap
CT_ECAP.ECCLR &= ECCLR_MSK;
// Abilito interrupts
CT_ECAP.ECEINT = ECEINT_CFG;
// Configure & start ecap
CT_ECAP.ECCTL1 = ECCTL1_CFG; // all rising edge, reset counter at any capture
CT_ECAP.ECCTL2 = ECCTL2_CFG & EC_STOP_MSK; // continuous, capture mode, wrap after capture 4, rearm, free running,synci/o disabled
uint8_t active = 0;
struct EcapData
{
char cmd[8];
uint32_t cap1[8];
uint32_t cap2[8];
uint32_t cap3[8];
uint32_t cap4[8];
};
uint32_t counter = 0;
struct EcapData *result = (struct EcapData *) payload;
strcpy(result->cmd, "DATA");
// result->cap1;
// result->cap2;
// result->cap3;
// result->cap4;
while (1)
{
if (active)
{
counter %= 8;
if (CT_ECAP.ECFLG & ECFLG_MSK)
//if (counter > 100000L)
{
if (CT_ECAP.ECFLG & 0x0002)
{
strcpy(result->cmd, "DATA");
result->cap1[counter] = CT_ECAP.CAP1_bit.CAP1;
result->cap2[counter] = CT_ECAP.CAP2_bit.CAP2;
result->cap3[counter] = CT_ECAP.CAP3_bit.CAP3;
result->cap4[counter] = CT_ECAP.CAP4_bit.CAP4;
CT_ECAP.ECCLR |= ECCLR_MSK; // remove EVT4 interrupt and INT
counter++;
if(counter == 8) {
pru_rpmsg_send(&transport, dst, src, payload,
sizeof(struct EcapData));
}
}
// if (CT_ECAP.ECFLG & 0x0004)
// {
// result->cap2 = CT_ECAP.CAP2_bit.CAP2;
// }
// if (CT_ECAP.ECFLG & 0x0008)
// {
// result->cap3 = CT_ECAP.CAP3_bit.CAP3;
// }
// if (CT_ECAP.ECFLG & 0x0010)
// {
// result->cap4 = CT_ECAP.CAP4_bit.CAP4;
// }
}
}
if (__R31 & HOST_INT)
{
if (pru_rpmsg_receive(&transport, &src, &dst, payload,
&len) == PRU_RPMSG_SUCCESS)
{
int eq = strncmp("START", (const char *) payload, 5);
if (eq == 0)
{
active = 1;
CT_ECAP.TSCTR = 0x00000000;
CT_ECAP.ECCTL2 = ECCTL2_CFG; // start ecap
pru_rpmsg_send(&transport, dst, src, "STARTED", 8);
CT_ECAP.ECFRC |= 0x0010; // force EVT4 (test scope)
}
else if (eq < 0)
{
active = 0;
CT_ECAP.ECCTL2 = ECCTL2_CFG & EC_STOP_MSK; // stop ecap
pru_rpmsg_send(&transport, dst, src, "MINOR", 6);
}
else if (eq > 0)
{
active = 0;
CT_ECAP.ECCTL2 = ECCTL2_CFG & EC_STOP_MSK; // stop ecap
pru_rpmsg_send(&transport, dst, src, "MAJOR", 6);
}
}
else
{
CT_INTC.SICR_bit.STS_CLR_IDX = FROM_ARM_HOST;
}
}
}
}