Bar Logo 3.8/7.6 kw Totem pole Demonstration Application (Part-No. (not specified))
 
Content
     
Loading...
Searching...
No Matches
drv_spi.c
Go to the documentation of this file.
1
11/*
12 (c) 2022 Microchip Technology Inc. and its subsidiaries. You may use this
13 software and any derivatives exclusively with Microchip products.
14
15 THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER
16 EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED
17 WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A
18 PARTICULAR PURPOSE, OR ITS INTERACTION WITH MICROCHIP PRODUCTS, COMBINATION
19 WITH ANY OTHER PRODUCTS, OR USE IN ANY APPLICATION.
20
21 IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE,
22 INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND
23 WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS
24 BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE
25 FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN
26 ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
27 THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
28
29 MICROCHIP PROVIDES THIS SOFTWARE CONDITIONALLY UPON YOUR ACCEPTANCE OF THESE
30 TERMS.
31 */
32
36#include <p33CH512MP506.h>
37#include <libpic30.h>
38
39#include "drv_spi.h"
40#include "driver/can/drv_can.h"
41
42// MCC header files
43#include "system/pins.h"
44#include "spi_client/spi1.h"
45#include "dma/dma.h"
46#include "timer/timer_interface.h"
47#include "timer/sccp1.h"
48#include "timer/sccp2.h"
49
50#include "system/pins.h"
51
52//------------------------------------------------------------------------------
53// local typedefs
54//------------------------------------------------------------------------------
55typedef struct
56{
58 uint16_t data[4];
61} DRV_SPI_t;
62
63
64//------------------------------------------------------------------------------
65// local variable definitions
66//------------------------------------------------------------------------------
67static DRV_SPI_t selfSpi __attribute__((address(0x1800))); // set fixed address for DMA
68
69//------------------------------------------------------------------------------
70// local function declarations
71//------------------------------------------------------------------------------
72static void SPI_Synchronize(void); // local
73
74//------------------------------------------------------------------------------
75// API function definitions
76//------------------------------------------------------------------------------
77
78
88{
89 selfSpi.timeout_counter = count;
90}
91
92
103{
104 return (selfSpi.connected);
105}
106
107
118{
119 return (selfSpi.checksum_ok);
120}
121
122
132{
133 return (selfSpi.data);
134}
135
136
146void Drv_SPI_Timeout(void) // API
147{
149 if (selfSpi.timeout_counter <= 0)
150 {
151 // this will only get executed if there
152 // has been no SPI comms for 1ms
153 selfSpi.timeout_counter = 10; // 1ms (10*100us)
154 selfSpi.connected = false; // SPI not connected
155 selfSpi.checksum_ok = false; // checksum invalid
156 SPI_Synchronize(); // try to sync to SPI bus
157 }
158}
159
160
173{
174 bool test_passed = false;
175
176 // checksum preset with 0x0055 so that transmission of all zeros won't
177 // result in a false pass
178 uint16_t i;
179 uint16_t checksum = 0x0055;
180 for (i = 0; i < 3; i++)
181 {
182 checksum = checksum + selfSpi.data[i];
183 }
184
185 // compare calculated checksum against checksum transmitted in word 3
186 if (checksum == selfSpi.data[3])
187 {
188 // calculated and transmitted checksums match
189 selfSpi.checksum_ok = true;
190 test_passed = true;
191 }
192 else
193 {
194 // calculated and transmitted checksums don't match
195 selfSpi.checksum_ok = false;
196 selfSpi.connected = false;
197
198 // reset timeout counter so as we attempt to re-sync to SPI bus
199 // as soon as possible
200 // setting 1 means that the next time Drv_SPI_Timeout() is called
201 // we will attempt to re-sync to SPI bus, this should be max 100us
203 test_passed = false;
204 }
205 return (test_passed);
206}
207
208
238static void SPI_Synchronize(void) // local
239{
240 DMA_ChannelDisable(0); // disable DMA channel 0
241 SPI1CON1Lbits.SPIEN = 0; // disable SPI
242
244
245// SCCP2_TMR_Start(); // set to time out after 40us
246 IFS1bits.CCT2IF = 0; // clear SCCP2 timer overflow flag
247
248 // clear timer (should use MCC API functions but they don't work)
249 CCP2TMRL = 0;
250 CCP2TMRH = 0;
251
253
254// SCCP1_TMR_Start(); // set to time out after 1us
255 IFS0bits.CCT1IF = 0; // clear timer overflow flag
256
257 // clear timer (should use MCC API functions but they don't work)
258 CCP1TMRL = 0;
259 CCP1TMRH = 0;
260
261 do
262 {
263 // stay here until one of the 2 timers expires
264// if (SCK1IN_GetValue() == 0)
265 if (_RC8 == 0)
266 {
267 // SPI_CLK is low, so SPI bus is not in idle state. Reset 1us timer
268 CCP1TMRL = 0;
269 CCP1TMRH = 0;
270 }
271 } while ((!IFS0bits.CCT1IF) && (!IFS1bits.CCT2IF));
272
273 // check which timer expired first
274 if (IFS0bits.CCT1IF)
275 {
276 // SCCP1 expired, meaning we detected that the SPI bus is idle
277 // (SPI_CLK has been high continuously for 1us)
278 // since SPI bus is idle, we can now enable the SPI and DMA peripherals
279 selfSpi.connected = true;
281 SPI1CON1Lbits.SPIEN = 1;
282
284
285 // address to which the DMA sends the incoming data (destination address)
286 // is overwritten via DMADST0 register
287 DMADST0 = (uint16_t) & selfSpi.data[0];
289 }
290 else
291 {
292 // SCCP2 expired, meaning we didn't detect SPI bus in idle over a 40us period
293 selfSpi.connected = false; // could not establish SPI connection, try again later
294 }
295
296 // stop timers and exit
297 Nop();
298 Nop();
299 Nop();
300 Nop();
301 Nop();
304}
305
This is the generated driver header file for the DMA driver.
This is the generated driver header file for the SPI1 driver.
This is the generated driver header file for the SCCP1-TIMER driver.
This is the generated driver header file for the SCCP2-TIMER driver.
header of the CAN Driver
bool Drv_SPI_get_Connected_Flag(void)
Definition drv_spi.c:102
static void SPI_Synchronize(void)
Definition drv_spi.c:238
void Drv_SPI_Reset_Timeout_Counter(uint16_t count)
Definition drv_spi.c:87
void Drv_SPI_Timeout(void)
Definition drv_spi.c:146
static DRV_SPI_t selfSpi
Definition drv_spi.c:67
uint16_t * Drv_SPI_get_Adr_Data_Obj(void)
Definition drv_spi.c:131
bool Drv_SPI_Checksum(void)
Definition drv_spi.c:172
bool Drv_SPI_get_ChecksumOK_Flag(void)
Definition drv_spi.c:117
This is the driver source file for spi builds upon mcc.
#define SPI_BusIdle_1us_Timer_Start
This macro defines the Custom Name for SCCP1_Timer_Start API.
Definition sccp1.h:80
#define SPI_Timeout_40us_Timer_Stop
This macro defines the Custom Name for SCCP2_Timer_Stop API.
Definition sccp2.h:85
#define SPI_BusIdle_1us_Timer_Stop
This macro defines the Custom Name for SCCP1_Timer_Stop API.
Definition sccp1.h:85
#define SPI_Timeout_40us_Timer_Start
This macro defines the Custom Name for SCCP2_Timer_Start API.
Definition sccp2.h:80
void DMA_Initialize(void)
Initializes the DMA module.
Definition dma.c:67
static void DMA_ChannelDisable(enum DMA_CHANNEL channel)
This inline function disables the DMA channel.
Definition dma.h:175
static void DMA_ChannelEnable(enum DMA_CHANNEL channel)
This inline function enables the DMA channel.
Definition dma.h:142
void SPI1_Initialize(void)
Initializes SPI1 module, using the given initialization data. This function must be called before any...
Definition spi1.c:86
int16_t timeout_counter
Definition drv_spi.c:60
bool checksum_ok
Definition drv_spi.c:59
uint16_t data[4]
Definition drv_spi.c:58
bool connected
Definition drv_spi.c:57