首页 > 其他分享 >mx25lxx驱动

mx25lxx驱动

时间:2023-12-21 10:25:34浏览次数:25  
标签:mx25lxx u8 buf mx25 len 驱动 MX25 define

  1 #ifndef _MX25LXX_H_
  2 #define _MX25LXX_H_
  3 
  4 #include "main.h"
  5 
  6 void mx25_spi_interface_init(void);
  7 uint8_t mx25_write_read_byte(uint8_t *in_buf, uint32_t in_len, uint8_t *out_buf, uint32_t out_len);
  8 /***************************************************************************/
  9 
 10 #define DUMMY_BYTE (0xA5)
 11 
 12 /*
 13 Block64 (64k Bytes)
 14 Block32 (32k Bytes)
 15 Sector  (4k Bytes)
 16 Page    (256 Bytes)
 17 
 18 so: 1*Sector = 16*Page;
 19 */
 20 #define SECTOR_SIZE (4096)
 21 #define PAGE_SIZE (256)
 22 
 23 #define Manufacturer_ID (0xC2)
 24 
 25 
 26 /***************************************************************************/
 27 
 28 /*chip command*/
 29 #define MX25_WREN (0x06)        /*Write Enable*/
 30 #define MX25_WRDI (0x04)        /*Write Disable*/
 31 #define MX25_FMEN (0x41)        /*Factory Mode Enable*/
 32 #define MX25_RDID (0x9F)        /*Read Identification*/
 33 #define MX25_RDP  (0xAB)        /*Realease from Deep Power-down*/
 34 #define MX25_REMS (0x90)        /*Read Electronic Manufacturer ID & Device ID*/
 35 #define MX25_RDSR (0x05)        /*Read Status Register*/
 36 #define MX25_RDCR (0x15)        /*Read Configuration Register*/
 37 #define MX25_WRSR (0x01)        /*Write Status Register*/
 38 #define MX25_READ (0x03)        /*Read Data Bytes (READ)*/
 39 #define MX25_FAST_READ (0x0B)   /*Read Data Bytes at Higher Speed (FAST_READ)*/
 40 #define MX25_DREAD (0x3B)       /*Dual Output Read Mode (DREAD)*/
 41 #define MX25_2READ (0xBB)       /*2 x I/O Read Mode (2READ)*/
 42 #define MX25_QREAD (0x6B)       /*Quad Read Mode (QREAD)*/
 43 #define MX25_4READ (0xEB)       /*4 x I/O Read Mode (4READ)*/
 44 #define MX25_BurstRead (0xC0)   /*Burst Read*/
 45 #define MX25_SE (0x20)          /*Sector Erase (SE)*/
 46 #define MX25_BE32K (0x52)       /*Block Erase (BE32K)*/
 47 #define MX25_BE64K (0xD8)       /*Block Erase (BE64K)*/
 48 #define MX25_CE (0xC7)          /*Chip Erase (CE)*/
 49 #define MX25_PP (0x02)          /*Page Program (PP)*/
 50 #define MX25_4PP (0x38)         /*4 x I/O Page Program (4PP)*/
 51 
 52 
 53 /*...below is rarely used command...*/
 54 #if 1
 55 #define MX25_DP (0xB9)  /*Deep Power-down (DP)*/
 56 #define MX25_ENSO (0xB1)  /*Enter Secured OTP (ENSO)*/
 57 #define MX25_EXSO (0xC1)  /*Exit Secured OTP (EXSO)*/
 58 #define MX25_RDSCUR (0x2B)  /*Read Security Register (RDSCUR)*/
 59 #define MX25_WRSCUR (0x2F)  /*Write Security Register (WRSCUR)*/
 60 #define MX25_WPSEL (0x68)  /*Write Protection Selection (WPSEL)*/
 61 //#define MX25_XX (0xXX)  /*Advanced Sector Protection*/
 62 #define MX25_RDLR (0x2D)  /*Read Lock Register (RDLR)*/
 63 #define MX25_WRLR (0x2C)  /*Write Lock Register (WRLR)*/
 64 #define MX25_RDSPB (0xE2)  /*Read SPB Status (RDSPB)*/
 65 #define MX25_ESSPB (0xE4)  /*SPB Erase (ESSPB)*/
 66 #define MX25_WRSPB (0xE3)  /*SPB Program (WRSPB)*/
 67 #define MX25_RDDPB (0xE0)  /*Read DPB Register (RDDPB)*/
 68 #define MX25_WRDPB (0xE1)  /*Write DPB Register (WRDPB)*/
 69 #define MX25_GBLK (0x7E)  /*Gang Block Lock (GBLK)*/
 70 #define MX25_GBULK (0x98)  /*Gang Block Unlock (GBULK)*/
 71 //#define MX25_Suspend (0xXX)  /*Program/Erase Suspend*/
 72 //#define MX25_Resume (0xXX)  /*Program/Erase Resume*/
 73 #define MX25_NOP (0x00)  /*No Operation*/
 74 #endif
 75 
 76 /***************************************************************************/
 77 typedef union
 78 {
 79     struct
 80     {
 81         u8 WIP: 1;
 82         u8 WEL: 1;
 83         u8 BP0: 1;
 84         u8 BP1: 1;
 85 
 86         u8 BP2: 1;
 87         u8 BP3: 1;
 88         u8 QE: 1;
 89         u8 SRWD: 1;
 90     } bits;
 91     u8 byte;
 92 } MX25_StatusRegister_u;
 93 typedef union
 94 {
 95     struct
 96     {
 97         u8 OTP: 1;
 98         u8 LDSO: 1;
 99         u8 PSB: 1;
100         u8 ESB: 1;
101 
102         u8 RES: 1;
103         u8 P_FAIL: 1;
104         u8 E_FAIL: 1;
105         u8 WPSEL: 1;
106     } bits;
107     u8 byte;
108 } MX25_SecurityRegister_u;
109 
110 
111 void mx25_WriteEn(void);
112 void mx25_WriteDis(void);
113 void mx25_ReadID(u8* ManufacturerId, u16* DeviceId);
114 void mx25_REMS(u8* ManufacturerId, u8* DeviceId);
115 u8 mx25_ReadStatusRegister(void);
116 void mx25_ReadBytes(u32 address, u8* out_buf, u32 out_len);
117 u8 mx25_Erase(u32 address, u8 cmd);
118 u8 mx25_PageProgram(u32 address, u8* buf, u16 len);
119 u8 mx25_WriteBytes(u32 address, u8* buf, u32 len);
120 
121 #endif
  1 /*
  2 file:mx25lxx.c
  3 auth:ycp
  4 date:2023.12.05
  5 */
  6 
  7 #include "mx25lxx.h"
  8 #include "user_spi.h"
  9 
 10 void mx25_delay_1ms(u32 n)
 11 {
 12     rt_thread_mdelay(n);
 13 }
 14 
 15 void mx25_spi_interface_init(void)
 16 {
 17     user_spi_init();
 18 }
 19 uint8_t mx25_write_read_byte(uint8_t *in_buf, uint32_t in_len, uint8_t *out_buf, uint32_t out_len)
 20 {
 21     if(in_buf == NULL)return 1;
 22     return spi_bytes_write_read( in_buf,  in_len,  out_buf,  out_len);
 23 }
 24 /***************************************************************************/
 25 
 26 void mx25_WriteEn(void)
 27 {
 28     u8 in_buf[10];
 29     in_buf[0] = MX25_WREN;
 30     mx25_write_read_byte(in_buf, 1, 0, 0);
 31     return;
 32 }
 33 void mx25_WriteDis(void)
 34 {
 35     u8 in_buf[10];
 36     in_buf[0] = MX25_WRDI;
 37     mx25_write_read_byte(in_buf, 1, 0, 0);
 38     return;
 39 }
 40 
 41 void mx25_ReadID(u8* ManufacturerId, u16* DeviceId)
 42 {
 43     u8 out_buf[10];
 44     u8 in_buf[10];
 45     in_buf[0] = MX25_RDID;
 46     in_buf[1] = DUMMY_BYTE;
 47     in_buf[2] = DUMMY_BYTE;
 48     in_buf[3] = DUMMY_BYTE;
 49     mx25_write_read_byte(in_buf, 4, out_buf, 4);
 50     *ManufacturerId = out_buf[1];
 51     *DeviceId = out_buf[2] << 8 | out_buf[3] << 0;
 52     //SYSTEM_DEBUG("ManufacturerId=%02X,DeviceId=%04X\n",*ManufacturerId,*DeviceId);
 53     return;
 54 }
 55 
 56 void mx25_REMS(u8* ManufacturerId, u8* DeviceId)
 57 {
 58     u8 out_buf[10];
 59     u8 in_buf[10];
 60     in_buf[0] = MX25_REMS;
 61     in_buf[1] = DUMMY_BYTE;
 62     in_buf[2] = DUMMY_BYTE;
 63     in_buf[3] = 0x00;
 64     in_buf[4] = DUMMY_BYTE;
 65     in_buf[5] = DUMMY_BYTE;
 66     mx25_write_read_byte(in_buf, 6, out_buf, 6);
 67     *ManufacturerId = out_buf[4];
 68     *DeviceId = out_buf[5];
 69     SYSTEM_DEBUG("ManufacturerId=%02X,DeviceId=%02X\n", *ManufacturerId, *DeviceId);
 70     return;
 71 }
 72 
 73 u8 mx25_ReadStatusRegister(void)
 74 {
 75     u8 out_buf[10];
 76     u8 in_buf[10];
 77     in_buf[0] = MX25_RDSR;
 78     in_buf[1] = DUMMY_BYTE;
 79     in_buf[2] = DUMMY_BYTE;
 80     mx25_write_read_byte(in_buf, 2, out_buf, 2);
 81     //SYSTEM_DEBUG("out[1]=%02X,out[2]=%02X\n", out_buf[1], out_buf[2]);
 82     return out_buf[1];
 83 }
 84 
 85 u8 mx25_ReadSecurityRegRegister(void)
 86 {
 87     u8 out_buf[10];
 88     u8 in_buf[10];
 89     in_buf[0] = MX25_RDSCUR;
 90     in_buf[1] = DUMMY_BYTE;
 91     in_buf[2] = DUMMY_BYTE;
 92     mx25_write_read_byte(in_buf, 2, out_buf, 2);
 93     //SYSTEM_DEBUG("out[1]=%02X,out[2]=%02X\n", out_buf[1], out_buf[2]);
 94     return out_buf[1];
 95 }
 96 
 97 /*
 98     address:
 99         any positoin.
100 */
101 void mx25_ReadBytes(u32 address, u8* out_buf, u32 out_len)
102 {
103     u8 remain_4byte[16];
104     u8 in_buf[10];
105     in_buf[0] = MX25_READ;
106     in_buf[1] = address >> 16;
107     in_buf[2] = address >> 8;
108     in_buf[3] = address >> 0;
109     if(out_len > 4)
110     {
111         mx25_write_read_byte(in_buf, 4, out_buf, out_len);
112         memmove(&out_buf[0], &out_buf[4], out_len - 4);
113 
114         //get the remain  bytes.
115         address += (out_len - 4);
116         in_buf[0] = MX25_READ;
117         in_buf[1] = address >> 16;
118         in_buf[2] = address >> 8;
119         in_buf[3] = address >> 0;
120         mx25_write_read_byte(in_buf, 4, remain_4byte, 8);
121         memcpy(&out_buf[out_len - 4], &remain_4byte[4], 4);
122     }
123     else
124     {
125         mx25_write_read_byte(in_buf, 4, remain_4byte, 4 + out_len);
126         memcpy(out_buf, &remain_4byte[4], out_len);
127 
128     }
129     //print_hex(__FUNCTION__, out_buf, out_len);
130     return ;
131 }
132 
133 /*
134 address:
135     Should 4kbytes align
136 
137 cmd:
138     0:Sector Erase(4k)
139     1:Block Erase(32k)
140     2:Block Erase(64k)
141     3:Chip Erase
142 */
143 u8 mx25_Erase(u32 address, u8 cmd)
144 {
145     cmd &= 0x03;
146     u32 timeout_ms[4] = {4000, 4000 * 8, 4000 * 16, 4000 * 100};
147     u8 command[4] = {MX25_SE, MX25_BE32K, MX25_BE64K, MX25_CE};
148     u8 in_buf[10];
149     MX25_StatusRegister_u SR;
150     MX25_SecurityRegister_u SecurityReg;
151     u32 ms = 0;
152 
153     mx25_WriteEn();
154     SR.byte = mx25_ReadStatusRegister();
155 
156     if(SR.bits.WEL == 0)return 1;
157     address &= 0xFFF000;
158     in_buf[0] = command[cmd];
159     in_buf[1] = address >> 16;
160     in_buf[2] = address >> 8;
161     in_buf[3] = address >> 0;
162     if(cmd == 3)
163     {
164         mx25_write_read_byte(in_buf, 1, 0, 0);
165     }
166     else
167     {
168         mx25_write_read_byte(in_buf, 4, 0, 0);
169     }
170 
171     ms = timeout_ms[cmd];
172     while(ms)
173     {
174         SR.byte = mx25_ReadStatusRegister();
175         if(SR.bits.WIP == 0)break;
176         mx25_delay_1ms(1);
177         if(ms)ms--;
178     }
179     SR.byte = mx25_ReadStatusRegister();
180     //SYSTEM_DEBUG("ms=%d,timeout_ms=%d,WEL=%d\n", ms, timeout_ms[cmd] - ms, SR.bits.WEL);
181     if((ms == 0) && (SR.bits.WEL))return 2;
182     SecurityReg.byte = mx25_ReadSecurityRegRegister();
183     if(SecurityReg.bits.E_FAIL)return 3;
184     SYSTEM_DEBUG("address=%08X Erase ok\n", address);
185 
186     return 0;
187 }
188 
189 /*1Page=256Bytes*/
190 u8 mx25_PageProgram(u32 address, u8* buf, u16 len)
191 {
192     u8 in_buf[300];
193     MX25_StatusRegister_u SR;
194     MX25_SecurityRegister_u SecurityReg;
195     u32 ms = 0;
196     mx25_WriteEn();
197     SR.byte = mx25_ReadStatusRegister();
198     if(SR.bits.WEL == 0)return 1;
199     address &= 0xFFFF00;
200 
201     memset(in_buf, 0xFF, sizeof(in_buf));
202     in_buf[0] = MX25_PP;
203     in_buf[1] = address >> 16;
204     in_buf[2] = address >> 8;
205     in_buf[3] = address >> 0;
206     memcpy(&in_buf[4], buf, len);
207 
208     mx25_write_read_byte(in_buf, 4 + 256, 0, 0);
209 
210     ms = 2000;
211     while(ms)
212     {
213         SR.byte = mx25_ReadStatusRegister();
214         if(SR.bits.WIP == 0)break;
215         mx25_delay_1ms(1);
216         if(ms)ms--;
217     }
218     SR.byte = mx25_ReadStatusRegister();
219     //SYSTEM_DEBUG("ms=%d,timeout_ms=%d,WEL=%d\n", ms, 2000 - ms, SR.bits.WEL);
220     if((ms == 0) && (SR.bits.WEL))return 2;
221     SecurityReg.byte = mx25_ReadSecurityRegRegister();
222     if(SecurityReg.bits.E_FAIL)return 3;
223     //SYSTEM_DEBUG("address=%08X len=%d PP ok\n", address, len);
224 
225     return 0;
226 }
227 /*
228 address:
229     Should 4kbytes align
230 
231 */
232 u8 mx25_WriteBytes(u32 address, u8* buf, u32 len)
233 {
234     u16 w_len = 0;
235     u8 i = 0;
236     address &= 0xFFF000;
237     //print_hex("-->",buf,len);
238     SYSTEM_DEBUG("address=%08X len=%d\n", address, len);
239 
240     while(len)
241     {
242         if(mx25_Erase(address, 0))return 1;
243         for(i = 0; i < (SECTOR_SIZE / PAGE_SIZE); i++)
244         {
245             w_len = (len >= PAGE_SIZE) ? PAGE_SIZE : len;
246             if(w_len == 0)break;
247             if(mx25_PageProgram(address + i * PAGE_SIZE, buf + i * PAGE_SIZE, w_len))return 2;
248             if(len >= PAGE_SIZE)
249             {
250                 len -= PAGE_SIZE;
251                 if(len == 0)break;
252             }
253             else
254             {
255                 len = 0;
256                 break;
257             }
258         }
259         if(len == 0)break;
260         address += SECTOR_SIZE;
261     }
262 
263     SYSTEM_DEBUG("WR ok\n");
264     return 0;
265 }

 

标签:mx25lxx,u8,buf,mx25,len,驱动,MX25,define
From: https://www.cnblogs.com/ycpkbql/p/17918381.html

相关文章

  • 网络驱动简单认识
    网络驱动     网络驱动是指在计算机系统中,用于控制和处理网络硬件设备的软件模块。它位于操作系统内核中,负责实现网络协议、处理数据包以及与网络设备进行通信。网络驱动的作用是将操作系统与网络设备之间的原始硬件操作进行抽象,以便于上层应用程序能够方便地使用网络功......
  • 世微 AP5219 平均电流型LED 降压恒流驱动器 兼容LN2516/LN2517
    产品描述AP5219是一款PWM工作模式,内置功率管,适用于5V~100V输入的高精度降压LED恒流驱动芯片。输出功率可达25W,电流2.5A。AP5219可实现全亮/半亮功能切换,通过MODE切换:全亮/半亮模式。AP5219工作频率固定在130KHZ,同时内置抖频电路,可以降低对其他设备的EMI干扰。另......
  • 实时湖仓技术选型,企业如何借实时湖仓赢在“数据驱动”时代
    在之前三期的实时湖仓系列文章中,我们从业务侧、产品侧、应用侧等几个方向,为大家介绍了实时湖仓方方面面的内容,包括实时湖仓对于企业数字化布局的重要性以及如何进行实时湖仓的落地实践等。本文将从纯技术的角度,为大家解析实时湖仓的存储原理以及生态选型,为企业建设实时湖仓给出技术......
  • 数智驱动未来,卧龙电驱构建端到端敏捷供应链!
    近日,电机板块位列国内第一的卧龙电气驱动集团股份有限公司(以下简称“卧龙电驱”)携手用友BIP采购云打造的数字化采购管理平台平稳落地。基于该平台,卧龙电驱将重塑整个供应链采购体系,以数智化提升企业采购的整体效率,打造卧龙特色的端到端供应链管理体系。卧龙电驱创建于1984年,是全球......
  • 实时湖仓技术选型,企业如何借实时湖仓赢在“数据驱动”时代
    在之前三期的实时湖仓系列文章中,我们从业务侧、产品侧、应用侧等几个方向,为大家介绍了实时湖仓方方面面的内容,包括实时湖仓对于企业数字化布局的重要性以及如何进行实时湖仓的落地实践等。本文将从纯技术的角度,为大家解析实时湖仓的存储原理以及生态选型,为企业建设实时湖仓给出技......
  • 字符驱动框架
    HelloWorld/*字符驱动框架*///*****************相关的头文件和宏定义*******************#include<linux/kernel.h>#include<linux/module.h>#include<linux/fs.h>#include<linux/device.h>#include<linux/version.h>#defineCLASS_NAME"......
  • STM32驱动步进电机
    一、步进电机的介绍17HS4401步进电机是一种步进电机,也称为双级四相混合式步进电机。它是一种旋转电机,可以控制旋转角度和速度,17HS4401步进电机通常被应用于一些需要精准控制转动的场合,例如打印机、CNC机床等。参数:1.步距角度:1.8度2.驱动方式:双级四相混合式3.工作电压:12V4.......
  • 世微 APS54085 22W高辉度调光降压恒流芯片 LED驱动IC
    产品描述       APS54085是一款PWM工作模式,简单、内置功率MOS管,适用于5-100V输入的高精度降压LED恒流驱动芯片。电流2.0A。APS54085可实现线性调光和PWM调光,线性调光有效电压范围0.52-2.55V.PWM调光频率范围100HZ-30KHZ。APS54085工作频率可以通过......
  • IT发展趋势:数字化时代的技术驱动力
    摘要:随着技术的不断进步和创新,信息技术(IT)领域在当今数字化时代变得越发重要。本文将探讨当前IT行业的发展趋势,包括人工智能(AI)、大数据、云计算、物联网(IoT)和区块链等关键技术,并讨论它们对各行各业的影响以及未来的发展前景。引言:在信息爆炸和数字化转型的背景下,IT技术正逐渐成为......
  • 国产显卡如何正确打开 —— Windows平台下使用驱动精灵为国产显卡更新驱动(兆芯平台)
    买了一个国产的电脑,全国产,CPU慢些也就忍了,软件兼容性差、稳定性差也忍了,大不了就用来上网看电影嘛,关键问题是这个国产显卡放电影居然有些卡,播放电影的时候存在明显的卡顿感,这简直是把国产电脑在我脑海中唯一的用处也给堵上了。最近想着用用Windows的11代操作系统,尝尝鲜,但是手上没......