Skip to content

Commit 58d0e0c

Browse files
committed
Merge pull request #311 from Sissors/K20
[K20D5M] SPI implementation - freq
2 parents 32deaca + da3c7c5 commit 58d0e0c

File tree

1 file changed

+23
-29
lines changed
  • libraries/mbed/targets/hal/TARGET_Freescale/TARGET_K20D5M

1 file changed

+23
-29
lines changed

libraries/mbed/targets/hal/TARGET_Freescale/TARGET_K20D5M/spi_api.c

Lines changed: 23 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel
5454
SPIName spi_ssel = (SPIName)pinmap_peripheral(ssel, PinMap_SPI_SSEL);
5555
SPIName spi_data = (SPIName)pinmap_merge(spi_mosi, spi_miso);
5656
SPIName spi_cntl = (SPIName)pinmap_merge(spi_sclk, spi_ssel);
57-
57+
5858
obj->spi = (SPI_Type*)pinmap_merge(spi_data, spi_cntl);
5959
if ((int)obj->spi == NC) {
6060
error("SPI pinout mapping failed");
@@ -63,9 +63,8 @@ void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel
6363
SIM->SCGC5 |= SIM_SCGC5_PORTC_MASK | SIM_SCGC5_PORTD_MASK;
6464
SIM->SCGC6 |= SIM_SCGC6_SPI0_MASK;
6565

66-
// halted state
67-
obj->spi->MCR &= ~SPI_MCR_MDIS_MASK;
68-
obj->spi->MCR |= SPI_MCR_HALT_MASK | SPI_MCR_DIS_RXF_MASK | SPI_MCR_DIS_TXF_MASK;
66+
obj->spi->MCR &= ~(SPI_MCR_MDIS_MASK | SPI_MCR_HALT_MASK);
67+
//obj->spi->MCR |= SPI_MCR_DIS_RXF_MASK | SPI_MCR_DIS_TXF_MASK;
6968

7069
// set default format and frequency
7170
if (ssel == NC) {
@@ -77,8 +76,6 @@ void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel
7776

7877
// not halt in the debug mode
7978
obj->spi->SR |= SPI_SR_EOQF_MASK;
80-
// enable SPI
81-
obj->spi->MCR &= (~SPI_MCR_HALT_MASK);
8279

8380
// pin out the spi pins
8481
pinmap_pinout(mosi, PinMap_SPI_MOSI);
@@ -93,9 +90,9 @@ void spi_free(spi_t *obj) {
9390
// [TODO]
9491
}
9592
void spi_format(spi_t *obj, int bits, int mode, int slave) {
96-
if ((bits != 8) && (bits != 16)) {
97-
error("Only 8/16 bits SPI supported");
98-
}
93+
if ((bits < 4) || (bits > 16))
94+
error("SPI: Only frames between 4 and 16-bit supported");
95+
9996

10097
if ((mode < 0) || (mode > 3)) {
10198
error("SPI mode unsupported");
@@ -109,64 +106,61 @@ void spi_format(spi_t *obj, int bits, int mode, int slave) {
109106
obj->spi->MCR |= ((!slave) << SPI_MCR_MSTR_SHIFT);
110107

111108
// CTAR0 is used
112-
obj->spi->CTAR[0] &= ~(SPI_CTAR_CPHA_MASK | SPI_CTAR_CPOL_MASK);
113-
obj->spi->CTAR[0] |= (polarity << SPI_CTAR_CPOL_SHIFT) | (phase << SPI_CTAR_CPHA_SHIFT);
109+
obj->spi->CTAR[0] &= ~(SPI_CTAR_CPHA_MASK | SPI_CTAR_CPOL_MASK | SPI_CTAR_FMSZ_MASK);
110+
obj->spi->CTAR[0] |= (polarity << SPI_CTAR_CPOL_SHIFT) | (phase << SPI_CTAR_CPHA_SHIFT) | ((bits - 1) << SPI_CTAR_FMSZ_SHIFT);
114111
}
115112

116113
static const uint8_t baudrate_prescaler[] = {2,3,5,7};
117-
static const uint32_t baudrate_scaler[] = {2, 4, 6, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768};
118-
static const uint8_t delay_prescaler[] = {1, 3, 5, 7};
114+
static const uint16_t baudrate_scaler[] = {2,4,6,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768};
119115

120116
void spi_frequency(spi_t *obj, int hz) {
121-
uint32_t error = 0;
117+
uint32_t f_error = 0;
122118
uint32_t p_error = 0xffffffff;
123119
uint32_t ref = 0;
124120
uint32_t br = 0;
125121
uint32_t ref_spr = 0;
126122
uint32_t ref_prescaler = 0;
123+
uint32_t ref_dr = 0;
127124

128125
// bus clk
129126
uint32_t PCLK = bus_frequency();
130-
uint32_t divisor = 2;
131-
uint32_t prescaler;
132127

133-
/* TODO */
134128
for (uint32_t i = 0; i < 4; i++) {
135-
prescaler = baudrate_prescaler[i];
136-
divisor = 2;
137-
for (br = 0; br <= 15; br++, divisor *= 2) {
129+
for (br = 0; br <= 15; br++) {
138130
for (uint32_t dr = 0; dr < 2; dr++) {
139-
ref = (PCLK / prescaler) * ((1U + dr) / divisor);
131+
ref = (PCLK * (1U + dr) / baudrate_prescaler[i]) / baudrate_scaler[br];
140132
if (ref > (uint32_t)hz)
141133
continue;
142-
error = hz - ref;
143-
if (error < p_error) {
134+
f_error = hz - ref;
135+
if (f_error < p_error) {
144136
ref_spr = br;
145137
ref_prescaler = i;
146-
p_error = error;
138+
ref_dr = dr;
139+
p_error = f_error;
147140
}
148141
}
149142
}
150143
}
151144

152145
// set PBR and BR
153-
obj->spi->CTAR[0] = ((ref_prescaler & 0x3) << SPI_CTAR_PBR_SHIFT) | (ref_spr & 0xf);
146+
obj->spi->CTAR[0] &= ~(SPI_CTAR_PBR_MASK | SPI_CTAR_BR_MASK | SPI_CTAR_DBR_MASK);
147+
obj->spi->CTAR[0] |= (ref_prescaler << SPI_CTAR_PBR_SHIFT) | (ref_spr << SPI_CTAR_BR_SHIFT) | (ref_dr << SPI_CTAR_DBR_SHIFT);
154148
}
155149

156150
static inline int spi_writeable(spi_t *obj) {
157151
return (obj->spi->SR & SPI_SR_TFFF_MASK) ? 1 : 0;
158152
}
159153

160154
static inline int spi_readable(spi_t *obj) {
161-
return (obj->spi->SR & SPI_SR_RFDF_MASK) ? 0 : 1;
155+
return (obj->spi->SR & SPI_SR_RFDF_MASK) ? 1 : 0;
162156
}
163157

164158
int spi_master_write(spi_t *obj, int value) {
159+
//clear RX buffer flag
160+
obj->spi->SR |= SPI_SR_RFDF_MASK;
165161
// wait tx buffer empty
166162
while(!spi_writeable(obj));
167-
obj->spi->PUSHR = SPI_PUSHR_TXDATA(value & 0xff) /*| SPI_PUSHR_EOQ_MASK*/;
168-
169-
while (!obj->spi->SR & SPI_SR_TCF_MASK); // wait for transfer to be complete
163+
obj->spi->PUSHR = SPI_PUSHR_TXDATA(value & 0xffff) /*| SPI_PUSHR_EOQ_MASK*/;
170164

171165
// wait rx buffer full
172166
while (!spi_readable(obj));

0 commit comments

Comments
 (0)