Initial commit, code based on LPC1224 support and LPC812-MAX CMSIS-DAP interface...
[lpc11u3x] / drivers / ssp.c
1 /****************************************************************************
2  *  drivers/ssp.c
3  *
4  * Copyright 2012 Nathael Pajani <nathael.pajani@ed3l.fr>
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  *
19  *************************************************************************** */
23 /***************************************************************************** */
24 /*                SSP                                                          */
25 /***************************************************************************** */
27 #include <stdint.h>
28 #include "core/lpc_regs_11u3x.h"
29 #include "core/lpc_core_cm0.h"
30 #include "core/system.h"
31 #include "core/pio.h"
32 #include "lib/string.h"
33 #include "drivers/ssp.h"
36 struct ssp_device
37 {
38         uint32_t num;
39         struct lpc_ssp* regs;
40         uint32_t current_clk;
41         uint32_t mutex;
42         volatile uint32_t int_rx_stats;
43         volatile uint32_t int_overrun_stats;
44         volatile uint32_t int_rx_timeout_stats;
46         uint32_t irq;
47         uint32_t clk_ctrl_bit;
48 };
50 #define NUM_SSPS 2
51 static struct ssp_device ssps[NUM_SSPS] = {
52         {
53                 .num = 0,
54                 .regs = LPC_SSP0,
55                 .current_clk = 0,
56                 .mutex = 0,
57                 .int_rx_stats = 0,
58                 .int_overrun_stats = 0,
59                 .int_rx_timeout_stats = 0,
60                 .irq = SSP0_IRQ,
61                 .clk_ctrl_bit = LPC_SYS_ABH_CLK_CTRL_SSP0,
62         },
63         {
64                 .num = 1,
65                 .regs = LPC_SSP1,
66                 .current_clk = 0,
67                 .mutex = 0,
68                 .int_rx_stats = 0,
69                 .int_overrun_stats = 0,
70                 .int_rx_timeout_stats = 0,
71                 .irq = SSP1_IRQ,
72                 .clk_ctrl_bit = LPC_SYS_ABH_CLK_CTRL_SSP1,
73         },
74 };
78 /* Handlers */
79 void SSP_0_Handler(void)
80 {
81         struct lpc_ssp* ssp = LPC_SSP0;
82         uint32_t intr_flags = ssp->masked_int_status;
84         /* Clear the interrupts. Other bits are cleared by fifo access */
85         ssp->int_clear = (intr_flags & (LPC_SSP_INTR_RX_OVERRUN | LPC_SSP_INTR_RX_TIMEOUT));
86         if (intr_flags & LPC_SSP_INTR_RX_OVERRUN) {
87                 ssps[0].int_overrun_stats += 1;
88         }
89         if (intr_flags & LPC_SSP_INTR_RX_TIMEOUT) {
90                 ssps[0].int_rx_timeout_stats += 1;
91         }
92 }
94 void SSP_1_Handler(void)
95 {
96         struct lpc_ssp* ssp = LPC_SSP1;
97         uint32_t intr_flags = ssp->masked_int_status;
99         /* Clear the interrupts. Other bits are cleared by fifo access */
100         ssp->int_clear = (intr_flags & (LPC_SSP_INTR_RX_OVERRUN | LPC_SSP_INTR_RX_TIMEOUT));
101         if (intr_flags & LPC_SSP_INTR_RX_OVERRUN) {
102                 ssps[0].int_overrun_stats += 1;
103         }
104         if (intr_flags & LPC_SSP_INTR_RX_TIMEOUT) {
105                 ssps[0].int_rx_timeout_stats += 1;
106         }
111 /***************************************************************************** */
112 /* SPI Bus mutex */
114 #if MULTITASKING == 1
115 int spi_get_mutex(uint8_t ssp_num)
117         /* Note : a multitasking OS should call the scheduler here. Any other system
118          *   will get frozen, unless some interrupt routine has been set to release
119          *   the mutex.
120          */
121         do {} while (sync_lock_test_and_set(&(ssps[ssp_num].mutex), 1) == 1);
122         return 1;
124 #else
125 int spi_get_mutex(uint8_t ssp_num)
127         if (sync_lock_test_and_set(&(ssps[ssp_num].mutex), 1) == 1) {
128                 return -EBUSY;
129         }
130         return 1;
132 #endif
133 void spi_release_mutex(uint8_t ssp_num)
135         sync_lock_release(&(ssps[ssp_num].mutex));
139 /***************************************************************************** */
140 /* This function is used to transfer a word (4 to 16 bits) to AND from a device
141  * As the SPI bus is full duplex, data can flow in both directions, but the clock is
142  *   always provided by the master. The SPI clock cannont be activated without sending
143  *   data, which means we must send data to the device when we want to read data from
144  *   the device.
145  * Note : the SSP device number is not checked, thus a value above the number of SSP
146  *   devices present on the micro-controller may break your programm.
147  *   Double check the value of the ssp_num parameter. The check is made on the call to
148  *   ssp_master_on() or ssp_slave_on().
149  * This function does not take care of the SPI chip select.
150  */
151 uint16_t spi_transfer_single_frame(uint8_t ssp_num, uint16_t data)
153         struct lpc_ssp* ssp_regs = ssps[ssp_num].regs;
154         ssp_regs->data = data;
155         /* Wait until the busy bit is cleared */
156         while (ssp_regs->status & LPC_SSP_ST_BUSY);
157         return ssp_regs->data;
162 /***************************************************************************** */
163 /* Multiple words (4 to 16 bits) transfer function on the SPI bus. */
165 /* Internal function used to send 9 to 16 bits wide data */
166 static int spi_transfer_words(struct lpc_ssp* ssp, uint16_t* data_out, uint16_t* data_in, int size)
168         int count = 0;
169         uint16_t data_read = 0; /* Used to store SPI Rx data */
171         /* Transfer */
172         do {
173                 /* Fill Tx fifo with available data, but stop if rx fifo is full */
174                 while ((count < size) &&
175                           ((ssp->status & (LPC_SSP_ST_TX_NOT_FULL | LPC_SSP_ST_RX_FULL)) == LPC_SSP_ST_TX_NOT_FULL)) {
176                         ssp->data = *data_out;
177                         count++;
178                         data_out++;
179                 }
181                 /* Read some of the replies, but stop if there's still data to send and the fifo
182                  *  is running short */
183                 while ((ssp->status & LPC_SSP_ST_RX_NOT_EMPTY) &&
184                                 !((count < size) && (ssp->raw_int_status & LPC_SSP_INTR_TX_HALF_EMPTY))) {
185                         /* Read the data (mandatory) */
186                         data_read = ssp->data;
187                         if (data_in != NULL) {
188                                 /* And store when requested */
189                                 *data_in = data_read;
190                                 data_in++;
191                         }
192                 }
193         /* Go on till both all data is sent and all data is received */
194         } while ((count < size) || (ssp->status & (LPC_SSP_ST_BUSY | LPC_SSP_ST_RX_NOT_EMPTY)));
196         return count;
198 /* Internal function used to send 4 to 8 bits wide data */
199 static int spi_transfer_bytes(struct lpc_ssp* ssp, uint8_t* data_out, uint8_t* data_in, int size)
201         int count = 0;
202         uint8_t data_read = 0; /* Used to store SPI Rx data */
204         /* Transfer */
205         do {
206                 /* Fill Tx fifo with available data, but stop if rx fifo is full */
207                 while ((count < size) &&
208                           ((ssp->status & (LPC_SSP_ST_TX_NOT_FULL | LPC_SSP_ST_RX_FULL)) == LPC_SSP_ST_TX_NOT_FULL)) {
209                         ssp->data = (uint16_t)(*data_out);
210                         count++;
211                         data_out++;
212                 }
214                 /* Read some of the replies, but stop if there's still data to send and the fifo
215                  *  is running short */
216                 while ((ssp->status & LPC_SSP_ST_RX_NOT_EMPTY) &&
217                                 !((count < size) && (ssp->raw_int_status & LPC_SSP_INTR_TX_HALF_EMPTY))) {
218                         /* Read the data (mandatory) */
219                         data_read = (uint8_t)ssp->data;
220                         if (data_in != NULL) {
221                                 /* And store when requested */
222                                 *data_in = data_read;
223                                 data_in++;
224                         }
225                 }
226         /* Go on till both all data is sent and all data is received */
227         } while ((count < size) || (ssp->status & (LPC_SSP_ST_BUSY | LPC_SSP_ST_RX_NOT_EMPTY)));
229         return count;
233 /* Multiple words (4 to 16 bits) transfer function on the SPI bus.
234  * The SSP fifo is used to leave as little time between frames as possible.
235  * Parameters :
236  *  ssp_num : ssp device number. The SSP device number is not checked, thus a value above
237  *            the number of SSP devices present on the micro-controller may break your
238  *            programm. Double check the value of the ssp_num parameter. The check is made
239  *            on the call to ssp_master_on() or ssp_slave_on().
240  *  size is the number of frames, each one having the configured data width (4 to 16 bits).
241  *  data_out : data to be sent. Data will be read in the lower bits of the 16 bits values
242  *             pointed by "data_out" for each frame. If NULL, then the content of data_in
243  *             will be used.
244  *  data_in : buffer for read data. If NULL, read data will be discarded.
245  * Returns the number of data words transfered or negative value on error.
246  * As the SPI bus is full duplex, data can flow in both directions, but the clock is
247  *   always provided by the master. The SPI clock cannont be activated without sending
248  *   data, which means we must send data to the device when we want to read data from
249  *   the device.
250  * This function does not take care of the SPI chip select.
251  * Note: there's no need to count Rx data as it is equal to Tx data
252  * Note : the SSP device number is not checked, thus a value above the number of SSP
253  *   devices present on the micro-controller may break your programm.
254  *   Double check the value of the ssp_num parameter. The check is made on the call to
255  *   ssp_master_on() or ssp_slave_on().
256  */
257 int spi_transfer_multiple_frames(uint8_t ssp_num, void* data_out, void* data_in, int size, int width)
259         struct lpc_ssp* ssp_regs = ssps[ssp_num].regs;
261         /* Did the user provide a buffer to send data ? */
262         if (data_out == NULL) {
263                 if (data_in == NULL) {
264                         return -EINVAL;
265                 }
266                 data_out = data_in;
267         }
268         /* Transfer using either byte or word transfer functions */
269         if (width > 8) {
270                 return spi_transfer_words(ssp_regs, (uint16_t*)data_out, (uint16_t*)data_in, size);
271         } else {
272                 return spi_transfer_bytes(ssp_regs, (uint8_t*)data_out, (uint8_t*)data_in, size);
273         }
278 /***************************************************************************** */
279 uint32_t ssp_clk_on(uint8_t ssp_num, uint32_t rate)
281         struct lpc_sys_control* sys_ctrl = LPC_SYS_CONTROL;
282         struct lpc_ssp* ssp_regs = ssps[ssp_num].regs;
283         uint32_t prescale = 0, pclk_div = 0;
284         uint32_t pclk = 0, div = 0;
286         /* Do not divide by 0 */
287         if (rate == 0) {
288                 return 0;
289         }
291         pclk = get_main_clock();
293         /* Make sure we can get this clock rate */
294         /* NOTE: We use only to divisors, so we could achieve lower clock rates by using
295          *   the third one. Any need for this though ?
296          */
297         if ((pclk / rate) > 0xFFF0) {
298                 /* What should we do ? */
299                 div = 0xFFF0;
300         } else {
301                 div = pclk / rate;
302         }
304         do {
305                 prescale += 2; /* Minimum value is 2, and must be even */
306                 pclk_div = (div / prescale);
307         } while ((prescale > 0xFF) || (pclk_div > 0xFF));
309         /* Activate the SSP clock (maybe divide main clock) */
310         switch (ssp_num) {
311                 case 0:
312                         sys_ctrl->ssp0_clk_div = pclk_div;
313                         break;
314                 case 1:
315                         sys_ctrl->ssp1_clk_div = pclk_div;
316                         break;
317         }
319         /* Set the prescaler */
320         ssp_regs->clk_prescale = prescale;
322         /* And return the achieved clock */
323         return (pclk / (prescale * pclk_div));
326 void ssp_clk_update(void)
328         int i = 0;
329         for (i = 0; i < NUM_SSPS; i++) {
330                 if (ssps[i].current_clk) {
331                         ssp_clk_on(i, ssps[i].current_clk);
332                 }
333         }
337 /***************************************************************************** */
338 /* SSP Setup as master */
339 /* Returns 0 on success
340  * Parameters :
341  *  frame_type is SPI, TI or MICROWIRE (use apropriate defines for this one:
342  *     LPC_SSP_FRAME_SPI - LPC_SSP_FRAME_TI - LPC_SSP_FRAME_MICROWIRE).
343  *  data_width is a number between 4 and 16.
344  *  rate : The bit rate, in Hz.
345  * The SPI Chip Select is not handled by the SPI driver in master SPI mode as it's
346  *   handling highly depends on the device on the other end of the wires. Use a GPIO
347  *   to activate the device's chip select (usually active low)
348  */
349 int ssp_master_on(uint8_t ssp_num, uint8_t frame_type, uint8_t data_width, uint32_t rate)
351         struct ssp_device* ssp = NULL;
352         struct lpc_ssp* ssp_regs = NULL;
354         if (ssp_num >= NUM_SSPS)
355                 return -EINVAL;
356         ssp = &ssps[ssp_num];
357         ssp_regs = ssp->regs;
359         NVIC_DisableIRQ(ssp->irq);
361         /* Power up the ssp block */
362         subsystem_power(ssp->clk_ctrl_bit, 1);
364         /* Configure the SSP mode */
365         ssp_regs->ctrl_0 = (LPC_SSP_DATA_WIDTH(data_width) | frame_type | LPC_SSP_SPI_CLK_LOW | LPC_SSP_SPI_CLK_FIRST);
366         ssp_regs->ctrl_1 = LPC_SSP_MASTER_MODE;
368         /* Configure the clock : done after basic configuration */
369         ssp->current_clk = ssp_clk_on(ssp_num, rate);
371         /* Enable SSP */
372         ssp_regs->ctrl_1 |= LPC_SSP_ENABLE;
374         NVIC_EnableIRQ(ssp->irq);
375         return 0; /* Config OK */
378 int ssp_slave_on(uint8_t ssp_num, uint8_t frame_type, uint8_t data_width, uint8_t out_en, uint32_t max_rate)
380         struct ssp_device* ssp = NULL;
381         struct lpc_ssp* ssp_regs = NULL;
383         if (ssp_num >= NUM_SSPS)
384                 return -EINVAL;
385         ssp = &ssps[ssp_num];
386         ssp_regs = ssp->regs;
388         NVIC_DisableIRQ(ssp->irq);
389         /* Power up the ssp block */
390         subsystem_power(ssp->clk_ctrl_bit, 1);
392         /* Configure the SSP mode */
393         ssp_regs->ctrl_0 = LPC_SSP_DATA_WIDTH(data_width);
394         ssp_regs->ctrl_0 |= (frame_type | LPC_SSP_SPI_CLK_LOW | LPC_SSP_SPI_CLK_FIRST);
395         ssp_regs->ctrl_1 = LPC_SSP_SLAVE_MODE;
396         if (!out_en) {
397                 ssp_regs->ctrl_1 |= LPC_SSP_SLAVE_OUT_DISABLE;
398         }
400         /* Configure the clock : done after basic configuration.
401          * Our clock must be at least 12 times the master clock */
402         ssp->current_clk = ssp_clk_on(ssp_num, max_rate * 16);
404         /* Enable SSP */
405         ssp_regs->ctrl_1 |= LPC_SSP_ENABLE;
407         NVIC_EnableIRQ(ssp->irq);
408         return 0; /* Config OK */
411 /* Turn off the SSP block */
412 void ssp_off(uint8_t ssp_num)
414         struct ssp_device* ssp = NULL;
416         if (ssp_num >= NUM_SSPS)
417                 return;
418         ssp = &ssps[ssp_num];
420         ssp->current_clk = 0;
421         NVIC_DisableIRQ(ssp->irq);
422         subsystem_power(ssp->clk_ctrl_bit, 0);
424         /* Can be done even if we don't hold the mutex */
425         sync_lock_release(&ssp->mutex);