Subversion Repositories Code-Repo

Rev

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

Rev 201 Rev 212
Line 3... Line 3...
3
#include "defines.h"
3
#include "defines.h"
4
#include "SPI1.h"
4
#include "SPI1.h"
5
 
5
 
6
static SPI1_DATA *spi_data_ptr;
6
static SPI1_DATA *spi_data_ptr;
7
 
7
 
8
void SPI1_Init(SPI1_DATA *data) {
8
void SPI1_Init(SPI1_DATA *data, void (*rx_callback)(char)) {
9
    spi_data_ptr = data;
9
    spi_data_ptr = data;
10
    spi_data_ptr->outBufferInd = 0;
10
    spi_data_ptr->buffer_out_ind = 0;
11
    spi_data_ptr->outBufferLen = 0;
11
    spi_data_ptr->buffer_out_len = 0;
12
#ifndef SPI1_WRITE_ONLY
-
 
13
    spi_data_ptr->inBufferInd = 0;
-
 
14
    spi_data_ptr->inBufferLen = 0;
12
    spi_data_ptr->rx_callback = rx_callback;
15
#endif
-
 
16
    
13
    
17
    INTDisableInterrupts();
14
    INTDisableInterrupts();
18
 
15
 
19
    // Note: FIFO enhanced buffer depth is 4/8/16 for 32/16/8 bit widths
16
    // Note: FIFO enhanced buffer depth is 4/8/16 for 32/16/8 bit widths
20
    
17
    
Line 36... Line 33...
36
    IFS0CLR     = 0x03800000;   // Clear any existing event
33
    IFS0CLR     = 0x03800000;   // Clear any existing event
37
    IPC5CLR     = 0x1F000000;   // Clear the priority
34
    IPC5CLR     = 0x1F000000;   // Clear the priority
38
    IPC5SET     = 0x19000000;   // Set IPL=6, Subpriority 1
35
    IPC5SET     = 0x19000000;   // Set IPL=6, Subpriority 1
39
    SPI1BRG     = 0x1;          // Use FPB/4 clock frequency
36
    SPI1BRG     = 0x1;          // Use FPB/4 clock frequency
40
    SPI1STATCLR = 0x40;         // Clear the Overflow
37
    SPI1STATCLR = 0x40;         // Clear the Overflow
41
#ifndef SPI1_WRITE_ONLY
38
#ifndef SPI_WRITE_ONLY
42
    IEC0SET = 0x01800000;       // Enable RX and Error interrupts
39
    IEC0SET = 0x01800000;       // Enable RX and Error interrupts
43
#endif
40
#endif
44
    // Enhanced buffer, SPI on, 8 bits transfer, SMP=1, Master mode
41
    // Enhanced buffer, SPI on, 8 bits transfer, SMP=1, Master mode
45
    // SPIxTXIF set on buffer empty, SPIxRXIF set on buffer not empty
42
    // SPIxTXIF set on buffer empty, SPIxRXIF set on buffer not empty
46
    SPI1CON     = 0x18225;
43
    SPI1CON     = 0x18225;
47
 
44
 
48
    INTEnableInterrupts();
45
    INTEnableInterrupts();
49
}
46
}
50
 
47
 
51
#ifndef SPI1_WRITE_ONLY
-
 
52
int SPI1_Read_Buffer(unsigned char *array, unsigned int count) {
-
 
53
    if (count > SPI1_BUFFER_SIZE)
-
 
54
        return 0;
-
 
55
    if (spi_data_ptr->inBufferLen == 0)
-
 
56
        return 0;
-
 
57
 
-
 
58
    // Save previous interrupt state
-
 
59
    int prev = IEC0 & 0x03800000;
-
 
60
     // Temporarily disable interrupts
-
 
61
    IEC0CLR = 0x03800000;
-
 
62
    int ret = spi_data_ptr->inBufferLen;
-
 
63
    int i;
-
 
64
    for (i = 0; i < count; i++) {
-
 
65
        array[i] = spi_data_ptr->inBuffer[i];
-
 
66
    }
-
 
67
    // Reset buffer pointers
-
 
68
    spi_data_ptr->inBufferInd = 0;
-
 
69
    spi_data_ptr->inBufferLen = 0;
-
 
70
    // Restore saved interrupt state
-
 
71
    IEC0SET = prev;
-
 
72
    // Return the number of valid bytes in the buffer
-
 
73
    return ret;
-
 
74
}
-
 
75
#endif
-
 
76
 
-
 
77
int SPI1_Write(unsigned char *array, unsigned int count, void (*callback)(void)) {
48
int SPI1_Write(unsigned char *array, unsigned int count, void (*tx_callback)(void)) {
78
    spi_data_ptr->callback_function = callback;
49
    spi_data_ptr->tx_callback = tx_callback;
79
 
50
 
80
    if (count > SPI1_BUFFER_SIZE)
51
    if (count > SPI1_BUFFER_SIZE)
81
        return 0;
52
        return 0;
82
    if (spi_data_ptr->outBufferLen != 0)
53
    if (spi_data_ptr->buffer_out_len != 0)
83
        return 0;
54
        return 0;
84
 
55
 
-
 
56
    // Put the data to send into the outbound buffer
85
    spi_data_ptr->outBufferLen = count;
57
    spi_data_ptr->buffer_out_len = count;
86
    spi_data_ptr->outBufferInd = count-1;
58
    spi_data_ptr->buffer_out_ind = count-1;
87
    int i;
59
    int i;
88
    for (i = 0; i < count; i++) {
60
    for (i = 0; i < count; i++) {
89
        spi_data_ptr->outBuffer[i] = array[i];
61
        spi_data_ptr->buffer_out[i] = array[i];
90
    }
62
    }
91
    IEC0SET = 0x02000000; // Enable TX interrupt
63
    IEC0SET = 0x02000000; // Enable TX interrupt
92
    return 1;
64
    return 1;
93
}
65
}
94
 
66
 
95
void __ISR(_SPI_1_VECTOR, ipl6) __SPI_1_Interrupt_Handler(void) {
67
void __ISR(_SPI_1_VECTOR, ipl6) __SPI_1_Interrupt_Handler(void) {
96
#ifndef SPI1_WRITE_ONLY
68
#ifndef SPI_WRITE_ONLY
97
    // Process SPI1 error flag
69
    // Process SPI1 error flag
98
    if (IFS0bits.SPI1EIF) {
70
    if (IFS0bits.SPI1EIF) {
99
        // Clear the receive overflow bit if it is set
71
        // Clear the receive overflow bit if it is set
100
        if (SPI1STATbits.SPIROV) {
72
        if (SPI1STATbits.SPIROV) {
101
            SPI1STATbits.SPIROV = 0;
73
            SPI1STATbits.SPIROV = 0;
Line 106... Line 78...
106
    // Process SPI1 receive flag
78
    // Process SPI1 receive flag
107
    if (IFS0bits.SPI1RXIF) {
79
    if (IFS0bits.SPI1RXIF) {
108
        int i;
80
        int i;
109
        // Read the data received from the last transfer
81
        // Read the data received from the last transfer
110
        int rxBufferCount = SPI1STATbits.RXBUFELM;
82
        int rxBufferCount = SPI1STATbits.RXBUFELM;
111
        if (spi_data_ptr->inBufferLen + rxBufferCount < SPI1_BUFFER_SIZE) {
-
 
112
            for (i = 0; i < rxBufferCount; i++) {
83
        for (i = 0; i < rxBufferCount; i++) {
113
                spi_data_ptr->inBuffer[spi_data_ptr->inBufferInd] = SPI1BUF;
-
 
114
                spi_data_ptr->inBufferInd++;
84
            char c = SPI1BUF;
115
                spi_data_ptr->inBufferLen++;
-
 
116
            }
-
 
117
        } else {
-
 
118
            // If buffer is full, discard data in enhanced buffer
85
            // Call the RX callback function on the received data
119
            for (i = 0; i < rxBufferCount; i++) {
86
            if (spi_data_ptr->rx_callback != NULL)
120
                int tmp = SPI1BUF;
87
                (*spi_data_ptr->rx_callback)(c);
121
            }
-
 
122
        }
88
        }
123
        IFS0CLR = 0x01000000; // Clear the RX flag
89
        IFS0CLR = 0x01000000; // Clear the RX flag
124
    }
90
    }
125
#endif
91
#endif
126
 
92
 
127
    // Process SPI1 transmit flag
93
    // Process SPI1 transmit flag
128
    if (IFS0bits.SPI1TXIF) {
94
    if (IFS0bits.SPI1TXIF) {
129
        int i;
95
        int i;
130
        // Disable the transmit interrupt if all data has been sent
96
        // Disable the transmit interrupt if all data has been sent
131
        if (spi_data_ptr->outBufferLen == 0) {
97
        if (spi_data_ptr->buffer_out_len == 0) {
132
            IEC0CLR=0x02000000;
98
            IEC0CLR=0x02000000;
133
            if (spi_data_ptr->callback_function != NULL)
99
            if (spi_data_ptr->tx_callback != NULL)
134
                (*spi_data_ptr->callback_function)();
100
                (*spi_data_ptr->tx_callback)();
135
        } else {
101
        } else {
136
            // Start transmitting the data in the buffer
102
            // Start transmitting the data in the buffer
137
            int txBufferFree = 16 - SPI1STATbits.TXBUFELM;
103
            int txBufferFree = 16 - SPI1STATbits.TXBUFELM;
138
            if (spi_data_ptr->outBufferLen > txBufferFree) {
104
            if (spi_data_ptr->buffer_out_len > txBufferFree) {
139
                for (i = 0; i < txBufferFree; i++) {
105
                for (i = 0; i < txBufferFree; i++) {
140
                    SPI1BUF = spi_data_ptr->outBuffer[spi_data_ptr->outBufferInd];
106
                    SPI1BUF = spi_data_ptr->buffer_out[spi_data_ptr->buffer_out_ind];
141
                    spi_data_ptr->outBufferInd--;
107
                    spi_data_ptr->buffer_out_ind--;
142
                }
108
                }
143
                spi_data_ptr->outBufferLen -= txBufferFree;
109
                spi_data_ptr->buffer_out_len -= txBufferFree;
144
            } else {
110
            } else {
145
                for (i = 0; i < spi_data_ptr->outBufferLen; i++) {
111
                for (i = 0; i < spi_data_ptr->buffer_out_len; i++) {
146
                    SPI1BUF = spi_data_ptr->outBuffer[spi_data_ptr->outBufferInd];
112
                    SPI1BUF = spi_data_ptr->buffer_out[spi_data_ptr->buffer_out_ind];
147
                    spi_data_ptr->outBufferInd--;
113
                    spi_data_ptr->buffer_out_ind--;
148
                }
114
                }
149
                spi_data_ptr->outBufferLen = 0;
115
                spi_data_ptr->buffer_out_len = 0;
150
            }
116
            }
151
        }
117
        }
152
        IFS0CLR = 0x02000000; // Clear the TX flag
118
        IFS0CLR = 0x02000000; // Clear the TX flag
153
    }
119
    }
154
}
120
}
155
121