OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [freertos-6.1.1/] [Demo/] [CORTEX_EFMG890F128_IAR/] [bsp/] [dvk_spi.c] - Blame information for rev 595

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 595 jeremybenn
/**************************************************************************//**
2
 * @file
3
 * @brief SPI implementation of Board Control interface
4
 *        This implementation use the USART2 SPI interface to control board
5
 *        control registers. It works
6
 * @author Energy Micro AS
7
 * @version 1.0.1
8
 ******************************************************************************
9
 * @section License
10
 * <b>(C) Copyright 2009 Energy Micro AS, http://www.energymicro.com</b>
11
 ******************************************************************************
12
 *
13
 * This source code is the property of Energy Micro AS. The source and compiled
14
 * code may only be used on Energy Micro "EFM32" microcontrollers.
15
 *
16
 * This copyright notice may not be removed from the source code nor changed.
17
 *
18
 * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
19
 * obligation to support this Software. Energy Micro AS is providing the
20
 * Software "AS IS", with no express or implied warranties of any kind,
21
 * including, but not limited to, any implied warranties of merchantability
22
 * or fitness for any particular purpose or warranties against infringement
23
 * of any proprietary rights of a third party.
24
 *
25
 * Energy Micro AS will not be liable for any consequential, incidental, or
26
 * special damages, or any other relief, or for any claim by any third party,
27
 * arising from your use of this Software.
28
 *
29
 *****************************************************************************/
30
 
31
#include "efm32.h"
32
#include "dvk.h"
33
#include "dvk_bcregisters.h"
34
 
35
#define clear_bit(reg, bit)    (reg &= ~(1 << bit))
36
 
37
static volatile uint16_t *lastAddr = 0;
38
 
39
/**************************************************************************//**
40
 * @brief  Initializes USART2 SPI interface for access to FPGA registers
41
 *         for board control
42
 *****************************************************************************/
43
static void spiInit(void)
44
{
45
  USART_TypeDef  *usart = USART2;
46
  GPIO_TypeDef   *gpio  = GPIO;
47
  uint32_t       clk, spidiv;
48
  const uint32_t baudrate = 7000000;
49
  const uint32_t div      = (2 * baudrate / 256);
50
 
51
  /* Configure SPI bus connect pins */
52
  gpio->P[2].MODEH &= ~(_GPIO_P_MODEH_MODE13_MASK);
53
  gpio->P[2].MODEH |= (GPIO_P_MODEH_MODE13_PUSHPULL);
54
  gpio->P[2].DOUT &= ~(1UL << 13);
55
 
56
  /* Configure SPI pins */
57
  gpio->P[2].MODEL &= ~(_GPIO_P_MODEL_MODE2_MASK |
58
                        _GPIO_P_MODEL_MODE3_MASK |
59
                        _GPIO_P_MODEL_MODE4_MASK |
60
                        _GPIO_P_MODEL_MODE5_MASK);
61
  gpio->P[2].MODEL |= (GPIO_P_MODEL_MODE2_PUSHPULL |
62
                       GPIO_P_MODEL_MODE3_PUSHPULL |
63
                       GPIO_P_MODEL_MODE4_PUSHPULL |
64
                       GPIO_P_MODEL_MODE5_PUSHPULL);
65
  gpio->P[2].DOUT |= (1UL << 5);
66
 
67
  /* Configure USART2 as SPI master with manual CS */
68
  /* Get peripheral clock - ensure updated SystemCoreClock */
69
  SystemCoreClockUpdate();
70
  clk = (SystemCoreClock >> ((CMU->HFPERCLKDIV & _CMU_HFPERCLKDIV_HFPERCLKDIV_MASK) >>
71
                             _CMU_HFPERCLKDIV_HFPERCLKDIV_SHIFT));
72
  /* Drive spi at max 7Mhz or half clockrate if core freq < 14Mhz */
73
  if (clk < 14000000)
74
  {
75
    spidiv = 0;
76
  }
77
  else
78
  {
79
    spidiv = (clk) / (div) - 256;
80
  }
81
 
82
  /* Never allow higher frequency than specified, round up 1/4 div */
83
  if (spidiv & 0x3f) spidiv += 0x40;
84
 
85
  usart->CLKDIV = spidiv;
86
  usart->CTRL   = USART_CTRL_SYNC;
87
  usart->CMD    = USART_CMD_CLEARRX | USART_CMD_CLEARTX;
88
  usart->ROUTE  = USART_ROUTE_TXPEN | USART_ROUTE_RXPEN | USART_ROUTE_CLKPEN;
89
  usart->CMD    = USART_CMD_MASTEREN | USART_CMD_TXEN | USART_CMD_RXEN;
90
}
91
 
92
/**************************************************************************//**
93
 * @brief  Disables GPIO pins and USART2 from FPGA register access
94
 *****************************************************************************/
95
static void spiDisable(void)
96
{
97
  USART_TypeDef *usart = USART2;
98
  GPIO_TypeDef  *gpio  = GPIO;
99
 
100
  /* Disable USART2 */
101
  usart->CTRL  = _USART_CTRL_RESETVALUE;
102
  usart->ROUTE = _USART_ROUTE_RESETVALUE;
103
  usart->CMD   = USART_CMD_MASTERDIS | USART_CMD_TXDIS | USART_CMD_RXDIS;
104
 
105
  /* Disable SPI pins */
106
  gpio->P[2].MODEH &= ~(_GPIO_P_MODEH_MODE13_MASK);
107
  gpio->P[2].MODEL &= ~(_GPIO_P_MODEL_MODE2_MASK |
108
                        _GPIO_P_MODEL_MODE3_MASK |
109
                        _GPIO_P_MODEL_MODE4_MASK |
110
                        _GPIO_P_MODEL_MODE5_MASK);
111
}
112
 
113
/**************************************************************************//**
114
 * @brief  Performs USART2 SPI Transfer
115
 *****************************************************************************/
116
static uint16_t spiAccess(uint8_t spiadr, uint8_t rw, uint16_t spidata)
117
{
118
  USART_TypeDef *usart = USART2;
119
  GPIO_TypeDef  *gpio  = GPIO;
120
  uint16_t      tmp;
121
 
122
  clear_bit(gpio->P[2].DOUT, 5);
123
 
124
  /* SPI address */
125
  usart->TXDATA = (spiadr & 0x3) | rw << 3;
126
  while (!(usart->STATUS & USART_STATUS_TXC)) ;
127
  tmp = (usart->RXDATA) << 0;
128
 
129
  /* SPI data LSB */
130
  usart->TXDATA = spidata & 0xFF;
131
  while (!(usart->STATUS & USART_STATUS_TXC)) ;
132
  tmp = (usart->RXDATA);
133
 
134
  /* SPI data MSB */
135
  usart->TXDATA = spidata >> 8;
136
  while (!(usart->STATUS & USART_STATUS_TXC)) ;
137
  tmp |= (usart->RXDATA) << 8;
138
 
139
  gpio->P[2].DOUT |= (1 << 5);
140
 
141
  return tmp;
142
}
143
 
144
/**************************************************************************//**
145
 * @brief  Performs USART2 SPI write to FPGA register
146
 * @param spiadr Address of register
147
 * @param spidata Data to write
148
 *****************************************************************************/
149
static void spiWrite(uint8_t spiadr, uint16_t spidata)
150
{
151
  spiAccess(spiadr, 0, spidata);
152
}
153
 
154
/**************************************************************************//**
155
 * @brief  Performs USART2 SPI read from FPGA register
156
 * @param spiadr Address of register
157
 * @param spidata Dummy data
158
 *****************************************************************************/
159
static uint16_t spiRead(uint8_t spiadr, uint16_t spidata)
160
{
161
  return spiAccess(spiadr, 1, spidata);
162
}
163
 
164
/**************************************************************************//**
165
 * @brief  Initializes DVK register access
166
 *****************************************************************************/
167
void DVK_SPI_init(void)
168
{
169
  uint16_t spiMagic;
170
 
171
  spiInit();
172
  /* Read "board control Magic" register to verify SPI is up and running */
173
  /*  if not FPGA is configured to be in EBI mode  */
174
 
175
  spiMagic = DVK_SPI_readRegister(BC_MAGIC);
176
  if (spiMagic != BC_MAGIC_VALUE)
177
  {
178
    /* Development Kit is configured to use EBI mode, restart of kit required */
179
    /* to use USART2-SPI for configuration */
180
    spiDisable();
181
    while (1) ;
182
  }
183
}
184
 
185
/**************************************************************************//**
186
 * @brief  Disable and free up resources used by SPI board control access
187
 *****************************************************************************/
188
void DVK_SPI_disable(void)
189
{
190
  spiDisable();
191
}
192
 
193
/**************************************************************************//**
194
 * @brief  Perform read from DVK board control register
195
 * @param  addr Address of register to read from
196
 *****************************************************************************/
197
uint16_t DVK_SPI_readRegister(volatile uint16_t *addr)
198
{
199
  uint16_t data;
200
 
201
  if (addr != lastAddr)
202
  {
203
    spiWrite(0x00, 0xFFFF & ((uint32_t) addr));             /*LSBs of address*/
204
    spiWrite(0x01, 0xFF & ((uint32_t) addr >> 16));         /*MSBs of address*/
205
    spiWrite(0x02, (0x0C000000 & (uint32_t) addr) >> 26);   /*Chip select*/
206
  }
207
  /* Read twice */
208
  data     = spiRead(0x03, 0);
209
  data     = spiRead(0x03, 0);
210
  lastAddr = addr;
211
  return data;
212
}
213
 
214
/**************************************************************************//**
215
 * @brief  Perform write to DVK board control register
216
 * @param addr Address of register to write to
217
 * @param data 16-bit to  write into register
218
 *****************************************************************************/
219
void DVK_SPI_writeRegister(volatile uint16_t *addr, uint16_t data)
220
{
221
  if (addr != lastAddr)
222
  {
223
    spiWrite(0x00, 0xFFFF & ((uint32_t) addr));             /*LSBs of address*/
224
    spiWrite(0x01, 0xFF & ((uint32_t) addr >> 16));         /*MSBs of address*/
225
    spiWrite(0x02, (0x0C000000 & (uint32_t) addr) >> 26);   /*Chip select*/
226
  }
227
  spiWrite(0x03, data);                                     /*Data*/
228
  lastAddr = addr;
229
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.