Kinetis微控制器知识库

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 

Kinetis Microcontrollers Knowledge Base

讨论

排序依据:
    作者 Shaozhong Liang     YAFFS(Yet Another Flash File System)文件系统是专门针对NAND闪存设计的嵌入式文件系统。在YAFFS中,文件是以固定大小的数据块进行存储的,块的大小可以是512字节、1024字节或者2048字节。这种实现依赖于它能够将一个数据块头和每个数据块关联起来。每个文件(包括目录)都有一个数据块头与之相对应,数据块头中保存了ECC(Error Correction Code)和文件系统的组织信息,用于错误检测和坏块处理。     YAFFS在文件进行改写时总是先写入新的数据块,然后删除旧的数据块,这样即使意外掉电,丢失的也只是这一次修改数据的最小写入单位,从而实现了掉电保护,保证了数据完整性。 YAFFS是为NAND FLASH设计的,它作了以下的假设或定义。     NAND Flash是基于块(block)的,每一个Block大小相同,由整数个chunk组成。每一个Block可单独擦除。一页(page,或chunk)为Flash的分配单元。所有的访问(读或者写)都是基于页(或chunk)的。     当对NAND Flash编程时,只有二进制中的0被编程,而1则“不关心”。比如,一个字节包含的二进制数为1010,那么当编程1001,会导致这两个数的位与操作。结果为1000.这和NOR FLASH不同。     YAFFS 分别用块号和 chunk id 标示块和 chunk 。它将空块(填满0xFF)当作空闲块或者已擦除块。这样,格式化一个YAFFS分区等价于擦除所有未损坏的块。 因此YAFFS最少需要一些函数能够擦除块,读一个页,写一个页。 1. 直接接口(Direct Interface)的相关文件     仅需要提取少量文件。使用yaffs的直接接口,你不需要所有的文件。你实际需要的文件列在下面,其余文件不需要编译。 direct/yaffsfs.c yaffs_guts.c direct/yaffscfg.c yaffs_nand.c yaffs_tagsvalidity.c yaffs_checkptrw.c yaffs_qsort.c yaffs_tagscompat.c yaffs_ecc.c yaffs_packedtags2.c 2. YAFFS  存储设备     YAFFS对文件系统上的所有内容(比如正常文件,目录,链接,设备文件等等)都统一当作文件来处理,每个文件都有一个页面专门存放文件头,文件头保存了文件的模式、所有者id、组id、长度、文件名、Parent Object ID等信息。因为需要在一页内放下这些内容,所以对文件名的长度,符号链接对象的路径名等长度都有限制。前面说到对于NAND FLASH上的每一页数据,都有额外的空间用来存储附加信息,通常NAND驱动只使用了这些空间的一部分,YAFFS正是利用了这部分空间中剩余的部分来存储文件系统相关的内容。以512+16B为一个PAGE的NAND FLASH芯片为例,Yaffs文件系统数据的存储布局如下所示: 0 to 511 数据区域 512 to 515 YAFFS TAG 516 Data status byte 517 Block status byte 坏块标志位 518 to 519 YAFFS TAG 520 to 522 后256字节数据的ECC校验结果 523 to 524 YAFFS TAG 525 to 527 前256字节数据的ECC校验结果     可以看到在这里YAFFS一共使用了8个BYTE用来存放文件系统相关的信息(yaffs_Tags)。这8个Byte的具体使用情况按顺序如下: Bits Content 20 ChunkID,该page在一个文件内的索引号,所以文件大小被限制在2^20 PAGE 即512Mb 2 2 bits serial number 10 ByteCount 该page内的有效字节数 18 ObjectID 对象ID号,用来唯一标示一个文件 12 Ecc, Yaffs_Tags本身的ECC校验和 2 Unused     其中Serial Number在文件系统创建时都为0,以后每次写具有同一ObjectID和ChunkID的page的时候都加一,因为YAFFS在更新一个PAGE的时候总是在一个新的物理Page上写入数据,再将原先的物理Page删除,所以该serial number可以在断电等特殊情况下,当新的page已经写入但老的page还没有被删除的时候用来识别正确的Page,保证数据的正确性。 ObjectID号为18bit,所以文件的总数限制在256K即26万个左右。     由于文件系统的基本组织信息保存在页面的备份空间中,因此,在文件系统加载时只需要扫描各个页面的备份空间,即可建立起整个文件系统的结构,而不需要像JFFS1/2 那样扫描整个介质,从而大大加快了文件系统的加载速度。     一个YAFFS设备是一个逻辑设备,它代表了一个物理设备的部分或整体。你可以认为它是一个Nand上的一个“分区”。比如,该分区可能覆盖整个NAND,也许只是一半,而另外一半就是另一个Yaffs_Device.它也可以用于你使用一个非flash设备(比如RAM)来测试的情况下。 一个Yaffs_Device记录了起始和结束块。通过改变它的起始和结束块,你就可以在同一个物理设备上使用不止一个的Yaffs_Device。 这里将需要你自己建立的Yaffs_Device结构的数据域列出,其他数据域由Yaffs自动创建。 int nDataBytesPerChunk     如其名,这是每一个chunk的字节数,还记得吧,在yaffs术语中,一个页就是一个chunk,因而它也是一页的字节数。它是数据字节数,即不包含OOB的数据。比如一页时2048字节+64字节的OOB,那么数值nDataBytesPerChunk为2048。 int nChunksPerBlock     物理Nand设备中每页包含的chunk(就是Nand上的页)的数目,最少是2。 int spareBytesPerChunk     空闲域(spare area)大小,比如:每个chunk(页)的OOB字节数。 int startBlock     该逻辑Yaffs_Device设备第一个块的块号(而字节地址),注意,yaffs需要第一个块是空闲的,因此你不可以设置该变量为0,如果设置为0,Yaffs会给它加1,并且会在结束块号上也加1,在你设置设备从块0开始,到最后一个块结束,这意味着yaffs试图写一个不存在的块,从而出现错误。 int endBlock     该逻辑Yaffs_Device设备的最后一个块号。如果startBlock为0,那么yaffs会使用endBlock+1,至少使startBlock+nReservedBlocks+2 int nReservedBlocks     这是YAFFS必须保留,用于垃圾回收和块错误恢复的可擦除块的数目。至少是2,但是5更好。如果你使用一个不会损坏的介质,比如RAM或者RAM盘,或者主机文件系统模拟,那么可以是2。 int nShortOpCaches     配置当前设备YAFFS Cache项的数目。0值表示不使用cache。对于大多数系统,推荐使用10到20之间的一个数值。不能大于YAFFS_MAX_SHORT_OP_CACHES定义的数值。 int useNANDECC     这是一个标志,用于指示是由yaffs执行ECC计算,还是由NAND驱动程序来执行ECC计算。(译者注:此数值取0,则使用yaffs来执行ECC计算,软件ECC计算。如果想要使用硬件ECC校验时,应该设置为1,并且在NAND驱动程序中加入硬件ECC校验的代码。) void *genericDevice     这是一个指针,它应该指向任何数据,底层NAND驱动程序需要知道以从物理设备读、写。 int isYaffs2     我们使用的是否YAFFS2版本? int inbandTags     是否为OOB区,如果不是,那么它为真,仅用于yaffs2 u32 totalBytesPerChunk     这个名字可能有点误导人,它应该等于nDataBytesPerChunk ,而非其名字暗示的nDataBytesPerChunk + spareBytesPerChunk。如果inbandTags为真,那么yaffs设置nDataBytesPerChunk,因此有足够的空闲空间存储数据,yaffs会在空闲域中正常存储。 write/readChunkWithTagsFromNAND, markNANDBlockBad queryNANDBlock 这些都是函数指针,你需要提供这些函数来给YAFFS,读写nand flash。 3.NAND Flash 访问函数 int (*writeChunkWithTagsToNAND) (struct yaffs_DeviceStruct * dev, int chunkInNAND, const u8 * data, const yaffs_ExtendedTags * tags);   dev: 要写入的yaffs_Device逻辑设备. chunkInNAND: 将chunk写入的页 Data: 指向需要写入的数据的指针 tags: 未压缩(打包)的OOB数据 Return: YAFFS_OK / YAFFS_FAIL 该函数将页(chunk)写入nand中,向nand中写入数据。数据和标签(tags)永远不应为 NULL. chunkInNand 是将要写入的页的页号,而不是需要转换的地址。 int (*readChunkWithTagsFromNAND) (struct yaffs_DeviceStruct * dev, int chunkInNAND, u8 * data, yaffs_ExtendedTags * tags);  dev: 要写入的yaffs_Device逻辑设备. chunkInNAND: 将chunk读入的页 Data: 指向需要读入的数据的缓冲区指针 tags: 指向未压缩(打包)的OOB数据的缓冲区指针 Return: YAFFS_OK / YAFFS_FAIL 该函数执行上一个函数的相反的功能,首先,读取数据和OOB字节,接着将这些输入放在一个由参数data指向的缓冲区中 int (*markNANDBlockBad) (struct yaffs_DeviceStruct * dev, int blockNo);   dev: 要写入的yaffs_Device逻辑设备. blockNo: 要标记的块. Return: YAFFS_OK / YAFFS_FAIL int (*queryNANDBlock) (struct yaffs_DeviceStruct * dev, int blockNo, yaffs_BlockState * state, u32 *sequenceNumber);   dev: 要写入的Yaffs_Device逻辑设备. blockNo: 要标记的块. state: Upon returning this should be set to the relevant state of this particular block. Sequance number: 该块的顺序号(The Sequence number),为0表示此块未使用 Return: YAFFS_OK / YAFFS_FAIL     它应检查一个块是否是有效的。如果在OOB中设置了坏块标记,那么*state应该被赋值为YAFFS_BLOCK_STATE_DEAD,*sequenceNumber赋值为0,然后返回YAFFS_FAIL。     如果该块没坏,那么应解压缩标签。标签解压缩后,若发现chunk已使用(查看tags.chunkUsed),则*sequenceNumber应赋值为tags.sequenceNumber,*state赋值为YAFFS_BLOCK_STATE_NEEDS_SCANNING,否则该块未使用,则*sequenceNumber赋值为0,*state赋值为YAFFS_BLOCK_STATE_EMPTY 4. YAFFS的缓存机制     由于NandFlash是有一定的读写次数的,所以在对一个文件进行操作的时候往往是先通过缓冲进行,对最后一次性写入NandFlash,这有效的减少了用户对NandFlash的频繁操作,延长了NandFlash的寿命。下面大致说一下YAFFS的缓存机制: 4.1.首先在yaffs_mount的时候会对yaffs_dev这个结构体进行注册,和缓冲部分相关的有: dev->nShortOpCaches//这个变量决定了有多少个缓冲,因为缓冲会大量的占用堆栈的空间,所以在yaffs不建议缓冲的数量很大,即使你填一个很大的数,系统也不会超过YAFFS_MAX_SHORT_OP_CACHES的总数。 yaffs_ChunkCache *srCache;//缓冲区的首地址,dev->srCache = YMALLOC( dev->nShortOpCaches * sizeof(yaffs_ChunkCache));下面介绍一下缓冲区这个结构体的组成: typedef struct { struct yaffs_ObjectStruct *object;//一个缓冲区对应一个文件 int chunkId; int lastUse; //通过lastUse来 int dirty; //标志了这一个缓冲区是否被使用 int nBytes; __u8 data[YAFFS_BYTES_PER_CHUNK];//数据区 } yaffs_ChunkCache; 4.2.什么时候用到缓冲区?        用到缓冲区最多的地方显而易见是对已经创建的文件进行写操作。而且是需要写的大小和512不一致的时候,这是因为如果是刚好512的话,系统会直接写入NandFlash中。对于小于512的系统首先会调用yaffs_FindChunkCache(in,chunk)这个函数来判断in这个object是否在缓冲区中存在。如果存在会调用已有缓冲区进行操作。当然如果是第一次对一个object进行操作,肯定在缓冲区中是不存在对应它的空间的,因此系统会调用yaffs_GrabChunkCache函数为此次操作分配一个缓冲区。 5. 应用层接口     YAFFS为连接的应用程序提供了一组函数。大部分跟标准C库函数,如open/close一致,只是增加了yaffs_前缀,如 yaffs_open. 这些函数定义在direct/yaffsfs.h中。     初始化yaffs来完成读写,你必须在每个你要使用的yaffs设备上调用yaffs_mount。比如yaffs_mount(”/boot”)。这可以在系统启动的时候执行,如果存在一个操作系统,那么程序需要考虑这点。在你完成使用的时候,你也需要调用yaffs_umount函数,这样yaffs就会将它需要状态写入磁盘。 如果读写文件的应用层接口已经存在,你可以根据相关的操作系统调用来封装相关的函数调用。 1 yaffs_mount( ) 功能说明:加载指定器件。 输入参数:path    要加载的器件。 输出参数:无。 返回值: 表明加载的状态。 调用的函数:yaffsfs_FindDevice( )、yaffs_GutsInitialise( )。 2 yaffs_open( ) 功能说明:按照指定方式打开文件。 输入参数:path    文件的绝对路径;           Oflag   打开的方式;           Mode    文件许可模式。 输出参数:无。 返回值:句柄。 调用的函数:yaffsfs_GetHandle( )、yaffsfs_FindDirectory( )、yaffs_MknodFile( )、yaffsfs_PutHandle( )、yaffs_ResizeFile( )、yaffsfs_FindObject( )。 3 yaffs_write( ) 功能说明:根据打开文件的句柄,从指定数组处读指定字节写入文件中。 输入参数:fd      要写入的文件的句柄;           Buf     要写入的数据的首地址;           Nbyte   要写入的字节数。 输出参数:无。 返回值: 写入了的字节数。 调用的函数:yaffs_WriteDataToFile( )、yaffsfs_GetHandlePointer( )、yaffsfs_GetHandleObject( ) 4 yaffs_read( ) 功能说明:根据打开文件的句柄,从文件中读出指定字节数据存入指定地址。 输入参数:fd       要读出的文件的句柄;           Buf      读出文件后要存入的数据的首地址;           Nbyte    要读出的字节数。 输出参数:无。 返回值: 读出了的字节数。 调用的函数:yaffs_ReadDataFromFile( )、yaffsfs_GetHandlePointer( ) 5 yaffs_close( ) 功能说明:关闭已经打开的文件句柄,yaffs 有缓冲机制,当调用yaffs_close()关闭文件之后能够保证将内容写入nandflash。 输入参数:fd    需要关闭的文件的句柄; 输出参数:无。 返回值:无。 6. YAFFS在MQX的应用案例     YAFFS提供了直接调用模式,可以方便移植到 none-OS或者light-weighted OS中。附件是将YAFFS移植到Freescale MQX实时操作系统的源代码和工程,可以在II型集中器的Demo Board上运行。     初步的测试表明YAFFS工作正常,能够完成创建目录,创建/删除文件,读/写文件操作等。 YAFFS非常适合none-OS或者是light-weighted OS,使用YAFFS需要关注的是RAM的消耗,适合小量文件(<20)。 如果不想使用MQX默认的MFS(FAT32文件系统),YAFFS可以作为一个文件系统的备选方案。
查看全文
The SAI of Kinetis supports 4 modes:normal mode, network mode, I2S mode, AC97 mode, the documentation give the brief introduction about the 4 modes, give the waveform of the 4 modes.
查看全文
Recently, some customers have provided us with feedback stating they have been experiencing difficulties when connecting  Kinetis L series  microcontrollers using Multilink Universal probes, after checking the connection and software settings no obvious errors could be found. This recurrent problem has been confirmed by several customers, the  problem is caused by a long connection line. My suggestion is to keep connection line length to 10cm or less; otherwise, the IDE may not be able to establish the connection through the Multilink Universal.
查看全文
Introduction What is a gated timer and why would I need one? A gated timer is a timer whose clock is enabled (or "gated") by some external signal.  This allows for a low code overhead method of synchronizing a timer with an event and/or measuring an event. This functionality is not commonly included on Freescale microcontroller devices (this functionality is only included on devices that are equipped with the upgraded TPM v2 peripheral; currently K66, K65, KL13, KL23, KL33, KL43, KL03) but can be useful in some situations.  Some applications which may find a gated timer useful include asynchronous digital sampling, pulse width duty cycle measurement, and battery charging. How do I implement a gated timer with my Kinetis FTM or TPM peripheral? To implement a true gated timer with a Kinetis device (that does not have the TPM v2 peripheral), additional hardware will be required to implement the enable/disable functionality of a gated timer.  This note will focus on two different ways (low-true and high-true) to implement a gated timer.  The method used will depend on the requirements of your application. Implementing a gated timer for Kinetis devices without the TPM v2 peripheral requires the use of a comparator and a resistive network to implement a gated functionality (NOTE:  Level shifters could be used to replace the resistive network described; however, a resistive network is likely more cost effective, and thus, is presented in this discussion).  Figure 1 below is the block diagram of how to implement a gated timer functionality.  The theory behind this configuration will be explained in later sections. Theory of Operation Comparator and resistive network implementation The comparator is the key piece to implementing this functionality. For those with little experience with comparators (or need a refresher), a comparator is represented by the following figure.  Notice that there are three terminals that will be of relevance in this application: a non-inverting input (labeled with a '+' sign), an inverting input (labeled with a '-' sign), and an output. A comparator does just what the name suggests: it compares two signals and adjusts the output based on the result of the comparison.  This is represented mathematically in the figure below. Considering the above figure, output of the comparator will be a  logic high when the non-inverting input is at a higher electric potential than the inverting input.  The output will be a logic low if the non-inverting input is at a lower electric potential than the inverting input.  The output will be unpredictable if the inputs are exactly the same (oscillations may even occur since comparators are designed to drive the output to a solid high or solid low).  This mechanism allows the clock enable functionality that is required to implement a gated timer function provided that either the non-inverting or inverting input is a clock waveform and the opposite input is a stable logic high or low (depending on the desired configuration) and neither input is ever exactly equal.  Comparator Configurations There are two basic signal configurations that an application can use to enable the clock output out of the comparator: low-true signals and high-true signals.  These two signals and some details on their implementation are explained in the following two sections.  Low-true enable A low-true enable is an enable signal that will have zero electric potential (relative to the microcontroller) or a "grounded" signal in the "active" state.  This configuration is a common implementation when using a push button or momentary switch to provide the enable signal.  When using this type of signal, you will want to connect the enable signal to the non-inverting input of the comparator, and connect the clock signal to the inverting input. The high level of the enable signal should be guaranteed to always be the highest voltage of the input clock plus the maximum input offset of the comparator. To find the maximum input offset of the comparator, consult the device specific datasheet.  See the figure below to see a graphical representation of areas where the signal will be on and off. The external hardware used should ensure that the low level of the enable signal never dips below the lowest voltage of the input clock plus the maximum input offset of the comparator. The following figure displays one possible hardware configuration that is relatively inexpensive and can satisfy these requirements. High-true enable A high-true enable is an enable signal that will have an electric potential equal to VDD of the microcontroller in the "active" state.  This configuration is commonly implemented when the enable signal is provided by an active source or another microcontroller.  When interfacing with this type of signal, you will want to connect the enable signal to the inverting input of the comparator, and connect the clock signal to the non-inverting input.  When the comparator is in the inactive state, it should be at or below the lowest voltage of the clock signal minus the maximum input offset of the comparator.  Refer to the following figure for a diagram of the "on" and "off" regions of the high true configurations. The external hardware will need to guarantee that the when the enable signal is in the active state, it does not rise above the highest voltage of the clock signal minus the maximum input offset of the comparator. The following figure displays one possible hardware configuration that is relatively inexpensive and can satisfy these requirements. Clocking Options Clocking waveform requirements will vary from application to application.  Specifying all of the possibilities is nearly impossible.  The point of this section is to inform what options are available from the Kinetis family and provide some insight as to when it might be relevant to investigate each option. The Kinetis family provides a clock output pin for most devices to allow an internal clock to be routed to a pin.  The uses for this option can vary.  In this particular scenario, it will be used to provide the source clock for the comparator clock input. Here are the most common clock output pin options across the Kinetis K series devices.  (NOTE:  If the application requires a clock frequency that the CLKOUT signal cannot provide, a separate FTM or TPM instance or another timer module can be used to generate the required clock.) In the Kinetis L series devices, the following options will be available. The clock option selected should be the slowest allowable clock for the application being designed.  This will minimize the power consumption of the application.  For applications that require high resolution, the Bus, Flash, or Flexbus clock should be selected (note that the Flexbus clock can provide an independently adjustable clock, if it is not being used in the application, as it is always running).  However, if the target application needs to be more power efficient, the LPO or MCGIRCLK should be used.  The LPO for the Kinetis devices is a fixed 1 kHz frequency and will, therefore, only be useful in applications that require millisecond resolutions.
查看全文
First let us see the clock tree: Core clock up to 112M, Bus clock up to 56M, Flash clock up to 28M. Clock can been from: System OSC、Slow IRC 、Fast IRC and System PLL 1. OSC SCG_SOSCCFG 2. PLL configuration formula: SPLL_CLK = (VCO_CLK)/2 VCO_CLK = SOSC_CLK/(PREDIV + 1) *(MULT + 16)  3. SCG_SPLLCSR void SystemClockInit(void) { SCG->SOSCCFG = 0x3C; SCG->SOSCCSR |= 1<<0; /* SOSCEN=1 enable SOSC clock */ /*wait clock active*/ while((SCG->SOSCCSR & SCG_SOSCCSR_SOSCVLD_MASK) == 0); SCG->SPLLCSR &= ~(0x1<<0) ; /* SPLLEN=0: disable PLL*/ SCG->SPLLCFG &= ~(0x7<<8); /* PREDIV=0: 1 */ SCG->SPLLCFG |= 0xCU<<16; /* MULT=12: 28   PLL VCO = 8/1*(12+16) = 224M */ SCG->SPLLCSR |= 0x1<<0; /* SPLLEN=1: enable PLL */ /* wait PLL active*/ while((SCG->SPLLCSR & SCG_SPLLCSR_SPLLVLD_MASK) == 0); SCG->RCCR |= SCG_RCCR_DIVCORE(0); /* DIVCORE=0: 1, CORE/SYS_CLK  112MHz */ SCG->RCCR |= SCG_RCCR_DIVBUS(1); /* DIVBUS=1: 2, BUS_CLK  56MHz */ SCG->RCCR |= SCG_RCCR_DIVSLOW(3); /* DIVSLOW=2: 4   FLASH_CLK  is 28MHz */ SCG->RCCR &= 0xFEFFFFFF; /* Initially set to SIRC so that LSB could be set as '0' */ SCG->RCCR |= SCG_RCCR_SCS(6); /* SCS=6: system clock System PLL */ }
查看全文
           This is a demo of NFC device to read and write the contactless card. Kinets K60 tower board and NXP PN512 board are used for this test enviroment. These connected pins from K60 tower board to PN512 RF board are listed as below:   SPI1:     SPI1_SIN : PTE1/SDHC0_D0     SPI1_SCK : PTE2/SDHC0_DCLK     SPI1_SOUT : PTE3/SDHC0_CMD     SPI1_PCS0 : PTE4/SDHC0_D3     Reset:     PTB9   External interrupt:     PTA26         Because the SPI1 port is used as the host interface of pn512, it is necessary to enable the SPI1 driver in the user configuration file of MQX.           To open the project file in the /build folder with CW10.5.    And the PSP and BSP libraries had to be built before test image is built, as they are needed in this test project.   The following diagram shows the serial numbers and block data of reading from the test card of Mifare one.
查看全文
This is an example for the Kinetis KE02Z devices, showing how to program the EEPROM with initial values when the flash is programmed.  The example works on the FRDM-KE02Z40M board, and was written with Kinetis Design Studio (KDS) v3.0.0.  The example also uses Processor Expert (PEx) to configure the UART and erase/program the EEPROM.  The EEPROM programming works with the P&E Micro Multilink Universal debugger, as well as the P&E Micro OpenSDA debugger app for the FRDM-KE02Z40M board. To program the EEPROM with initial values, the application declares constants for the EEPROM locations, and initializes these in the source code in eeprom.c. Compiler pragmas/attributes are used to force the linker to place these constants in EEPROM, using the m_eeprom memory section defined in the linker command file \Project_Settings\Linker_Files\ProcessorExpert.ld.  The P&E Micro flash programming algorithms initialize the EEPROM in 4Byte words. Therefore, any initialized EEPROM locations should be in aligned 4Byte words. This example initializes the first 4Bytes in the EEPROM as 0, 64, 128, 192. The example uses a terminal program to display EEPROM information.  It connects to the OpenSDA COM port on the FRDM-KE02Z40M board using UART1 from the KE02Z. The terminal settings are:   Baud Rate: 38,400   Data: 8bit   Parity: None   Stop: 1bit   Flow Control: None The example prints 5 bytes of EEPROM to the terminal after reset: the 4 initialized bytes, plus the following EEPROM byte which was not initialized. Then the example increments the first byte, and decrements the second byte, and writes the new values back to EEPROM.  The other 3 bytes are not changed. Then the application prints the new EEPROM values of all 5 bytes.  Everytime the MCU is reset, it will print the existing EEPROM data and then the changed data.  Below is the example output from the terminal after initially programming the KE02Z, and then doing a single reset: Terminal output:   KE02Z EEPROM example   EEPROM values after reset = 0 64 128 192 255   EEPROM values after updating = 1 63 128 192 255   KE02Z EEPROM example   EEPROM values after reset = 1 63 128 192 255   EEPROM values after updating = 2 62 128 192 255
查看全文
Introduction Even with the prevalence of universal asynchronous receiver/transmitter (UART) peripherals on microcontrollers (MCUs), bit banged UART algorithms are still used.  The reasons for this vary from application to application.  Sometimes it is simply because more UARTs are needed than the selected device provides.  Maybe application or layout restrictions require certain pins to be used for the UART functions but the device does not route UART pins to the required package pins.  Maybe the application requires a non-standard or proprietary UART scheme. Whatever the reason, there are applications where a bit banged UART is used and is typically a pure software implementation (a timer is used and the MCU core controls a GPIO pin directly).  A better alternative may be to use Flextimer (FTM) or Timer/PWM Module (TPM) to take advantage of the features of these peripherals and possibly offload the CPU.  This document will explain and provide a sample application of how to emulate a UART using the FTM or TPM peripheral.  A Kinetis SDK example (for the TWR-K22F120M and FRDM-K22F platforms) and a baremetal legacy code example (for the FRDM-KL26Z) are provided here. UART protocol Before creating an application to emulate a UART, the UART protocol and encoding must be understood. The UART protocol is an asynchronous protocol that typically includes a start bit, payload (of 7-10 data bits), and a stop bit but does allow for many variations on the number of stop bits and what/how to transfer the data.  For this document and application example, the focus will be UART transmission that follows 1 start bit, 8 data bits, 1 stop bit, no parity, and no flow control.  The data will be transmitted least significant bit (LSB) first.  The following image is a block diagram of this transmission. However, this doesn't specify what the transmission looks like electrically. The figure below shows a screenshot of an oscilloscope capture of a UART transmission.  The data transmitted is 0x55 or a "U" in the ASCII representation. Notice that the transmission line is initially a logic high, and then transitions low to signal the start of the transmission.  The transmission line must stay low for one bit width for the receiver to detect it.  Then there are 8 data bits, followed by 1 stop bit.  In the case shown above, the data bits are 0x55 or 0b0101_0101.  Remember that the transmissions are sent LSB first, so the screenshot shows 1-0-1-0-1-0-1-0.  The last transition high marks the beginning of the stop bit and the line remains in that state until the start of the next transmission.  The receiver, being asynchronous, does not require any type of identifying transition to mark the end of the stop bit. FTM/TPM configuration The first question many may ask when beginning a project like this is "How do I configure the FTM/TPM when emulating a UART".  The answer to this depends on the aspect of this problem you are trying to solve.  Transmitting and receiving characters require two different configurations.  Transmission requires a configuration that manipulates the output pin at specific points in time.  Receiving characters requires a configuration that samples the receive pin and measures the time between pin transitions.  The FTM and TPM have the modes listed in the following table: The FTM and TPM have four different modes that manipulate an output:  Output compare (no pulse), Output compare (with pulse), Edge-aligned PWM, and Center-aligned PWM.  Neither PWM mode is ideal for the requirements of the application.  This is because the PWM modes are designed to produce a continuous waveform and are always going to return to the initialized state once during the cycle of the waveform.  However, the UART protocol may have continuous 1's or 0's in the data without pin transitions between them. The output compare mode (high-true or low-true pulse modes) is designed to only manipulate the pin once, and only produces pulses that are one FTM/TPM clock cycle in duration.  So this is obviously not desirable for the application.  The output compare mode (Set/Clear/Toggle on match) is promising.  This mode manipulates the output pin every cycle.  There are three different options:  clear output on match, set output on match, and toggle output on match.  Neither "clear output on match" nor "set output on match" are ideal as either would require configuration changes during the transmission of a character.  The "toggle output on match", however, can be used and is the selected configuration mode for this sample application. To receive characters, there is only one mode that is intuitive:  "the input capture mode".  This mode records the timer count value on an edge transition of the selected input pin.  Similar to the output compare mode chosen for the transmit functionality, the input capture mode has three sub-modes:  capture on rising edge, capture of falling edge, and capture on either edge.  It is clear from the descriptions that capture on either edge should be selected. Transmit encoding The selection of the FTM/TPM mode is moderately intuitive, but using this mode to emulate a UART transmission is not.  There are two issues that make this a little tricky. 1) The output pin is initialized low. However, the UART protocol needs the pin to begin in a logical high state. 2) The pin transitions on every cycle provided the channel value is less than the value of the MOD register. Due to continuous strings of 1's or 0's, it is necessary to have periods where the pin does not transition. Both of these points have workarounds. Output pin initialization For the first issue, the channel interrupt is first enabled and the channel value register is loaded with a value much less than the value in the MOD register.  Then in the channel interrupt service routine, the pin is sampled to ensure that it is in the logic high state and the channel interrupt is disabled (and will not be re-enabled throughout the life of the application).  The code for this interrupt service routine is as follows. Output pin control For the second issue, a method of not transitioning the pin value while allowing the timer to continue counting normally is necessary.  The Output Compare mode uses the channel value register to determine when the pin transition occurs.  If a value greater than MOD is written to the channel value register, the channel value will never match the count register and thus, a pin transition will never occur.  So, when a series of continuous 1's or 0's need to be transmitted, a value greater than the value in the MOD register can be written to the channel value register to keep the output pin in its current state. However, when a value greater than MOD is written to the channel value register, no channel match will occur (which means channel interrupts will not occur).  So the timer overflow interrupt must be used to continue writing values.  This requires the updates to be output pin to be planned ahead of time and makes the transmission algorithm a little tricky.  The following diagram displays when which values should be written to the channel value register at which points in time to generate the appropriate pulses. Writing a function to translate a number into the appropriate series of MOD/2 and MOD+1 values can be a little tricky. To do this, we must first notice that MOD/2 needs to be written when changes on the transmission pin are need and MOD+1 needs to be written when pin transmissions are not desired.   So, what logical function can we use to determine when a change has happened?  XOR is the correct answer.  So what two values need to be XOR'd together?  One value is obviously the value that we want to send.  But what is the second value?  It turns out that the second value is a shifted version of the value that we want to send.  Specifically, the second value is the desired value to send shifted to the left by one.  (You can think of it as sort of a "future" value of the desired value).  The following pictures show how to determine the queue to use for the transmission. Receive decoding The receive functionality has an advantage over the transmit functions in that it is possible to use DMA for the reception of characters.  This is because the receive function takes advantage of the input capture functionality of the FTM / TPM and therefore can use the channel match interrupt.  The example application provided with this document implements a DMA method and a non-DMA method for reception. First, the non-DMA method will be discussed. Before discussing the specifics of gathering the input pulse widths, some details of the receive pin need to be discussed. Detecting the start bit The receive pin needs to be able to determine when the start of the packet transmission begins.  To do this, the receive pin is configured as an FTM / TPM pin. At the same time, the GPIO interrupt functionality is configured on the same pin for a falling edge interrupt.  The GPIO interrupt capabilities are enabled in any digital mode, so the GPIO interrupt will still be able to be routed to the Nested Vector Interrupt Controller (NVIC).  The pin interrupt is used to start the FTM / TPM clock when a new character reception begins. In the GPIO interrupt for this pin, the FTM / TPM counter register is reset and the clock to the FTM / TPM is turned on.  The code for the GPIO interrupt service routine is shown below.  Receiving characters without DMA Now, when receiving characters and not using DMA, the first thing to understand is that the Interrupt Service Routine (ISR) will be used and it will mainly be used to record the captured count values.  The interrupt service routine also tracks the current receive character length and resets the counter register.  This is so that the values in the receive queue reflect the time since the last pin transition.  The interrupt function for the non-DMA application is shown below. Notice that the first two actions in the ISR are resetting the count register, and clearing the channel event interrupt flag.  Then the channel value is stored in the receive pulse width array (this is simply an array that holds the receive pulse widths of the current character being received).  Next, recvQueueLength, the variable which holds the current length of the character being received, is updated to reflect the latest character length.  The next step is to determine if the full character has been received.  This is determined by comparing recvQueueLength to the RECV_QUEUE_THRESH, which is the threshold as determined by multiplying the number of expected bits by the expected bit width plus another bit width (for the start bit).  If the recvQueueLength is greater than the RECV_QUEUE_THRESH, then a semaphore is set, recvdChar, to indicate that a full character has been received.  The FTM / TPM clock is turned off, and the pin interrupt functionality of the receive pin is enabled.  The final step in the interrupt routine is to increment the receive queue index, recvQueueIndex.  This variable points to the current entry in the receive queue array. Using DMA to receive characters When using DMA, the receive FTM / TPM interrupt is much different. The interrupt routine simply needs to clear the channel interrupt flag, stop the FTM / TPM timer, disable the DMA channel, and set the received character semaphore.  The character is then decoded outside of the interrupt routine.  The interrupt function when using DMA is shown below: Decoding the received pulse widths Once the array of pulse widths has been populated, the received character needs to be translated into a single number.  This varies slightly when using DMA and when not using DMA. However, the basic principle is the same.  The number of bits in a single entry is determined by dividing by the expected bit width and this is translated into a temporary array that contains 1's and 0's, and then that is used to shift in the appropriate number of 1's and 0's into the returned char variable.  A temporary array is needed because the values are shifted into the UART LSB first, so the bit must be physically flipped from the first entry to the last.  There is no logical operation that will do this automatically. The algorithm to perform this translation is shown below.  In this algorithm, note that recvPulseWidth is the array that contains the raw count value of the pulse width.  The array tempRxChar holds the decoded character in reverse order and rxChar is a char variable that holds the received character. Conclusion This document provides an overview of the UART protocol and describes a method for creating a software UART using the timing features of the FTM or TPM peripheral.  This method allows for accurate timing and while not relying entirely on the CPU and the latency associated with the interrupt and the GPIO pins.  The receive function is open to further optimization by using DMA, which can provide further unloading of the CPU.
查看全文
浙江地区去年下半年开始到现在,在一些电机控制客户中推广KE02,主要是低功率风机,BLDC,交流异步电机等。 总结了一些KE02在做电机控制方面的不足。 增加一点: (1) KE02 FTM PWM输出与NMI Pin 复用,上电容易烧管子
查看全文
Heart rate monitors measure the heart rate during exercise or vigorous activity and gauge how hard the patient is working. Newer heart rate monitors consist of two main components: a signal acquisition sensor/transmitter and a receiver (wrist watch or smart phone). In some cases, the signal acquisition is integrated into fabric worn by the user or patient. MCUs analyze the ECG signal and determine the heat rate, while an 8-bit MCU can suffice for a simple heart rate monitor. For more complex analysis, such as heart rate variability, activity level and breathing rate, a high-end 32-bit MCU may be used. Furthermore, low power wireless technologies are used to allow the sensor to communicate to the receiver. Freescale offers 8-bit and 32-bit MCUs that are applicable across the entire spectrum of heart rate monitors. In addition, the Freescale portfolio includes inertial sensors or accelerometers for activity monitoring and ZigBee® and proprietary wireless solutions to enable communication between the sensors and the receiver. For more information go to freescale.com/APLHRM
查看全文
    Curve22519 is a Montgomery elliptic-curve. Such as Apple HomeKit, most of network and IoT software use it in Diffie-Hellman algorithm for key exchanging.     On the Security Kinets MCU chip,if we use just the software algorithm (base on mbedTLS), Curve25519 will spend 180ms for calculation of the shared security.     It is faster than other 256bit elliptic-curve with software algorithm, Because of the shared security calculation will take more than 1200ms with a Weierstrass’s BP256R1curve when use software algorithm.     With LTC ECC HW acceleration, it take only 16ms to calculate the shared security on 256bit elliptic-curve. Whatever you do, the speed of hardware acceleration always faster than the software algorithm.     Now that we should also want to use the LTC to accelerate the Curve22519. The LTC, however, only supported Weierstrass form curve, but Curve22519 is a Montgomery curve…     Although, we can't use LTC in Curve22519 directly, we can use it by mapping it to a Weierstrass form to use it.  As below, we gave parameters of these curves, transform formulas, example code and test result to show how and why to do it. 1. Curve parameter:    Cuvre22519 in Montgomery form:    Y^2 = X^3 + A*X^2 + X    Fp = 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed    A= 486662    Gx = 9    Gy = 0x20ae19a1b8a086b4e01edd2c7748d14c923d4d7e6d7c61b229e9c5a27eced3d9    Order of G point  =  0x1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed      Cuvre22519 in Weierstrass form :    Y^2 = X^3 + a*X + b    Fp = 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed    a  =  0x2aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa984914a144L    b  =  0x7b425ed097b425ed097b425ed097b425ed097b425ed097b4260b5e9c7710c864L    Gx = 0x2aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaad245a    Gy = 0x20ae19a1b8a086b4e01edd2c7748d14c923d4d7e6d7c61b229e9c5a27eced3d9    Order of G point  =  0x1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed    2. Calculation formula:   x_w –  x-coordinate value in  Weierstrass form   y_w –  y-coordinate value in  Weierstrass form   x_m - x-coordinate value in  Montgomory form   y_m -  we don’t care y-coordinate value in  Weierstrass mode   a_m – a coefficient of Montgomery equation (   Y^2 = X^3 + a_m * X^2 + X)   a_w – a coefficient of Weierstrass equation (   Y^2 = X^3 + a*X + b )   b_w – a coefficient of Weierstrass equation (   Y^2 = X^3 + a*X + b )     a)  x_w = (x_m + a_m/3)  %  p     b)  y_w ^2 = x_w ^ 3 + a_w*x_w + b_w c)   x_m = (x_w - a_m/3) % p You could reference these document as below: https://en.wikipedia.org/wiki/Curve25519 https://en.wikipedia.org/wiki/Montgomery_curve 3. example code: // public and private at Montgomery end #define M255_d      "0x7178DAC11D42AA5F39B10A62A8584DB0C8864564ADC9DF84EC0B13D9AEC220F8" #define M255_Qx     "0x3BA5048381744348D84E754B9944ABE080B37F7D4158DCE60CD79F66B98AB89E" // public and private at Weierstrass end #define WTS255_d    "0x09CC5CCF43C656C1309EE5A3491D5A8361607CEEB0C9B2B31A575E0FEF2B8835" #define WTS255_Qx   "0x3F4BDE110EE7AF71EF428D1018D188E35BAFB019F34F84E6465C5194B363DC2D" #define WTS255_Qy   "0x7540577CE6F920354E2A9D38CE88847D7447E66FA4D188AC75CB63C17210B718" #define WTS255_Qx_TO_M255_Qx     "0x14A13366643D04C74497E2656E26DE38B105056F48A4DA3B9BB1A6EA08B6B7DC" #define AM_INV3                  "0x2aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaad2451" int ecdh_wts_curve_end( ) {     unsigned int ticks;     int ret = 0;     size_t blen = 0, blen_peer = 0;     ecdh_context ecdh;     ecdh_context ecdh_peer;   // to_wts255     ecdh_context ecdh_peer_m255;     mpi R;     mpi_init(&R);     ecdh_init( &ecdh);     ecdh_init( &ecdh_peer);     ecdh_init( &ecdh_peer_m255);     MPI_CHK(ecp_use_known_dp( &ecdh.grp, ECP_DP_WTS25519 ));     MPI_CHK(ecp_use_known_dp( &ecdh_peer.grp, ECP_DP_WTS25519 ));     MPI_CHK(ecp_use_known_dp( &ecdh_peer_m255.grp, ECP_DP_M255 ));     blen = set_hash_buff(/*TEST_ECP_GRP_ID*/ECP_DP_WTS25519, &secret_buf, ecp_name);     if(blen == 0) {         ret = -1;         goto cleanup;     }     mpi_read_string(&ecdh.d, 16,  WTS255_d);     mpi_read_string(&ecdh.Q.X, 16,  WTS255_Qx);     mpi_read_string(&ecdh.Q.Y, 16,  WTS255_Qy);     mpi_lset(&ecdh.Q.Z, 1);     mpi_read_string(&ecdh_peer_m255.d, 16, M255_d);     mpi_read_string(&ecdh_peer_m255.Q.X, 16, M255_Qx);     mpi_init(&ecdh_peer_m255.Q.Y);     mpi_lset(&ecdh_peer_m255.Q.Z, 1);     // map M255 point to WTS255 point     my_timer_start();     mpi_read_string(&R, 16, AM_INV3);         mpi_add_mpi(&ecdh_peer.Q.X, &ecdh_peer_m255.Q.X, &R);     mpi_mod_mpi(&ecdh_peer.Q.X, &ecdh_peer.Q.X, &ecdh_peer_m255.grp.P);        mpi_lset(&R, 3);     mpi_exp_mod (&ecdh_peer_m255.Q.Y , &ecdh_peer.Q.X, &R, &ecdh_peer_m255.grp.P, NULL);     mpi_mul_mpi(&R, &ecdh_peer.grp.A, &ecdh_peer.Q.X);     mpi_mod_mpi(&R, &R, &ecdh_peer.grp.P);          mpi_add_mpi(&ecdh_peer_m255.Q.Y, &ecdh_peer_m255.Q.Y, &R);     mpi_add_mpi(&ecdh_peer_m255.Q.Y, &ecdh_peer_m255.Q.Y, &ecdh_peer.grp.B);     mpi_mod_mpi(&ecdh_peer_m255.Q.Y, &ecdh_peer_m255.Q.Y, &ecdh_peer.grp.P);     mpi_mod_sqrt(&ecdh_peer.Q.Y, &ecdh_peer_m255.Q.Y, &ecdh_peer_m255.grp.P);     // z = 1     mpi_lset(&ecdh_peer.Q.Z, 1);     MPI_CHK(ecp_copy(&ecdh.Qp,  &ecdh_peer.Q));     MPI_CHK(ecdh_calc_secret_wts2mont( &ecdh, &blen, secret_buf, blen, myrand, NULL));     mpi_read_string(&R, 16, AM_INV3);         mpi_sub_mpi(&ecdh_peer_m255.Q.X, &ecdh.Q.X, &R);     mpi_mod_mpi(&ecdh_peer_m255.Q.X, &ecdh_peer_m255.Q.X, &ecdh_peer_m255.grp.P);     ticks = my_timer_stop();     // print out message     polarssl_printf("Weierstrass curve shared secutiy:\n");     mpi_printf_string( &ecdh.z, 16);     polarssl_printf("%s ecdh peer to peer: %lu ticks, %d ms (%d) \n", ecp_name , ticks, ticks / (CLOCK_SYS_GetPitFreq(0) / 1000),CLOCK_SYS_GetPitFreq(0) );     cleanup:     if( ret !=0 )         polarssl_printf( "%s test Unexpected error, return code = %08X\n", ecp_name, ret );     mpi_free(&R);     ecdh_free( &ecdh);     ecdh_free( &ecdh_peer);     ecdh_free( &ecdh_peer_m255);         return( 0 );    } int ecdh_mont_curve_end( ) {     int verbose = 1;     unsigned int ticks;     int ret = 0;     size_t blen = 0, blen_peer = 0;     ecdh_context ecdh;     ecp_point Q_peer;          // peer public point     ecdh_init( &ecdh);     ecp_point_init( &Q_peer);     MPI_CHK(ecp_use_known_dp( &ecdh.grp, ECP_DP_M255 ));     blen_peer = set_hash_buff(ECP_DP_M255, &secret_buf_peer, ecp_name);     if(blen_peer == 0) {         ret = -1;         goto cleanup;     }     mpi_read_string(&ecdh.d, 16,  M255_d);     mpi_read_string(&ecdh.Q.X, 16,  M255_Qx);     mpi_init(&ecdh.Q.Y);   // don't care Y, only init it     mpi_lset(&ecdh.Q.Z, 1);     mpi_read_string(&Q_peer.X, 16, WTS255_Qx_TO_M255_Qx);     mpi_init(&Q_peer.Y);     mpi_lset(&Q_peer.Z, 1);        MPI_CHK(ecp_copy(&ecdh.Qp,  &Q_peer));     my_timer_start();     MPI_CHK(ecdh_calc_secret( &ecdh, &blen_peer, secret_buf_peer, blen_peer, myrand, NULL));     ticks = my_timer_stop();     polarssl_printf("%s ecdh peer to peer: %lu ticks, %d ms (%d) \n", ecp_name , ticks, ticks / (CLOCK_SYS_GetPitFreq(0) / 1000),CLOCK_SYS_GetPitFreq(0) );     polarssl_printf("Montogemory curve shared secutiy:\n");     mpi_printf_string( &ecdh.z, 16);     polarssl_printf( "passed\n" );     cleanup:     if( ret !=0 && verbose != 0 )         polarssl_printf( "%s test Unexpected error, return code = %08X\n", ecp_name, ret );     ecdh_free( &ecdh);     ecp_point_free( &Q_peer);     if( verbose != 0 )         polarssl_printf( "\n" );         return( 0 );    } ‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍ 4. Test result: Test result of curv25519 in  Weierstrass form with LTC:     2. Test result of curve25519 in Montgomery form with software algorithm:      We could see that the shared security both in Weierstrass form with LTC and Montgomery form are “0x1454BDCD6A94D6336AA5A76F3CB40BBE12B65A2CDC9DA6B478948906638896D1”. But the calculation speed with LTC was ten times faster than other one.
查看全文
Intro to Cortex-M0+ main features presented by Alejandro Lozano, Freescale, TIC. Intro to Cortex M0+. Kinetis L series description. Introducción al Cortex-M0+. Principales características presentadas por Alejandro Lozano, Freescale TIC. Introducción al Cortex-M0+ Descripción de la familia Kinetis L.
查看全文
Basic explanation of the ADC module. Explicación básica del modulo de ADC.
查看全文
How to byte program SPI flash via QSPI QSPI module are used in many Kinetis MCU, like K8x, K27/28 and KL8x. QSPI expands the internal flash range and can run in a fast speed. Compared to DSPI, QSPI is very complex and often takes a lot of time to learn. In KSDK there are two QSPI demo which shows how to program SPI flash in DMA mode and polling mode. Both of them program the QSPI flash with a word type array. But can the QSPI module program SPI Flash in byte? Yes, this article shows how to do it. Device: FRDM_KL82Z Tool: MCUXpresso IDE Debug firmware: JLINK I build the test project base on KL82 SDK/driver_example/qspi/polling_transfer. To byte program SPI flash, a new LUT item must be added. uint32_t lut[FSL_FEATURE_QSPI_LUT_DEPTH] =    {/* Seq0 :Quad Read */          /* CMD:       0xEB - Quad Read, Single pad */          /* ADDR:       0x18 - 24bit address, Quad pads */          /* DUMMY:     0x06 - 6 clock cyles, Quad pads */          /* READ:       0x80 - Read 128 bytes, Quad pads */        …        …        [32] = QSPI_LUT_SEQ(QSPI_CMD, QSPI_PAD_1, 0x02, QSPI_ADDR, QSPI_PAD_1, 0x18),        [13] = QSPI_LUT_SEQ(QSPI_WRITE, QSPI_PAD_1, 0x1, 0, 0, 0),        …        /* Match MISRA rule */        [63] = 0}; This item tells system how to program a single byte. Then when we write the data to TxBuffer, we must write the byte 4 times. This is because a write transaction on the flash with data size of less than 32 bits will lead to the removal of four data entry from Txbuffer. The valid bit will be used and the rest of the bits will be discard. Then before we start programming, we must set the data size.      QSPI_SetIPCommandSize(EXAMPLE_QSPI,1);   After byte program, we can see the result from 0x68000000. Attachment is the demo project. You can find that 0x03 was written to 0x68000005 after running.
查看全文
Hi Team :      Recently we are working on USB DFU , there are some experience to share with you . Best regards, David
查看全文
This document explains a potential issue where interrupts appear to be disabled after enterring debug mode. This is as a result of the NMI being active when debug is enabled.
查看全文
本文分享自China-FAE Team,谢谢同事的sharing! MQX如何自适应10/100Mbps网络          Kinetis K60 媒体接入控制器MAC(Media Access Layer)实现了数据链路层,同时支持10Mbps和100Mbps两种速率。MAC通过MII/RMII接口与PHY芯片连接。         现有的MQX4.0 RTCS协议栈在K60  Tower System Board无法支持与10Mbps交换机等网络设备通信。问题的原因是MQX4.0 BSP初始化代码macnet_init.c默认将MAC配置为100Mbps/Full Duplex模式。     MQX4.0 BSP针对TWR-SER所使用的PHY芯片(KSZ8041NL)的初始化代码没有考虑用户指定链路速率的情况,仅由PHY做默认设置。为了能够自适应链路速率,不仅需要设置KSZ8041NL的控制寄存器(0.13 Speed Select、0.8 Duplex Mode),还要设置K60的ENET_RCR/ENET_TCR寄存器。 解决办法: 修改MQX4.0 BSP代码,使能PHY芯片与网络设备端进行链路速率自动协商,然后读取PHY协议好的链路速率,通过这个链路速率设置MAC的相关寄存器ENET_RCR/ENET_TCR。MQX4.0的 PHY的接口函数已经提供了speed和duplex函数,可供MAC初始化调用,可以保证系统代码的可移植性。 测试结果: 修改后的MQX4.0 BSP代码能够自适应10/100Mbps网络,网络通信正常。
查看全文
Hi All, All training examples were tested on TWR-KM34Z75M board. We will be using the same board during the hands-on. If you have this board, please take it with you. We have in Roznov 15 pcs which will be given for use during the training. We will be using IAR Embedded Workbench for ARM. During installation, we recommend to download a 30 day eval version from IAR home page. The course license will be provided to you in Roznov prior training. Please install the following tool chains prior training: Tool description Link IAR Embedded Workbench for ARM 7.60.1 http://netstorage.iar.com/SuppDB/Protected/PRODUPD/011007/EWARM-CD-7601-11216.exe FreeMASTER 2.0 FreeMASTER 2.0 Application Installation TWR-KM34Z75M training examples Kinetis-M Bare metal drivers and examples 4.1.5
查看全文
You can put the code directory in the SDK_2.6.0_FRDM-K64F\boards\frdmk64f to use. 1、Introduction As is known to all, we use debugger to download the program or debug the device. FRDMK64 have the opsenSDA interface on the board, so wo do not need other’s debugger. But if we want to design a board without debugger but can download the program, we can use the bootloader. The bootloader is a small program designed to update the program with the interface such as UART,I2C,SPI and so on. This document will describe a simple bootloader based on the FRDMK64F.The board uses SD card to update the application. User can put the binary file into the card. When the card insert to the board ,the board will update the application automatically. The bootloader code and application code are all provided so that you can test it on your own board.   2、Bootloader’s implementation   The schematic for SD card is shown below. The board uses SDHC module to communicate with SD card.                                                  Figure 1.Schematic for SD card   We use the 2.6.0 version of FRDM-K64F’s SDK.You can download the SDK in our website. The link is “mcuxpresso.nxp.com”. The bootloader uses SDHC and fafts file system. So we should add files to support it.                   Figure 2.The support file   In main code, the program will wait until the card has inserted. Then it will find the file named “a000.bin” in sd card to update the application. If the file do not exist, the board will directly execute the application. If there is no application, the program will end. The following code shows how the program wait for inserting sd card. It will also check if the address has the application’s address.                      Figure 3.The code -- wait for inserting card   The following code shows how the program opens the binary file. If sd card doesn’t have the file, the program will go to the application. Figure 4.Open the binary file   If the program opens the file normally, the update will begin. It will erase 200k’s space from 0xa000. You can adjust it according to your project. Now I will explain update’s method in detail. Our data is written to the buffer called “rBUff”. The buffer size is 4K. Before write data to it, it is cleared.  Please note that when we erase or program the flash, we should disable all interrupts and when the operations finish we should enable the interrupts.  The file size will decide which way to write the data to flash.  1、If the size < 4k ,we just read the file’s data to buffer and judge if its size aligned with 8 byte. If not , we increase the size of “readSize” to read more data in our data buffer called “rBuffer”. The more data we read is just 0.    2、If the size > 4K, we use “remainSize” to record how much data is left. We read 4k each time until its size is smaller than 4k and then repeat step 1. When finish the operation at a  time, we should clear the buffer and increase the sector numer to prepare the next transmission. Figure 5.Write flash operation code   The way to clear the space is shown in the figure. It will initialize the flash and erase the given size from the given address.  “SectorNum” is used to show which sector to erase. Figure 6.Erase operation code   The following figure shows how to write the data to flash.              Figure 7.Program operation code    Before we go to the application, we should modify the configuration we did in the bootloader.     Close the systick, clear its value.     Set the VTOR to default value.     Our bootloader runs in PEE mode. So we should change it to FEI mode.     Disable the all pins. You should disable the global interrupt when run these codes. And don’t forget to enable the global interrupt. Figure 8.Deinitalization code   Then we can go to the application. Figure 9.Go to Application   3、Memory relocation The FRDMK64 has the 1M flash, from 0x00000000 to 0x00100000.As shown in figure 10,we use the 0xa000 as the application’s start address.            Figure 10.The memory map   Now, I will show you how to modify the link file for user application in different IDE. In IAR                                    Figure 11.IAR’s ICF In MDK Figure 12.MDK’s SCF   In MCUXpresso Figure 13.MCUXpresso’s flash configuration 4、Run the demo 1) Download the bootloader first. 2) Prepare a user application program. We use the “led blinky” as an example. 3) Modify the Link file. 4) Generate the binary file with your IDE, please name it as “a000.bin”. 5) Put it into the sd card like figure 5. Figure 14.SD card’s content        6) Insert the card. And power on. Wait for a moment, the application will execute automatically. 5、Reference 1) Kinetis MCU的bootloader解决方案 2) KEA128_can_bootloader
查看全文
20141030    Release the Alpha version by Jiunn.Yang@freescale.com         a) Support FRDM-KL25Z and TWR-K60D100M.         b) Support X-modem 256 and 1K, and test by Teraterm, http://ttssh2.sourceforge.jp/
查看全文