Closed janjongboom closed 7 years ago
There was no change in SPI for v147, neither in drivers (please look at git log to confirm that nothing has changed there) for this target that could cause this.
I tested LPC1768 SPI with Fujitsu MB85RSxxx FRAM component and the result are not identical between mbed library Rev. 146 and 147.
I will find out further.
[Rev.146]
Fujitsu MB85RSxxx FRAM test program
read device ID = 0x4 0x7f 0x28 0x3
read status (WREN) = 0x2
read status (WRDI) = 0x0
00000000 : 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
00000010 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00000020 : 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
00000030 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00000040 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00000050 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00000060 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00000070 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00000000 : 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
00000010 : 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F
00000020 : 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F
00000030 : 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
00000040 : 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F
00000050 : 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F
00000060 : 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F
00000070 : 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F
00000080 : 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F
00000090 : 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F
000000A0 : A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF
000000B0 : B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF
000000C0 : C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF
000000D0 : D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF
000000E0 : E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF
000000F0 : F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF
[Rev.147]
Fujitsu MB85RSxxx FRAM test program
read device ID = 0x2 0x3f 0x14 0x1
read status (WREN) = 0x1
read status (WRDI) = 0x0
00000000 : 00 00 01 01 02 02 03 03 04 04 05 05 06 06 07 07
00000010 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00000020 : 00 00 01 01 02 02 03 03 04 04 05 05 06 06 07 07
00000030 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00000040 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00000050 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00000060 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00000070 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00000000 : C0 00 01 01 02 02 03 03 04 04 05 05 06 06 07 07
00000010 : 08 08 09 09 0A 0A 0B 0B 0C 0C 0D 0D 0E 0E 0F 0F
00000020 : 10 10 11 11 12 12 13 13 14 14 15 15 16 16 17 17
00000030 : 18 18 19 19 1A 1A 1B 1B 1C 1C 1D 1D 1E 1E 1F 1F
00000040 : 20 20 21 21 22 22 23 23 24 24 25 25 26 26 27 27
00000050 : 28 28 29 29 2A 2A 2B 2B 2C 2C 2D 2D 2E 2E 2F 2F
00000060 : 30 30 31 31 32 32 33 33 34 34 35 35 36 36 37 37
00000070 : 38 38 39 39 3A 3A 3B 3B 3C 3C 3D 3D 3E 3E 3F 3F
00000080 : C0 C0 C1 C1 C2 C2 C3 C3 C4 C4 C5 C5 C6 C6 C7 C7
00000090 : C8 C8 C9 C9 CA CA CB CB CC CC CD CD CE CE CF CF
000000A0 : D0 D0 D1 D1 D2 D2 D3 D3 D4 D4 D5 D5 D6 D6 D7 D7
000000B0 : D8 D8 D9 D9 DA DA DB DB DC DC DD DD DE DE DF DF
000000C0 : E0 E0 E1 E1 E2 E2 E3 E3 E4 E4 E5 E5 E6 E6 E7 E7
000000D0 : E8 E8 E9 E9 EA EA EB EB EC EC ED ED EE EE EF EF
000000E0 : F0 F0 F1 F1 F2 F2 F3 F3 F4 F4 F5 F5 F6 F6 F7 F7
000000F0 : F8 F8 F9 F9 FA FA FB FB FC FC FD FD FE FE FF FF
The constructor of the component library is something like:
MB85RSxx_SPI::MB85RSxx_SPI(PinName mosi, PinName miso, PinName sclk, PinName cs)
:
_spi(mosi, miso, sclk),
_cs(cs)
{
uint8_t buf[4];
_cs = 1;
_spi.format(8, 0);
read_device_id(buf);
if ((buf[2] & 0x1F) > MB85_DENSITY_512K) {
_address_bits = 24;
} else {
_address_bits = 16;
}
}
I temporary added frequency() function call like below and the test program works fine as same as rev 146.
MB85RSxx_SPI::MB85RSxx_SPI(PinName mosi, PinName miso, PinName sclk, PinName cs)
:
_spi(mosi, miso, sclk),
_cs(cs)
{
uint8_t buf[4];
_cs = 1;
_spi.format(8, 0);
_spi.frequency(1000000); // *** Added this ***
read_device_id(buf);
if ((buf[2] & 0x1F) > MB85_DENSITY_512K) {
_address_bits = 24;
} else {
_address_bits = 16;
}
}
@toyowata Can you pinpoint to the changeset that affects this? I cant locate any changes in SPI API, neither HAL for this target?
@0xc0170 This should be an issue in HAL, not SPI API. I just quick checked to review SPI HAL code of the LPC1768 and found that spi_format()
function wrongly broken control register bits for SPI serial clock rate setting. It works if SPI::frequency() is called just after the SPI::format() call to set correct serial clock rate.
I will find out more detail tomorrow.
This is not only for LPC1768 SPI issue, but also other NXP LPC platforms (LPC11U68, LPC1114, LPC4337 and more?), because the LPC1768 code was reused for same SSP/SPI peripheral module.
The control register of LPC1768 SSP/SPI is below:
The SCR bits are configured for SPI serial clock rate. This CR0 register is updated in the spi_format
function in the spi_api.c
(LPC1768 SPI HAL). It reads the current CR0 register value to tmp
local variable and clears bits [8:0] to update new SPI format value. However, it wrongly clears bits [15:0] include SCR field, then serial clock rate is broken.
https://github.com/ARMmbed/mbed-os/blob/master/targets/TARGET_NXP/TARGET_LPC176X/spi_api.c#L101
As far as I checked, following platform are affected this problem.
LPC1768, LPC11Uxx, LPC11U68, LPC4337, LPC1114, LPC11Cxx and LPC13xx
I will make fixes and PR for all targets above.
It also affects TARGET_LPC408X, and there of course both TARGET_LPC4088 and TARGET_LPC4088_DM, so LPC408x should be fixed too.
Regards Neni
Thanks @toyowata for looking at this.
I still fail to understand why it is not broken in earlier mbed lib versions?
Hi @0xc0170
I still fail to understand why it is not broken in earlier mbed lib versions?
In the Rev.146 SPI code, SPI::format() always set NULL to SPI::_owner which means calling the SPI::format() always calls both spi_format() and spi_frequency() of target HAL.
In the Rev.147 (and current code), SPI::format() calls only spi_format() HAL function, because _owner variable was set by _acquire() call from the constructor when instance is created.
https://github.com/ARMmbed/mbed-os/blob/master/drivers/SPI.cpp#L40 https://github.com/ARMmbed/mbed-os/blob/master/drivers/SPI.cpp#L91 https://github.com/ARMmbed/mbed-os/blob/master/drivers/SPI.cpp#L50
That is different behavior of SPI API. Obviously, behavior of the Rev.147 is correct and unvailed latent problem in LPCs SPI HAL implimentation.
See https://developer.mbed.org/questions/78684/SPI-stopped-working-in-MBED-2-rev-147/
Maybe related to CMSIS5 or did that not get rolled out on mbed 2?