Weekly Progress Report (Week 1) - SPI Flash Emulator

93 views
Skip to first unread message

Patryk Mężydlo

unread,
May 3, 2016, 3:00:29 PM5/3/16
to beaglebo...@googlegroups.com

Hi beagleboard community,


I’m working on the project “SPI Flash Emulator” and this is my weekly report.


Week 1 (community bounding period):

    -create first kernel patch

    -send my patch to linux-kernel,

    -send email for linux-spi mailing list with question about project,

    -research about device driver  and kernel coding style

    -preparation of GSoC introduction video


Thanks,

Patryk

Patryk Mężydlo

unread,
May 24, 2016, 4:26:13 PM5/24/16
to BeagleBoard GSoC
After Week 1 (23 May -29 May)

What is done:
- add basic information on wiki page (introduction, block diagram, how to build, etc)
- create skeleton LKM
- create DTS for SPI Slave
- create .travis.yml script (works very well)  
- create Makefile (build on x86 and arm)

Issues: 

I wrote simple applications using spidev before the community bounding,

it doesn’t work on the new image. I want to write similar applications

for testing. I must spend more time and look for the problem.



Next weak goals:
- prepare test code for device SPI(using spidev)
- add more information about how works a driver (describe main problems)
- beginning work on platform device
- determinate base address (reading DTS device resources)


Thanks,

Patryk

Patryk Mężydlo

unread,
May 31, 2016, 1:23:04 PM5/31/16
to beaglebo...@googlegroups.com

Week 1(24 May - 31 May)


What is done:

- create basic function: probe, remove, init exit

- prepare test application(using spidev)

- add more information about a driver works (describe main problems)

- determinate McSPI base address (reading DTS device resources)

- create device structure(keeps all the elements of the controller)

- allocate memory for device

- define McSPI register

- function for reading and writing McSPI registers


Issues:

I found a bug in the McSPI master driver. The driver increments the base address (resources), when the driver is repeatedly installed, the address is not correct. I solved this problem in my driver by creating  copies of resources(memcpy). For me, everything is probably ok. I'm not sure whether I write it correctly, it works but I do not know if this code[1] looks like it should. Your opinion would be appreciated.


Next weak goals:

- familiarize myself with the McSPI controller

- set McSPI registers in slave mode

- (optional) beginning work on fifo


Thanks,

Patryk




--
You received this message because you are subscribed to the Google Groups "BeagleBoard GSoC" group.
To unsubscribe from this group and stop receiving emails from it, send an email to beagleboard-gs...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Michael Welling

unread,
Jun 1, 2016, 12:29:25 AM6/1/16
to beaglebo...@googlegroups.com
Patryk,

Here are some comments about your driver:

The probe function should return -ENOMEM instead of just printing and
continuing here:
https://github.com/pmezydlo/SPI_slave_driver_implementation/blob/master/driver/spi-mcspi-slave.c#L123

The following line should go below the error checking on res:
https://github.com/pmezydlo/SPI_slave_driver_implementation/blob/master/driver/spi-mcspi-slave.c#L171

The error checking on res should also be handled properly! If there is
no resource exit the function with
the appropriate error code. Same goes for the error checking on the ioremap.

Read about kernel style function exiting on errors here:
http://lxr.free-electrons.com/source/Documentation/CodingStyle#L389

The following line will output a compiler warning:
https://github.com/pmezydlo/SPI_slave_driver_implementation/blob/master/driver/spi-mcspi-slave.c#L183

It is not necessary to have a separate variable anyways. Instead do
something like this:
slave->base = devm_ioremap_resource(&pdev->dev, &cp_res);

if (IS_ERR(slave->base)) {
...

The are a lot of coding style issues with the driver:
- All functions should have the open curly brace on the next line.
http://lxr.free-electrons.com/source/Documentation/CodingStyle#L116

- There should always be a space between before the curly brace otherwise.

- You should not use C99 comments with //:
http://lxr.free-electrons.com/source/Documentation/CodingStyle#L464

- There are now wrapper macros for printk. Use them instead ->
pr_info, pr_err, pr_debug.
http://lxr.free-electrons.com/source/include/linux/printk.h#L239

A lot of those can be found using checkpatch with the --file option.
Please use it before committing.
http://prabhakarlad.blogspot.com/2014/03/checkpatch-from-linux.html

Also remember to sign off your commits. git commit -s
http://elinux.org/Developer_Certificate_Of_Origin

Regards,
Michael
--
Michael Welling

Embedded System Architect / Contractor
QWERTY Embedded Design - www.qwertyembedded.com

Patryk Mężydlo

unread,
Jun 6, 2016, 9:13:58 AM6/6/16
to beaglebo...@googlegroups.com

Week 2(31 May - 07 June)


What is done:
-set driver in slave mode

-set the majority of important registers, except for those related to DMA, interrupts and fifo
-familiarizing myself with the basics of McSPI controller

-reading and writing McSPI registers

-synchronization (pm_runtime)

-clean up all kernel coding style issues

-resolve all warnings


Issues:
For now, everything is ok, The plan for this week is done.

Next week goals:

-first tests (I will try to do some easy tests and receive at least one word)
- finalize setting mcspi registers(I will check all settings(bit by bit)

-(optional) beginning work on interrupt


This week I will have a few exams. I think I can do 5-6 commits. I am a bit ahead of the plan, so it's ok.

Patryk Mężydlo

unread,
Jun 14, 2016, 12:10:24 PM6/14/16
to beaglebo...@googlegroups.com

Week 3(07 June - 14 June)


What is done:

- familiarizing myself and setting McSPI transmit register

-first test (echo); send back data which the driver receives from master

-  setting interrupt (I had a few problems with this)

- adding function which waits for register bit

- second test (interrupt); generating interrupt after 4 bits and checking how subtracted words count


Issues:

It's hard to tell at which point the driver should transfer data from FIFO to the driver buffer. We cannot do this during the transmission from master to slave. It's also hard to tell when the transaction ends without the use of cs lines. One solution is adding option in the DTS in which you specify whether the transfer will be longer or shorter than 32 bytes. When the transfer is longer than 32 bytes, the driver should use DMA; when the transfer is shorter, the driver should use PIO. For now, everything is ok, The plan for this week is done.

Next week goals:

-further work on the pio transfer

-plan and describe the exact plan on how slave controller should work.

- transfer data from the FIFO to controller buffer (for each word length)

-(optional) transfer data from controller buffer to FIFO (for each word length)


On wednesday I have an exam and I won't be present on meeting.


Patryk Mężydlo

unread,
Jun 21, 2016, 2:40:51 PM6/21/16
to beaglebo...@googlegroups.com

Week 4 (14 June - 21 June)

- transfer data from the FIFO to the driver buffer (for each word length) in both sides

- finalized working on pio transfer

- using tasklets for pio functions

- a lot of tests (various lengths transfers and various length words(bits per word))

- beginning work on char driver as a framework for slave driver


Issues:

For now, everything is ok. The plan for this week is done.

Next week goals:

-further work on the char driver

-adding entries to the DTS

-adding platform device structures, probe, remove function, etc (all platform device stuff)

-(optional) familiarizing with ioctl, poll


Simple introduction “What are the possibilities of pio transfers”

  1. McSPI generating interrupt (tx empty) only before and after transfer between master and slave.

  2. In this moment FIFO is loading. Maximum content is 32 bytes for transmit.

  3. Transfers to 32 bytes is ok. The driver recharges content after every transfer.

  4. In transfers longer than 32 bytes McSPI sends all content with fifo, next bytes is 0x00.

  5. In receiving the driver has no restrictions.McSPI is generating interrupt (rx full) always and even during transfer.

  6. I tested different SPI clock speeds. At 15 Mhz everything is ok but at 20Mhz there are glitches. 1-3 bits at 64 bits.

  7. The size of loading and unloading, as well as after how many bytes McSPI generates interruption, is declared. Transactions of known sizes can be more optimal and allow to lessen the amount of generated interrupts. However, in transactions of unknown sizes must be received and transmitted after one word.


My midterm evaluation is complete.

Patryk Mężydlo

unread,
Jun 28, 2016, 3:55:21 PM6/28/16
to beaglebo...@googlegroups.com

Week 5(21 June - 28 June)

-registration and removal of char driver for each platform device

-adding functions: open, read, write, release, etc

-adding device to device list

-create application for user on slave device


Issues:

This week I lost a lot of time working on bus. I will try to make up for it in next week.

Char driver stuff requires a few changes. After attempting to read or write to a driver (cat, echo) driver has segmentation fault. I need to work on this.


Next week goals:

-finalize work on char driver

-improving prototype slave application and pio transfer

-adding ioctl and poll

-(optional) begin work on DMA


Patryk Mężydlo

unread,
Jul 5, 2016, 6:02:19 PM7/5/16
to beaglebo...@googlegroups.com

Week 6(28 June - 05 July)


What is done:

- finalized work on char driver
- improved prototype slave application and pio transfer
- added  ioctl

- made thorough reconstruction of the driver


This reconstruction brings me closer to the final appearance of user api and the very way of how the driver works.

The reconstruction might take me about 2-3 days more, then the driver will be a ready prototype able to conduct the majority of short transfers. We will devote the remaining half of GSoC on DMA, separating user api from the driver and building bus. I want to spend the last month (this is an optimistic version) on deleting bugs and improving the driver.


Issues:

I had some minor problems; it's too much at once and I'm a bit lost.

I have a big problem with errors in transmission. With transmission of some data is ok, but it’s different in other cases. It either loses first bits or shifts every bit’s place by one.

E.g.:
TX(SLAVE) -> 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA
RX(MASTER) -> 0x35 0x55 0x55 0x55 0x55 0x55 0x55 0x55

TX(SLAVE) -> 0xDE 0xAD 0xBE 0xEF 0x12 0x21 0x82 0x13
RX(MASTER) -> 0x5E  0xAD 0xBE 0xEF 0x12 0x21 0x82 0x13

It’s alright with messages such as:

TX(SLAVE) ->0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08
RX(MASTER) ->  0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08

TX(SLAVE) -> 0x4A 0x75 0x73 0x74 0x79 0x6E 0x61 0x0A 0x00
RX(MASTER) -> 0x4A 0x75 0x73 0x74 0x79 0x6E 0x61 0x0A 0x00


Next week goals:

- further work on thorough reconstruction of the driver.

- first prototype test

- finalize work on ioctl and poll

- finalize work on prototype slave application and pio transfer

- (optional) begin work on DMA

Patryk Mężydlo

unread,
Jul 12, 2016, 5:06:26 PM7/12/16
to beaglebo...@googlegroups.com

Week 7(05 July - 12 July)


What is done:

- finalized work on thorough reconstruction of the driver.

- first prototype test

- finalized work on ioctl and poll

- finalized work on prototype slave application and pio transfer

- familiarizing myself with DMA

- searched for bugs and repaired them

- upgraded travis script

- made a nice diagram  


link is here: https://raw.githubusercontent.com/pmezydlo/SPI_slave_driver_implementation/master/documentation/how_pio_works.png




Issues:

I'm waiting for my oscilloscope; it was supposed to arrive today, but the delivery was delayed till tomorrow.

I’m going to have first test results with oscilloscope before meeting.

Next week goals:

- testing with an oscilloscope and finding errors

- beginning work on DMA


When creating dma, I'm going to base on code omap2_mcspi.c


Patryk Mężydlo

unread,
Jul 19, 2016, 5:46:28 PM7/19/16
to beaglebo...@googlegroups.com

Week 8(12 July - 17 July)


What is done:

- testing with an oscilloscope and finding errors (there was no connection ground(GND))

- allocation of resources under DMA

- created new branch for work on DMA

- changes in the driver’s structure enabling the transfer of DMA or PIO

- added screenshots from oscilloscope to documentation

- fixed 3 bugs in PIO transfer

- tested modes of sending for data with various number of bytes (8, 16, 32)

-dma request channel(works well)


Issues:

My work progresses a bit slower than I’ve expected.

I’m wondering if it’s already time to remind the linux-spi mailing list about my case, as my first attempt to contact them had no effect.

Now we have a fully functional driver, but it lacks DMa and shiny new SPI Slave Framework - similar to the one created by Wolfram Sang. Do you think it’s a good idea?



Next week goals:

- further work on DMA

- first DMA transfer

- searching for errors in PIO


Is there something I should do at this point? What do you think, what should I change, fix, add? What would bring me closer to upstream?

Michael Welling

unread,
Jul 19, 2016, 6:20:22 PM7/19/16
to beaglebo...@googlegroups.com
On Tue, Jul 19, 2016 at 4:46 PM, Patryk Mężydlo <mezy...@gmail.com> wrote:
> Week 8(12 July - 17 July)
>
>
> What is done:
>
> - testing with an oscilloscope and finding errors (there was no connection
> ground(GND))
>
> - allocation of resources under DMA
>
> - created new branch for work on DMA
>
> - changes in the driver’s structure enabling the transfer of DMA or PIO
>
> - added screenshots from oscilloscope to documentation
>
> - fixed 3 bugs in PIO transfer
>
> - tested modes of sending for data with various number of bytes (8, 16, 32)
>
> -dma request channel(works well)
>
>
> Issues:
>
> My work progresses a bit slower than I’ve expected.
>
> I’m wondering if it’s already time to remind the linux-spi mailing list
> about my case, as my first attempt to contact them had no effect.
>
> Now we have a fully functional driver, but it lacks DMa and shiny new SPI
> Slave Framework - similar to the one created by Wolfram Sang. Do you think
> it’s a good idea?

I would not quite call this a framework yet. It is more of a
standalone driver. It is not clearly
dividing the driver into core and controller specific parts.

It never hurts to try for more community involvement but always expect
more work if you do.

Patryk Mężydlo

unread,
Jul 26, 2016, 5:28:58 PM7/26/16
to beaglebo...@googlegroups.com

Week 9(19 July - 26 July)


What is done:

-updated documentation (I got a few emails from people interested in my project, so I made an update including exact information regarding installation, usage, etc)

Here is a link: https://github.com/pmezydlo/SPI_slave_driver_implementation/wiki#building-on-x86-platform

- work on DMA

-configuration of the DMA transfer (filling config structure)

-added callback function

-enable and disable DMA request

-DMA channel request (old way)

-clearing DMA source


Issues:

I have a big problem with DMA and I’m stuck. I intended DMA to carry out transfer (one word) after interruption, copying from device to memory and from memory to device.

I can’t find anything interesting that could help me. I was trying to rewrite part of the code concerning DMA to SPI slave, transfer one word and then add another way of triggering, but it’s not working. I need to work on it a bit longer.


Next week goals:

- further work on DMA

- first DMA transfer


hong...@gmail.com

unread,
Jul 27, 2016, 1:17:47 AM7/27/16
to BeagleBoard GSoC
Thanks Patryk, it's a great work!
I once tried to modify the existing omap2 mcspi master driver to enable the slave mode with DMA, it somehow works but still has some weird issue and transmission rate is not that well. So I think a dedicated slave driver is definitely necessary. I'm following you this project on GitHub and will keeping following your progressese 

Patryk Mężydlo

unread,
Aug 2, 2016, 7:06:50 AM8/2/16
to beaglebo...@googlegroups.com

Week 10(26 July - 02 August)

What is done:

- familiarizing myself with Buses

- debugging dma

- testing the driver in the 3.8.x version of the image (at the request of a colleague who is interested the driver)


Issues:

I spent a week on finding errors in the DMA. I made a test proposed by Alex Hiam. The test consists

of displaying the contents of the register after the transfer. I used functions:

wait_for_completion(&dma_channel->dma_tx_completion);

The driver blocked on this function and never came out of it..


I tried to set the interrupt END OF COUNTER because the DMA uses exactly this interrupt and

I set the END OF WORD COUNTER (It is required). No visible results, though.


I checked all the issues:

struct dma_chan *dma_tx

z dma_addr_t tx_dma

The name is similar and sometimes I confuse it.


I feel stupid to say this, but I feel like I wasted a week I'm annoyed.


Next week goals (the third week in a row):

- further work on DMA

- first DMA transfer

- beginning work on bus



--

Patryk Mężydlo

unread,
Aug 9, 2016, 4:37:29 PM8/9/16
to beaglebo...@googlegroups.com

Week 11(02 August - 09 August)

What is done:

- created a new driver (spi-slave-core.ko) which manages bus

- created a new device (spi-slave-dev.ko) which manages fs operations

- added register and unregister spislave bus, devices and driver

- created functions for the registration of other slaves (more generic framework)

- matched device and driver after modalias

- registered device which child node is located in DTS file

- cleaned up code

- prepared code for review by the linux maintainers (thanks Michael for this)


Issues:

Now everything seems fine. As for bugs, we correct them with Michael as we go along.

Tomorrow I will make corrections he sent me. This week I am satisfied with my progress.

Thanks Michael - Greg Kroah-Hartman will check my code himself which makes me

very glad. As for the rest of gsoc, I’m planning to give up work on dma and focus on

polishing framework.More info coming next week in my final report.


Next day goals before meeting:

-make corrections sent by Michael

-tests

-if necessary, entering my own corrections

-cleaning up code

-merge generic_framework branch


Next week goals:

- further work on generic framework

- more test

- documentatnion and final report


To unsubscribe from this group and stop receiving emails from it, send an email to beagleboard-gsoc+unsubscribe@googlegroups.com.

Patryk Mężydlo

unread,
Aug 16, 2016, 8:17:27 PM8/16/16
to beaglebo...@googlegroups.com

Final report: SPI slave implementation


The project’s initial version involved the creation of SPI driver in slave mode. The first implementation

of realized framework was supposed to be SPI Flash Emulator. To ensure optimal performance, the

driver was meant to use SPI controller, DMA and interrupt.

 

After contacting linux-spi and finding Marek Vašut, a developer who already had experience with

SPI slave drivers, we had a constructive exchange of ideas. Marek introduced me to many

critical elements. Michael noticed a limitation that made it impossible to create a fully generic

slave driver. The project needed a thorough reconstruction.


The project consists of three layers. The first and the lowest layer supports the SPI hardware controller.

McSPI controller is located in BeagleBone Black, and the driver was developed exactly to this controller.

The whole implementation is located in spi-mcspi-slave.c[1] file. The controller easily handles small

transfers to 32 bytes with clock to 24 MHz. It supports a variety of word lengths, from 4 bits to 32 bits per word.

DMA was supposed to provide support for longer transfer lengths; however, I was not able to develop it

before the end of GSoC. DMA support will be added after GSoC.


The second layer is responsible for communication between the lowest layer and userspace. This layer

consists of a core (bus) which connects the device and driver. It is a bus and a set of functions registering

and managing other SPI slave devices. It was implemented in files spi-slave-core.c [2] and spi-slave-core.h

[3]. Framework uses device tree overlay. On the basis of DTB, it matches the device to the driver. I have

created two files dts for McSPI 0 slave.dts [4] and SPI1_slave.dts [5].


A simple user interface, allowing to carry out the transfer has been added in spi-slave-dev.c [6]

and spi-slave-dev.h[7] files. For each installed device, the driver provides file in userspace

(/dev/spislave0 and /dev/spislave1). The driver has the usual fs operations and a number of IOCTL

functions (described in more detail in spi-slave-dev.h [7]), as well as POLL methods used to inform

about the end of transaction.


I have added a simple spislave_app.c [8] application, which is using SPI slave framework.

It is a good example on how to use SPI slave.


Documentation located on wiki page [9] and in the documentation directory [10] in repository

describes the driver, clarifies and explains its limitations and shows the main problems

because of which a fully generic spi driver in slave mode is difficult to obtain. It also

provides information concerning work plan for each GSoC week. Moreover, it shows

stage by stage how to compile, install and use the framework, as well as the way the

master is connected to the slave on example of BeagleBoard Black.


[1]https://github.com/pmezydlo/SPI_slave_driver_implementation/blob/master/driver/spi-mcspi-slave.c

[2]https://github.com/pmezydlo/SPI_slave_driver_implementation/blob/master/driver/spi-slave-core.c

[3]https://github.com/pmezydlo/SPI_slave_driver_implementation/blob/master/driver/spi-slave-core.h

[4]https://github.com/pmezydlo/SPI_slave_driver_implementation/blob/master/DTS/SPI0_slave.dts

[5]https://github.com/pmezydlo/SPI_slave_driver_implementation/blob/master/DTS/SPI1_slave.dts

[6]https://github.com/pmezydlo/SPI_slave_driver_implementation/blob/master/driver/spi-slave-dev.c

[7]https://github.com/pmezydlo/SPI_slave_driver_implementation/blob/master/driver/spi-slave-dev.h

[8]https://github.com/pmezydlo/SPI_slave_driver_implementation/blob/master/slave_app/slave_app.c

[9]https://github.com/pmezydlo/SPI_slave_driver_implementation/wiki

[10]https://github.com/pmezydlo/SPI_slave_driver_implementation/tree/master/documentation


What did not work and why:

DMA is the only part of the project which -  despite being planned to be involved in the project’s

final version  - was not successful. DMA was supposed to provide support for transactions larger

than 32 bytes. Support for DMA has been written, however, I could not merge it. This is the

element that I am going to add after GSoC, for it proved to be too difficult for such limited time.


What I have learned during GSoC:

- upstream process and interaction with maintainers,

-how to create a variety of types of modules connected to the linux kernel,

- handling devices mapped in memory,

-creating a correct and visually aesthetic code compatible with the linux kernel coding style,

-planning and describing a project

-how bus, device and driver work

-character device drivers and fs operations in practice,

-methods for debugging and fault finding,

-better git use

-and many more ;)


What's next:

Currently I am after third review of my code. Greg pointed to many mistakes and provided me with

valuable advices, so my code looks a lot better now. I learned a lot thanks to his help.

As for upstream code for kernel, I am quite skeptical. It is difficult and my code does not necessarily

correspond to the image of SPI slave preferred by linux-spi. Nevertheless, I still wish to continue work

on this code. We will see what happens.


A few words in conclusion.

The final report does not end my adventure with linux kernel and BeagleBoard community. These three

months have shown me that writing elements of Linux is not quite that difficult. I have also met a great

BeagleBoard community and I have got to know many wonderful people. I would like to thank Michael for

rescuing me when I got stuck and for such great amount of knowledge he shared with me. I’m especially

thankful for Andrew for his support during the draft preparation. Many thanks to everyone who helped and

supported me during GSoC. You are amazing.


Thanks

Patryk Mężydło

Reply all
Reply to author
Forward
0 new messages