@@ -34,7 +34,15 @@ void flash_bgo_callback(flash_callback_args_t *p_args)
34
34
atomic_or (event_flag , FLASH_FLAG_ERASE_COMPLETE );
35
35
} else if (FLASH_EVENT_WRITE_COMPLETE == p_args -> event ) {
36
36
atomic_or (event_flag , FLASH_FLAG_WRITE_COMPLETE );
37
- } else {
37
+ }
38
+ #if defined(CONFIG_FLASH_RENESAS_RA_HP_CHECK_BEFORE_READING )
39
+ else if (FLASH_EVENT_BLANK == p_args - > event ) {
40
+ atomic_or (event_flag , FLASH_FLAG_BLANK );
41
+ } else if (FLASH_EVENT_NOT_BLANK == p_args -> event ) {
42
+ atomic_or (event_flag , FLASH_FLAG_NOT_BLANK );
43
+ }
44
+ #endif /* CONFIG_FLASH_RENESAS_RA_HP_CHECK_BEFORE_READING */
45
+ else {
38
46
atomic_or (event_flag , FLASH_FLAG_GET_ERROR );
39
47
}
40
48
}
@@ -50,9 +58,62 @@ static bool flash_ra_valid_range(struct flash_hp_ra_data *flash_data, off_t offs
50
58
return true;
51
59
}
52
60
61
+ #if defined(CONFIG_FLASH_RENESAS_RA_HP_CHECK_BEFORE_READING )
62
+ /* This feature prevents erroneous reading. Values read from an
63
+ * area of the data flash that has been erased but not programmed
64
+ * are undefined.
65
+ */
66
+ static int is_area_readable (const struct device * dev , off_t offset , size_t len )
67
+ {
68
+ struct flash_hp_ra_data * flash_data = dev -> data ;
69
+ struct flash_hp_ra_controller * dev_ctrl = flash_data -> controller ;
70
+ int ret = 0 ;
71
+ flash_result_t result = FLASH_RESULT_BGO_ACTIVE ;
72
+ fsp_err_t err ;
73
+
74
+ k_sem_take (& dev_ctrl -> ctrl_sem , K_FOREVER );
75
+
76
+ err = R_FLASH_HP_BlankCheck (& dev_ctrl -> flash_ctrl ,
77
+ (long )(flash_data -> area_address + offset ), len , & result );
78
+
79
+ if (err != FSP_SUCCESS ) {
80
+ ret = - EIO ;
81
+ goto end ;
82
+ }
83
+
84
+ /* Wait for the blank check result event if BGO is SET */
85
+ if (true == dev_ctrl -> fsp_config .data_flash_bgo ) {
86
+ while (!(dev_ctrl -> flags & (FLASH_FLAG_BLANK | FLASH_FLAG_NOT_BLANK ))) {
87
+ if (dev_ctrl -> flags & FLASH_FLAG_GET_ERROR ) {
88
+ ret = - EIO ;
89
+ atomic_and (& dev_ctrl -> flags , ~FLASH_FLAG_GET_ERROR );
90
+ break ;
91
+ }
92
+ k_sleep (K_USEC (10 ));
93
+ }
94
+ if (dev_ctrl -> flags & FLASH_FLAG_BLANK ) {
95
+ LOG_DBG ("read request on erased offset:0x%lx size:%d" ,
96
+ offset , len );
97
+ result = FLASH_RESULT_BLANK ;
98
+ }
99
+ atomic_and (& dev_ctrl -> flags , ~(FLASH_FLAG_BLANK | FLASH_FLAG_NOT_BLANK ));
100
+ }
101
+
102
+ end :
103
+ k_sem_give (& dev_ctrl -> ctrl_sem );
104
+
105
+ if (result == FLASH_RESULT_BLANK ) {
106
+ return - ENODATA ;
107
+ }
108
+
109
+ return ret ;
110
+ }
111
+ #endif /* CONFIG_FLASH_RENESAS_RA_HP_CHECK_BEFORE_READING */
112
+
53
113
static int flash_ra_read (const struct device * dev , off_t offset , void * data , size_t len )
54
114
{
55
115
struct flash_hp_ra_data * flash_data = dev -> data ;
116
+ int rc = 0 ;
56
117
57
118
if (!flash_ra_valid_range (flash_data , offset , len )) {
58
119
return - EINVAL ;
@@ -64,9 +125,23 @@ static int flash_ra_read(const struct device *dev, off_t offset, void *data, siz
64
125
65
126
LOG_DBG ("flash: read 0x%lx, len: %u" , (long )(offset + flash_data -> area_address ), len );
66
127
67
- memcpy (data , (uint8_t * )(offset + flash_data -> area_address ), len );
128
+ #if defined(CONFIG_FLASH_RENESAS_RA_HP_CHECK_BEFORE_READING )
129
+ if (flash_data -> FlashRegion == DATA_FLASH ) {
130
+ rc = is_area_readable (dev , offset , len );
131
+ }
132
+ #endif /* CONFIG_FLASH_RENESAS_RA_HP_CHECK_BEFORE_READING */
133
+
134
+ if (!rc ) {
135
+ memcpy (data , (uint8_t * )(offset + flash_data -> area_address ), len );
136
+ #if defined(CONFIG_FLASH_RENESAS_RA_HP_CHECK_BEFORE_READING )
137
+ } else if (rc == - ENODATA ) {
138
+ /* Erased area, return dummy data as an erased page. */
139
+ memset (data , 0xFF , len );
140
+ rc = 0 ;
141
+ #endif /* CONFIG_FLASH_RENESAS_RA_HP_CHECK_BEFORE_READING */
142
+ }
68
143
69
- return 0 ;
144
+ return rc ;
70
145
}
71
146
72
147
static int flash_ra_erase (const struct device * dev , off_t offset , size_t len )
0 commit comments