Skip to content

Commit 978352f

Browse files
authored
feat: dma functions for logic analyzer (#122)
1 parent e0134a7 commit 978352f

File tree

28 files changed

+1349
-104
lines changed

28 files changed

+1349
-104
lines changed

pslab-core.X/bus/i2c/i2c.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -800,6 +800,7 @@ response_t I2C_CommandEnableSMBus(void) {
800800
I2C2CONbits.SMEN = 1;
801801
// Enables I2C2 module and configure SDA2 and SCL2 as serial port pins
802802
I2C2CONbits.I2CEN = 1;
803+
803804
return SUCCESS;
804805
}
805806

@@ -810,6 +811,7 @@ response_t I2C_CommandDisableSMBus(void) {
810811
I2C2CONbits.SMEN = 0;
811812
// Enables I2C2 module and configure SDA2 and SCL2 as serial port pins
812813
I2C2CONbits.I2CEN = 1;
814+
813815
return SUCCESS;
814816
}
815817

pslab-core.X/commands.c

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,14 @@
22
#include "bus/i2c/i2c.h"
33
#include "helpers/buffer.h"
44
#include "helpers/device.h"
5+
#include "helpers/interval.h"
56
#include "helpers/light.h"
67
#include "helpers/rtc.h"
8+
#include "instruments/logicanalyzer.h"
79
#include "instruments/multimeter.h"
810
#include "instruments/oscilloscope.h"
911
#include "instruments/powersource.h"
12+
#include "instruments/sensors.h"
1013
#include "instruments/wavegenerator.h"
1114
#include "registers/system/pin_manager.h"
1215
#include "instruments/sensors.h"
@@ -224,20 +227,20 @@ command_func_t* const cmd_table[NUM_PRIMARY_CMDS + 1][NUM_SECONDARY_CMDS_MAX + 1
224227
Undefined, Undefined, Undefined, Undefined,
225228
},
226229
{ // 10 TIMING
227-
// 0 1 GET_TIMING 2 3
228-
Undefined, Unimplemented, Undefined, Undefined,
229-
// 4 START_ONE_CHAN_LA 5 START_TWO_CHAN_LA 6 START_FOUR_CHAN_LA 7 FETCH_DMA_DATA
230-
Unimplemented, Unimplemented, Unimplemented, Unimplemented,
231-
// 8 FETCH_INT_DMA_DATA 9 FETCH_LONG_DMA_DATA 10 COMPARATOR_TO_LA 11 GET_INITIAL_STATES
232-
Unimplemented, Unimplemented, Unimplemented, Unimplemented,
233-
// 12 TIMING_MEASUREMENTS 13 INTERVAL_MEASUREMENTS 14 CONFIGURE_COMPARATOR 15 START_ALTERNATE_ONE_CHAN_LA
234-
Unimplemented, Unimplemented, Unimplemented, Unimplemented,
235-
// 16 START_THREE_CHAN_LA 17 STOP_LA 18 19
236-
Unimplemented, Unimplemented, Undefined, Undefined,
237-
// 20 21 22 23
238-
Undefined, Undefined, Undefined, Undefined,
239-
// 24 25 26 27
240-
Undefined, Undefined, Undefined, Undefined,
230+
// 0 1 GET_TIMING 2 3
231+
Undefined, Unimplemented, Undefined, Undefined,
232+
// 4 START_ONE_CHAN_LA 5 START_TWO_CHAN_LA 6 START_FOUR_CHAN_LA 7 FETCH_DMA_DATA
233+
LOGICANALYZER_OneChannel, LOGICANALYZER_TwoChannel, LOGICANALYZER_FourChannel, Removed,
234+
// 8 FETCH_INT_DMA_DATA 9 FETCH_LONG_DMA_DATA 10 COMPARATOR_TO_LA 11 GET_INITIAL_STATES
235+
BUFFER_FetchInt, BUFFER_FetchLong, Unimplemented, INTERVAL_GetState,
236+
// 12 TIMING_MEASUREMENTS 13 INTERVAL_MEASUREMENTS 14 CONFIGURE_COMPARATOR 15 START_ALTERNATE_ONE_CHAN_LA
237+
Unimplemented, Unimplemented, Removed, LOGICANALYZER_OneChannelAlt,
238+
// 16 START_THREE_CHAN_LA 17 STOP_LA 18 19
239+
LOGICANALYZER_ThreeChannel, LOGICANALYZER_Stop, Undefined, Undefined,
240+
// 20 21 22 23
241+
Undefined, Undefined, Undefined, Undefined,
242+
// 24 25 26 27
243+
Undefined, Undefined, Undefined, Undefined,
241244
},
242245
{ // 11 COMMON
243246
// 0 1 GET_CTMU_VOLTAGE 2 GET_CAPACITANCE 3 GET_FREQUENCY

pslab-core.X/helpers/buffer.c

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,49 @@
22
#include "../bus/uart/uart1.h"
33
#include "../commands.h"
44
#include "../registers/system/pin_manager.h"
5+
#include "buffer.h"
56

67
// Space in memory to store data.
7-
int16_t volatile __attribute__((section(".adc_buffer"), far)) BUFFER[10000];
8+
uint16_t volatile __attribute__((section(".adc_buffer"), far)) BUFFER[BUFFER_SIZE];
89

910
response_t BUFFER_Retrieve(void) {
10-
int16_t volatile* idx = &BUFFER[UART1_ReadInt()];
11-
int16_t volatile* end = idx + UART1_ReadInt();
11+
12+
uint16_t volatile* idx = &BUFFER[UART1_ReadInt()];
13+
uint16_t volatile* end = idx + UART1_ReadInt();
1214

15+
LED_SetLow();
1316
while (idx != end) UART1_WriteInt(*(idx++));
17+
LED_SetHigh();
18+
19+
return SUCCESS;
20+
}
21+
22+
response_t BUFFER_FetchInt(void) {
23+
24+
uint16_t counter = UART1_ReadInt();
25+
uint8_t channel = UART1_Read();
26+
27+
LED_SetLow();
28+
uint16_t i;
29+
for (i = 0; i < counter; i++) {
30+
UART1_WriteInt(BUFFER[i + channel * (BUFFER_SIZE / 4)]);
31+
}
32+
LED_SetHigh();
1433

34+
return SUCCESS;
35+
}
36+
37+
response_t BUFFER_FetchLong(void) {
38+
39+
uint16_t counter = UART1_ReadInt();
40+
uint8_t channel = UART1_Read();
41+
42+
LED_SetLow();
43+
uint16_t i;
44+
for (i = 0; i < counter; i++) {
45+
UART1_WriteInt(BUFFER[i + 2 * channel * (BUFFER_SIZE / 4)]);
46+
UART1_WriteInt(BUFFER[i + (2 * channel + 1) * (BUFFER_SIZE / 4)]);
47+
}
1548
LED_SetHigh();
1649

1750
return SUCCESS;

pslab-core.X/helpers/buffer.h

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,16 @@
33

44
#include <stdint.h>
55

6+
#define BUFFER_SIZE 10000
7+
68
#ifdef __cplusplus
79
extern "C" {
810
#endif
911

10-
extern int16_t volatile __attribute__((section(".adc_buffer"), far)) BUFFER[10000];
12+
extern uint16_t volatile __attribute__((section(".adc_buffer"), far)) BUFFER[BUFFER_SIZE];
1113

1214
/**
13-
* @brief
14-
* Send buffer contents.
15+
* @brief Send buffer contents.
1516
*
1617
* @description
1718
* This command function takes two arguments over serial:
@@ -24,6 +25,36 @@ extern "C" {
2425
*/
2526
response_t BUFFER_Retrieve(void);
2627

28+
/**
29+
* @brief Send buffer content as integers.
30+
*
31+
* @description
32+
* This command function takes two arguments over serial:
33+
* 1. The starting index in the buffer from which to send values.
34+
* 2. The number of values to be sent.
35+
*
36+
* It returns the requested data over serial.
37+
* It sends an acknowledge byte (SUCCESS)
38+
*
39+
* @return SUCCESS
40+
*/
41+
response_t BUFFER_FetchInt(void);
42+
43+
/**
44+
* @brief Send buffer content as longs.
45+
*
46+
* @description
47+
* This command function takes two arguments over serial:
48+
* 1. The starting index in the buffer from which to send values.
49+
* 2. The number of values to be sent.
50+
*
51+
* It returns the requested data over serial.
52+
* It sends an acknowledge byte (SUCCESS)
53+
*
54+
* @return SUCCESS
55+
*/
56+
response_t BUFFER_FetchLong(void);
57+
2758
/**
2859
* @brief Populate BUFFER array
2960
*

pslab-core.X/helpers/interval.c

Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
#include "../bus/uart/uart1.h"
2+
#include "../registers/comparators/cmp4.h"
3+
#include "../registers/comparators/cvr.h"
4+
#include "../registers/comparators/ic1.h"
5+
#include "../registers/comparators/ic2.h"
6+
#include "../registers/comparators/ic3.h"
7+
#include "../registers/comparators/ic4.h"
8+
#include "../registers/comparators/ic_params.h"
9+
#include "../registers/memory/dma.h"
10+
#include "../registers/system/interrupt_manager.h"
11+
#include "../registers/system/pin_manager.h"
12+
#include "../registers/timers/tmr2.h"
13+
#include "buffer.h"
14+
15+
static uint8_t DIGITAL_STATES = 0;
16+
void SetDIGITAL_STATES(uint8_t V) { DIGITAL_STATES = V; }
17+
void SetDefaultDIGITAL_STATES(void) { DIGITAL_STATES = ((PORTB >> 10) & 0xF) | (_C4OUT << 4); }
18+
uint8_t GetDIGITAL_STATES(void) { return DIGITAL_STATES; }
19+
20+
static uint8_t DIGITAL_STATES_ERROR = 0;
21+
void SetDefaultDIGITAL_STATES_ERROR(void) { DIGITAL_STATES_ERROR = ((PORTB >> 10) & 0xF) | (_C4OUT << 4); }
22+
uint8_t GetDIGITAL_STATES_ERROR(void) { return DIGITAL_STATES_ERROR; }
23+
24+
void INTERVAL_CaptureOne(uint16_t count, uint8_t channel, uint8_t mode, uint8_t trig) {
25+
26+
INTERRUPT_ClearPinChangeInterruptsFlag();
27+
INTERRUPT_DisablePinChangeInterrupts();
28+
29+
DMA_ChannelDisable(DMA_CHANNEL_0);
30+
DMA_ChannelDisable(DMA_CHANNEL_1);
31+
32+
DMA_PrepareChannel0(count, BUFFER, DMA_PERIPHERAL_IRQ_IC1);
33+
DMA_PrepareChannel1(count, BUFFER + BUFFER_SIZE / 4, DMA_PERIPHERAL_IRQ_IC1);
34+
DMA_InterruptEnable(DMA_CHANNEL_0);
35+
36+
IC1_Initialize();
37+
IC2_Initialize();
38+
39+
SetDMA_MODE(DMA_MODES_ONE_CHANNEL);
40+
41+
if (channel == 4) {
42+
CVR_SetupComparator();
43+
CMP4_SetupComparator();
44+
}
45+
RPINR7bits.IC1R = PIN_MANAGER_DIGITAL_PINS[channel];
46+
47+
IC1_SetCaptureTimer(IC_PARAMS_CAPTURE_TIMER_PERIPHERAL);
48+
IC1_CombineOddEvenICModules();
49+
IC1_UseSourceTo(IC_PARAMS_SOURCE_TASK_TRIGGER);
50+
51+
IC2_SetCaptureTimer(IC_PARAMS_CAPTURE_TIMER_PERIPHERAL);
52+
IC2_CombineOddEvenICModules();
53+
IC2_UseSourceTo(IC_PARAMS_SOURCE_TASK_TRIGGER);
54+
55+
if (trig & 7) {
56+
if ((trig >> 4) == 4) {
57+
CVR_SetupComparator();
58+
CMP4_SetupComparator();
59+
}
60+
RPINR8bits.IC4R = PIN_MANAGER_DIGITAL_PINS[(trig >> 4) & 0xF];
61+
IC4_SetCaptureTimer(IC_PARAMS_CAPTURE_TIMER_PERIPHERAL);
62+
IC1_SetCaptureSource(IC_PARAMS_CAPTURE_SOURCE_IC4);
63+
IC2_SetCaptureSource(IC_PARAMS_CAPTURE_SOURCE_IC4);
64+
}
65+
66+
DMA_ChannelEnable(DMA_CHANNEL_0);
67+
DMA_ChannelEnable(DMA_CHANNEL_1);
68+
69+
IC1_SetCaptureMode(mode);
70+
IC2_SetCaptureMode(mode);
71+
72+
IC4_SetCaptureMode(trig & 7);
73+
}
74+
75+
void INTERVAL_CaptureTwo(uint16_t count, uint8_t mode, uint8_t channel) {
76+
77+
DMA_DisableAllChannels();
78+
79+
DMA_PrepareChannel0(count, BUFFER, DMA_PERIPHERAL_IRQ_IC1);
80+
DMA_PrepareChannel2(count, BUFFER + BUFFER_SIZE / 2, DMA_PERIPHERAL_IRQ_IC3);
81+
DMA_PrepareChannel1(count, BUFFER + BUFFER_SIZE / 4, DMA_PERIPHERAL_IRQ_IC1);
82+
DMA_PrepareChannel3(count, BUFFER + 3 * BUFFER_SIZE / 4, DMA_PERIPHERAL_IRQ_IC3);
83+
84+
DMA_InterruptEnable(DMA_CHANNEL_0);
85+
86+
IC_PARAMS_InitiateAll();
87+
88+
SetDMA_MODE(DMA_MODES_TWO_CHANNEL);
89+
90+
RPINR7bits.IC1R = PIN_MANAGER_DIGITAL_PINS[channel & 0xF];
91+
RPINR8bits.IC3R = PIN_MANAGER_DIGITAL_PINS[(channel >> 4) & 0xF];
92+
93+
IC_PARAMS_SetCaptureTimer(IC_PARAMS_CAPTURE_TIMER_PERIPHERAL);
94+
IC_PARAMS_CombineOddEvenModules();
95+
IC_PARAMS_UseSourceTo(IC_PARAMS_SOURCE_TASK_TRIGGER);
96+
97+
DMA_EnableAllChannels();
98+
99+
IC1_SetCaptureMode(mode & 0xF);
100+
IC2_SetCaptureMode(mode & 0xF);
101+
IC3_SetCaptureMode((mode >> 4) & 0xF);
102+
IC4_SetCaptureMode((mode >> 4) & 0xF);
103+
}
104+
105+
void INTERVAL_CaptureThree(uint16_t count, uint16_t mode, uint8_t trig) {
106+
107+
DMA_ChannelDisable(DMA_CHANNEL_0);
108+
DMA_ChannelDisable(DMA_CHANNEL_1);
109+
DMA_ChannelDisable(DMA_CHANNEL_2);
110+
111+
DMA_PrepareChannel0(count, BUFFER, DMA_PERIPHERAL_IRQ_IC1);
112+
DMA_PrepareChannel1(count, BUFFER + BUFFER_SIZE / 4, DMA_PERIPHERAL_IRQ_IC2);
113+
DMA_PrepareChannel2(count, BUFFER + BUFFER_SIZE / 2, DMA_PERIPHERAL_IRQ_IC3);
114+
115+
DMA_InterruptEnable(DMA_CHANNEL_0);
116+
117+
IC_PARAMS_InitiateAll();
118+
119+
SetDMA_MODE(DMA_MODES_THREE_CHANNEL);
120+
121+
RPINR7bits.IC1R = PIN_MANAGER_DIGITAL_PINS_LA1;
122+
RPINR7bits.IC2R = PIN_MANAGER_DIGITAL_PINS_LA2;
123+
RPINR8bits.IC3R = PIN_MANAGER_DIGITAL_PINS_LA3;
124+
125+
IC_PARAMS_SetCaptureTimer(IC_PARAMS_CAPTURE_TIMER_PERIPHERAL);
126+
127+
IC1_UseSourceTo(IC_PARAMS_SOURCE_TASK_TRIGGER);
128+
IC2_UseSourceTo(IC_PARAMS_SOURCE_TASK_TRIGGER);
129+
IC3_UseSourceTo(IC_PARAMS_SOURCE_TASK_TRIGGER);
130+
131+
if (trig & 7) {
132+
if ((trig >> 4) == 4) {
133+
CVR_SetupComparator();
134+
CMP4_SetupComparator();
135+
}
136+
RPINR8bits.IC4R = PIN_MANAGER_DIGITAL_PINS[(trig >> 4) & 0xF];
137+
IC1_SetCaptureSource(IC_PARAMS_CAPTURE_SOURCE_IC4);
138+
IC2_SetCaptureSource(IC_PARAMS_CAPTURE_SOURCE_IC4);
139+
IC3_SetCaptureSource(IC_PARAMS_CAPTURE_SOURCE_IC4);
140+
}
141+
142+
DMA_ChannelEnable(DMA_CHANNEL_0);
143+
DMA_ChannelEnable(DMA_CHANNEL_1);
144+
DMA_ChannelEnable(DMA_CHANNEL_2);
145+
146+
IC1_SetCaptureMode(mode & 0xF);
147+
IC2_SetCaptureMode((mode >> 4) & 0xF);
148+
IC3_SetCaptureMode((mode >> 8) & 0xF);
149+
IC4_SetCaptureMode(trig & 7);
150+
}
151+
152+
void INTERVAL_CaptureFour(uint16_t count, uint16_t mode, uint8_t prescaler) {
153+
154+
DMA_DisableAllChannels();
155+
156+
DMA_PrepareChannel0(count, BUFFER, DMA_PERIPHERAL_IRQ_IC1);
157+
DMA_PrepareChannel1(count, BUFFER + BUFFER_SIZE / 4, DMA_PERIPHERAL_IRQ_IC2);
158+
DMA_PrepareChannel2(count, BUFFER + BUFFER_SIZE / 2, DMA_PERIPHERAL_IRQ_IC3);
159+
DMA_PrepareChannel3(count, BUFFER + 3 * BUFFER_SIZE / 4, DMA_PERIPHERAL_IRQ_IC4);
160+
161+
DMA_InterruptEnable(DMA_CHANNEL_0);
162+
163+
IC_PARAMS_InitiateAll();
164+
165+
SetDMA_MODE(DMA_MODES_FOUR_CHANNEL);
166+
167+
RPINR7bits.IC1R = PIN_MANAGER_DIGITAL_PINS_LA1;
168+
RPINR7bits.IC2R = PIN_MANAGER_DIGITAL_PINS_LA2;
169+
RPINR8bits.IC3R = PIN_MANAGER_DIGITAL_PINS_LA3;
170+
RPINR8bits.IC4R = PIN_MANAGER_DIGITAL_PINS_LA4;
171+
172+
TMR2_Initialize();
173+
TMR2_PrescalerSet(prescaler & 0xF);
174+
TMR2_Counter16BitSet(1);
175+
176+
IC_PARAMS_SetCaptureTimer(IC_PARAMS_CAPTURE_TIMER2);
177+
IC_PARAMS_UseSourceTo(IC_PARAMS_SOURCE_TASK_TRIGGER);
178+
179+
DMA_EnableAllChannels();
180+
181+
IC1_SetCaptureMode(mode & 0xF);
182+
IC2_SetCaptureMode((mode >> 4) & 0xF);
183+
IC3_SetCaptureMode((mode >> 8) & 0xF);
184+
IC4_SetCaptureMode((mode >> 12) & 0xF);
185+
}
186+
187+
response_t INTERVAL_GetState(void) {
188+
189+
UART1_WriteInt(__builtin_dmaoffset(&BUFFER));
190+
UART1_WriteInt(DMA0STAL);
191+
UART1_WriteInt(DMA1STAL);
192+
UART1_WriteInt(DMA2STAL);
193+
UART1_WriteInt(DMA3STAL);
194+
UART1_Write(DIGITAL_STATES);
195+
UART1_Write(DIGITAL_STATES_ERROR);
196+
197+
return SUCCESS;
198+
}

0 commit comments

Comments
 (0)