Subversion Repositories Code-Repo

Rev

Rev 199 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 199 Rev 201
Line 1... Line 1...
1
#include <xc.h>
1
#include <xc.h>
2
#include <plib.h>
2
#include <plib.h>
3
#include "defines.h"
3
#include "defines.h"
4
#include "SPI1.h"
4
#include "SPI1.h"
5
 
5
 
6
static SPI1_DATA *data_ptr;
6
static SPI1_DATA *spi_data_ptr;
7
static void (*callback_function)(void);
-
 
8
 
7
 
9
void SPI1_Init(SPI1_DATA *data) {
8
void SPI1_Init(SPI1_DATA *data) {
10
    data_ptr = data;
9
    spi_data_ptr = data;
11
    data_ptr->outBufferInd = 0;
10
    spi_data_ptr->outBufferInd = 0;
12
    data_ptr->outBufferLen = 0;
11
    spi_data_ptr->outBufferLen = 0;
13
#ifndef SPI1_WRITE_ONLY
12
#ifndef SPI1_WRITE_ONLY
14
    data_ptr->inBufferInd = 0;
13
    spi_data_ptr->inBufferInd = 0;
15
    data_ptr->inBufferLen = 0;
14
    spi_data_ptr->inBufferLen = 0;
16
#endif
15
#endif
17
    
16
    
18
    INTDisableInterrupts();
17
    INTDisableInterrupts();
19
 
18
 
20
    // Note: FIFO enhanced buffer depth is 4/8/16 for 32/16/8 bit widths
19
    // Note: FIFO enhanced buffer depth is 4/8/16 for 32/16/8 bit widths
Line 51... Line 50...
51
 
50
 
52
#ifndef SPI1_WRITE_ONLY
51
#ifndef SPI1_WRITE_ONLY
53
int SPI1_Read_Buffer(unsigned char *array, unsigned int count) {
52
int SPI1_Read_Buffer(unsigned char *array, unsigned int count) {
54
    if (count > SPI1_BUFFER_SIZE)
53
    if (count > SPI1_BUFFER_SIZE)
55
        return 0;
54
        return 0;
56
    if (data_ptr->inBufferLen == 0)
55
    if (spi_data_ptr->inBufferLen == 0)
57
        return 0;
56
        return 0;
58
 
57
 
59
    // Save previous interrupt state
58
    // Save previous interrupt state
60
    int prev = IEC0 & 0x03800000;
59
    int prev = IEC0 & 0x03800000;
61
     // Temporarily disable interrupts
60
     // Temporarily disable interrupts
62
    IEC0CLR = 0x03800000;
61
    IEC0CLR = 0x03800000;
63
    int ret = data_ptr->inBufferLen;
62
    int ret = spi_data_ptr->inBufferLen;
64
    int i;
63
    int i;
65
    for (i = 0; i < count; i++) {
64
    for (i = 0; i < count; i++) {
66
        array[i] = data_ptr->inBuffer[i];
65
        array[i] = spi_data_ptr->inBuffer[i];
67
    }
66
    }
68
    // Reset buffer pointers
67
    // Reset buffer pointers
69
    data_ptr->inBufferInd = 0;
68
    spi_data_ptr->inBufferInd = 0;
70
    data_ptr->inBufferLen = 0;
69
    spi_data_ptr->inBufferLen = 0;
71
    // Restore saved interrupt state
70
    // Restore saved interrupt state
72
    IEC0SET = prev;
71
    IEC0SET = prev;
73
    // Return the number of valid bytes in the buffer
72
    // Return the number of valid bytes in the buffer
74
    return ret;
73
    return ret;
75
}
74
}
76
#endif
75
#endif
77
 
76
 
78
int SPI1_Write(unsigned char *array, unsigned int count, void (*callback)(void)) {
77
int SPI1_Write(unsigned char *array, unsigned int count, void (*callback)(void)) {
79
    callback_function = callback;
78
    spi_data_ptr->callback_function = callback;
80
 
79
 
81
    if (count > SPI1_BUFFER_SIZE)
80
    if (count > SPI1_BUFFER_SIZE)
82
        return 0;
81
        return 0;
83
    if (data_ptr->outBufferLen != 0)
82
    if (spi_data_ptr->outBufferLen != 0)
84
        return 0;
83
        return 0;
85
 
84
 
86
    data_ptr->outBufferLen = count;
85
    spi_data_ptr->outBufferLen = count;
87
    data_ptr->outBufferInd = count-1;
86
    spi_data_ptr->outBufferInd = count-1;
88
    int i;
87
    int i;
89
    for (i = 0; i < count; i++) {
88
    for (i = 0; i < count; i++) {
90
        data_ptr->outBuffer[i] = array[i];
89
        spi_data_ptr->outBuffer[i] = array[i];
91
    }
90
    }
92
    IEC0SET = 0x02000000; // Enable TX interrupt
91
    IEC0SET = 0x02000000; // Enable TX interrupt
93
    return 1;
92
    return 1;
94
}
93
}
95
 
94
 
Line 107... Line 106...
107
    // Process SPI1 receive flag
106
    // Process SPI1 receive flag
108
    if (IFS0bits.SPI1RXIF) {
107
    if (IFS0bits.SPI1RXIF) {
109
        int i;
108
        int i;
110
        // Read the data received from the last transfer
109
        // Read the data received from the last transfer
111
        int rxBufferCount = SPI1STATbits.RXBUFELM;
110
        int rxBufferCount = SPI1STATbits.RXBUFELM;
112
        if (data_ptr->inBufferLen + rxBufferCount < SPI1_BUFFER_SIZE) {
111
        if (spi_data_ptr->inBufferLen + rxBufferCount < SPI1_BUFFER_SIZE) {
113
            for (i = 0; i < rxBufferCount; i++) {
112
            for (i = 0; i < rxBufferCount; i++) {
114
                data_ptr->inBuffer[data_ptr->inBufferInd] = SPI1BUF;
113
                spi_data_ptr->inBuffer[spi_data_ptr->inBufferInd] = SPI1BUF;
115
                data_ptr->inBufferInd++;
114
                spi_data_ptr->inBufferInd++;
116
                data_ptr->inBufferLen++;
115
                spi_data_ptr->inBufferLen++;
117
            }
116
            }
118
        } else {
117
        } else {
119
            // If buffer is full, discard data in enhanced buffer
118
            // If buffer is full, discard data in enhanced buffer
120
            for (i = 0; i < rxBufferCount; i++) {
119
            for (i = 0; i < rxBufferCount; i++) {
121
                int tmp = SPI1BUF;
120
                int tmp = SPI1BUF;
Line 127... Line 126...
127
 
126
 
128
    // Process SPI1 transmit flag
127
    // Process SPI1 transmit flag
129
    if (IFS0bits.SPI1TXIF) {
128
    if (IFS0bits.SPI1TXIF) {
130
        int i;
129
        int i;
131
        // Disable the transmit interrupt if all data has been sent
130
        // Disable the transmit interrupt if all data has been sent
132
        if (data_ptr->outBufferLen == 0) {
131
        if (spi_data_ptr->outBufferLen == 0) {
133
            IEC0CLR=0x02000000;
132
            IEC0CLR=0x02000000;
134
            if (callback_function != NULL)
133
            if (spi_data_ptr->callback_function != NULL)
135
                (*callback_function)();
134
                (*spi_data_ptr->callback_function)();
136
        } else {
135
        } else {
137
            // Start transmitting the data in the buffer
136
            // Start transmitting the data in the buffer
138
            int txBufferFree = 16 - SPI1STATbits.TXBUFELM;
137
            int txBufferFree = 16 - SPI1STATbits.TXBUFELM;
139
            if (data_ptr->outBufferLen > txBufferFree) {
138
            if (spi_data_ptr->outBufferLen > txBufferFree) {
140
                for (i = 0; i < txBufferFree; i++) {
139
                for (i = 0; i < txBufferFree; i++) {
141
                    SPI1BUF = data_ptr->outBuffer[data_ptr->outBufferInd];
140
                    SPI1BUF = spi_data_ptr->outBuffer[spi_data_ptr->outBufferInd];
142
                    data_ptr->outBufferInd--;
141
                    spi_data_ptr->outBufferInd--;
143
                }
142
                }
144
                data_ptr->outBufferLen -= txBufferFree;
143
                spi_data_ptr->outBufferLen -= txBufferFree;
145
            } else {
144
            } else {
146
                for (i = 0; i < data_ptr->outBufferLen; i++) {
145
                for (i = 0; i < spi_data_ptr->outBufferLen; i++) {
147
                    SPI1BUF = data_ptr->outBuffer[data_ptr->outBufferInd];
146
                    SPI1BUF = spi_data_ptr->outBuffer[spi_data_ptr->outBufferInd];
148
                    data_ptr->outBufferInd--;
147
                    spi_data_ptr->outBufferInd--;
149
                }
148
                }
150
                data_ptr->outBufferLen = 0;
149
                spi_data_ptr->outBufferLen = 0;
151
            }
150
            }
152
        }
151
        }
153
        IFS0CLR = 0x02000000; // Clear the TX flag
152
        IFS0CLR = 0x02000000; // Clear the TX flag
154
    }
153
    }
155
}
154
}
156
155