Skip to content

Commit da3c7c5

Browse files
committed
K20D5(0)M SPI code
Other pinouts still need to be done. PTC6 as MOSI possibly has issues. There are also some changes which technically aren't required, but were made in the search to why on earth it wasn't doing anything.
1 parent 32deaca commit da3c7c5

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)